Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
e2fada8
Resolve abspos baseline fallback against the containing grid
skyturkish Sep 25, 2026
b87178a
Saturate position offsets instead of truncating them to int16
skyturkish Sep 25, 2026
776d325
Use the baseline fallback when flex baselines run along the cross axis
skyturkish Sep 25, 2026
1e8dc17
Apply align-self to abspos static positions inside a line box
skyturkish Sep 25, 2026
f6f05d3
Skip node-dependent background placement for detached boxes
skyturkish Sep 25, 2026
b6f4259
Clip local backgrounds of scroll containers to the padding box
skyturkish Sep 25, 2026
5256e47
Paint each rounded-border row once as outer minus inner span
skyturkish Sep 25, 2026
dbace15
Support background-clip: border-area for background colors
skyturkish Sep 25, 2026
c8da31a
Support text-align-last and ignore edge spaces when aligning lines
skyturkish Sep 25, 2026
3ddc895
Paint outer box-shadows
skyturkish Sep 25, 2026
ffd9442
Paint opaque constant linear gradients as solid fills
skyturkish Sep 25, 2026
8d7dfa3
Support line-clamp, max-lines and continue: collapse
skyturkish Sep 25, 2026
ec78181
Support vertical-align keywords in inline formatting
skyturkish Sep 25, 2026
1dcde54
Support position: sticky
skyturkish Sep 25, 2026
820a2f8
Keep floats from splitting unbreakable inline content
skyturkish Sep 25, 2026
207872a
Paint the block ellipsis at a line-clamp clamp point
skyturkish Sep 25, 2026
19a37c8
Paint transformed borders and clip overflow to rounded shapes
skyturkish Sep 25, 2026
0b73468
Keep opaque glyphs out of the background-clip: text mask
skyturkish Sep 25, 2026
e91e8e3
Lay out multi-column containers
skyturkish Sep 25, 2026
8eb91b8
Support border-style and its longhands
skyturkish Sep 25, 2026
d1facdd
Support logical properties for horizontal-tb ltr
skyturkish Sep 25, 2026
3da89c1
Align lines of several inline items and resolve start by direction
skyturkish Sep 25, 2026
6c5529b
Contain abspos children of fragmented inlines in their fragments
skyturkish Sep 26, 2026
bfe894e
Support text-emphasis
skyturkish Sep 26, 2026
f54c982
Support background-blend-mode and clip text backgrounds once
skyturkish Sep 26, 2026
babf6f6
Support border-image with gradient sources
skyturkish Sep 26, 2026
868054b
Split decorated inline boxes around their blocks
skyturkish Sep 26, 2026
5fa5f2f
Snap fractional flex and percentage edges like browsers
skyturkish Sep 26, 2026
7e4faca
Establish block formatting contexts for flow-root and align-content
skyturkish Sep 26, 2026
0851077
Follow CSS operator precedence in calc()
skyturkish Sep 26, 2026
b940614
Clamp lines by height with box ends, margins and BFC boundaries
skyturkish Sep 26, 2026
4849068
Lay out inline-flex and inline-grid as atomic inline-level boxes
skyturkish Sep 26, 2026
4e081d6
Align absolute boxes on their static position in block containers
skyturkish Sep 26, 2026
a310dbc
Lay out display: inline and inline-block
skyturkish Sep 26, 2026
bb2d214
Align absolute boxes between insets and on their static rectangle
skyturkish Sep 26, 2026
4150dbe
Apply center/end align-content to fixed-height block containers
skyturkish Sep 26, 2026
35f9cbe
Place inline-level absolute boxes on a hypothetical line in block flow
skyturkish Sep 26, 2026
cc3a55d
Size block flex items to their content in a flex row
skyturkish Sep 26, 2026
aea4039
Place a float after a one-line run at the top of that line
skyturkish Sep 26, 2026
3615ae1
Trim item margins against flex and grid container edges
skyturkish Sep 26, 2026
13c8945
Resolve transform: inherit to the parent's transform
skyturkish Sep 26, 2026
299ef19
Support the + and ~ sibling combinators in selectors
skyturkish Sep 26, 2026
c2faa78
Size auto aspect ratios by content box and clamp flex minimums by them
skyturkish Sep 26, 2026
8e8fd35
Honor auto margins for blocks laid out in a float context
skyturkish Sep 26, 2026
9504ab3
Draw bare flex text on its baseline unless the container centres it
skyturkish Sep 26, 2026
62668c7
Store box widths and heights as 32-bit so huge boxes lay out and paint
skyturkish Sep 26, 2026
0c750b4
Restyle a subtree without walking every selector to the root
skyturkish Oct 12, 2026
fe17141
Write one span per row in small opaque fills
skyturkish Oct 12, 2026
adc3c87
Read the tree state pointer inline
skyturkish Oct 12, 2026
8d721ae
Keep whether a text collapses with the text, not scanned per draw
skyturkish Oct 12, 2026
9aa7c4e
Bring the line-clamp fixes over to css-fix
skyturkish Oct 20, 2026
7e73032
Clip background layers to the border area and keep rounded clips unde…
skyturkish Oct 21, 2026
79cf109
Fix right-to-left and contentless-span static positions, translate su…
skyturkish Oct 21, 2026
51d1864
Lay out vertical writing modes and map flow-relative properties per e…
skyturkish Oct 21, 2026
5a63a6c
Paint url() background images and size images by their natural ratio
skyturkish Oct 21, 2026
1d4357e
Skip the image-reference prune when the display list holds no image
skyturkish Oct 21, 2026
ac78a14
Lay out CSS tables
skyturkish Oct 21, 2026
90b1d4d
Place formatting contexts and inline floats as browsers do
skyturkish Oct 22, 2026
97477b1
Align block-level boxes with justify-self and hide singular transforms
skyturkish Oct 22, 2026
c4ad116
Add the stretch sizing keyword
skyturkish Oct 22, 2026
4934d2b
Size replaced boxes by their natural and transferred sizes
skyturkish Oct 22, 2026
52c0ac1
Align grid items by their first baselines
skyturkish Oct 22, 2026
c8b9015
Apply a background shorthand's placement and round its image tiles
skyturkish Oct 22, 2026
9485ad1
Make a hidden back face in a 3D rendering context a containing block
skyturkish Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/core/include/graphics/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ const RasterizedFontData *lookupFontForFamily(int familyId, int sizePx);
int lookupFontFamily(const char *family);
const char *lookupFontFamilyName(int familyId);
const std::uint8_t *lookupRuntimeTtfFontForFamily(int familyId, unsigned long *length);
// False rasterizes the family's runtime TTF glyphs without antialiasing.
bool runtimeTtfFontAntialiased(int familyId);
void ensureLinked();

} // namespace generated
Expand Down
25 changes: 17 additions & 8 deletions packages/core/scripts/build-gea-vite-geatsc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1623,22 +1623,27 @@ function parseStaticSelectorPlanSpec(selector) {
if (!text) return null
const parts = []
let nextDirect = false
// Relation to the previous part: 1 next sibling (+), 2 any earlier sibling (~).
let nextSibling = 0
const combinator = (char) => char === '>' || char === '+' || char === '~'
let i = 0
while (i < text.length) {
while (i < text.length && text.charCodeAt(i) <= 32) i++
if (i >= text.length) break
if (text[i] === '>') {
nextDirect = true
if (combinator(text[i])) {
nextDirect = text[i] === '>'
nextSibling = text[i] === '+' ? 1 : text[i] === '~' ? 2 : 0
i++
continue
}
const start = i
while (i < text.length && text.charCodeAt(i) > 32 && text[i] !== '>') i++
while (i < text.length && text.charCodeAt(i) > 32 && !combinator(text[i])) i++
if (i <= start) continue
const simple = parseStaticSimpleSelectorSpec(text.slice(start, i))
if (!simple) return null
parts.push({ simple, directParent: nextDirect })
parts.push({ simple, directParent: nextDirect, sibling: nextSibling })
nextDirect = false
nextSibling = 0
}
return parts.length > 0 ? { text, parts } : null
}
Expand All @@ -1651,7 +1656,7 @@ function staticSimpleSelectorSpecCode(simple) {
}

function staticSelectorPartSpecCode(part) {
return `{${staticSimpleSelectorSpecCode(part.simple)}, ${part.directParent ? 'true' : 'false'}}`
return `{${staticSimpleSelectorSpecCode(part.simple)}, ${part.directParent ? 'true' : 'false'}, ${part.sibling}}`
}

function staticSelectorPlanRegistration(selector) {
Expand Down Expand Up @@ -2132,7 +2137,8 @@ function cssStaticPropertyValue(property, rawValue) {
const length = simpleStaticLength(value)
switch (property) {
case 'display': {
const values = new Map([['block', 0], ['none', 1], ['grid', 2], ['inline-grid', 2], ['flex', 3], ['inline-flex', 3]])
// Keyword flags above the box kind, as in the engine's displayValue().
const values = new Map([['block', 0], ['none', 1], ['grid', 2], ['inline-grid', 66], ['flex', 3], ['inline-flex', 67], ['flow-root', 32], ['inline', 64], ['inline-block', 96]])
return values.has(value) ? direct('Display', values.get(value)) : null
}
case 'box-sizing':
Expand Down Expand Up @@ -2227,9 +2233,12 @@ function cssStaticPropertyValue(property, rawValue) {
if (lower === 'scale-down') return direct('ImageFit', 4)
return null
case 'text-align':
if (value === 'left' || value === 'start') return direct('TextAlign', 0)
// 0 start, 1 center, 2 right, 3 left, 4 end (see textAlignValue in style.cpp).
if (value === 'start') return direct('TextAlign', 0)
if (value === 'center') return direct('TextAlign', 1)
if (value === 'right' || value === 'end') return direct('TextAlign', 2)
if (value === 'right') return direct('TextAlign', 2)
if (value === 'left') return direct('TextAlign', 3)
if (value === 'end') return direct('TextAlign', 4)
return null
case 'text-decoration':
case 'text-decoration-line':
Expand Down
3 changes: 2 additions & 1 deletion packages/core/test/native_test_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ void resetNativeHost()
gea::platform::display::Display::setAA(0);
gea::embedded::ui::Document::instance().clear();
resetDisplay();
// disposeAll() keeps an image that is still referenced (a stylesheet's url()
// image) until its last release, so the pixels it was given stay allocated.
imageStore().disposeAll();
gTestImagePixels.clear();
gStorage.clear();
gAssetDataImageCache.clear();
gAssetPathImageCache.clear();
Expand Down
5 changes: 3 additions & 2 deletions packages/core/test/test_css_block_and_flexbasis_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4372,11 +4372,12 @@ void testBaselineAlignment()
StyleSheet::instance().registerRule("baseline-child", "align-self", "last baseline");
StyleSheet::instance().registerRule("baseline-child", "justify-self", "baseline last");
tree.mount(root, 300, 200);
// The fallback end belongs to the grid, not the child's own
// direction or writing mode (WPT grid-abspos-staticpos-*-002).
const bool reversed = std::strcmp(mode, "ltr") != 0;
const bool endAtLeft = reversed && !ownWritingMode;
const int areaLeft = positioned && !small ? (reversed ? 21 : 5) : 3;
const int areaWidth = small ? 2 : positioned ? 20 : 40;
const int x = areaLeft + (endAtLeft ? 0 : areaWidth - 8);
const int x = areaLeft + (reversed ? 0 : areaWidth - 8);
const int y = small ? -1 : positioned ? 19 : 37;
expectEqual(tree.node(child).layout.x - tree.node(grid).layout.x, x, "absolute baseline fallback uses logical horizontal end without overflow clamp");
expectEqual(tree.node(child).layout.y - tree.node(grid).layout.y, y, "absolute baseline fallback uses logical vertical end without overflow clamp");
Expand Down
148 changes: 80 additions & 68 deletions packages/engine/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1768,10 +1768,11 @@ void Canvas::fillRect(int x, int y, int w, int h, pixel::native_t color)
return;
}
// Large opaque fills (e.g. a full-screen page/paper background) skip the
// per-pixel occlusion scan below. That scan READS every pixel just to
// minimize the dirty rect — worth it for a small changed region, but pure
// overhead for a page-sized fill that gets repainted wholesale anyway. Here
// we memset each row (fillSpanColor) and mark the whole rect dirty once.
// per-pixel occlusion scan below. That scan READS pixels just to minimize
// the dirty rect (a whole row when nothing in it changes) — worth it for a
// small changed region, but pure overhead for a page-sized fill that gets
// repainted wholesale anyway. Here we memset each row (fillSpanColor) and
// mark the whole rect dirty once.
// (Packed targets take the word-scan below for EVERY size: on e-paper the
// erase fill repaints a mostly-unchanged page, and skipping the matching
// words costs one sequential read instead of a full write-allocate pass —
Expand All @@ -1782,8 +1783,8 @@ void Canvas::fillRect(int x, int y, int w, int h, pixel::native_t color)
return;
}
#endif
for (int row = y0; row <= y1; row++) {
#if GEA_PIXEL_STORAGE_PACKED
for (int row = y0; row <= y1; row++) {
// Byte/word-wise occlusion scan: a packed byte holds kPxPerByte pixels,
// so comparing whole bytes against the replicated value (and aligned
// 32-bit words against it ×4) skips already-correct spans without
Expand Down Expand Up @@ -1845,23 +1846,38 @@ void Canvas::fillRect(int x, int y, int w, int h, pixel::native_t color)
markDirty(runStart, row, xe, row);
runStart = -1; // keep the shared tail below a no-op
}
if (runStart >= 0) markDirty(x0 + runStart, row, x1, row);
}
#else
pixel::native_t *dst = &pixels_[rowToPhysical(row) * stride_ + x0];
int runStart = -1;
for (int i = 0; i < count; i++) {
if (dst[i] == c) {
if (runStart >= 0) {
markDirty(x0 + runStart, row, x0 + i - 1, row);
runStart = -1;
}
continue;
}
if (runStart < 0) runStart = i;
dst[i] = c;
// One span per row, from the first to the last pixel the fill changes,
// written at store speed. Reading and comparing every pixel and marking
// each differing run dirty cost more than the fill itself: a row
// background whose colour toggles differs everywhere, and its 13 rows x
// 410 px compared one by one were half of a 200 us desktop frame. The
// pixels are the same; the dirty rect also covers pixels inside the span
// that already had the colour. Rows with the same span share one rect.
int spanX0 = 0, spanX1 = -1, spanY0 = 0;
for (int row = y0; row <= y1; row++) {
const int phys = rowToPhysical(row);
const pixel::native_t *dst = &pixels_[phys * stride_ + x0];
int first = 0;
while (first < count && dst[first] == c) first++;
if (first == count) {
if (spanX1 >= 0) markDirty(spanX0, spanY0, spanX1, row - 1);
spanX1 = -1;
continue;
}
#endif
if (runStart >= 0) markDirty(x0 + runStart, row, x1, row);
int last = count - 1;
while (dst[last] == c) last--;
fillSpanColor(phys, x0 + first, last - first + 1, c);
if (spanX1 >= 0 && x0 + first == spanX0 && x0 + last == spanX1) continue;
if (spanX1 >= 0) markDirty(spanX0, spanY0, spanX1, row - 1);
spanX0 = x0 + first;
spanX1 = x0 + last;
spanY0 = row;
}
if (spanX1 >= 0) markDirty(spanX0, spanY0, spanX1, y1);
#endif
} else if (globalAlpha_ != 0) {
const int a = globalAlpha_;
#if GEA_EMBEDDED_DISPLAY_ROTATE_LANDSCAPE
Expand Down Expand Up @@ -4253,57 +4269,53 @@ void Canvas::strokeRoundedRect(int x, int y, int w, int h, int tl, int tr, int b
markDirty(dirtyX0, dirtyY0, dirtyX1, dirtyY1);
return;
}
fillRect(x + tl, y, w - tl - tr, lw, color);
fillRect(x + bl, y + h - lw, w - bl - br, lw, color);
fillRect(x, y + tl, lw, h - tl - bl, color);
fillRect(x + w - lw, y + tr, lw, h - tr - br, color);
for (int q = 0; q < 4; q++) {
int r, cx, cy;
switch (q) {
case 0: r = tr; cx = x + w - 1 - r; cy = y + r; break;
case 1: r = tl; cx = x + r; cy = y + r; break;
case 2: r = bl; cx = x + r; cy = y + h - 1 - r; break;
case 3: r = br; cx = x + w - 1 - r; cy = y + h - 1 - r; break;
default: continue;
}
if (r <= 0) continue;
if (cx + r < clip->x0 || cx - r > clip->x1 ||
cy + r < clip->y0 || cy - r > clip->y1)
// Each row is painted once as the outer shape's span minus the inner
// (padding-edge) shape's span, using fillRoundedRect's scanline so the ring
// is the exact complement of a fill of the inner box. Separate edge and
// corner pieces used to overlap, blending translucent borders twice where
// they met and bulging 1px into the padding area at the curves.
const int ix = x + lw, iy = y + lw, iw = w - 2 * lw, ih = h - 2 * lw;
const int innerMax = std::min(iw / 2, ih / 2);
auto innerRadius = [&](int r) { return std::min(std::max(0, r - lw), std::max(0, innerMax)); };
const int itl = innerRadius(tl), itr = innerRadius(tr), ibr = innerRadius(br), ibl = innerRadius(bl);
auto rowSpan = [](int bx, int by, int bw, int bh, int rtl, int rtr, int rbr, int rbl, int sy, int &left, int &right) {
if (bw <= 0 || bh <= 0 || sy < by || sy >= by + bh) return false;
left = bx + bw;
right = bx - 1;
auto corner = [&](int r, int cy, bool leftSide) {
const int dy = sy > cy ? sy - cy : cy - sy;
const int dx = CanvasMath::integerSqrt(r * r - dy * dy);
if (leftSide) left = std::min(left, bx + r - dx);
else right = std::max(right, bx + bw - 1 - r + dx);
};
const bool inTopLeft = rtl > 0 && sy <= by + rtl, inBottomLeft = rbl > 0 && sy >= by + bh - 1 - rbl;
const bool inTopRight = rtr > 0 && sy <= by + rtr, inBottomRight = rbr > 0 && sy >= by + bh - 1 - rbr;
if (inTopLeft) corner(rtl, by + rtl, true);
if (inBottomLeft) corner(rbl, by + bh - 1 - rbl, true);
if (!inTopLeft && !inBottomLeft) left = bx;
if (inTopRight) corner(rtr, by + rtr, false);
if (inBottomRight) corner(rbr, by + bh - 1 - rbr, false);
if (!inTopRight && !inBottomRight) right = bx + bw - 1;
return left <= right;
};
auto paint = [&](int sy, int sx0, int sx1) {
if (sx0 < clip->x0) sx0 = clip->x0;
if (sx1 > clip->x1) sx1 = clip->x1;
if (sx0 < 0) sx0 = 0;
if (sx1 >= width_) sx1 = width_ - 1;
if (sx0 <= sx1) fillSpanGlobalAlpha(rowToPhysical(sy), sx0, sx1 - sx0 + 1, color);
};
int row0 = std::max(std::max(y, clip->y0), 0);
int row1 = std::min(std::min(y + h - 1, clip->y1), height_ - 1);
for (int sy = row0; sy <= row1; ++sy) {
int oL, oR, iL, iR;
if (!rowSpan(x, y, w, h, tl, tr, br, bl, sy, oL, oR)) continue;
if (!rowSpan(ix, iy, iw, ih, itl, itr, ibr, ibl, sy, iL, iR)) {
paint(sy, oL, oR);
continue;
int ri = r - lw;
if (ri < 0) ri = 0;
int dy0 = 0;
int dy1 = r;
if (q == 0 || q == 1) {
if (cy - dy0 > clip->y1) dy0 = cy - clip->y1;
if (cy - dy1 < clip->y0) dy1 = cy - clip->y0;
} else {
if (cy + dy0 < clip->y0) dy0 = clip->y0 - cy;
if (cy + dy1 > clip->y1) dy1 = clip->y1 - cy;
}
if (dy0 < 0) dy0 = 0;
if (dy1 > r) dy1 = r;
if (dy0 > dy1) continue;
for (int dy = dy0; dy <= dy1; dy++) {
int dx_outer = CanvasMath::integerSqrt(r * r - dy * dy);
int dx_inner = (dy <= ri) ? CanvasMath::integerSqrt(ri * ri - dy * dy) : 0;
int sx0, sx1, sy;
switch (q) {
case 0: sx0 = cx + dx_inner; sx1 = cx + dx_outer; sy = cy - dy; break;
case 1: sx0 = cx - dx_outer; sx1 = cx - dx_inner; sy = cy - dy; break;
case 2: sx0 = cx - dx_outer; sx1 = cx - dx_inner; sy = cy + dy; break;
case 3: sx0 = cx + dx_inner; sx1 = cx + dx_outer; sy = cy + dy; break;
default: continue;
}
if (sy < clip->y0 || sy > clip->y1) continue;
if (sx0 < clip->x0) sx0 = clip->x0;
if (sx1 > clip->x1) sx1 = clip->x1;
if (sx0 < 0) sx0 = 0;
if (sx1 >= width_) sx1 = width_ - 1;
if (sx0 > sx1 || sy < 0 || sy >= height_) continue;

fillSpanGlobalAlpha(rowToPhysical(sy), sx0, sx1 - sx0 + 1, color);
}
paint(sy, oL, std::min(oR, iL - 1));
paint(sy, std::max(oL, iR + 1), oR);
}
markDirtyClipped(x, y, x + w - 1, y + h - 1);
}
Expand Down
16 changes: 15 additions & 1 deletion packages/engine/rasterized_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ void runtimeTtfTrace(const char *, ...) {}
constexpr int kRuntimeAsciiFirst = 0x20;
constexpr int kRuntimeAsciiLast = 0x7e;
constexpr int kRuntimeAsciiCount = kRuntimeAsciiLast - kRuntimeAsciiFirst + 1;
constexpr int kRuntimeExtraGlyphs = 1;
// Beyond ASCII: the degree sign and the horizontal ellipsis, which the
// block ellipsis of line-clamp and text-overflow draws when the font has it.
constexpr int kRuntimeExtraGlyphs = 2;
constexpr int kRuntimeGlyphCapacity = kRuntimeAsciiCount + kRuntimeExtraGlyphs;
constexpr int kRuntimeFontCacheSlots = 64;
constexpr int kRuntimeMaxAtlasWidth = 256;
Expand Down Expand Up @@ -143,6 +145,7 @@ int runtimeCodepointAt(int index)
{
if (index >= 0 && index < kRuntimeAsciiCount) return kRuntimeAsciiFirst + index;
if (index == kRuntimeAsciiCount) return 0x00b0;
if (index == kRuntimeAsciiCount + 1) return 0x2026;
return -1;
}

Expand Down Expand Up @@ -408,6 +411,11 @@ void ensureRuntimeGlyphCoverage(const RasterizedFontData *data, const Glyph &gly
scale,
scale,
slotGlyph.codepoint);
// Without antialiasing a pixel is covered when most of it is inside the outline.
if (generated::runtimeTtfFontAntialiased(slot->familyId)) return;
std::uint8_t *pixels = slot->atlas + slotGlyph.sourceY * data->atlasWidth + slotGlyph.sourceX;
for (int row = 0; row < slotGlyph.height; row++)
for (int x = 0; x < slotGlyph.width; x++) pixels[row * data->atlasWidth + x] = pixels[row * data->atlasWidth + x] >= 128 ? 255 : 0;
}

const RasterizedFontData *runtimeTtfFontForFamily(int familyId, int sizePx)
Expand Down Expand Up @@ -605,6 +613,12 @@ __attribute__((weak)) const std::uint8_t *lookupRuntimeTtfFontForFamily(int fami
return nullptr;
}

__attribute__((weak)) bool runtimeTtfFontAntialiased(int familyId)
{
(void)familyId;
return true;
}

} // namespace generated

} // namespace gea::framework::graphics
5 changes: 3 additions & 2 deletions packages/engine/ui/canvas_element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2657,8 +2657,8 @@ void CanvasRenderer::record(const Node &node)
cmd->canvasBatch = {static_cast<int16_t>(id),
node.layout.x,
node.layout.y,
node.layout.width,
node.layout.height,
static_cast<int16_t>(node.layout.width),
static_cast<int16_t>(node.layout.height),
CanvasRenderingContext2D::stateFor(id)->identity_};
return;
}
Expand Down Expand Up @@ -2687,6 +2687,7 @@ void CanvasRenderer::record(const Node &node)
// grayscale targets that is sub-byte packed (2 px/byte on GRAY4, 4 px/byte on
// GRAY2), so flag it for the blit to unpack.
cmd->blit.sourcePacked = GEA_PIXEL_STORAGE_PACKED ? 1 : 0;
cmd->blit.boundsClip = 0;
}

#endif
Expand Down
Loading
Loading