sammycage / lunasvg

SVG rendering and manipulation library in C++
MIT License
866 stars 124 forks source link

Fix stride in bitmap clear and convert #74

Closed fdwr closed 2 years ago

fdwr commented 2 years ago

Calling clear from https://github.com/sammycage/lunasvg/commit/0d3e6a2897a76c907becbe48c1726685531ab455 for https://github.com/sammycage/lunasvg/issues/73 causes other adjacent bitmaps to be wiped out too because the outer loop ignores byte stride (I'm rendering multiple into a larger atlas texture with stride) while leaving bottom rows uncleared.

e.g. my calling code

for (uint32_t iconIndex; iconIndex < totalIcons; ++iconIndex)
{
    ...
    // Draw the icon into a subrect of the larger atlas texture,
    // adjusting the pointer offset while keeping the correct stride.
    uint32_t pixelOffset = y * atlasBitmap.stride() + x * sizeof(uint32_t);
    renderBitmap.reset(g_bitmap.data() + pixelOffset, iconSize, iconSize, atlasBitmap.stride());
    renderBitmap.clear(BgraToAbgr(backgroundColor));
    ...
    svgDocument->render(renderBitmap, matrix);
    ...
}
fdwr commented 2 years ago

Btw, I also considered including two other changes:

  1. An early return if both unpremultiply was false and the indices order was (2,1,0,3 -> BGRA) which is a nop.
  2. A small equation change to convert that makes it almost twice as fast (e.g. this icon https://icons8.com/icon/63250/clock takes 4.86ms vs 8.19ms to clear the background 300 times)
...
    uint32_t f = (16777215 / a);
    r = (r * f) >> 16;
    g = (g * f) >> 16;
    b = (b * f) >> 16;
...

But I didn't include them since I don't use unpremultiplied anyway, and since the results of the faster equation are not identical to x * 255 / a. Before that, I wanted to look more closely into other parts of LunaSvg and plutovg for equation consistency and to ensure the reverse equation has symmetry (they are very close though, and the faster one pleasantly yields a more symmetric distribution of the values between 0 and 255).

sammycage commented 2 years ago

Thank You <3 <3 <3