This works fine on macOS
But on Windows if you use bitmapforcahcing to hold onto a picture properly configured like the graphics you get in a paint event (so you can do measurements etc outside the pain event) and use code like
Dim p As picture = Self.BitmapForCaching(1,1)
System.debuglog "g.StringWidth = " + Str(g.StringWidth("abcdefghijklmn"))
System.debuglog "p.Graphics.StringWidth = " + Str(p.Graphics.StringWidth("abcdefghijklmn"))
you will find that you do NOT get the same measurements
The recommendation is to create a picture with alpha and then it measures the same way the graphics surface does. Which means you need to write your own version of bitmapforcaching
And here you go
So you can, for windows, pass in a depth which is needed if you want to get string measurements the same as you would get from the graphics in a paint event
This at least gives you the option to get one that measures strings the same
And, like so many things, it doesnt matter which you use on macOS as it just measures the same either way
Public Function BetterBitmapForCaching(extends g as graphics, width as integer, height as integer, depth as integer = 0) as Picture
Dim p As picture
If depth <> 0 Then
p = New picture(width * g.ScaleX, height * g.ScaleY, depth )
Else
p = New picture(width * g.ScaleX, height * g.ScaleY )
End If
p.Graphics.ScaleX = g.ScaleX
p.Graphics.ScaleY = g.ScaleY
p.Graphics.AntiAlias = g.AntiAlias
p.Graphics.AntiAliasMode = g.AntiAliasMode
p.Graphics.Bold = g.Bold
p.Graphics.ForeColor = g.ForeColor
p.Graphics.Italic = g.Italic
p.Graphics.PenHeight = g.PenHeight
p.Graphics.PenWidth = g.PenWidth
p.Graphics.TextFont = g.TextFont
p.Graphics.TextSize = g.TextSize
p.Graphics.TextUnit = g.TextUnit
p.Graphics.Transparency = g.Transparency
p.Graphics.Underline = g.Underline
return p
End Function
Public Function BetterBitmapForCaching(extends w as Window, width as integer, height as integer, depth as integer = 0) as Picture
Dim base As picture = w.BitmapForCaching(1,1)
If base <> Nil Then
Dim g As graphics = base.Graphics
Dim p As picture
If depth <> 0 Then
p = New picture(width * g.ScaleX, height * g.ScaleY, depth )
Else
p = New picture(width * g.ScaleX, height * g.ScaleY )
End If
p.Graphics.ScaleX = g.ScaleX
p.Graphics.ScaleY = g.ScaleY
p.Graphics.AntiAlias = g.AntiAlias
p.Graphics.AntiAliasMode = g.AntiAliasMode
p.Graphics.Bold = g.Bold
p.Graphics.ForeColor = g.ForeColor
p.Graphics.Italic = g.Italic
p.Graphics.PenHeight = g.PenHeight
p.Graphics.PenWidth = g.PenWidth
p.Graphics.TextFont = g.TextFont
p.Graphics.TextSize = g.TextSize
p.Graphics.TextUnit = g.TextUnit
p.Graphics.Transparency = g.Transparency
p.Graphics.Underline = g.Underline
Return p
End If
End Function
I’m not sure I understand your problem. Probably not. Why don’t you continue using Xojo’s own BitmapForCaching and create a MeasurePicture with the dimension 1, 1? Then you can use it to get the string width.
Does this mean that we can’t use BitmapForCaching on Windows at all, as it has existed for years?
If you have code in the paint event that uses the passed in graphics to measure strings you will get a different measurement than one created from BitMapForCaching
Try this on macOS and Windows
new desktop app
add paint event to window1
in the paint event put
Dim p As picture = Self.BitmapForCaching(1,1)
System.debuglog "g.StringWidth = " + Str(g.StringWidth("abcdefghijklmn"))
System.debuglog "p.Graphics.StringWidth = " + Str(p.Graphics.StringWidth("abcdefghijklmn"))
you get different measurements for the same string - one from the passed in graphics and one from bitmapforcaching
So IF you create a bitmapforcaching to retain & use outside the paint event you will get the wrong sizes
feedback://showreport?report_id=60512