1

I am drawing a (large) Boolean Table (Binary 0,1 values in a large grid pattern) with a PaintBox. As in the code below. Note: The code is simplified, only drawing random 0 and 1, to represent the problem. Also I have updated the question with the full code, since the commenter stated the initial question was vague.

Utilising the FillText to draw the (hundreds) of individual binary (0 or 1) values turned out to be SLOW!. Also when doing a lot of panning across the PaintBox, the app would freeze, and force close on the Android device.

So clearly the FillText is not sufficient for this case, and are wondering if anyone knows of a better technique?

procedure TMainWin.PaintBoxPaint(Sender: TObject; Canvas: TCanvas);
VAR Fcstroke:TStrokeBrush;
    xp,yp,Tsze:INTEGER;
    tw,th:SINGLE;
    p1,p2:TPointF;
    MyRect:TRectF;
begin
   Canvas.BeginScene;
   // Clear
   Canvas.Clear(TAlphaColorRec.Beige);
   Canvas.Fill.Color:= TAlphaColorRec.Black;
   Canvas.Fill.Kind:= TBrushKind.Solid;
   // Text Prop
   Canvas.Font.Family:= 'Roboto';
   Canvas.Font.Style:= [];
   Canvas.Font.Size:= 40;
   Canvas.Stroke.Thickness:= 2;
   Canvas.Stroke.Kind:= TBrushKind.Solid;
   Canvas.Stroke.DefaultColor:= TAlphaColorRec.Black;
   tw:= Canvas.TextWidth('0')*1.2;
   th:= Canvas.TextHeight('0');
   Fcstroke:= TStrokeBrush.Create(TBrushKind.Solid,TAlphaColorRec.Green);
   Fcstroke.DefaultColor:= TAlphaColorRec.Green;
   Fcstroke.Thickness:= 2;
   // Table
   Tsze:= 50;
   FOR yp:= 1 TO Tsze DO
   BEGIN
      // Horz table Line
      p1:= TPointF.Create(         tw,yp*th);
      p2:= TPointF.Create((Tsze+1)*tw,yp*th);
      Canvas.DrawLine(p1,p2,1,Fcstroke);
      // Vert table Line
      p1:= TPointF.Create(yp*tw,         th);
      p2:= TPointF.Create(yp*tw,(Tsze+1)*th);
      Canvas.DrawLine(p1,p2,1,Fcstroke);
      // Text
      FOR xp:= 1 TO Tsze DO
      BEGIN
         MyRect:= TRectF.Create(xp*tw,yp*th,xp*tw+tw,yp*th+th);
         IF (Random(10)>5) THEN
           Canvas.FillText(MyRect,'0',False,100,[],TTextAlign.Center,TTextAlign.Center)
         ELSE
           Canvas.FillText(MyRect,'1',False,100,[],TTextAlign.Center,TTextAlign.Center);
      END;
   END;
   // End
   Canvas.EndScene;
end;
ChasH
  • 11
  • 3
  • 1
    Canvas.FillText is not suitable for drawing a lot of text in a loop. I am not sure if there is more appropriate method (hence, I will not answer), but FillText creates transient TTextLayout object to do the actual drawing. You can integrate that code into yours to create that instance only once and then use it to draw text in a loop without calling Canvas.FillText – Dalija Prasnikar Sep 15 '18 at 09:04

1 Answers1

0

You must encapsulate your your drawing by BeginScene and EndScene, or else the drawing will be very slow:

Canvas.BeginScene;
try
  //all your painting routines here
  Canvas.FillText(...);
  ... 
finally
  Canvas.EndScene;
end;
Hans
  • 2,220
  • 13
  • 33
  • Yes I am well aware of needing BeginScene and EndScene, and my code does have this already. Still the FillText commands are seemingly highly resource intensive. When I use Circles (DrawEllipse) for "0" and Lines (DrawLine) for "1" the code runs fine, fast and does not crash (force close). So there is something highly resource intensive for FillText. I can keep using Circles and Lines, for 0 and 1, but longer term, I would like to use actual 0 and 1 characters, – ChasH Sep 12 '18 at 05:19
  • In that case your question is not good because you do not mention that in your question at all. The most common reason for bad performance in FMX is missing Begin/EndScene, and that is what I answered. No reason to downvote my answer because you made an incomplete question! Please correct your question. – Hans Sep 12 '18 at 07:22
  • @Hans OP could not down vote your answer because he does not have enough reputation to down vote. He does not even have enough reputation to upvote either. – Dalija Prasnikar Sep 15 '18 at 08:56
  • You posted wild guess answer that has nothing to do with the question. Even original question (while it did lack more code) had enough information to pinpoint the issue. Issue lies in FillText not in BeginScene/EndScene. – Dalija Prasnikar Sep 15 '18 at 08:58
  • @DalijaPrasnikar You are right that it's a guess, but certainly not a wild guess, as the most common reason for low painting performance on FMX is for that reason. Since ChasH is new on SO I also assumed he was new to FMX. Of course I could have made a comment to the question instead, but I tried to work against the trend on SO that everyone answers as a comment, being afraid of downvotes and flaming. – Hans Sep 15 '18 at 11:14
  • @Hans If you are willing to wild guess, then you have to accept the possibility that your answer might be wrong. I suggest that you remove this answer. It will not get more correct with time (unless you completely rewrite it) and it can only accumulate more down votes. – Dalija Prasnikar Sep 15 '18 at 12:30