Open Lpsd opened 1 month ago
The next lunasvg version has no convert
method. Maybe we can optimize and prepare the solution for the future update:
Faster convert function
void CClientVectorGraphicDisplay::UnpremultiplyBitmap(Bitmap &bitmap)
{
auto width = bitmap.width();
auto height = bitmap.height();
auto stride = bitmap.stride();
auto rowData = bitmap.data();
for (std::uint32_t y = 0; y < height; y++)
{
auto data = rowData;
for (std::uint32_t x = 0; x < width; x++)
{
auto &b = data[0];
auto &g = data[1];
auto &r = data[2];
auto &a = data[3];
if (a != 0)
{
r = (r * 255) / a;
g = (g * 255) / a;
b = (b * 255) / a;
}
data += 4;
}
rowData += stride;
}
}
Avoid additional memory allocation and memcpy
IDirect3DSurface9* surface = m_pVectorGraphic->GetRenderItem()->m_pD3DRenderTargetSurface;
if (!surface)
return;
// Lock surface
D3DLOCKED_RECT LockedRect;
if (SUCCEEDED(surface->LockRect(&LockedRect, nullptr, D3DLOCK_DISCARD)))
{
auto surfaceData = static_cast<std::uint8_t*>(LockedRect.pBits);
auto stride = static_cast<std::uint32_t>(LockedRect.Pitch);
Bitmap bitmap{surfaceData, pVectorGraphicItem->m_uiSizeX, pVectorGraphicItem->m_uiSizeY, stride};
svgDocument->render(bitmap);
UnpremultiplyBitmap(bitmap);
// Unlock surface
surface->UnlockRect();
}
Just making sure status is known, as this was discussed on Discord - I tried the above code but unfortunately the size of the resulting texture seems to be slightly off, by a few pixels? I'll get some screenshots later, but in this case it looks like drawing a 103x103 rect to a 100x100 canvas at 0x0.
Maybe there are differences in texture generation from render
compared to renderToBitmap
, I don't see anything wrong in the calculations for UnpremultiplyBitmap
or how it is being drawn to the device.
Resolves #3828
bg.png