Solved

Delphi 5 - formatting text onto a page

Posted on 2004-04-29
8
204 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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

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 33

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

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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

708 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

12 Experts available now in Live!

Get 1:1 Help Now