Rotate multi-line text on any angle

Posted on 2004-11-14
Last Modified: 2008-03-03
I need to rotate MULTI-LINE text on canvas.

All examples shows how to rotate single-line text.

Function must to work on any windows (95-XP) (SetWorldTransform isn't suitable).
Question by:BlackTigerLV
    LVL 4

    Accepted Solution

    Taken from win32 programmer reference:

    The CreateFont function creates a logical font that has specific characteristics. The logical font can subsequently be selected as the font for any device.

    HFONT CreateFont(

        int nHeight,      // logical height of font
        int nWidth,      // logical average character width
        int nEscapement,      // angle of escapement
        int nOrientation,      // base-line orientation angle
        int fnWeight,      // font weight
        DWORD fdwItalic,      // italic attribute flag
        DWORD fdwUnderline,      // underline attribute flag
        DWORD fdwStrikeOut,      // strikeout attribute flag
        DWORD fdwCharSet,      // character set identifier
        DWORD fdwOutputPrecision,      // output precision
        DWORD fdwClipPrecision,      // clipping precision
        DWORD fdwQuality,      // output quality
        DWORD fdwPitchAndFamily,      // pitch and family
        LPCTSTR lpszFace       // pointer to typeface name string

    with this you can create the font of your choice then you output the text with

    This is the definition in Win32 programmers reference but you can also use the TCanvas.Textout
    BOOL TextOut(

        HDC hdc,      // handle of device context
        int nXStart,      // x-coordinate of starting position  
        int nYStart,      // y-coordinate of starting position  
        LPCTSTR lpString,      // address of string
        int cbString       // number of characters in string

    oh .. for multiline .. either use Textout once for each line ( if you want to choose the space between the lines or in most cases you can use the combination #13#10 in your text.
    'text1' + #13#10 + 'Text2';

    good luck
    LVL 18

    Assisted Solution

    There is a component available that I use and modified to easily rotate a bitmap. It is available (freeware with source) from :

    (I had to fix/add the transparent property to the main routine)

    With that component it is easy to rotate and image to any angle. Now I also do multiline rotations using a TMemo. First you need to create a rectangle to contain the test as a graphic. Use one line in the memo for one line fo text. I use this an OnMouseDwon event in a TImage. I can also load an image if I want to paste the text onto it.


    procedure TFAddSticky.Image1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
     bmp : TBitmap;
     IsMouseDown := True;
     image1.Picture := nil;
     bmp := TBitmap.Create;
       bmp.Width := 210;
       bmp.Height := 165;
       bmp.Canvas.Brush.Color := ColorComboBox1.ColorValue;
       bmp.Canvas.FillRect(rect(0, 0, bmp.Width, bmp.Height));
       if (ColorComboBox1.ColorValue = clBlack) or (ColorComboBox1.ColorValue = clMaroon) or
       (ColorComboBox1.ColorValue = clGreen) or (ColorComboBox1.ColorValue = clNavy) then
       bmp.Canvas.Font.Color := clWhite
         bmp.Canvas.Font.Color := clBlack;
       if ColorComboBox1.ColorValue = clWhite then
        bmp.Transparent := True
          bmp.Transparent := False;
       bmp.Canvas.TextOut(10, 5, Memo1.Lines[0]);
       bmp.Canvas.TextOut(10, 20, Memo1.Lines[1]);
       bmp.Canvas.TextOut(10, 35, Memo1.Lines[2]);
       bmp.Canvas.TextOut(10, 50, Memo1.Lines[3]);
       bmp.Canvas.TextOut(10, 65, Memo1.Lines[4]);
       bmp.Canvas.TextOut(10, 80, Memo1.Lines[5]);
       bmp.Canvas.TextOut(10, 95, Memo1.Lines[6]);
       bmp.Canvas.TextOut(10, 110, Memo1.Lines[7]);
       bmp.Canvas.TextOut(10, 125, Memo1.Lines[8]);
       bmp.Canvas.TextOut(10, 140, Memo1.Lines[9]);
        tempbmp := TBitmap.Create;
       // Get an image (bmp) I want to stick this text on
        tempbmp.LoadFromFile(ExtractFileDir(ParamStr(0)) + '\~tmp.bmp');    
      // Stick this sticky on the canvas where  the mouse is at and clicked. NOT NEEDED NOW
      // I would use ...Draw(0,0,bmp) for now.
      tempbmp.Canvas.Draw(Round(X*3.333), Round(Y*3.33),bmp);
        Image1.Picture.Bitmap := tempbmp;  

    To rotate the image add the rotimg.pas to your uses clauses (no need to install the component) and then somewhere above and before sticking the image to the canvas rotate it. I.E. (a snippet)

    if ComboBox2.Text = 'Angled Down' then // ComboBox has a numeric value for angles
         TheAngle := -SpinEdit2.Value;
         tempbmp.Canvas.Draw(Round(X*2.6), Round(Y*3),CreateRotatedBitmap(bmp, TheAngle, 16777215));
       if ComboBox2.Text = 'Angled Up' then
         TheAngle := SpinEdit2.Value;   //3.86          //4.3
         tempbmp.Canvas.Draw(Round(X*3), Round(Y*0.8),CreateRotatedBitmap(bmp, TheAngle, 16777215));
         ComboBox2.Text := 'Horizontal';
         TheAngle := 0;                         //4.5
         tempbmp.Canvas.Draw(Round(X*3.3), Round(Y*3.35),CreateRotatedBitmap(bmp, TheAngle, 16777215));
        Image1.Picture.Bitmap := tempbmp;

    Haope this may help you.
    LVL 14

    Assisted Solution

    Will this help? Of course, it only works with TrueType fonts:

    procedure DrawAngledText(Canvas: TCanvas; X, Y: Integer;
      const Angle: Double; Alignment: Integer; const Text: String);
      LogFont: TLogFont;
      FontHandle: THandle;
      TextAlign: Integer;
      GetObject(Canvas.Font.Handle, SizeOf(LogFont), @LogFont);
      LogFont.lfEscapement := Round(Angle * 10);
      LogFont.lfOrientation := LogFont.lfEscapement;
      LogFont.lfQuality := PROOF_QUALITY;
      FontHandle := SelectObject(Canvas.Handle, CreateFontIndirect(LogFont));
      TextAlign := SetTextAlign(Canvas.Handle, Alignment);
      Canvas.TextOut(X, Y, Text);
      SetTextAlign(Canvas.Handle, TextAlign);
      DeleteObject(SelectObject(Canvas.Handle, FontHandle));

    The Angle parameter is in degrees and the Alignment parameter specifies the text alignment by using a mask of the values in the following list. Only one flag can be chosen from those that affect horizontal and vertical alignment.

    The reference point will be on the base line of the text.

    The reference point will be on the bottom edge of the bounding rectangle.

    The reference point will be on the top edge of the bounding rectangle.

    The reference point will be aligned horizontally with the center of the bounding rectangle.

    The reference point will be on the left edge of the bounding rectangle.

    The reference point will be on the right edge of the bounding rectangle.

    sample usage:
    procedure TForm1.FormPaint(Sender: TObject);
      DrawAngledText(Canvas, ClientWidth div 2, ClientHeight div 2,
      45, TA_BOTTOM or TA_CENTER, 'Powered by Borland Delphi.');

    Code is courtesy of Kambiz of

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Join & Write a Comment

    Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
    Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
    how to add IIS SMTP to handle application/Scanner relays into office 365.
    This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor ( If you're looking for how to monitor bandwidth using netflow or packet s…

    729 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now