Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: How to turn a string into a shape?


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jul 18, 2014 11:54 AM Last Post By: Peter Below
Alain Forget

Posts: 6
Registered: 1/11/14
How to turn a string into a shape?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 17, 2014 2:08 PM
I'm trying to convert a string into a shape on a canvas. In Java, there is a class called GlyphVector (http://docs.oracle.com/javase/7/docs/api/java/awt/font/GlyphVector.html) in which an instance is created by a Font. I was wondering if there was something similar to this in Delphi. If not, what would be the way to convert a string into a shape?

Java code:
private static final FontRenderContext FRC
= new FontRenderContext(null, true, true);
public Shape generate(final Font font, final double weight, final String word,
final double orientation) {
final Font sizedFont = font.deriveFont((float) weight);
final char[] chars = word.toCharArray();
final int direction = Bidi.requiresBidi(chars, 0, chars.length) ?
Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT;
final GlyphVector gv =
sizedFont.layoutGlyphVector(FRC, chars, 0, chars.length, direction);
Shape result = gv.getOutline();
if (orientation != 0.0){
result = AffineTransform.getRotateInstance(orientation)
.createTransformedShape(result);
}
return result;
}


Alain
Robert Triest

Posts: 687
Registered: 3/24/05
Re: How to turn a string into a shape?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 17, 2014 2:41 PM   in response to: Alain Forget in response to: Alain Forget
You can use OpenGL for this.

http://www.sulaco.co.za/opengl_project_3D_font_tutorial.htm

Is that what you mean?
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: How to turn a string into a shape?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 18, 2014 11:54 AM   in response to: Alain Forget in response to: Alain Forget
Alain Forget wrote:

I'm trying to convert a string into a shape on a canvas. In Java,
there is a class called GlyphVector
(http://docs.oracle.com/javase/7/docs/api/java/awt/font/GlyphVector.ht
ml) in which an instance is created by a Font. I was wondering if
there was something similar to this in Delphi. If not, what would be
the way to convert a string into a shape?

Delphi does not wrap the full APIs available in Windows for working
with fonts, only the most commonly used.
The API has functions like GetGlyphOutline, for example, and it also
has a Postscript-like set of drawing functions (BeginPath, use normal
font output with a truetype font, CloseFigure, EndPath, StrokePath
etc.).

To create a rotated font you don't need to go that deep into the API,
however. There are two approaches available: rotate the coordinate
system, or create a font with an rotation angle <> 0 (only works for
truetype fonts).

Drawing rotated text using world transforms

function HeightOfRect(const aRect: TRect): Integer;
begin
Result := aRect.Bottom - Arect.Top;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
PB: TPaintbox;
CV: TCanvas;
XF: TXForm;
R, R2: TRect;
const
SWrapText = 'This is some rather long text that wraps.';
begin
PB := Sender as Tpaintbox;
CV := PB.Canvas;
CV.Brush.Color := clWhite;
CV.Brush.Style := bsSolid;
CV.FillRect(PB.ClientRect);
CV.Font.Name := 'Tahoma';
CV.Font.Size := 12;
CV.TextOut(10, 10, 'Example text');
FillChar(XF, Sizeof(XF), 0);
SetGraphicsMode(CV.Handle, GM_ADVANCED);
try
// set up rotation by 90 degress counterclockwise
XF.eM11 := 0.0; // cos(-Pi/2)
XF.eM12 := -1.0; // sin(-Pi/2);
XF.eM21 := 1.0; // -sin(-Pi/2);
XF.eM22 := 0.0; // cos(-Pi/2);
XF.eDx := PB.ClientWidth / 2; // center coordinate origin
XF.eDy := PB.ClientHeight / 2;
SetWorldTransform(CV.Handle, XF);
CV.MoveTo(-100, 0);
CV.LineTo(100, 0);
CV.MoveTo(0, -100);
CV.LineTo(0, 100);
R:= Rect(0, 0, 200, 100);
CV.Pen.COlor := clRed;
CV.Rectangle(R);
R2 := R;
// Vertically center the wrapped text in R. DT_VCENTER only
// works for single line text!
DrawText(Cv.Handle, SWrapText, Length(SWrapText), R2,
DT_NOPREFIX or DT_WORDBREAK or DT_CALCRECT);
R.Top := R.Top + (HeightOfRect(R) - HeightOfRect(R2)) div 2;
DrawText(Cv.Handle, SWrapText, Length(SWrapText), R,
DT_NOPREFIX or DT_WORDBREAK);
finally
ModifyWorldTransform(CV.Handle, XF, MWT_IDENTITY);
SetGraphicsMode(CV.Handle, GM_COMPATIBLE);
end;
CV.TextOut(10, 100, 'Example text 2');
end;

Example for display of rotated text:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls, Buttons, ExtCtrls, Grids;

type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
FontDialog1: TFontDialog;
Panel1: TPanel;
PaintBox1: TPaintBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button2Click(Sender: TObject);
begin
If fontdialog1.execute then
panel1.font := fontdialog1.font;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
lf: TLogFont;
begin
FillChar( lf, sizeof(lf), 0 );
GetObject( panel1.font.handle, sizeof(lf), @lf );
lf.lfEscapement := StrToInt( edit1.text );
lf.lfOrientation := lf.lfEscapement;
panel1.font.handle := CreateFontIndirect( lf );
panel1.invalidate;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
With (Sender As TPaintbox) Do Begin
Canvas.TextOut( 10,10, '' );
SetTextAlign( Canvas.handle, TA_CENTER or TA_BASELINE );
TextOut( Canvas.Handle,
clientwidth div 2 + left,
clientheight div 2 + top,
'Teststring',
10 );
End;
end;

end.

{
object Form1: TForm1
Left = 192
Top = 128
Width = 487
Height = 347
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 120
TextHeight = 16
object Label1: TLabel
Left = 8
Top = 256
Width = 135
Height = 16
Caption = 'Angle in 1/10 degrees:'
end
object Edit1: TEdit
Left = 8
Top = 280
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit1'
end
object Button1: TButton
Left = 144
Top = 280
Width = 75
Height = 25
Caption = 'SetAngle'
TabOrder = 1
OnClick = Button1Click
end
object Button2: TButton
Left = 248
Top = 280
Width = 75
Height = 25
Caption = 'Font...'
TabOrder = 2
OnClick = Button2Click
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 479
Height = 241
Align = alTop
TabOrder = 3
object PaintBox1: TPaintBox
Left = 1
Top = 1
Width = 477
Height = 239
Align = alClient
OnPaint = PaintBox1Paint
end
end
object FontDialog1: TFontDialog
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'MS Sans Serif'
Font.Style = []
MinFontSize = 0
MaxFontSize = 0
Left = 408
Top = 272
end
end
}

--
Peter Below (TeamB)

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02