Generated reference › API — ICoreEssentials/Geometry
kind: generated#api#icoreessentials-geometry

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.

HeaderDefinesDeclarationsBases
ICorePoint.hICorePoint16—
ICoreRect.hICoreRect18—

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. A Backends/<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) AND LQ.14 DELETED 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.

};