Work-around required for FPC / macOS
manliomazzon opened this issue · 1 comments
I discovered that when compiling for macOS on Apple Silicon machines (M1, M2, etc) and targeting x86_64, there is a compiler bug that causes Canvas.TextOut to ignore the Brush.color, even if Brush.style is NOT bsClear.
In other words, if you set a Brush.Color, and then set Brush.Style := bsSolid, and then call TextOut, the background color will NOT be applied. The result will be as if Brush.Style = bsClear.
This bug affects THtmlViewer, for example here: <span style="background-color:yellow;">Highlighted text</span> because ultimately that background color is applied with Brush.Style := bsSolid.
I have made my own crude work-around like this:
-
I Declare a global variable: var BuggyCanvas: TCanvas = nil;
-
In procedure DrawTheText (unit HTMLSubs), right under the line Canvas.Brush.Style := bsSolid; I add this new line: BuggyCanvas := Canvas;
-
When the time comes to actually write the text, in unit HtmlMisc, function ExtTextOutW(...), just before calling ExtTextOut, I do this:
{$IFDEF DARWIN}
{$IFDEF CPUX86_64}
if BuggyCanvas <> nil then begin
BuggyCanvas.FillRect(X, Y, X + BuggyCanvas.TextWidth(s), Y + BuggyCanvas.TextHeight(s));
BuggyCanvas := nil;
end;
{$ENDIF}
{$ENDIF}
// next line is the original code
Result := ExtTextOut(DC, X, Y, etc...
Explanation:
- Whenever the situation arises in which text must be written with a non-transparent background color (point 2 above), then I save the canvas to the variable BuggyCanvas.
- Just before writing text with TextOut/ExtTextOut, I check if BuggyCanvas is not nil, and in that case, knowing that TextOut will not do the job, I paint myself a rectangle of the correct size (TextWidth and TextHeight) at the correct position (X, Y) where the text is about to be painted. This work-around works perfectly for me.
- The two conditional defines ensure that the work-around is only applied when necessary.
Again this only happens when compiling on an Apple Silicon machine, targeting x86_64 i.e. Intel Apple machines.
Figuring this whole thing out took me a lot of time and effort, and so I hope that if you come across the same problem you'll find this solution quickly as well.
Thanks for this detailed description and workaround.