<Question>
When programming printing code, how to measure string?
<Answers>
Yang Ning:
You can't use Graphics.MeasureString Function, and must use typographic StringFormat object.
Reason is: when printing string size is resolution-dependent.
And if you using MeasureString function or use defaultgraphic StringFormat object, it is resolution-independent,
the result will be smaller than the true one.
Below is sample code:
Public Shared Function GetTextSize(ByVal g As Graphics, _
ByVal text As String, _
ByVal textFont As Font) As SizeF
If text.Length = 0 Then Return New SizeF(0, 0)
Dim s As StringFormat = StringFormat.GenericTypographic
s.FormatFlags = StringFormatFlags.MeasureTrailingSpaces
Dim textRect As RectangleF
Dim characterRanges As CharacterRange() = {New CharacterRange(0, text.Length)}
s.SetMeasurableCharacterRanges(characterRanges)
textRect = g.MeasureCharacterRanges(text, textFont, New RectangleF(0, 0, 4000, 4000), s)(0).GetBounds(g)
Return New SizeF(textRect.Right, textRect.Bottom)
End Function
BTW:
We found a bug when we use code like above. The bug is FlexGrid's column caption will display disorder. So We use following code instead
Public Shared Function GetTextSize(ByVal g As Graphics, _
ByVal text As String, _
ByVal textFont As Font) As SizeF
If text.Length = 0 Then Return New SizeF(0, 0)
Dim s As StringFormat = StringFormat.GenericTypographic
Dim oldFlags As StringFormatFlags
oldFlags = s.FormatFlags
s.FormatFlags = StringFormatFlags.MeasureTrailingSpaces
Try
Dim textRect As RectangleF
Dim characterRanges As CharacterRange() = {New CharacterRange(0, text.Length)}
s.SetMeasurableCharacterRanges(characterRanges)
textRect = g.MeasureCharacterRanges(text, textFont, New RectangleF(0, 0, 4000, 4000), s)(0).GetBounds(g)
Return New SizeF(textRect.Right, textRect.Bottom)
Finally
StringFormat.GenericTypographic.FormatFlags = oldFlags
End Try
End Function