From: Tingzhong Luo luotingzhong@uniontech.com
Signed-off-by: Tingzhong Luo luotingzhong@uniontech.com --- dlls/dwrite/gdiinterop.c | 9 ++- dlls/dwrite/tests/font.c | 111 ++++++++++++++++++++++++++++ dlls/dwrite/tests/rect_fallback.sfd | 75 +++++++++++++++++++ dlls/dwrite/tests/rect_fallback.ttf | Bin 0 -> 1600 bytes dlls/dwrite/tests/resource.rc | 3 + 5 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 dlls/dwrite/tests/rect_fallback.sfd create mode 100644 dlls/dwrite/tests/rect_fallback.ttf
diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c index 5b542d93e32..c07f9e094ba 100644 --- a/dlls/dwrite/gdiinterop.c +++ b/dlls/dwrite/gdiinterop.c @@ -347,7 +347,7 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac DWRITE_RENDERING_MODE1 rendermode; DWRITE_GRID_FIT_MODE gridfitmode; DWRITE_TEXTURE_TYPE texturetype; - DWRITE_GLYPH_RUN scaled_run; + DWRITE_MATRIX scaled_matrix; IDWriteFontFace3 *fontface; RECT target_rect, bounds; HRESULT hr; @@ -429,9 +429,10 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac return hr; }
- scaled_run = *run; - scaled_run.fontEmSize *= target->ppdip; - hr = IDWriteFactory7_CreateGlyphRunAnalysis(target->factory, &scaled_run, &target->m, rendermode, measuring_mode, + scaled_matrix = target->m; + scaled_matrix.m11 *= target->ppdip; + scaled_matrix.m22 *= target->ppdip; + hr = IDWriteFactory7_CreateGlyphRunAnalysis(target->factory, run, &scaled_matrix, rendermode, measuring_mode, gridfitmode, target->antialiasmode, originX, originY, &analysis); if (FAILED(hr)) { diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 81008db6f23..a5e5d296865 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -1205,11 +1205,41 @@ static void test_CreateFontFromLOGFONT(void) ok(ref == 0, "factory is not released, %lu\n", ref); }
+static IDWriteFontFace *create_rectfallback_fontface(IDWriteFactory *factory) +{ + static IDWriteFontFileLoader rloader = { &resourcefontfileloadervtbl }; + IDWriteFontFace *face; + IDWriteFontFile *file; + HRSRC fontsrc; + HRESULT hr; + + hr = IDWriteFactory_RegisterFontFileLoader(factory, &rloader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + fontsrc = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(2), (LPCSTR)RT_RCDATA); + ok(fontsrc != NULL, "Failed to find font resource\n"); + + hr = IDWriteFactory_CreateCustomFontFileReference(factory, &fontsrc, sizeof(HRSRC), &rloader, &file); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(file != NULL, "Failed to create font file reference\n"); + + hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(face != NULL, "Failed to create font face\n"); + + hr = IDWriteFactory_UnregisterFontFileLoader(factory, &rloader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDWriteFontFile_Release(file); + return face; +} + static void test_CreateBitmapRenderTarget(void) { IDWriteBitmapRenderTarget *target, *target2; IDWriteBitmapRenderTarget1 *target1; IDWriteRenderingParams *params; + DWRITE_GLYPH_OFFSET offsets[2]; IDWriteGdiInterop *interop; IDWriteFontFace *fontface; IDWriteFactory *factory; @@ -1217,6 +1247,7 @@ static void test_CreateBitmapRenderTarget(void) HBITMAP hbm, hbm2; UINT16 glyphs[2]; DWRITE_MATRIX m; + RECT box, box2; DIBSECTION ds; XFORM xform; COLORREF c; @@ -1507,6 +1538,86 @@ static void test_CreateBitmapRenderTarget(void) &run, params, RGB(255, 0, 0), NULL); ok(hr == S_OK, "Failed to draw a run, hr %#lx.\n", hr);
+ hr = IDWriteBitmapRenderTarget_SetPixelsPerDip(target, 1.0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* Check glyph position */ + IDWriteFontFace_Release(fontface); + fontface = create_rectfallback_fontface(factory); + + /* 'A' map to a full black rectangle */ + ch = 'A'; + glyphs[0] = 0; + hr = IDWriteFontFace_GetGlyphIndices(fontface, &ch, 1, glyphs); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(glyphs[0] > 0, "got %u\n", glyphs[0]); + glyphs[1] = glyphs[0]; + + offsets[0].advanceOffset = 0; + offsets[0].ascenderOffset = 0; + offsets[1].advanceOffset = 6; + offsets[1].ascenderOffset = 0; + + memset(&run, 0, sizeof(run)); + run.glyphCount = 2; + run.fontEmSize = 30.0f; + run.fontFace = fontface; + run.glyphIndices = glyphs; + run.glyphOffsets = offsets; + hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target); + ok(hdc != NULL, "got %p\n", hdc); + + hr = IDWriteBitmapRenderTarget_Resize(target, 400, 400); + ok(hr == S_OK, "Failed to resize target, hr %#lx.\n", hr); + + SetDCBrushColor(hdc, 0); + SelectObject(hdc, GetStockObject(DC_BRUSH)); + Rectangle(hdc, 0, 0, 400, 400); + SetRectEmpty(&box); + hr = IDWriteBitmapRenderTarget_DrawGlyphRun(target, 30.0f, 65.0f, DWRITE_MEASURING_MODE_GDI_NATURAL, + &run, params, RGB(255, 0, 0), &box); + ok(hr == S_OK, "Failed to draw a run, hr %#lx.\n", hr); + ok(!IsRectEmpty(&box), "got empty rect\n"); + + /* hit first glyphs */ + c = GetPixel(hdc, box.left + 10, box.top + 10); + ok(c == RGB(255, 0, 0), "got 0x%08lx\n", c); + + /* blank between glyphs */ + c = GetPixel(hdc, (box.right + box.left) / 2, (box.top + box.bottom) / 2); + ok(c == RGB(0, 0, 0), "got 0x%08lx\n", c); + + /* Doubled ppdip */ + hr = IDWriteBitmapRenderTarget_SetPixelsPerDip(target, 2.0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + SetDCBrushColor(hdc, 0); + SelectObject(hdc, GetStockObject(DC_BRUSH)); + Rectangle(hdc, 0, 0, 400, 400); + SetRectEmpty(&box2); + hr = IDWriteBitmapRenderTarget_DrawGlyphRun(target, 30.0f, 65.0f, DWRITE_MEASURING_MODE_GDI_NATURAL, + &run, params, RGB(255, 0, 0), &box2); + ok(hr == S_OK, "Failed to draw a run, hr %#lx.\n", hr); + ok(!IsRectEmpty(&box2), "got empty rect\n"); + + /* blank between glyphs */ + c = GetPixel(hdc, (box.right + box.left) / 2, (box.top + box.bottom) / 2); + ok(c == RGB(0, 0, 0), "got 0x%08lx\n", c); + + /* cleared */ + c = GetPixel(hdc, box.left + 10, box.top + 10); + ok(c == RGB(0, 0, 0), "got 0x%08lx\n", c); + + /* hit first glyphs */ + c = GetPixel(hdc, box2.left + 10, box2.top + 10); + ok(c == RGB(255, 0, 0), "got 0x%08lx\n", c); + + /* bounds should be scaled */ + ok(abs(box2.left - box.left * 2) <= 2, "unexpect left bounds: %ld -> %ld\n", box.left, box2.left); + ok(abs(box2.right - box.right * 2) <= 2, "unexpect right bounds: %ld -> %ld\n", box.right, box2.right); + ok(abs(box2.top - box.top * 2) <= 2, "unexpect top bounds: %ld -> %ld\n", box.top, box2.top); + ok(abs(box2.bottom - box.bottom * 2) <= 2, "unexpect bottom bounds: %ld -> %ld\n", box.bottom, box2.bottom); + IDWriteRenderingParams_Release(params);
/* Zero sized target returns earlier. */ diff --git a/dlls/dwrite/tests/rect_fallback.sfd b/dlls/dwrite/tests/rect_fallback.sfd new file mode 100644 index 00000000000..4d2925a2366 --- /dev/null +++ b/dlls/dwrite/tests/rect_fallback.sfd @@ -0,0 +1,75 @@ +SplineFontDB: 3.2 +FontName: rect_fallback +FullName: rect_fallback +FamilyName: rect_fallback +Weight: Regular +Copyright: Copyright (c) 2023, LTZ +UComments: "2023-9-5: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -102 +UnderlineWidth: 51 +Ascent: 819 +Descent: 205 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "+gMxmbwAA" 1 +Layer: 1 0 "+Uk1mbwAA" 0 +XUID: [1021 32 1840475288 9054806] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1693875904 +ModificationTime: 1693887136 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 0 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +Encoding: ISO8859-1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 24 24 10 +BeginPrivate: 0 +EndPrivate +BeginChars: 256 1 + +StartChar: A +Encoding: 65 65 0 +Width: 1024 +VWidth: 0 +Flags: HWO +LayerCount: 2 +Back +SplineSet +0 816 m 1 + 1024 816 l 1 + 1024 -207 l 1 + 0 -207 l 1 + 0 816 l 1 +EndSplineSet +Fore +SplineSet +0 823 m 1 + 1024 823 l 1 + 1024 -201 l 1 + 0 -201 l 1 + 0 823 l 1 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/dlls/dwrite/tests/rect_fallback.ttf b/dlls/dwrite/tests/rect_fallback.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3e1a00f11c867858b587ee20838b00239284d5cf GIT binary patch literal 1600 zcmdT^Jx>%t7=C7V??B}<(U_2nSx$^#xMSH1oRBL(<fOoWNH77CV>#}FcwadV1F<1i z#zq=rG<J3rCS3dl7Dgk+#=?R`ZEO^cg|We$&+P7@7%42B&CL6}A2a*RJMRnxfCj8V z#auKxdGTS#`g6eBMyv0_`Qa#z;VAW5sgGUmGN--s9zdk2&&9J=0gdVx>TlT3#jllg z_?4T0>Z4yvSxbdVg)75L6}73%YVy*|)4TL{QZJ+v*21YPFJBOUV((4UP;*C(a4q@& zwsf|%QU~~{Kcn81$;U0sW0LcA>W8z|N&zG2qkn|Dp0l!v-uvIf^gjTUa3Q}`s=P%n z;CW5|8OXh|zsh~si8V&P;fO{9@ZQ%o;K&&rsDw4BTm!XGq?L_x)Nmz?Stp*OT<Q0w z*%obYj+`lM+W>-gpvI7OFn7v5Ws8>Ejuame5{GDohojr}tv;R{Uced#F{p+rA<U8+ zPpHbkW~xJw6Z6ERyPbl0x4X}cjZl*-`xvBCYW$==$TPCX%9HA<f(KS5A>>}FnIN=V z)mhd5CguPC?`GFB>qdTOxfR8(MN`>eCTkGf6zGbSYc%Ybn_ka$q^v50*i@z2BhBR+ zuh@;0nZg}2)ZE&9I@Em9FPc7YZ7CZ+ru<6MPP1Ea%ojsiHSDt5cAd;M;L+Ye9Eagz zfqE>sSRs=eE>_WwZ5L~(7p*S#pizvu*h~9$SqYk~H(8qw7HHvJa<IY|q3B{2<GAHw z4K2dsVh>J;E*E=gk6{RT6tK#fi%21j6058oadc3c<ZdE_PU2DC;AvneUsx?JrqU(7 zJ>H?4h8gPAM<?khBEeZD#E^uA48M8GIIhx_h?inXE0dYG;#4OXnZhz7EY8A2BDI{c z2%=<?;|fw18IiCV1j#{1Kl{OdaQr<8@Kp)yu|_nXD@F6gR6;j{hTgC5<3YVA&=-(9 z_!sh1q*cTclO@UOBxj(T2O^~bOeKm-i}{>x7~Mg`py6QBf2O5+TPu&5@n09&sVF(h lM?x^F%{B?%f5oj1ppNgo^gAzDb+(X^@4kBFyT9+f{0W|L%P#-`
literal 0 HcmV?d00001
diff --git a/dlls/dwrite/tests/resource.rc b/dlls/dwrite/tests/resource.rc index b761ebcfc32..9353cd6cae5 100644 --- a/dlls/dwrite/tests/resource.rc +++ b/dlls/dwrite/tests/resource.rc @@ -22,3 +22,6 @@
/* @makedep: wine_test.ttf */ 1 RCDATA wine_test.ttf + +/* @makedep: rect_fallback.ttf */ +2 RCDATA rect_fallback.ttf