Generated reference › API — ICoreEssentials/UI/Backends/Web/Painting
kind: generated#api#icoreessentials-ui-backends-web-painting

API — ICoreEssentials/UI/Backends/Web/Painting

The public contract of 5 header(s) under ICoreEssentials/UI/Backends/Web/Painting — 9 class/struct definition(s), 21 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

ICoreWebCanvas.h#

ICoreEssentials/UI/Backends/Web/Painting/ICoreWebCanvas.h

The web backend's one bridge to Canvas2D. Every other file in this zone calls these functions; only ICoreWebCanvas.cpp writes JavaScript.

⚠ A CANVAS IS AN INTEGER, NOT A POINTER. A JavaScript object cannot live in WebAssembly linear memory, so the bridge keeps a table on the JS side and hands out small positive integers into it; 0 is "no canvas". The table holds both kinds of surface: an OffscreenCanvas this side created (a pixmap, a scratch surface) and a page <canvas> element that the window seat registers from JavaScript. Drawing does not care which.

⚠ A HANDLE IS VALID ON THE THREAD THAT MADE IT AND NO OTHER. The table is a property of one JavaScript realm, and a pthread is a Web Worker with its own. The UI tier is main-thread-only on every backend, so this restates that rule rather than adding one -- but a pixmap made on a worker is a null pixmap on

ICoreWebTextBox#

ICoreWebCanvas.h:101 · struct · 1 declaration(s)

Measurement, on one shared scratch context -- no surface needed.

struct ICoreWebTextBox {
public:
    double advance = 0.0;       // measureText().width
    double inkLeft = 0.0;       // actualBoundingBoxLeft (positive = left of origin)
    double inkRight = 0.0;      // actualBoundingBoxRight
    double inkAscent = 0.0;     // actualBoundingBoxAscent
    double inkDescent = 0.0;    // actualBoundingBoxDescent
};
};

File-scope declarations#

// The path buffer: a flat run of doubles, each op followed by its operands.
enum ICoreWebCanvasPathOp : int {
    kIcoreWebMoveTo = 0,    // x y
    kIcoreWebLineTo = 1,    // x y
    kIcoreWebCubicTo = 2,   // c1x c1y c2x c2y x y
    kIcoreWebClose = 3,     //
};

ICoreWebPaintAccess.h#

ICoreEssentials/UI/Backends/Web/Painting/ICoreWebPaintAccess.h

The web backend's copy of UI/Backends/Gtk4/Painting/ICoreGtk4PaintAccess.h.

⚠ THIS FILE NAMES NO TOOLKIT, AND IT IS THE GTK4 SEAT'S CODE WITH THE BACKEND NAME CHANGED. The reasoning behind every line -- the measurements, the traps, the value semantics -- is in the comments of that file, and is not repeated here (one fact, one place). A change to the shared behaviour belongs in BOTH copies; the web and GTK4 value tiers are expected to agree to the bit.

ICoreWebPaintStop#

ICoreWebPaintAccess.h:18 · struct · 0 declaration(s)

struct ICoreWebPaintStop {
public:
    double position = 0.0;              // 0..1
    ICoreColor color;
};
};

ICoreWebBrushSpec#

ICoreWebPaintAccess.h:30 · struct · 0 declaration(s)

struct ICoreWebBrushSpec {
public:
    ICoreWebBrushKind kind = ICoreWebBrushKind::None;

    ICoreColor color;                   // Solid

    double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0;

    double centerX = 0.0, centerY = 0.0, radius = 0.0;

    std::vector<ICoreWebPaintStop> stops;
};
};

ICoreWebPenSpec#

ICoreWebPaintAccess.h:42 · struct · 0 declaration(s)

struct ICoreWebPenSpec {
public:
    ICoreWebBrushSpec brush;
    double width = 0.0;
    ICorePenStyle style = ICorePenStyle::Solid;
    ICorePenCap cap = ICorePenCap::Square;
    ICorePenJoin join = ICorePenJoin::Bevel;
    bool cosmetic = false;
};
};

File-scope declarations#

enum class ICoreWebBrushKind {
    None = 0,
    Solid = 1,
    LinearGradient = 2,
    RadialGradient = 3,
};

ICoreWebPathAccess.h#

ICoreEssentials/UI/Backends/Web/Painting/ICoreWebPathAccess.h

The web backend's copy of UI/Backends/Gtk4/Painting/ICoreGtk4PathAccess.h.

⚠ THIS FILE NAMES NO TOOLKIT, AND IT IS THE GTK4 SEAT'S CODE WITH THE BACKEND NAME CHANGED. The reasoning behind every line -- the measurements, the traps, the value semantics -- is in the comments of that file, and is not repeated here (one fact, one place). A change to the shared behaviour belongs in BOTH copies; the web and GTK4 value tiers are expected to agree to the bit.

ICoreWebPathNode#

ICoreWebPathAccess.h:27 · struct · 0 declaration(s)

struct ICoreWebPathNode {
public:
    ICoreWebPathOp op = ICoreWebPathOp::Built;

    std::vector<ICorePathBuilderElement> elements;

    int fillRule = 1;   // matches ICoreFillRule: 0 NonZero, 1 EvenOdd

    ICoreWebPathRef operandA;
    ICoreWebPathRef operandB;

    double strokeWidth = 0.0;
};
};

File-scope declarations#

enum class ICoreWebPathOp {
    Built = 0,          // the element list is the whole answer
    Union = 1,          // operandA ∪ operandB
    StrokedRound = 2,   // the outline of operandA stroked `strokeWidth` across
};

using ICoreWebPathRef = std::shared_ptr<const ICoreWebPathNode>;

ICoreWebRichText.h#

ICoreEssentials/UI/Backends/Web/Painting/ICoreWebRichText.h

The web backend's reader for the HTML subset ICorePainter::drawRichText takes, and its line layout.

⚠ A THIRD READER, AND THIS TIME IT HAS TO LAY OUT AS WELL AS PARSE. The GTK4 reader (UI/Backends/Gtk4/Painting/ICoreGtk4RichText.h) turns the ten tags into Pango markup and lets Pango break the lines. Canvas2D draws one run on one baseline and knows nothing about paragraphs, so this one produces styled RUNS and breaks them into lines itself, measuring every token with the same measurer the painter draws by. The grammar -- which tags, what a paragraph break is, how whitespace collapses, which entities -- is the GTK4 reader's, so the two backends agree on what a description says.

⚠ ONE LAYOUT, TWO READERS OF IT. drawRichText and icoreRichTextSize both call icoreWebRichTextLayout; neither computes a height of its own, so the two

ICoreWebRichRun#

ICoreWebRichText.h:29 · struct · 1 declaration(s)

struct ICoreWebRichRun {
public:
    std::string text;
    ICoreWebFontFace face;
    double x = 0.0;         // from the line's left edge
    double rise = 0.0;      // px ABOVE the line's baseline (sup > 0, sub < 0)
    double width = 0.0;
};
};

ICoreWebRichLine#

ICoreWebRichText.h:37 · struct · 0 declaration(s)

struct ICoreWebRichLine {
public:
    std::vector<ICoreWebRichRun> runs;
    double width = 0.0;
    double ascent = 0.0;    // above the baseline, including any raised run
    double descent = 0.0;
};
};

ICoreWebRichLayout#

ICoreWebRichText.h:44 · struct · 0 declaration(s)

struct ICoreWebRichLayout {
public:
    std::vector<ICoreWebRichLine> lines;
    double width = 0.0;     // the widest line
    double height = 0.0;    // the sum of line heights
};
};

ICoreWebTextSelection.h#

ICoreEssentials/UI/Backends/Web/Painting/ICoreWebTextSelection.h

ICoreWebTextSelection#

ICoreWebTextSelection.h:28 · class · pImpl · 19 declaration(s)

Mouse and keyboard selection over painted rich text (web backend, WB5.3) -- the peer of ../../Gtk4/Painting/ICoreGtk4TextSelection.h, over ICoreWebRichLayout where that one walks a PangoLayout.

class ICoreWebTextSelection {
public:
    ICoreWebTextSelection();
    ~ICoreWebTextSelection();
    ICoreWebTextSelection(const ICoreWebTextSelection&) = delete;
    ICoreWebTextSelection& operator=(const ICoreWebTextSelection&) = delete;

    void setLayoutProvider(std::function<ICoreWebRichLayout()> provider);
    // Where the layout's top-left is, in the host's coordinates (scroll included).
    void setOrigin(double x, double y);

    void setEnabled(bool enabled);
    [[nodiscard]] bool isEnabled() const;

    [[nodiscard]] std::vector<ICoreRect> bands();
    [[nodiscard]] bool hasSelection() const;

    bool press(double x, double y);
    bool drag(double x, double y);
    void release();
    [[nodiscard]] bool isDragging() const;
    // 2 = the word under the pointer, 3 = its line.
    bool multiClick(double x, double y, int pressCount);
    void selectAll();
    void clearSelection();

    // UTF-8; lines joined by '\n'.
    [[nodiscard]] std::string selectedText() const;

    // Ctrl/Cmd+A selects all, Ctrl/Cmd+C copies (to ICoreClipboard). Returns
    // whether the key was taken.
    bool keyPressed(int icoreKey, unsigned int modifiers);

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};