Foxite.COM Community Weblog

Foxite.COM Community Weblog - free weblog service for the Visual FoxPro Community.
Welcome to Foxite.COM Community Weblog Sign in | Join | Help
in
Home Blogs Forum Photos Forum Archives

VFP IMAGING



Full-Justified Text with GdiPlus-X

 

According to Wikipedia, "In typesetting, justification (can also be referred to as 'full justification') is the typographic alignment setting of text or images within a column or "measure" to align along both the left and right margin. Text set this way is said to be "justified".

 

In justified text, the spaces between words, and, to a lesser extent, between glyphs or letters (kerning), are stretched or sometimes compressed in order to make the text align with both the left and right margins. When using justification, it is customary to treat the last line of a paragraph separately by left or right aligning it, depending on the language direction. Lines in which the spaces have been stretched beyond their normal width are called loose lines, while those whose spaces have been compressed are called tight lines."

To create Full-Justified texts, the main point is to know exactly the measures of each word, and to be able to draw each word exactly in a certain position. Unfortunately, VFP does not bring thiese possibilities natively. Yes, I know we have TXTWIDTH and FONTMETRIC(6), but they are not that accurate. A good but not beautiful solution was to use some monospace fonts, like Courier New or Lucida Console, that every character has the same measures.

So, if we wanted to use any fonts, one of the few options was to use the RTF Active-X control, or to use an OLE Word object in a VFP form.

With the GdiPlus-X library, from now on you can also draw Full Justified texts in a very easy way too.

GDI+ originally allows to draw texts in three String Format Alignments: Left, Center and Right. In these last years, I've noticed that it's a very common request from VFP developers the ability to draw texts in FullJustified mode.

To draw Full-Justified strings we need to have the accurate measurements of each of the words in a paragraph, and draw each word individually in a calculated position. Well, no need to say that GDI+ provides the needed tools for the task. So, we added a new method to the Graphics class of the GdiPlus-X library, DRAWSTRINGJUSTIFIED.

Maybe you find that the natural choice would be to add a new StringFormat Alignment fot FullJustifying purposes, and let the method "DrawString" deal with the text and the received parameters and draw. But we believe that the original library, GdiPlus.dll will receive some updates in the future, and MS can possibly include a specific "StringFormat.Alignment" for our case. So, we found the best solution would be to create a new method, with a different name. The usage is very similar to the original "DrawString":

 

Method: DrawStringJustified(tcString, toFont as xfcFont, toBrush as xfcBrush, toRectangle as xfcRectangle)

PARAMETERS

tcString Character, String to Draw
toFont Object, Font that defines the text format of the string.
toBrush Object, Brush that determines the color and texture of the drawn text.
toRectangle Object, Rectangle structure that specifies the location of the drawn text.

 

HOW IT WORKS

Basically, DrawStringJustified receives the 4 parameters above, very similar to DrawString. But intead of drawing the whole text in one time, this function needs to make some calculations in order to know where exactly each word from the string will be drawn. It starts by populating an array of words and the calculated measures of each word, using GdipMeasureString. Then, calculates how many words will fit on each line. Next step is to calculate the resulting space between the words of the related line. After collecting all information needed, we draw each word at a time, at the calculated position.

For maximum performance, we used direct API calls to gdiplus.dll for the main process, measuring and drawing each string. I did some tests, and the difference is huge, about 5 times faster.

VERY IMPORTANT - READ THIS !

All samples below require that you have the latest PLANNED RELEASE, 0.08A. It's a little bit hidden at codeplex, so I'm putting below the link for direct downloading:

http://www.codeplex.com/VFPX/Release/ProjectReleases.aspx?ReleaseId=1711

TIME TO PLAY

1 - Draw Full-Justified strings in image files

The PRG below shows how to draw a text in 4 ways, left, centered, right and full justified, just like the picture above, and saves he image to a file.

** Program: FullJustCode.prg
** Sample program that draws text in 4 modes:
** 1 - Left Aligned
** 2 - Centered
** 3 - Right Aligned
** 4 - Full Justified

* The code performs the following actions:
* Creates a String
* Draws text in 4 modes and shows the results
* Locate and load GdiPlus-X
DO LOCFILE("System.App")
LOCAL lcText as Character
TEXT TO
lcText NOSHOW
GDIPlusX is a set of VFP 9.0 class libraries that wrap the 603 GDI+ Flat API functions of GDIPlus.dll.
The
library currently consist of 83 VFP classes and 1,146 methods. The project is still under development so not all classes have been completed and several of the classes/methods are still being tested.
ENDTEXT

WITH _Screen.System.Drawing

* Create Image
LOCAL loBmp as xfcBitmap
loBmp = .
Bitmap.New(400,600)

* Create a Graphics object to be able to draw on image
LOCAL loGfx as xfcGraphics
loGfx = .Graphics.FromImage(loBmp)

* Fill Image with White Background color
loGfx.Clear(.Color.White)

* Create a DarkBlue Brush
LOCAL loTextBrush AS xfcSolidBrush
loTextBrush = .SolidBrush.New(.
Color.DarkBlue)

* Create Font Object
LOCAL loFont AS xfcFont
loFont = .
Font.New("Tahoma", 11, .FontStyle.Regular)

* Create a StringFormat object
LOCAL loStringFormat as xfcStringFormat
loStringFormat = .StringFormat.New()

LOCAL lnHeight, lnWidth
lnWidth = 400
lnHeight = 150
 
* Draw Left Aligned Text
loStringFormat.Alignment = .StringAlignment.Near
loGfx.DrawString(lcText, loFont, loTextBrush, ;
   .Rectangle.New(0, 0, lnWidth, lnHeight), ;
   loStringFormat)
 
* Draw Centered Text
loStringFormat.Alignment = .StringAlignment.Center
loGfx.DrawString(lcText, loFont, loTextBrush, ;
   .Rectangle.New(0, lnHeight + 1, lnWidth, lnHeight), ;
   loStringFormat)
 
* Draw Right Aligned Text
loStringFormat.Alignment = .StringAlignment.Far
loGfx.DrawString(lcText, loFont, loTextBrush, ;
   .Rectangle.New(0, lnHeight * 2 + 1, lnWidth, lnHeight), ;
   loStringFormat)

* Draw Full Justified
loGfx.DrawStringJustified(lcText, loFont, loTextBrush, ;
   .Rectangle.New(0, lnHeight * 3 + 1, lnWidth, lnHeight))
 
* Draw a Red Border
loGfx.DrawRectangle(.Pen.New(.Color.Red,1), 0, 0, 399, 599)
 
* Save Image to Disk
loBmp.Save("c:\TestAlignment.png", .Imaging.ImageFormat.Png)

* Show Generated Text
RUN /n explorer.exe c:\TestAlignment.png

ENDWITH
RETURN

2 - Draw Full-Justified strings in Forms

The easiest way to draw a Full-Justified string in a form is using the ImageCanvas object. Below is the code that you need to add to the "BeforeDraw" method if the ImgCanvas. In my previous post, Direct Draw with the Image Canvas from GdiPlus-X you'll get a tutorial showing how to work with it, and some tips.

Note that I chose to reduce the code of the GDI+ drawing part, to show that with only two lines of code you can draw your Full-Justified string with the image canvas.

LOCAL lcText as Character
TEXT TO
lcText
NOSHOW
GDIPlusX is a set of VFP 9.0 class libraries that wrap the 603 GDI+ Flat API functions of GDIPlus.dll.
The library currently consist of 83 VFP classes and 1,146 methods. The project is still under development so not all classes have been completed and several of the classes/methods are still being tested. The Readme.htm file, included with the download, shows the current coding status of each class. As of August 31, 2006, the overall status of the library is about 97% coded and 60% tested.
ENDTEXT

WITH _Screen.System.Drawing
   * Fill Image with Background color
   This.oGfx.Clear(.Color.White)

   * Draw the Full-Justified text
   This.oGfx.DrawStringJustified(lcText, .Font.New("Tahoma", 12), ;
      .Brushes.Black, This.Rectangle)
ENDWITH

In the samples folder of the GdiPlus-X libary you'll find the form "FULLJUSTIFIED.SCX". Don't miss to run it, and play, changing the fonts, sizes, style, alignment type. But, in my opinion the most interesting feature of that sample is that you can resize the form, and the whole image will be redrawn in a flash ! Doing that you'll see how fast this routine works.

 

3 - Draw Full-Justified strings in reports.

This has become very easy too, after the creation of a specific report listener... but I prefer to leave this for my next post.

 

Maybe you have interest in the DRAWSTRINGJUSTIFIED method. To see the code, open the class xfcGraphics from the file Drawing.vcx. Look for the method "DrawStringJustified".

This method was not too much tested yet, so if you find any bug on it, or have any suggestion to improve its performance, or any other thing, please tell us !

Hope you enjoy !

PS: Of course, the above image was created with the library too.

Published Friday, March 30, 2007 4:02 AM by cesarchalom
Filed Under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Kevin Cully said:

Is there supposed to be an embedded image in this page?  The TestAlignment.png?  I'm not seeing it, and I don't see a reference to it in the HTML.

Hi Kevin,

Yes... it was a problem in the server where the images were hosted... Still trying to find the best place to host the pictures of this blog. I hope this is working fine right now. Thanks for reporting !

Regards

Cesar

March 30, 2007 1:30 PM
 

Kevin Cully said:

Working now and it looks great!

Great ! Thanks for coming back.

Here's a question that Dave Bernard always asks: is there a way of streaming an image straight into a variable without first writing the image to disk first?  He writes a lot of COM based web server stuff and this is always a sticking point.

Yes, that's totally possible. One of the few classes that is still missing in the library is the Stream management class. In GdiPlus-X we're already using streams with the image canvas, but that still needs some improvements. For the next release, Bo Durban has promised to finish that class. For this case, there's an extra work that needs to be done in C++, because VFP can't manage streams directly.  I hope to write about this soon too.

Keep up the great work!

Regards

Cesar

March 30, 2007 3:47 PM
 

Victor Espinoza said:

Excellent work!

I can't wait for the custom report listener, hopefully it will help me solve some of the problems with the "kerning" in the standard report listener. As you know the standard report listener renders different than the non-object-assisted reporting mode, causing some report forms to not display properly, more on that here:
http://msdn2.microsoft.com/en-us/library/ms978941(VS.80).aspx

Keep up the great work!

Regards

Victor

Hola Victor,

Thanks for the positive feedback ! I hope to post the listener and some new samples next week.

Keep in Touch !

March 30, 2007 8:17 PM
 

Olivier GAMOU said:

Hi Cesar !

Congratulation for your work ! , i wait this functionnality since years ago.

How do you dock your toolBar in the previewer ?
It's possible to have the code ?

thank's for all,
I follow your blog all week.
Olivier

Hi Olivier, thanks very much for your words.

Sorry, but I didn't understand your question... Are you looking forward to programatically dock your Print Toolbar  when previewing ?

If yes, there are some techniques available. Hope you can find some help at this link: http://support.microsoft.com/default.aspx?scid=kb;en-us;317466 http://support.microsoft.com/kb/317466/fr 

Regards

Cesar

April 4, 2007 12:15 PM
 

Victor Espinoza said:

Cesar, I believe Olivier meant the code for your custom report preview.

Olivier, you can find the source code for The report Preview directly from Micro$oft, it is part of the xsource download, here:

http://msdn2.microsoft.com/en-us/vfoxpro/bb190232.aspx

Micro$oft indicated that it's possible to use & modify code from the Xbase source. Read the license agreement.

Another sample of an improved ReportViewer, from here:

http://www.sweetpotatosoftware.com/SPSBlog/SearchView.aspx?q=reportpreview

Olivier, I hope this info helps you as much as it helped me.

Cesar, I tried sending this info to Olivier directly, but he left no email address and his link was no help, I hope you don't mind.

Hola Victor,

Oh, yes, now I understand. I'm using a customized reportpreview.app that I downloaded from UT, created by Dorin Vasilescu. That's pretty cool, and allows to make searches when previewing reports. Here's the direct link for this app: http://www.universalthread.com/wconnect/wc.dll?2,54,33,28296

Gracias !

Cesar

April 4, 2007 9:42 PM
 

Cesar Chalom said:


This is a continuation of my previous post, Full-Justified Text with GdiPlusX . Now I'll show...
April 5, 2007 2:39 PM
 

Christ said:

IS there any CHM for GDIPLUS Reference that can be download ?

Not that I'm aware.

I've installed a free copy of Visual Studio Express, and I use its Help. Works very nice, and as GdiPlusX is compatible with .NET GDI+ classes, you can have huge benefits using the Help,

Hope this helps

Cesar

April 10, 2007 7:35 AM
 

VFP IMAGING said:


 
The GdiPlusX library is intended to be compatible with the .NET Framework’s System.Drawing...
May 26, 2008 6:59 PM
 

etat vfp et justification des paragraphes | hilpers said:

April 9, 2009 5:03 PM
 

Zaheer Ahmed said:

Found a problem when justifying text to image file.  If 'SET STATUS BAR OFF' the Form processing code goes blank and every thing is stuck for a three finger salute.  It happens in design environment.
July 21, 2009 12:25 PM
 

Rüya Tabirleri said:

Thank you comment
September 1, 2010 8:37 PM

What do you think?

(required) 
(optional)
(required) 

This Blog

Post Calendar

<March 2007>
SuMoTuWeThFrSa
25262728123
45678910
11121314151617
18192021222324
25262728293031
1234567

Syndication