Link to home
Start Free TrialLog in
Avatar of Primoz Ivancic
Primoz Ivancic

asked on

Delphi XE7 Firemonkey - text turns black after tabbing between applications on android

Hi all,

I'm developing a project with Delphi XE7 primarily for android users, and everything works fine more or less. If I minimize the app and then tab back into it with the home button, originally nothing was drawing (everything was black), but I fixed that by removing images off the form and loading them via resources. Unfortunately the text drawing cannot be moved into a resource and needs to be fixed as is. See attached screenshot where it shows some text drawing correctly and some not drawing/black boxes. Note that this is on a second page of the app, all text on the first page was turned black, and only the same letters were turned black on the second. The game does continue to work as expected only the text is black.

I have a multidevice application project with a Layer3D on the form, and an image inside that. I draw into the canvas of that image (including the text). I needed to do it this way since regular refreshing did not appear to work without a Layer3D.

Procedure TForm1.DrawText(Canvas: TCanvas; Text: String; Rect: TRectF; FontSize: Single; Color: TColor; Opacity: Single; Align: TTextAlign = TTextAlign.Center);
Begin
  Canvas.Font.Size := FontSize;
  Canvas.Stroke.Color := TAlphaColors.Alpha;
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(OffsetRect(Rect, -1, -1), Text, True, Opacity, [], Align, TTextAlign.Center);
  Canvas.FillText(OffsetRect(Rect, -1,  1), Text, True, Opacity, [], Align, TTextAlign.Center);
  Canvas.FillText(OffsetRect(Rect,  1,  1), Text, True, Opacity, [], Align, TTextAlign.Center);
  Canvas.FillText(OffsetRect(Rect,  1, -1), Text, True, Opacity, [], Align, TTextAlign.Center);
  Canvas.Fill.Color := Color;
  Canvas.FillText(Rect, Text, True, Opacity, [], Align, TTextAlign.Center);
End;


          DrawText(Canvas, IntToStr(I), ButtonMenuLevelSelectLevelsTitle[I], ButtonMenuLevelSelectLevelsTitle[I].Height / 6 * 3, TAlphaColors.White, 1.0);

Open in new window


Any help is appreciated,
Thanks,
Primoz
Not-Ok-v2.png
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

use beginscene/endscene ....
if Canvas.BeginScene then
begin
  try
    Canvas.Font.Size := FontSize;
    Canvas.Stroke.Color := TAlphaColors.Alpha;
    Canvas.Fill.Color := TAlphaColors.Black;
    Canvas.FillText(RectF(Rect.Left - 1, Rect.Top - 1, Rect.Right - 1, Rect.Bottom - 1),
      Text, True, Opacity, [], Align, TTextAlign.Center);
    Canvas.FillText(RectF(Rect.Left - 1, Rect.Top + 1, Rect.Right - 1, Rect.Bottom + 1),
      Text, True, Opacity, [], Align, TTextAlign.Center);
    Canvas.FillText(RectF(Rect.Left + 1, Rect.Top + 1, Rect.Right + 1, Rect.Bottom + 1),
      Text, True, Opacity, [], Align, TTextAlign.Center);
    Canvas.FillText(RectF(Rect.Left + 1, Rect.Top - 1, Rect.Right + 1, Rect.Bottom - 1),
      Text, True, Opacity, [], Align, TTextAlign.Center);
    Canvas.Fill.Color := Color;
    Canvas.FillText(Rect, Text, True, Opacity, [], Align, TTextAlign.Center);
  finally
    Canvas.EndScene;
  end;
end;

Open in new window


You draw text 4 times.... to get outline.... another idea is to use paths:
var
  TextLayout: TTextLayout;
  TextPath: TPathData;
Begin
if Canvas.BeginScene then
begin
  try
    Canvas.Stroke.Color := TAlphaColors.Black;
    Canvas.Stroke.Kind := TBrushKind.Solid;
    Canvas.StrokeThickness := 1;
    Canvas.Font.Size := FontSize;

    TextLayout := TTextLayoutManager.DefaultTextLayout.Create;
    try
      TextPath := TPathData.Create;
      try
        TextLayout.Font.Assign(Canvas.Font);
        TextLayout.Text := Text;
        TextLayout.ConvertToPath(TextPath);
        TextPath.ApplyMatrix(TMatrix.CreateTranslation(Rect.Left, Rect.Top));
        Canvas.Fill.Color := Color;
        Canvas.FillPath(TextPath, Opacity);
        Canvas.DrawPath(TextPath, Opacity);
      finally
        TextPath.Free;
      end;
    finally
      TextLayout.Free;
    end;
  finally
    Canvas.EndScene;
  end;
end;

Open in new window


Two problems is here too. There is no word wrapping nor clipping....
Avatar of Primoz Ivancic
Primoz Ivancic

ASKER

Thanks, I already use beginscene and endscene, inside a timer which calls this procedure. Sorry I didn't post all the code, figured this was enough to be relevant.
  DrawCanvas.Canvas.BeginScene();
  DrawCanvas.Canvas.Clear(TAlphaColorRec.Black);
...
drawtext code and other stuff
...
  DrawCanvas.Canvas.EndScene();

  //Refresh the screen
  Form1.Invalidate;

Open in new window


Note that just calling begin/end scene itself does not actually draw anything onto the screen, i have to call invalidate.

Thanks for the font paths suggestion - i didn't even know such a thing existed. This is completely off topic (and let me know if you think I should make a seperate question for it), but considering you know a lot about this - do you know how to load custom fonts from resource (google has been unhelpful)?

Thanks,
Primoz
ASKER CERTIFIED SOLUTION
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you very much, after I moved the code into OnRender (and as such had to add FMX.Types3D) everything started drawing perfectly. I'm not sure if it was one or the other but the issue is fixed. You're a legend.