Solved

Delphi 5 - formatting text onto a page

Posted on 2004-04-29
8
217 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
[X]
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
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

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.

Question has a verified solution.

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

Suggested Solutions

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…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

730 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