Aurigma Forums
»
Graphics Mill
»
Discussions – Graphics Mill
»
What is the best way to know the font size that will result in a specific BlackBox?
Rank: Member
Groups: Guest
Joined: 1/10/2016(UTC) Posts: 15
Thanks: 7 times
|
I'm trying to write program using GraphicsMill that will generate a PDF with a specific size. What is the best way to draw an ArtText that will fill the maximum area available as possible without having to stretch it? I'm trying to guess what is the best font size doing an exhaustive search for the font size starting on 1. That's not efficient at all and can take a lot of time depending on the target size. Do you have something to recommend? Code:
Imports Aurigma.GraphicsMill
Imports Aurigma.GraphicsMill.AdvancedDrawing
Imports Aurigma.GraphicsMill.AdvancedDrawing.Art
Imports Aurigma.GraphicsMill.AdvancedDrawing.Effects
Imports Aurigma.GraphicsMill.Codecs
Imports DPointF = System.Drawing.PointF
Imports DRectangleF = System.Drawing.RectangleF
(...)
Private Shared Sub UpdateFontSize(options As WarpedTextOptions, graphics As Graphics, targetRect As DRectangleF)
Dim unionBlackbox As New DRectangleF
Dim targetRectPixels As New DRectangleF(
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.X, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Y, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Width, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Height, Unit.Point))
options.TextFontSize = 1
Do
options.TextFontSize = options.TextFontSize + 1
Dim artText = GetArtText(options, graphics)
Dim textBlackBox = artText.GetBlackBox()
Dim shadowBlackbox As New DRectangleF(textBlackBox.Location, textBlackBox.Size)
shadowBlackbox.Inflate(options.Shadow.SizePixels, options.Shadow.SizePixels)
shadowBlackbox.Offset(options.Shadow.OffsetXPixels, options.Shadow.OffsetYPixels)
unionBlackbox = DRectangleF.Union(textBlackBox, shadowBlackbox)
Loop While unionBlackbox.Width < targetRectPixels.Width AndAlso unionBlackbox.Height < targetRectPixels.Height
options.TextFontSize = options.TextFontSize - 1
End Sub
(...)
|
|
|
|
Rank: Member
Groups: Guest
Joined: 1/10/2016(UTC) Posts: 15
Thanks: 7 times
|
As suggested by a friend of mine, I refactored the code to use binary search, that increased the performance from seconds to milliseconds. Does anyone see any problem on using the max value as the targetRect height. Code:
Imports Aurigma.GraphicsMill
Imports Aurigma.GraphicsMill.AdvancedDrawing
Imports Aurigma.GraphicsMill.AdvancedDrawing.Art
Imports Aurigma.GraphicsMill.AdvancedDrawing.Effects
Imports Aurigma.GraphicsMill.Codecs
Imports DPointF = System.Drawing.PointF
Imports DRectangleF = System.Drawing.RectangleF
(...)
Private Shared Sub UpdateFontSize(
options As WarpedTextOptions, graphics As Graphics, targetRect As DRectangleF)
Dim unionBlackbox As New DRectangleF
Dim targetRectPixels As New DRectangleF(
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.X, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Y, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Width, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Height, Unit.Point))
Dim min = MIN_FONT_SIZE
Dim max = targetRect.Height
options.TextFontSize = min
While min < max
Dim mid As Integer = CInt((min + max) / 2)
options.TextFontSize = mid
Dim artText = GetArtText(options, graphics)
Dim textBlackBox = artText.GetBlackBox()
Dim shadowBlackbox As New DRectangleF(textBlackBox.Location, textBlackBox.Size)
shadowBlackbox.Inflate(options.Shadow.SizePixels, options.Shadow.SizePixels)
shadowBlackbox.Offset(options.Shadow.OffsetXPixels, options.Shadow.OffsetYPixels)
unionBlackbox = DRectangleF.Union(textBlackBox, shadowBlackbox)
If (unionBlackbox.Width < targetRectPixels.Width AndAlso
unionBlackbox.Height < targetRectPixels.Height) Then
min = mid + 1
Else
max = mid - 1
End If
End While
End Sub
(...)
Edited by user Tuesday, August 30, 2016 4:11:31 PM(UTC)
| Reason: typo
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
Hi, Here is my code review. Code: Private Shared Sub UpdateFontSize(
options As WarpedTextOptions, graphics As Graphics, targetRect As DRectangleF)
Dim unionBlackbox As New DRectangleF
Dim targetRectPixels As New DRectangleF(
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.X, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Y, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Width, Unit.Point),
UnitConverter.ConvertUnitsToPixels(options.DPI, targetRect.Height, Unit.Point))
'Dim min = MIN_FONT_SIZE
' 1. The maximum size of inscribed figure is a diagonal of a rectangle
' 2. Use a font size of the float (Single) type. Otherwise you can get an inaccurate result
Dim max As Single = System.Math.Sqrt(targetRect.Height * targetRect.Height + targetRect.Width * targetRect.Width)
'Dim max = targetRect.Height
Dim max As Single = targetRect.Height
'options.TextFontSize = min
' 3. Limit an iteration count to prevent hanging
Const MAX_ITERATIONS As Integer = 20
Dim i = 0
'While min < max
' 4. Use a condition based on precison
Const PRECISION As Single = 0.05F
While (max - min) / max > PRECISION AndAlso i < MAX_ITERATIONS
' Dim mid As Integer = CInt((min + max) / 2)
' See p. 2
Dim mid As Single = CSng((min + max) / 2.0F)
options.TextFontSize = mid
Dim artText = GetArtText(options, graphics)
Dim textBlackBox = artText.GetBlackBox()
Dim shadowBlackbox As New DRectangleF(textBlackBox.Location, textBlackBox.Size)
shadowBlackbox.Inflate(options.Shadow.SizePixels, options.Shadow.SizePixels)
shadowBlackbox.Offset(options.Shadow.OffsetXPixels, options.Shadow.OffsetYPixels)
unionBlackbox = DRectangleF.Union(textBlackBox, shadowBlackbox)
' 5. There is no need to increment/decrement the mid value:
If (unionBlackbox.Width < targetRectPixels.Width AndAlso
unionBlackbox.Height < targetRectPixels.Height) Then
'min = mid + 1
min = mid
Else
'max = mid - 1
max = mid
End If
i = i + 1
End While
End Sub
Please be advised that the code is untested. Edited by user Wednesday, August 31, 2016 3:30:18 AM(UTC)
| Reason: Not specified |
Best regards, Fedor Skvortsov
|
1 user thanked Fedor for this useful post.
|
|
|
Rank: Member
Groups: Guest
Joined: 1/10/2016(UTC) Posts: 15
Thanks: 7 times
|
Hi Fedor, why the max font size should be the max size of the inscribed figure (diagonal)?
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
Please see the attached image:
|
Best regards, Fedor Skvortsov
|
|
|
|
Aurigma Forums
»
Graphics Mill
»
Discussions – Graphics Mill
»
What is the best way to know the font size that will result in a specific BlackBox?
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.