Graphics.PictureBrush reliably causes a hard crash on Windows & Linux

Feedback Case Number 68188:

Using Graphics.PictureBrush causes a hard application crash that is uncatchable on Windows 11 and Linux. The code runs fine on macOS.

Put the following code in the Paint event of a Canvas on a window:

Var pb As New PictureBrush
pb.Image = CheckerboardPattern
pb.Mode = PictureBrush.Modes.Tile
g.Brush = pb
g.FillRoundRectangle(0, 0, g.Width, g.Height, g.Height, g.Height)

Checkerboard is an ImageSet dragged onto the Xojo IDE.

The app will run correctly on macOS and crash immediately on Windows and Linux.

There is no workaround.

The bug is present in the latest public release also the latest testing release.

Has anybody actually ever tested PictureBrush on anything other than macOS?? Seems amazing that such a hard crash has escaped testing.

Here’s an example project: Dropbox - PictureBrush Bug.zip - Simplify your life

This works here:

pb.Image = CheckerboardPattern.BestRepresentation(16, 16, me.ScaleFactor)

Edit: But the picture is not drawn in the required size on HiDPI screens. Seems that the picture brush fill method ignores the scaling.

Edit 2: What maybe works (not tested): Create a picture based on the scaling and set the hor and ver resolution to 72 * ScalingFactor manually.

1 Like

Thanks @Carsten_Belling.

This kind of works but I’m a little confused by your second edit.

This is what it should look like (macOS):

With this code:

pb.Image = CheckerboardPattern.BestRepresentation(16, 16, me.ScaleFactor)

I get this (on Windows):

I tried tinkering around with setting the resolution with this code:

Var p As Picture = Self.Window.BitmapForCaching(16, 16)
p.HorizontalResolution = 72 * g.ScaleX
p.VerticalResolution = 72 * g.ScaleY
p.Graphics.DrawPicture(CheckerboardPattern, 0, 0)
pb.Image = p

But I get the same appearance.

Am I doing the resolution computation wrong?

This works here on both macOS and Windows:

Var pb As New PictureBrush

#if TargetMacOS
  pb.Image = CheckerboardPattern
  
#else
  var f   as double = me.ScaleFactor
  var src as Picture = CheckerboardPattern.BestRepresentation(16, 16, f)
  var p   as new Picture(16 * f, 16 * f)
  
  p.Graphics.DrawPicture(src, 0, 0, p.Width, p.Height, 0, 0, src.Width, src.Height)
  p.HorizontalResolution = 72 * f
  p.VerticalResolution   = p.HorizontalResolution
  
  pb.Image = p
#endif

pb.Mode = PictureBrush.Modes.Tile
g.Brush = pb
g.FillRoundRectangle(0, 0, g.Width, g.Height, g.Height, g.Height)

Note: If you inspect the picture ‘p’ in the debugger at a scaling <> 1.0 after the checkerboard pattern is drawn into it, you will see a incorrect result.

Thanks for helping with this @Carsten_Belling but it’s still not working how I expect it (this could be my misunderstanding).

I’ve changed the height of the canvas to 16 pixels (new binary file attached).

On macOS it looks like this:

but on Windows it looks like this:

Can you see the difference? On macOS its showing the full image (which is 16 pixels tall @1x) but you only see half the squares on Windows.

Project file.

Different scaling on mac? (may be x2 ?)

Sorry Garry, I must have been deceived by the checkerboard pattern. I have Windows set to 125 DPI. Then the difference is not so big. If I change to 200 DPI I see the same as in your screenshot. So it doesn’t work like that, because PictureBrush under Windows doesn’t care about the DPI of the image.

It seems that this works for every DPI setting under Windows:

#If TargetMacOS
  pb.Image = CheckerboardPattern
#Else
  pb.Image = CheckerboardPattern.BestRepresentation(16, 16, 1.0)
#EndIf
1 Like

It works. Awesome. Cheers mate.