Skip to content

Commit be39085

Browse files
committed
New code to find max width of strings when rendered
Added new routines to return the maximum width of a list of strings when rendered in a given font. Two routines added: MaxStringWidthPx and MaxStringWidthTwips to return the maximum string width in pixels and twips respectively.
1 parent 21f6e7c commit be39085

File tree

1 file changed

+96
-5
lines changed

1 file changed

+96
-5
lines changed

Src/UGraphicUtils.pas

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ interface
1717

1818
uses
1919
// Delphi
20-
Windows, Graphics,
21-
// Project
22-
UStructs;
23-
20+
Windows, Graphics;
2421

2522
function CreateDisplayDC: HDC;
2623
{Creates a display device context.
@@ -45,6 +42,28 @@ function StringExtent(const S: string; const Font: TFont): TSize; overload;
4542
@return Structure containing width and height of string in pixels.
4643
}
4744

45+
/// <summary>Returns width, in pixels, of the widest of the given strings when
46+
/// rendered a specified font.</summary>
47+
/// <param name="AStrings"><c>array of string</c> [in] Strings whose rendered
48+
/// width is to be measured.</param>
49+
/// <param name="AFont"><c>TFont</c> [in] Font in which strings are to be
50+
/// rendered.</param>
51+
/// <returns><c>SmallInt</c>. Width of widest string in array in pixels.
52+
/// </returns>
53+
function MaxStringWidthPx(const AStrings: array of string; const AFont: TFont):
54+
SmallInt;
55+
56+
/// <summary>Returns width, in twips, of the widest of the given strings when
57+
/// rendered a specified font.</summary>
58+
/// <param name="AStrings"><c>array of string</c> [in] Strings whose rendered
59+
/// width is to be measured.</param>
60+
/// <param name="AFont"><c>TFont</c> [in] Font in which strings are to be
61+
/// rendered.</param>
62+
/// <returns><c>SmallInt</c>. Width of widest string in array in twips.
63+
/// </returns>
64+
function MaxStringWidthTwips(const AStrings: array of string;
65+
const AFont: TFont): SmallInt;
66+
4867
function GetTextRect(const Text: string; const Canvas: TCanvas;
4968
const Rect: TRect; const Flags: Longint): TRect;
5069
{Gets rectangle of size required to display text in a specified canvas.
@@ -59,8 +78,10 @@ implementation
5978

6079

6180
uses
81+
// Delphi
82+
SysUtils,
6283
// Project
63-
SysUtils;
84+
UStructs;
6485

6586

6687
{ Helper routines }
@@ -91,6 +112,43 @@ procedure FreeDisplayCanvas(var Canvas: TCanvas);
91112
end;
92113
end;
93114

115+
/// <summary>Returns width of the widest of the given strings when rendered a
116+
/// specified font.</summary>
117+
/// <remarks>Width is calculated in pixels, but is converted to returned value
118+
/// by closure passed as a parameter.</remarks>
119+
/// <param name="AStrings"><c>array of string</c> [in] Strings whose rendered
120+
/// width is to be measured.</param>
121+
/// <param name="AFont"><c>TFont</c> [in] Font in which strings are to be
122+
/// rendered.</param>
123+
/// <param name="AConverter"><c>TFunc&lt;HDC, Integer, SmallInt&gt;</c> [in]
124+
/// Converter function used to convert result to required units, using the
125+
/// handle of the font canvas.</param>
126+
/// <returns><c>SmallInt</c>. Width of widest string in array in twips.
127+
/// </returns>
128+
function InternalMaxStringWidth(const AStrings: array of string;
129+
const AFont: TFont; const AConverter: TFunc<HDC, Integer, SmallInt>):
130+
SmallInt;
131+
var
132+
Str: string;
133+
StrWidth: Integer;
134+
MaxStrWidth: Integer;
135+
Canvas: TCanvas; // canvas used to measure text extent
136+
begin
137+
MaxStrWidth := 0;
138+
Canvas := CreateDisplayCanvas(AFont);
139+
try
140+
for Str in AStrings do
141+
begin
142+
StrWidth := Canvas.TextExtent(Str).cx;
143+
if StrWidth > MaxStrWidth then
144+
MaxStrWidth := StrWidth;
145+
end;
146+
Result := AConverter(Canvas.Handle, MaxStrWidth);
147+
finally
148+
FreeDisplayCanvas(Canvas);
149+
end;
150+
end;
151+
94152
{ Public routines }
95153

96154
function CreateDisplayDC: HDC;
@@ -144,6 +202,39 @@ function StringExtent(const S: string; const Font: TFont): TSize; overload;
144202
end;
145203
end;
146204

205+
function MaxStringWidthTwips(const AStrings: array of string;
206+
const AFont: TFont): SmallInt;
207+
begin
208+
Result := InternalMaxStringWidth(
209+
AStrings,
210+
AFont,
211+
function (CanvasHandle: HDC; MaxStrWidthPx: Integer): SmallInt
212+
var
213+
PxPerInchX: Integer;
214+
const
215+
TwipsPerInch = 1440;
216+
begin
217+
// convert pixels to twips
218+
PxPerInchX := GetDeviceCaps(CanvasHandle, LOGPIXELSX);
219+
Result := SmallInt(Round(MaxStrWidthPx * TwipsPerInch / PxPerInchX));
220+
end
221+
);
222+
end;
223+
224+
function MaxStringWidthPx(const AStrings: array of string; const AFont: TFont):
225+
SmallInt;
226+
begin
227+
Result := InternalMaxStringWidth(
228+
AStrings,
229+
AFont,
230+
function (CanvasHandle: HDC; StrWidthPx: Integer): SmallInt
231+
begin
232+
// no conversion
233+
Result := SmallInt(StrWidthPx);
234+
end
235+
);
236+
end;
237+
147238
function GetTextRect(const Text: string; const Canvas: TCanvas;
148239
const Rect: TRect; const Flags: Longint): TRect;
149240
{Gets rectangle of size required to display text in a specified canvas.

0 commit comments

Comments
 (0)