Closed zcream closed 2 years ago
Since the Canvas
format (ARGB32 Premultiplied) is not always the same as theBitmap
format (RGBA plain), so we have to convert the Bitmap
format to theCanvas
format by erasing it with the backgroundColor
before rendering.
Could the API offer an option to supply ARGB32 directly? It would be a simple change and save the byte swap and background fill.
void Document::renderARGB(Bitmap bitmap, const Matrix& matrix, std::uint32_t backgroundColor) const
{
RenderState state(nullptr, RenderMode::Display);
state.canvas = Canvas::create(bitmap.data(), bitmap.width(), bitmap.height(), bitmap.stride());
state.transform = Transform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
// state.canvas->clear(backgroundColor);
root->render(state);
// Comment out - pixels[x] = (a << 24) | (b << 16) | (g << 8) | r;
state.canvas->rgba();
}
The Canvas
format is not always ARGB32_PREMULTIPLIED because I want to target multiple renderers
@zcream I had the same experience. I'm rendering multiple SVG icons into an existing atlas texture (with the target bitmap subrect window adjusted accordingly) to draw toolbar and menu icons for arbitrary DPI's, and there's no need for the background pixels to be cleared because I already did that anyway. Additionally the atlas texture bitmap pixels passed into render()
are BGRA premultiplied so that I can use them with multiple renderers (SDL, Cairo, GDI, GDI+, Direct3D, OpenGL) which either require or at least work most efficiently with premultiplied textures. So lunasvg undoing plutovg's canvas output is counterproductive here.
0d3e6a2897a76c907becbe48c1726685531ab455 You can now use one image buffer to render multiple images @fdwr @zcream
Example :
auto document = Document::loadFromFile("tiger.svg");
const int tileW = 300;
const int tileH = 300;
Bitmap bitmap(900, 900);
bitmap.clear(0xF0FFF0FF); // HoneyDew
for(int y = 0;y < bitmap.height();y += tileH)
{
for(int x = 0;x < bitmap.width();x += tileW)
{
Matrix matrix(tileW / document->width(), 0, 0, tileH / document->height(), x, y);
document->render(bitmap, matrix);
}
}
bitmap.convertToRGBA();
stbi_write_png("tiledtiger.png", bitmap.width(), bitmap.height(), 4, bitmap.data(), 0);
tiledtiger.png :
Using
Bitmap(std::uint8_t* data, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
one can supply a custom buffer with a background image.However, both
render
andrenderToBitmap
have a background color. Does this mean that lunasvg will always overwrite the custom background?