Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Rotate multi-line text on any angle

Posted on 2004-11-14
6
Medium Priority
?
1,335 Views
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).
0
Comment
Question by:BlackTigerLV
3 Comments
 
LVL 4

Accepted Solution

by:
Mikho earned 336 total points
ID: 12581966
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
TextOut

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
0
 
LVL 18

Assisted Solution

by:Johnjces
Johnjces earned 332 total points
ID: 12584932
There is a component available that I use and modified to easily rotate a bitmap. It is available (freeware with source) from :

http://www.delphiarea.com/products/#TRotateImage

(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.

I.E.

procedure TFAddSticky.Image1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
 bmp : TBitmap;
begin
 IsMouseDown := True;
 image1.Picture := nil;
 bmp := TBitmap.Create;
 try
   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
    else
     bmp.Canvas.Font.Color := clBlack;
   if ColorComboBox1.ColorValue = clWhite then
    bmp.Transparent := True
     else
      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]);
   try
    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;  
     finally
      bmp.Free;
   end;
  finally
 end;
end;

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
    begin
     TheAngle := -SpinEdit2.Value;
     tempbmp.Canvas.Draw(Round(X*2.6), Round(Y*3),CreateRotatedBitmap(bmp, TheAngle, 16777215));
    end
     else
   if ComboBox2.Text = 'Angled Up' then
    begin
     TheAngle := SpinEdit2.Value;   //3.86          //4.3
     tempbmp.Canvas.Draw(Round(X*3), Round(Y*0.8),CreateRotatedBitmap(bmp, TheAngle, 16777215));
    end
     else
    begin
     ComboBox2.Text := 'Horizontal';
     TheAngle := 0;                         //4.5
     tempbmp.Canvas.Draw(Round(X*3.3), Round(Y*3.35),CreateRotatedBitmap(bmp, TheAngle, 16777215));
    end;
    Image1.Picture.Bitmap := tempbmp;
     finally
      bmp.Free;
   end;
  finally
 end;
end;

Haope this may help you.
0
 
LVL 14

Assisted Solution

by:DragonSlayer
DragonSlayer earned 332 total points
ID: 12586637
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);
var
  LogFont: TLogFont;
  FontHandle: THandle;
  TextAlign: Integer;
begin
  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));
end;

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.


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

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

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

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

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

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

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

Code is courtesy of Kambiz of DelphiArea.com
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Suggested Courses

810 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