Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Delphi 5 - formatting text onto a page

Posted on 2004-04-29
8
212 Views
Last Modified: 2010-04-05
I am very much a beginner programmer using Delphi5.  The app I am trying to complete is to create a graphical representation of a label before it is copied to a text file and sent to a novell print queue.  The user has up to 7 individual lines that they can choose to have text on and for each of those lines, they can have 1 of 5 text styles; be centred, l/j or r/j; and have different text widths and heights.  What I need is a way of stretching the text for the display.  I have tried using the text as a label, but have had no luck displaying it properly.  The only other thought that I have is to create each line as a bitmap, and then using some form of stretching it to size.

Any other thoughts would be most appreciated.  I can email the project to anybody who wants to see what I am actually doing.

REMEMBER TO SPEAK SLOWLY AND CLEARLY AS I AM A NEWBIE!!

Many thanks
Peter
0
Comment
Question by:peetah
  • 3
  • 3
8 Comments
 
LVL 3

Expert Comment

by:Kunfufaresi
ID: 10954400
Hello,

You can do it by creating a canvas then use textout to write text on it and later save it as bitmap or whatever format you need.

Kunfu Faresi
0
 
LVL 3

Expert Comment

by:Kunfufaresi
ID: 10954450
--snip--
var
  Bitmap : tbitmap;

begin
  Bitmap := TBitmap.Create;

  Bitmap.Width := 300;
  Bitmap.Height := 100;
 
  Bitmap.Canvas.Font.Name  := 'Arial';
  Bitmap.Canvas.Font.Color := RGB(0,255,0);
  Bitmap.Canvas.Font.Style := [];
  Bitmap.Canvas.Font.Style + [fsBold];
//  Bitmap.Canvas.Font.Style + [fsItalic];  you can use some "if ..then" to add these styles
//  Bitmap.Canvas.Font.Style + [fsUnderline];
  Bitmap.Canvas.Font.Size := 12;
  Bitmap.Canvas.brush.Style := bsClear; // make it transparent background if you want text to be on top of image
  Bitmap.Canvas.TextOut(Rect( 10, 10, ' Hello World!');
  Bitmap.SaveToFile('c:\temp.bmp');
end;
--snip--  

This should do it. Write one line of text into a bitmap, just increase the font size and initial size of graphic to get higher resolution. screens are ususally 72-75dpi, so you can do the math of 17" screen with 1024 resolution about how much you need for a 300dpi printing. the font size can be doubled the same way, if you want 12dpi on 72 then it should be around 48 on 300 dpi, and image width should be 1200 for this example.

Kunfu Faresi
0
 
LVL 3

Expert Comment

by:Kunfufaresi
ID: 10954470
Also about alignment, you would have to use TextRect instead of textOut. Also you will need to to get width using TextExtent function, then you can center for instance by saying disply x position of text is (width of paper/2)-(width of text/2), left align is just make x=1, and right align is x=width of paper - width of text
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:peetah
ID: 10954602
The problem that I have is that the user may choose to increase the width of the font, but not the height.  I am writing to a text file (simple writeln) to be interpreted by the printer using EPL1 print language.  The format of the output file is:

Ap1,p2,p3,p4,p5,p6,p7,"TEXT"

A is a constant
p1 is x position on the label (to be calculated by the app depending on font, width, and alignment)
p2 is y position on the label (to be calculated by the app depending on top of the previous line - height of previous text - line spacer)
p3 is rotation (not changed in my app)
p4 is font selection 1 = 12x20 dots }
                            2 = 16x28        }
                            3 = 20x36        }  All fonts are fixed size, not proportional.
                            4 = 24x44        }
                            5 = 48x80        }
p5 is width multiplier (1-6)
p6 is vertical multiplier (1-9)
p7 is normal or reversed text
"TEXT" is the text from the TEdit field

As an example a line may be:

Axxx,yyy,0,2,2,3,"Hello"

This means that the characters are going to be 32x84 (font 2 16x28, width multiplier 2, height multiplier 3).

Each line could be different and the problem is in the drawing of the label reflecting this.  If it was a DOS app, then the screen font is pretty easy, but it is trying to do it under Windows without creating a new font.

I hope I have expanded what I need properly.

Peter
0
 

Author Comment

by:peetah
ID: 10955706
Just re-read it again - what I need a way of representing the font with different sizes and alignments on the screen only - in a kind of MS Office 'Print Preview'.  When it prints, it doesn't use printer drivers, but saves it as a text-file with each line as Ap1,p2,p3,p4,p5,p6,p6"TEXT" and copies it to the print queue.
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 125 total points
ID: 10965259
hello peetah, I have used a TMetaFile to have Text that is Resizable, able to be stretched to fit in a certain Rectangle, here is some code for a button click that will show you some of how to do this -

procedure TForm1.sbut_DrawMetaFileTextClick(Sender: TObject);
var
MetaFile: TMetaFile;
oFont: TFont;
i, TextHeight, oWidth, oHeight: Integer;
Str1: String;
begin
oFont := TFont.Create;
oFont.Assign(PaintBox1.Canvas.Font);
PaintBox1.Canvas.Font.Name := 'Arial';
PaintBox1.Canvas.Font.Height := -20;
TextHeight := PaintBox1.Canvas.TextHeight('M');

Str1 := 'Text in String';
MetaFile := TMetaFile.Create;
MetaFile.Width := PaintBox1.Canvas.TextWidth(Str1);
{Make the width and height of the metafile as the TextWidth and TextHeight
for the font and text you want to place in the metafile}
MetaFile.Height := PaintBox1.Canvas.TextHeight(Str1);
PaintBox1.Canvas.Font.Assign(oFont);
FreeAndNil(oFont);

with TMetafileCanvas.Create(MetaFile, 0) do
  begin
  Font.Name := 'Arial';  // same font as TextWidth and TextHeight
  Font.Height := -20;
  SetBkMode(Handle, Transparent);
  {set the background Mode to Transparent}
  TextOut(0,0,Str1);
  Free;
  end;
oWidth := MetaFile.Width;
oHeight := MetaFile.Height;
PaintBox1.Canvas.Draw(4, 4, MetaFile);

MetaFile.Width := MetaFile.Width-19;
{unlike a Bitmap, , a MetaFile will stretch Everything on it to the new
Width and Height, so if there is Text on the metafile, it will expand
or contract with the new metafile dimentions}
MetaFile.Height := MetaFile.Height -3;
{you might experiment with the metafile width and height, to see
what it will do with the text that it contains}
PaintBox1.Canvas.Draw(4, 34, MetaFile);

MetaFile.Width := oWidth + 94;
// change the width and height to your own specs
MetaFile.Height := oHeight + 11;
PaintBox1.Canvas.Draw(4, 64, MetaFile);

FreeAndNil(MetaFile);
end;


 = = = = = = = = = = = = = = = = = = = = = = =

below is some code that might help you in your Preview print thing, I can not understand your printer specs - -
Ap1,p2,p3,p4,p5,p6,p7,"TEXT"

, so I did not try and use those.
You may can get some ideas fom this, this form has One PaintBox, Width = 260 , Height = 202, , , and One SpeenButton on it.




type
  TLineRec = record
    Empty: Boolean; //true if text string is empty
    PosX, PosY: Integer;
    MetaF: TMetaFile;
    end;
{the TLineRec will have the Position PosX and PosY for drawing the TMetaFile, MetaF}


  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    sbut_SetPreView: TSpeedButton;
    sbut_DrawMetaFileText: TSpeedButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure sbut_SetPreViewClick(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);

  private
    { Private declarations }
    PreViewLines: Array[0..6] of TLineRec;




procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 6 do
  PreViewLines[i].Empty := True; // set all empty
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i: Integer;
begin
for i := 0 to 6 do
  FreeAndNil(PreViewLines[i].MetaF);
// be sure to Free metafiles
end;


procedure TForm1.sbut_SetPreViewClick(Sender: TObject);
const
FontHeight: Integer = -24;

var
aryStr: Array[0..6] of String;
oFont: TFont;
i, TextHeight: Integer;

begin
{This is the button click that fills the PreViewLines array with data}
oFont := TFont.Create;
oFont.Assign(PaintBox1.Canvas.Font);
PaintBox1.Canvas.Font.Name := 'Courier New';
PaintBox1.Canvas.Font.Height := FontHeight;
TextHeight := PaintBox1.Canvas.TextHeight('M');
aryStr[0] := 'This is the FIRST Line';
aryStr[1] := 'the Second one';
aryStr[2] := 'Line Number three';
aryStr[4] := 'Fifth Line';
aryStr[6] := 'Line Seven here';
{aryStr  has the string text to place in the Lines,
some of the lines have no text}

for i := 0 to 6 do
  begin
{this FOR loop fills the PreViewLines Array with the, drawing Position
PosX and Pos Y, and Creates a TMetaFile, to have the Text to draw. . .
but you can set each of the PreViewLines array data individually, outside
of a loop, I used a FOR loop for code line reduction}

  if aryStr[i] = '' then
    begin
    PreViewLines[i].Empty := True; // set Empty to true if no text
    FreeAndNil(PreViewLines[i].MetaF); // Free the metaFile
    Continue;
    end;
  PreViewLines[i].Empty := False;
  PreViewLines[i].PosX := 1+(i * 12);
  {you can set the PosX to where you need it, I just
   use a formular for this loop}
  PreViewLines[i].PosY := 1 + (i * TextHeight);
  {the PosY should be increased by TextHeight for each different line}
  FreeAndNil(PreViewLines[i].MetaF);
{the way to Clear a metaFile is to Free it and ReCreate it}
  PreViewLines[i].MetaF := TMetaFile.Create;
  PreViewLines[i].MetaF.Width := PaintBox1.Canvas.TextWidth(aryStr[i]);
  {set the width and height to the Text dimentions}
  PreViewLines[i].MetaF.Height := PaintBox1.Canvas.TextHeight(aryStr[i]);
  with TMetafileCanvas.Create(PreViewLines[i].MetaF, 0) do
    begin
    Font.Name := 'Courier New';
    Font.Height := FontHeight;
    SetBkMode(Handle, Transparent);
    {set the background Mode to Transparent}
    TextOut(0,0,aryStr[i]);
    Free;
    end;
  PreViewLines[i].MetaF.Width := PaintBox1.Width - (PreViewLines[i].PosX+1);
  {the Width is Reset so that ALL text is expanded to the right border
  of the PaintBox}
  end;

PaintBox1.Canvas.Font.Assign(oFont);
FreeAndNil(oFont);
PaintBox1Paint(PaintBox1); // refresh paintbox
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
i: Integer;
begin
{this is the PaintBox1 OnPaint event}
PaintBox1.Canvas.Brush.Color := clWhite;
Paintbox1.Canvas.Rectangle(PaintBox1.ClientRect);
for i := 0 to 6 do
  if not PreViewLines[i].Empty then
    PaintBox1.Canvas.Draw(PreViewLines[i].PosX,
               PreViewLines[i].PosY, PreViewLines[i].MetaF);
    {for loop and draw all of the PreViewLines Array Metafiles}
end;

 = = = = = = = = = = = = = = = = = = = =  = =

ask questions if you need more information
0
 

Author Comment

by:peetah
ID: 10983223
Whew!

It's going to take me a while to digest this!  When I follow it fully I will respond.

Many, many thanks
Peter
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Simple Delphi Question 9 95
how to center only a line in richedit? 4 61
Reconfigure Delphi Install? 2 60
Error E2158 compiling with Delphi XE10 Seattle 2 112
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

792 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