@@ -14,14 +14,14 @@ extern "C" int D2DAcquire(IDXGISurface *GlyphTransferSurface,
1414 struct ID2D1SolidColorBrush **DWriteFillBrush)
1515{
1616 int Result = 0 ;
17-
17+
1818 // TODO(casey): Obey "ClearType" here.
19-
19+
2020 // TODO(casey): Not sure about these props...
2121 D2D1_RENDER_TARGET_PROPERTIES Props = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_DEFAULT,
2222 D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
2323 0 , 0 );
24-
24+
2525 ID2D1Factory *Factory = 0 ;
2626 D2D1_FACTORY_OPTIONS Options = {};
2727 Options.debugLevel = D2D1_DEBUG_LEVEL_ERROR;
@@ -34,10 +34,10 @@ extern "C" int D2DAcquire(IDXGISurface *GlyphTransferSurface,
3434 (*DWriteRenderTarget)->CreateSolidColorBrush (D2D1::ColorF (1 .0f , 1 .0f , 1 .0f , 1 .0f ), DWriteFillBrush);
3535 Result = (*DWriteFillBrush != 0 );
3636 }
37-
37+
3838 Factory->Release ();
3939 }
40-
40+
4141 return Result;
4242}
4343
@@ -49,7 +49,7 @@ extern "C" void D2DRelease(struct ID2D1RenderTarget **DWriteRenderTarget,
4949 (*DWriteFillBrush)->Release ();
5050 *DWriteFillBrush = 0 ;
5151 }
52-
52+
5353 if (*DWriteRenderTarget)
5454 {
5555 (*DWriteRenderTarget)->Release ();
@@ -60,33 +60,35 @@ extern "C" void D2DRelease(struct ID2D1RenderTarget **DWriteRenderTarget,
6060extern " C" int DWriteInit (glyph_generator *GlyphGen, IDXGISurface *GlyphTransferSurface)
6161{
6262 int Result = 0 ;
63-
63+
6464 DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), (IUnknown**)&GlyphGen->DWriteFactory );
6565 if (GlyphGen->DWriteFactory )
6666 {
6767 Result = 1 ;
6868 }
69-
69+
7070 return Result;
7171}
7272
7373extern " C" SIZE DWriteGetTextExtent (glyph_generator *GlyphGen, int StringLen, wchar_t *String)
7474{
7575 SIZE Result = {0 };
76-
76+
7777 IDWriteTextLayout *Layout = 0 ;
7878 GlyphGen->DWriteFactory ->CreateTextLayout (String, StringLen, GlyphGen->TextFormat ,
7979 (float )GlyphGen->TransferWidth , (float )GlyphGen->TransferHeight , &Layout);
8080 if (Layout)
8181 {
8282 DWRITE_TEXT_METRICS Metrics = {0 };
8383 Layout->GetMetrics (&Metrics);
84- Result.cx = (uint32_t )Metrics.width ;
85- Result.cy = (uint32_t )Metrics.height ;
86-
84+ Assert (Metrics.left == 0 );
85+ Assert (Metrics.top == 0 );
86+ Result.cx = (uint32_t )(Metrics.width + 0 .5f );
87+ Result.cy = (uint32_t )(Metrics.height + 0 .5f );
88+
8789 Layout->Release ();
8890 }
89-
91+
9092 return Result;
9193}
9294
@@ -97,14 +99,48 @@ void DWriteReleaseFont(glyph_generator *GlyphGen)
9799 GlyphGen->FontFace ->Release ();
98100 GlyphGen->FontFace = 0 ;
99101 }
102+ }
103+
104+ void IncludeLetterBounds (glyph_generator *GlyphGen, wchar_t Letter)
105+ {
106+ IDWriteTextLayout *Layout = 0 ;
107+ GlyphGen->DWriteFactory ->CreateTextLayout (&Letter, 1 , GlyphGen->TextFormat ,
108+ (float )GlyphGen->TransferWidth , (float )GlyphGen->TransferHeight , &Layout);
109+ if (Layout)
110+ {
111+ // TODO(casey): Real cell size determination would go here - probably with input from the user?
112+ DWRITE_TEXT_METRICS CharMetrics = {0 };
113+ Layout->GetMetrics (&CharMetrics);
114+
115+ DWRITE_LINE_METRICS LineMetrics = {0 };
116+ UINT32 Ignored;
117+ Layout->GetLineMetrics (&LineMetrics, 1 , &Ignored);
118+
119+ if (GlyphGen->FontHeight < (uint32_t )(LineMetrics.height + 0 .5f ))
120+ {
121+ GlyphGen->FontHeight = (uint32_t )(LineMetrics.height + 0 .5f );
122+ }
123+
124+ if (GlyphGen->FontHeight < (uint32_t )(CharMetrics.height + 0 .5f ))
125+ {
126+ GlyphGen->FontHeight = (uint32_t )(CharMetrics.height + 0 .5f );
127+ }
128+
129+ if (GlyphGen->FontWidth < (uint32_t )(CharMetrics.width + 0 .5f ))
130+ {
131+ GlyphGen->FontWidth = (uint32_t )(CharMetrics.width + 0 .5f );
132+ }
133+
134+ Layout->Release ();
100135 }
136+ }
101137
102138extern " C" int DWriteSetFont (glyph_generator *GlyphGen, wchar_t *FontName, uint32_t FontHeight)
103139{
104140 int Result = 0 ;
105-
141+
106142 DWriteReleaseFont (GlyphGen);
107-
143+
108144 if (GlyphGen->DWriteFactory )
109145 {
110146 GlyphGen->DWriteFactory ->CreateTextFormat (FontName,
@@ -119,31 +155,16 @@ extern "C" int DWriteSetFont(glyph_generator *GlyphGen, wchar_t *FontName, uint3
119155 {
120156 GlyphGen->TextFormat ->SetParagraphAlignment (DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
121157 GlyphGen->TextFormat ->SetTextAlignment (DWRITE_TEXT_ALIGNMENT_LEADING);
122-
123- wchar_t M = L' M' ;
124- IDWriteTextLayout *Layout = 0 ;
125- GlyphGen->DWriteFactory ->CreateTextLayout (&M, 1 , GlyphGen->TextFormat ,
126- (float )GlyphGen->TransferWidth , (float )GlyphGen->TransferHeight , &Layout);
127- if (Layout)
128- {
129- // TODO(casey): Real cell size determination would go here - probably with input from the user?
130- DWRITE_TEXT_METRICS CharMetrics = {0 };
131- Layout->GetMetrics (&CharMetrics);
132-
133- DWRITE_LINE_METRICS LineMetrics = {0 };
134- UINT32 Ignored;
135- Layout->GetLineMetrics (&LineMetrics, 1 , &Ignored);
136-
137- GlyphGen->FontHeight = (uint32_t )LineMetrics.height ;
138- GlyphGen->FontWidth = (uint32_t )CharMetrics.width ;
139-
140- Layout->Release ();
141-
142- Result = 1 ;
143- }
158+
159+ GlyphGen->FontWidth = 0 ;
160+ GlyphGen->FontHeight = 0 ;
161+ IncludeLetterBounds (GlyphGen, L' M' );
162+ IncludeLetterBounds (GlyphGen, L' g' );
163+
164+ Result = 1 ;
144165 }
145166 }
146-
167+
147168 return Result;
148169}
149170
@@ -154,7 +175,7 @@ extern "C" void DWriteDrawText(glyph_generator *GlyphGen, int StringLen, WCHAR *
154175 float XScale, float YScale)
155176{
156177 D2D1_RECT_F Rect;
157-
178+
158179 Rect.left = (float )Left;
159180 Rect.top = (float )Top;
160181 Rect.right = (float )Right;
@@ -176,12 +197,12 @@ extern "C" void DWriteDrawText(glyph_generator *GlyphGen, int StringLen, WCHAR *
176197extern " C" void DWriteRelease (glyph_generator *GlyphGen)
177198{
178199 /* NOTE(casey): There is literally no point to this function
179- whatsoever except to stop the D3D debug runtime from
200+ whatsoever except to stop the D3D debug runtime from
180201 complaining about unreleased resources when the program
181202 exits. EVEN THOUGH THEY WOULD BE AUTOMATICALLY RELEASED
182203 AT THAT TIME. So now here I am manually releasing them,
183204 which wastes the user's time, for no reason at all. */
184-
205+
185206 DWriteReleaseFont (GlyphGen);
186207 if (GlyphGen->DWriteFactory ) GlyphGen->DWriteFactory ->Release ();
187208}
0 commit comments