Skip to content

Commit 04f297b

Browse files
authored
Fix SVG bitmap and optimize rendering (#3981)
1 parent f91e1de commit 04f297b

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

Client/mods/deathmatch/logic/CClientVectorGraphicDisplay.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "StdInc.h"
1111
#include "CClientVectorGraphicDisplay.h"
1212
#include "CClientVectorGraphic.h"
13-
#include <lunasvg.h>
1413

1514
using namespace lunasvg;
1615

@@ -45,6 +44,37 @@ void CClientVectorGraphicDisplay::Render()
4544
}
4645
}
4746

47+
void CClientVectorGraphicDisplay::UnpremultiplyBitmap(Bitmap& bitmap)
48+
{
49+
auto width = bitmap.width();
50+
auto height = bitmap.height();
51+
auto stride = bitmap.stride();
52+
auto rowData = bitmap.data();
53+
54+
for (std::uint32_t y = 0; y < height; y++)
55+
{
56+
auto data = rowData;
57+
for (std::uint32_t x = 0; x < width; x++)
58+
{
59+
auto& b = data[0];
60+
auto& g = data[1];
61+
auto& r = data[2];
62+
auto& a = data[3];
63+
64+
if (a != 0)
65+
{
66+
r = (r * 255) / a;
67+
g = (g * 255) / a;
68+
b = (b * 255) / a;
69+
}
70+
71+
data += 4;
72+
}
73+
74+
rowData += stride;
75+
}
76+
}
77+
4878
void CClientVectorGraphicDisplay::UpdateTexture()
4979
{
5080
if (!m_pVectorGraphic || m_pVectorGraphic->IsDestroyed())
@@ -62,25 +92,19 @@ void CClientVectorGraphicDisplay::UpdateTexture()
6292
if (!surface)
6393
return;
6494

65-
Bitmap bitmap = svgDocument->renderToBitmap(pVectorGraphicItem->m_uiSizeX, pVectorGraphicItem->m_uiSizeY);
66-
if (!bitmap.valid())
67-
return;
95+
// SVG has a predefined width and height. We need transform it to the requested size
96+
const Matrix transformationMatrix(pVectorGraphicItem->m_uiSizeX / svgDocument->width(), 0, 0, pVectorGraphicItem->m_uiSizeY / svgDocument->height(), 0, 0);
6897

6998
// Lock surface
7099
D3DLOCKED_RECT LockedRect;
71100
if (SUCCEEDED(surface->LockRect(&LockedRect, nullptr, D3DLOCK_DISCARD)))
72101
{
73-
auto surfaceData = static_cast<byte*>(LockedRect.pBits);
74-
auto sourceData = static_cast<const byte*>(bitmap.data());
102+
auto surfaceData = static_cast<std::uint8_t*>(LockedRect.pBits);
103+
auto stride = static_cast<std::uint32_t>(LockedRect.Pitch);
75104

76-
for (uint32_t y = 0; y < bitmap.height(); ++y)
77-
{
78-
memcpy(surfaceData, sourceData, bitmap.width() * 4); // 4 bytes per pixel
79-
80-
// advance row pointers
81-
sourceData += bitmap.stride();
82-
surfaceData += LockedRect.Pitch;
83-
}
105+
Bitmap bitmap{surfaceData, pVectorGraphicItem->m_uiSizeX, pVectorGraphicItem->m_uiSizeY, stride};
106+
svgDocument->render(bitmap, transformationMatrix);
107+
UnpremultiplyBitmap(bitmap);
84108

85109
// Unlock surface
86110
surface->UnlockRect();

Client/mods/deathmatch/logic/CClientVectorGraphicDisplay.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class CClientVectorGraphicDisplay;
1313

1414
#include "CClientDisplay.h"
1515
#include "CClientDisplayManager.h"
16+
#include <lunasvg.h>
1617

1718
class CClientVectorGraphicDisplay final : public CClientDisplay
1819
{
@@ -34,6 +35,9 @@ class CClientVectorGraphicDisplay final : public CClientDisplay
3435

3536
void Update();
3637

38+
private:
39+
void UnpremultiplyBitmap(lunasvg::Bitmap& bitmap);
40+
3741
private:
3842
CClientVectorGraphic* m_pVectorGraphic;
3943

0 commit comments

Comments
 (0)