API — ICoreEssentials/Geometry
The public contract of 2 header(s) under ICoreEssentials/Geometry — 2 class/struct definition(s), 34 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICorePoint.h | ICorePoint | 16 | — |
ICoreRect.h | ICoreRect | 18 | — |
ICorePoint.h#
ICoreEssentials/Geometry/ICorePoint.h
⚠ FORWARD-DECLARED, NOT INCLUDED (A9.3, on A1.8's template). Both uses need only an incomplete type -- a reference parameter and a return-by-value in a DECLARATION -- so this header can stop carrying two Qt headers into every translation unit that reaches a model coordinate, while the DECLARATIONS stay byte-identical on every backend. That last part is the load-bearing half: §0.48's lesson is that a switch which changes what a header DECLARES compiles against one backend and links against the other.
The definitions live in Geometry/QtSeam/ICorePoint.cpp [deleted], which compiles whenever Qt is in the build AT ALL -- either switch (A9.1).
⚠ THAT PATH WAS
Geometry/Backends/Qt/FOR HALF A DAY AND IT WAS THE WRONG DIRECTORY, in a way that broke the one configuration the core switch exists for. ABackends/<Name>/directory answers "which IMPLEMENTATION compiles",
ICorePoint#
ICorePoint.h:157 · class · 16 declaration(s)
ICorePoint -- a coordinate in the MODEL, not on a screen.
class ICorePoint {
public:
// ⚠ THE STORAGE IS AN OPAQUE BUFFER (H1.9, 2026-08-14) holding two plain
// doubles this project owns -- there is no Qt type inside, and never was
// since B28. 16 bytes / align 8.
//
// Like ICoreChar, this type declares NONE of the five special members and
// stays TRIVIALLY COPYABLE: the state is two doubles, so the implicit copy
// is a 16-byte memcpy and it is correct. That is load-bearing rather than
// tidy. A point is passed and returned BY VALUE at 146 call sites and in
// every arithmetic operator below; a user-declared copy constructor would
// stop it travelling in registers at all of them, which is exactly the cost
// this rollout is not supposed to add to a 16-byte value.
//
// The .cpp static_asserts the size, the alignment and both trivialities, so
// a future change that breaks the assumption is a build error.
static constexpr std::size_t kNativeStorageSize = 16;
static constexpr std::size_t kNativeStorageAlign = 8;
// Default-constructs to (0, 0), matching QPointF. Several call sites rely
// on it -- `const ICorePoint& offset = ICorePoint()` is the "no offset"
// default of ICoreRecipeFileTransfer::importRecipeText and of
// ICoreTemplateLibrary::instantiate.
//
// ⚠ NOT `= default` any more: a defaulted default constructor would leave
// the buffer uninitialised, where the two members it replaced carried
// `= 0.0` initialisers. That would turn "no offset" into garbage.
ICorePoint();
ICorePoint(double x, double y);
double x() const noexcept;
double y() const noexcept;
void setX(double x) noexcept;
void setY(double y) noexcept;
// EXACT, matching qIsNull -- see the second warning in the header note.
bool isNull() const noexcept;
// Arithmetic as members -- see the design note. The right operand accepts a
// QPointF too, through the implicit constructor above, which is what lets a
// migrated expression mix with an unmigrated screen-side getter without a
// cast: `offset + anchor->pos()`.
ICorePoint operator+(const ICorePoint& o) const;
ICorePoint operator-(const ICorePoint& o) const;
ICorePoint operator*(double f) const;
// The assert is QPointF::operator/'s own precondition (qpoint.h:215,
// Q_ASSERT(!qFuzzyIsNull(c))), kept rather than quietly dropped: this is a
// Debug build, so removing it would turn a diagnosed division by zero into
// a silent infinity -- a behaviour change smuggled in under a storage swap.
ICorePoint operator/(double d) const;
ICorePoint operator-() const;
ICorePoint& operator+=(const ICorePoint& o);
ICorePoint& operator-=(const ICorePoint& o);
// FUZZY, reproducing QPointF exactly -- see the header note. Do not
// "simplify" these to == ; the differential test will fail, which is what
// it is for.
bool operator==(const ICorePoint& o) const noexcept;
bool operator!=(const ICorePoint& o) const noexcept;
// Named accessor, NOT a conversion operator -- see the design note. Every
// use of it is a model coordinate crossing to the screen side, and it is
// meant to be visible.
//
// Returns BY VALUE now; it used to return `const QPointF&` into the member,
// and that reference is precisely what a storage swap cannot honour. All 20
// call sites were audited first and every one consumes the result
// immediately as a function argument (offsetPosition, optimizePath,
// translateBranch, addCornerAtEnd, push_back, mapToGlobal), so none was
// binding it to a stored reference. A QPointF is 16 bytes, so the copy is
// free; the audit, not the size, is what made this safe.
//
// ⚠ AND FIVE OF THE SINKS THAT AUDIT NAMES NO LONGER TAKE A QPointF AT ALL
// (A9.3, 2026-08-21). offsetPosition, optimizePath, translateBranch and
// addCornerAtEnd were migrated to `ICorePoint` by later PIMPL_CONVERSION
// batches and NOBODY REMOVED THE CONVERSIONS, so 23 call sites in
// src/ICoreSDK spent a round trip turning an ICorePoint into a QPointF and
// straight back through the implicit constructor above. They are gone.
// ⚠ The lesson is about the audit, not the sites: this comment was correct
// when written and became a list of reasons to keep something that no
// longer had them. It took a compile error to notice, because a round trip
// through two correct conversions computes the right answer.
//
// What is left is 20 call sites in UI/Backends/Qt/ -- the wrapper zone,
// where handing a point to Qt is the job -- and two in ICoreCanvas.cpp
// whose sinks really are Qt-typed.
};
ICoreRect.h#
ICoreEssentials/Geometry/ICoreRect.h
⚠ A GUARDED
#include <QRectF>STOOD HERE (2026-09-10 main merge) ANDLQ.14DELETED IT ON 2026-09-17, with the two members below it.
ICoreRect#
ICoreRect.h:86 · class · 18 declaration(s)
ICoreRect -- an axis-aligned area in the MODEL, not on a screen.
class ICoreRect {
public:
// ⚠ THE STORAGE IS AN OPAQUE BUFFER (H1.8, 2026-08-14) holding four plain
// doubles this project owns -- no Qt type is inside, and none has been
// since B28. 32 bytes / align 8.
//
// As with ICorePoint, this type declares NONE of the five special members
// and stays TRIVIALLY COPYABLE, because the state is four doubles and the
// implicit copy is a correct 32-byte memcpy. The .cpp static_asserts the
// size, the alignment and both trivialities.
static constexpr std::size_t kNativeStorageSize = 32;
static constexpr std::size_t kNativeStorageAlign = 8;
// Default-constructs to a null rect, matching QRectF.
//
// ⚠ NOT `= default`: that would leave the buffer uninitialised, where the
// four members it replaced carried `= 0.0` initialisers.
ICoreRect();
ICoreRect(double x, double y, double w, double h);
// QRectF's edge convention, NOT QRect's: right() is x + width, with no
// -1 anywhere (qrect.h:524). Getting this wrong is the classic QRect/QRectF
// confusion and would move every edge by one unit.
double left() const noexcept;
double right() const noexcept;
double top() const noexcept;
double bottom() const noexcept;
double width() const noexcept;
double height() const noexcept;
// ===========================================================================
// ⚠⚠ TEMPORARY Qt COMPATIBILITY SEAM -- ADDED BY THE 2026-09-10 main MERGE.
//
// EVERYTHING BELOW IS SCHEDULED FOR DELETION. It exists because main is the
// tested release and its Qt code is written against the wrapper contract this
// class USED to have: implicit conversion to and from the toolkit type. ui-swap
// removed that contract (A9.5/A9.6 moved it to QtSeam/, LQ.4 deleted QtSeam/),
// and the merge brought main's callers back. Restoring the conversion here was
// the owner's ruling: take main's functionality now, swap the Qt later.
//
// ⚠ THIS BREAKS R2 ON PURPOSE AND THE CENSUS WILL SAY SO. That is the honest
// reading -- this header names Qt again. Do not silence the row; it is
// measuring a real, deliberate, temporary regression.
//
// ⚠ DO NOT BUILD ON IT. No NEW caller may use these. Every use is one more
// thing the swap has to unpick, and the guard below is what makes the
// deletion mechanical: when the last caller is gone, delete the block.
//
// Owned by: W10.31 (Windows), A10.8 (Apple), L9.62 (Linux) -- and LQ.14 is the
// row that removes the seam itself once all three are closed.
// ===========================================================================
// ⚠ THE SEAM'S TWO MEMBERS STOOD HERE -- `ICoreRect(const QRectF&)` and
// `operator QRectF()`, restored by the 2026-09-10 main merge and deleted by
// `LQ.14` on 2026-09-17. `Geometry/QtSeam/ICoreGeometryQt.h [deleted, LQ.13]` has the free
// functions.
ICorePoint topLeft() const;
ICorePoint bottomLeft() const;
ICorePoint topRight() const;
ICorePoint bottomRight() const;
ICorePoint center() const;
// QRectF::contains, reproduced: edge-INCLUSIVE, and false for any rect with
// a zero extent in either axis even when the point sits exactly on it. The
// negative-extent handling is why this is not simply four comparisons -- a
// rect built by a drag up-and-left has negative width until it is
// normalized(), and it still has to contain the points it visually covers.
bool contains(const ICorePoint& p) const noexcept;
// EXACT, like ICorePoint::isNull and unlike ICorePoint::operator==
// (qrect.h:686). A rect is null when BOTH extents are zero -- note that
// this is not isEmpty(), which Qt defines as either extent <= 0 and which
// has no call site here.
bool isNull() const noexcept;
// The two transforms that genuinely produce a new area. normalized() is
// what a drag rectangle needs (the user may drag up and left); adjusted()
// is the snap threshold around a tab bar.
ICoreRect normalized() const;
// qrect.h:841 -- note the width term is w + x2 - x1, not w + x2.
ICoreRect adjusted(double dx1, double dy1, double dx2, double dy2) const;
ICoreRect translated(const ICorePoint& offset) const;
// NOTHING CONVERTS OUT. ICorePoint keeps a toQPointF() because 20 call
// sites hand a point to an StudioObjects-declared sink; a rect never
// crosses that boundary, so the accessor this file used to carry had no
// caller at all and was deleted (Rule 3). That is what made B28's swap
// free of call-site risk on this half: the Qt member was reachable
// from nowhere outside the class, so replacing it changed no signature.
};