Josef Švejk
Josef Švejk

Reputation: 1068

Draw glyph and WordWrap text together

I have a Canvas, Glyph, Text and variable Space as Integer. I want to draw Glyph and Text onto Canvas in according to TRadioGroup's ItemIndex (for example, if ItemIndex = 1 then draw Glyph by left side of the Text etc.) In any cases Space must be inserted as a blank space between Glyph and Text. Both, Glyph and Text must be centered onto Canvas, even if Canvas's width less then Glyph's width + Text's width.

I was trying to implement this task, but I was confused some calculations. Attaching my code below:

procedure TForm1.Button1Click(Sender: TObject);
var
  R1, R2: TRect;
  S: String;
  G, D: Integer;
  B, C: TBitmap;   
begin
  S := 'This is an example text to show how WordWrap works';
  B := TBitmap.Create;
  B.LoadFromFile('C:\g.bmp');

  C := TBitmap.Create;
  C.Width := 242;
  C.Height := 96;

  Form1.Repaint;
  Form1.Canvas.Brush.Color := clGreen;
  Form1.Canvas.FillRect(Rect(0, 0, TrackBar1.Position, C.Height));

  // left
  if RadioGroup1.ItemIndex = 0 then
    begin
      R1 := Rect(B.Width + TrackBar2.Position, 0, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]);

      Form1.Canvas.Brush.Color := clWebSkyBlue;
      R2 := Rect(B.Width + TrackBar2.Position, (C.Height - R1.Bottom) div 2, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]);

      Form1.Canvas.Draw((TrackBar1.Position - R1.Right - TrackBar2.Position) div 2, (C.Height - B.Height) div 2, B);
    end;

  //right
  if RadioGroup1.ItemIndex = 1 then
    begin
      R1 := Rect(B.Width + TrackBar2.Position, 0, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]);

      Form1.Canvas.Brush.Color := clWebSkyBlue;
      R2 := Rect(0, (C.Height - R1.Bottom) div 2, TrackBar1.Position - B.Width - TrackBar2.Position, C.Height);
      Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]);

      Form1.Canvas.Draw((TrackBar1.Position + R1.Right - (B.Width*2) + TrackBar2.Position) div 2, (C.Height - B.Height) div 2, B);
    end;

  //top
  if RadioGroup1.ItemIndex = 2 then
    begin
      R1 := Rect(0, B.Height + TrackBar2.Position, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]);

      G := B.Height + R1.Bottom - R1.Top;
      D := (C.Height - G) div 2;

      Form1.Canvas.Brush.Color := clWebSkyBlue;
      R2 := Rect(0, D + TrackBar2.Position, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]);

      Form1.Canvas.Draw((TrackBar1.Position - B.Width) div 2, D - TrackBar2.Position, B);
    end;

  //bottom
  if RadioGroup1.ItemIndex = 3 then
    begin
      R1 := Rect(0, B.Height + TrackBar2.Position, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]);

      G := B.Height + R1.Bottom - R1.Top;
      D := (C.Height + G) div 2;

      Form1.Canvas.Brush.Color := clWebSkyBlue;
      R2 := Rect(0, D - R1.Bottom - R1.Top + B.Height + TrackBar2.Position, TrackBar1.Position, C.Height);
      Form1.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]);

      Form1.Canvas.Draw((TrackBar1.Position - B.Width) div 2, D + TrackBar2.Position, B);
    end;

  FreeAndNil(B);
end;

How to use this code: put two TrackBars onto Form and set their Max value in 242 for the first and in 10 for the second; put TRadioGroup onto Form and set 4 items in its Items property in the next order: Left, Right, Top, Bottom.

So, when Left or Right item is chosen, the code work correctly (correctly - as I expect), but whe Top or Bottom item is chosen, Glyph and Text paintings not correct. I mean, for example, we choose item 'Top' and click Button1. What are we see? Right, Glyph is drawn on Text (see picture for more details). I have tried to defeat that but not successful, unfortunately:

Top glyph's issue

Well, is there any ways to improve this code? Or I should use another way to reach my goal?

P.S. Sorry for my poor English ;)

EDIT Update source code.

Upvotes: 2

Views: 426

Answers (1)

whosrdaddy
whosrdaddy

Reputation: 11860

Your calculations for top and bottom are wrong. And you can draw directly on the bitmap canvas instead of the form canvas. Here is the fixed version:

  //top
  if RadioGroup1.ItemIndex = 2 then
    begin
      R1 := Rect(0, B.Height + TrackBar2.Position, TrackBar1.Position, C.Height);
      C.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]);
      G := (C.Height div 2);
      // D is top for centered text rec + glyph size and spacing
      D := G + ((R1.Height + B.Height + Trackbar2.Position) div 2);
      C.Canvas.Brush.Color := clWebSkyBlue;
      R2 := Rect(0, D - R1.Height, TrackBar1.Position, D+R1.Height);
      C.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]);
      C.Canvas.Draw((TrackBar1.Position - B.Width) div 2, R2.Top - B.Height - TrackBar2.Position, B);
    end;

  //bottom
  if RadioGroup1.ItemIndex = 3 then
    begin
      R1 := Rect(0, 0, TrackBar1.Position, C.Height);
      C.Canvas.TextRect(R1, S, [tfWordBreak, tfNoClip, tfCenter, tfCalcRect]);
      // G is absolute middle of draw canvas
      G := (C.Height div 2);
      // D is top for centered text rec + glyph size and spacing
      D := G - ((R1.Height + B.Height + Trackbar2.Position) div 2);
      C.Canvas.Brush.Color := clWebSkyBlue;
      R2 := Rect(0, D, TrackBar1.Position, D + R1.Height);
      C.Canvas.TextRect(R2, S, [tfWordBreak, tfNoClip, tfCenter]);
      C.Canvas.Draw((TrackBar1.Position - B.Width) div 2, R2.Bottom + TrackBar2.Position, B);
    end;

Upvotes: 2

Related Questions