Recent

Author Topic: TextOutAngle with subscript and superscript chars  (Read 441 times)

vertnik

  • New Member
  • *
  • Posts: 20
TextOutAngle with subscript and superscript chars
« on: September 17, 2019, 09:58:56 am »
Hi!

It is possible to use subscript or superscript chars with text routines (TextOutAngle or Canvas2D.Text)?
I would like to draw text with chemical formulas.

Robert

Handoko

  • Hero Member
  • *****
  • Posts: 3237
  • My goal: build my own game engine using Lazarus
Re: TextOutAngle with subscript and superscript chars
« Reply #1 on: September 17, 2019, 02:23:27 pm »
If you don't need angle calculation, subscript and superscript can be easily done using TCanvas:

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, Graphics, StdCtrls, Types;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.     fTextPosX: Integer;
  19.     fTextPosY: Integer;
  20.     fFontSize: Integer;
  21.     fFontColor: TColor;
  22.   public
  23.     procedure TextInit(X, Y, S: Integer; C: TColor);
  24.     procedure TextColor(C: TColor);
  25.     procedure TextNormal(const S: string);
  26.     procedure TextSuperscript(const S: string);
  27.     procedure TextSubscript(const S: string);
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure TForm1.Button1Click(Sender: TObject);
  40. begin
  41.  
  42.   TextInit(30, 20, 18, clBlack);
  43.   TextNormal('E := MC');
  44.   TextSuperscript('2');
  45.  
  46.   TextInit(30, 60, 18, clBlack);
  47.   TextNormal('H');
  48.   TextSubscript('3');
  49.   TextNormal('O');
  50.   TextSuperscript('+');
  51.  
  52.   TextInit(30, 100, 18, clBlack);
  53.   TextNormal('Lazarus is ');
  54.   TextColor(clRed);    TextNormal('a');
  55.   TextColor(clPurple); TextNormal('w');
  56.   TextColor(clGreen);  TextNormal('e');
  57.   TextColor(clBlue);   TextNormal('s');
  58.   TextColor(clWhite);  TextNormal('o');
  59.   TextColor(clMaroon); TextNormal('m');
  60.   TextColor(clYellow); TextNormal('e');
  61.  
  62. end;
  63.  
  64. procedure TForm1.TextInit(X, Y, S: Integer; C: TColor);
  65. begin
  66.   fTextPosX  := X;
  67.   fTextPosY  := Y;
  68.   fFontSize  := S;
  69.   fFontColor := C;
  70. end;
  71.  
  72. procedure TForm1.TextColor(C: TColor);
  73. begin
  74.   fFontColor := C;
  75. end;
  76.  
  77. procedure TForm1.TextNormal(const S: string);
  78. var
  79.   TextSize: TSize;
  80. begin
  81.   with Canvas do
  82.   begin
  83.     Brush.Style := bsClear;
  84.     Font.Color  := fFontColor;
  85.     Font.Size   := fFontSize;
  86.     TextSize    := TextExtent(S);
  87.     TextOut(fTextPosX, fTextPosY, S);
  88.   end;
  89.   Inc(fTextPosX, TextSize.cx);
  90. end;
  91.  
  92. procedure TForm1.TextSuperscript(const S: string);
  93. var
  94.   NewSize  : Integer;
  95.   TextSize : TSize;
  96. begin
  97.   NewSize := (fFontSize*2) div 3;
  98.   with Canvas do
  99.   begin
  100.     Brush.Style := bsClear;
  101.     Font.Color  := fFontColor;
  102.     Font.Size   := NewSize;
  103.     TextSize    := TextExtent(S);
  104.     TextOut(fTextPosX, fTextPosY, S);
  105.   end;
  106.   Inc(fTextPosX, TextSize.cx);
  107. end;
  108.  
  109. procedure TForm1.TextSubscript(const S: string);
  110. var
  111.   NewSize  : Integer;
  112.   TextSize : TSize;
  113. begin
  114.   NewSize := (fFontSize*2) div 3;
  115.   with Canvas do
  116.   begin
  117.     Brush.Style := bsClear;
  118.     Font.Color  := fFontColor;
  119.     Font.Size   := NewSize;
  120.     TextSize    := TextExtent(S);
  121.     TextOut(fTextPosX, fTextPosY+NewSize, S);
  122.   end;
  123.   Inc(fTextPosX, TextSize.cx);
  124. end;
  125.  
  126. end.

The code above doesn't need BGRABitmap but you can modify it to use BGRABitmap with no or some little changes.
« Last Edit: September 17, 2019, 02:29:14 pm by Handoko »

wp

  • Hero Member
  • *****
  • Posts: 6486
Re: TextOutAngle with subscript and superscript chars
« Reply #2 on: September 17, 2019, 06:39:37 pm »
ChemText is a ready-made component to display chemical formulas. Install via Online-Package-Manager.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

vertnik

  • New Member
  • *
  • Posts: 20
Re: TextOutAngle with subscript and superscript chars
« Reply #3 on: September 19, 2019, 07:11:07 pm »
Handoko, I implemented your approach with BGRABitmap. It works.

With Bitmap.Canvas2D:
Code: Pascal  [Select]
  1. Bitmap.Canvas2D.resetTransform; // to reset previous transformations
  2. Bitmap.Canvas2D.translate(x,y); // move pen to start position of text
  3. Bitmap.Canvas2D.rotate(rotation); // in case we need rotation
  4. Bitmap.Canvas2D.beginPath;
  5.   {here, I use Bitmap.Canvas2D.measureText(S) and
  6.   Bitmap.Canvas2D.Text(S, fTextPosX, fTextPosY) to draw normal,
  7.   superscript or subscript text}
  8. Bitmap.Canvas2D.fill; // to draw whole text    
  9.  

wp, chemtext is very good component, but I think can not be used in BGRABitmap.

Thank you both,

Robert


winni

  • Hero Member
  • *****
  • Posts: 591
Re: TextOutAngle with subscript and superscript chars
« Reply #4 on: September 19, 2019, 08:01:48 pm »
@vertnik:

You can use ChemText together with BGRABitmap. The main drawing function in ChemText is:

Code: Pascal  [Select]
  1. function ChemTextOut(ACanvas: TCanvas;  X, Y:integer; const AText: String;
  2.   Arrow: TChemArrow = caAsciiSingle; Measure: Boolean = false): TSize;

So you only need a canvas to paint on. The BGRABitmap has a "normal and simple" canvas.

You can write

Code: Pascal  [Select]
  1. Var bit: TBGRABitmap;
  2.       ts: Tsize;
  3.  
  4. begin
  5. .......
  6. ts := ChemTextOut ( bit.canvas, 10, 10, 'C21H30O2', caUTF8, false);
  7. end;
  8.  

Winni
« Last Edit: September 19, 2019, 08:15:52 pm by winni »

vertnik

  • New Member
  • *
  • Posts: 20
Re: TextOutAngle with subscript and superscript chars
« Reply #5 on: September 20, 2019, 05:30:14 am »
@winni:

Thanks, but I also need rotation and antialliasing. I will use chemtextout in other
controls, like drawing into the cell of stringgrid.

vertnik