I've been using BGRABitmap for a few years now. After initial problems with my SVGs, it worked like a charm... until two days ago I updated Lazarus & FPC to the latest trunk, and updated BGRABitmap as well, from 9.9.1 (or .3?) to 10.6.2.0 (from OPM). Now my GUI crashes on calling draw on TBGRASVG objects, ignoring the existing exception handling...
Project Test raised exception class 'External: SIGSEGV'.
At address 5B0EC5
Here's the crash callstack:
#0 BGRASVGTYPE$_$TSVGELEMENT_$__$$_APPLYSTROKESTYLE$TBGRACANVAS2D$TCSSUNIT at :0
#1 BGRASVGSHAPES$_$TSVGPATH_$__$$_INTERNALDRAW$TBGRACANVAS2D$TCSSUNIT at :0
#2 BGRASVGSHAPES$_$TSVGPATH_$__$$_INTERNALDRAW$TBGRACANVAS2D$TCSSUNIT at :0
#3 BGRASVGTYPE$_$TSVGELEMENT_$__$$_DRAW$TBGRACANVAS2D$TCSSUNIT at :0
#4 ?? at :0
Here's the crashing code example:
procedure TForm1.Button1Click(Sender: TObject);
var
w, h: TFloatWithCSSUnit;
c: TCSSUnitConverter;
dWidth, dHeight: single;
ico: TBGRASVG;
bmp: TBGRABitmap;
begin
ico := TBGRASVG.Create('c:\qa\bgra-test.svg');
w := ico.Width;
h := ico.Height;
c := TCSSUnitConverter.Create;
try
dWidth := c.ConvertWidth(w.Value, w.CSSUnit, cuPixel) * ScreenInfo.PixelsPerInchX / 96;
dHeight := c.ConvertHeight(h.Value, h.CSSUnit, cuPixel) * ScreenInfo.PixelsPerInchY / 96;
bmp := TBGRABitmap.Create((Round(dWidth)), (Round(dHeight)), BGRAPixelTransparent);
try
ico.Draw(bmp.Canvas2D, 0, 0, cuPixel); // this call crashes
Image1.Picture.Assign(bmp.Bitmap);
bmp.SaveToFile(ExtractFilePath(ParamStr(0)) + 'test.png');
except
on E: Exception do begin
{$IFDEF MSWindows}
// not triggered, program already crashed
OutputDebugString('Unable to convert resource from SVG to PNG');
{$ENDIF MSWindows}
end;
end;
finally
c.Free;
end;
end;
I've been trying out various things. If I add BGRABitmap by source path (and remove the package code), debug mode will work (as will 64 bit Windows release binary, but not 32 bit Windows release binary).
This looks like some kind of optimization kills functionality in release mode (standard release mode from build mode manager) - both if directly compiled by source path, and by using the package (which is with release mode settings I guess).
Without the package, at least the exception handling gets triggered, with an "Access violation".