Page 1 of 3

xPrint - Printing Engine (WIP)

Posted: Thu Jun 22, 2006 10:44 pm
by Xombie
Alright, so this is definitely another work-in-progress. My latest project. I needed a way to print reports from work and this was my solution.

I've tried to mirror the way PB does it's window/gadgets creation. To create a report you simply have to do this...

Code: Select all

If xp_CreatePrintJob(#PrintMain, "Purebasic Invoice")
   ; Create a sample invoice.
   If xp_AddPage(1)
      ;
      xp_AddImage(#pLogo, 10, 60, -1, -1, "", ?PBLogo)
      xp_AddText(#pCompanyName, xp_GetX(#pLogo) + xp_GetWidth(#pLogo) + 50, 10, 1400, 180, "<fs18>Fantaisie Software")
      xp_AddLine(#pCompanyDivider, xp_GetX(#pCompanyName), xp_GetY(#pCompanyName) + xp_GetHeight(#pCompanyName) + 20, xp_GetX(#pCompanyName) + xp_GetWidth(#pCompanyName), xp_GetY(#pCompanyName) + xp_GetHeight(#pCompanyName) + 20, 1)
   EndIf
   ;
EndIf
So basically you're using a page as a kind of 'window' and adding stuff to it. Right now I have text, image, line, rectangle and custom object that can be used. It's a work-in-progress so features are missing and there are bugs. The largest bug is that the preview window is not WYSIWYG. I'm having issues with scaling to get the stuff properly placed.

Preview window? Yes, there is a preview window. So, once you have your report designed you only have to call...

Code: Select all

xp_Preview(#PrintMain)
Where '#PrintMain' was the printjob identifier from the first code block. You can print from the preview window or just call "xp_Print(#PrintMain)". You can set print options in 2 different ways. "xp_SetPrintingOptions" actually sets things like number of copies, pages you want to print, etc... "xp_SetPrintJobOptions" is more for the printer options themselves. Most of the options set there are remembered (should be) so that you can call multiple prints and keep the settings.

The largest part of this code is the way text is handled. I've implemented formatting tags. So, you can change bold text, underline, etc... in the middle of a text block. No need to to have multiple text objects just to change formatting.

I like to think the text printing is pretty darn good. Line breaking is properly handled for multiple lines of text and you can center or right-align your text. This is handled via custom code so it takes into account all that nice formatting you do mid-line. So far, the formatting stuff is...
  • 1. Bold text <b> </b>
    2. Italicize Text <i> </i>
    3. Underline Text <u> </u>
    4. Font Size <fsXX> </fs>
    5. Font Name <fnYYYYYYYYYY> </fn>
    6. Font Color <fcXXXXXXXX> </fc>
    7. Line Break <br>
    8. Tab <tab>
    9. Custom Tab Stops <tstopXX>
For most of them, you surround the text with the tags - like "<b>This is bold</b> but this is not." For the ones like line break, you just use the simple tag. I try to use an example of most of these functions in 'Main.pb' in the example report.

It took a lot of time to get the text to behave properly :x

You can have multiple pages for your report. The preview window will show them and all you to cycle through each page to see what it's like.

Images may be added by path or by address in memory so you can IncludeBinary your image and load it from there.

Please note that I use UseEC_OLEImageDecoder which can be grabbed from...

http://www.purebasic.fr/english/viewtop ... c&start=45
http://www.purearea.net/pb/download/use ... LE_2.3.zip

You can also create a 'custom' object and pass a procedure as one of the parameters. xPrint will call your procedure as needed and pass along the hdc, x/y/width/height and a couple other things so that you can do your own drawing. So if you're using a third part library for something like a barcode, you can draw it yourself through that procedure.

I welcome any extra ideas and info on any bugs you notice. As I said - there are two main ones - print preview doesn't scale properly and sometimes the border will not be completely drawn around text objects.

Oh, yeah, you can specify whether or not you want a border drawn around your text and whether you want a back color for the text area.

I'll continue working on this as I need it for work. If you find it useful, great :D If not, maybe you'll be able to use parts as examples.

It's released under LGPL. Take it easy 8)

http://www.seijin.net/Storage/Code/xPrint.zip

Posted: Fri Jun 23, 2006 10:33 am
by flaith
Hi Xombie, thanks a lot for your work, but i've an issue here (Open the scanned image)
It's ok when i use PDF Creator as a Printer.
NB: My printer is a HPDeskjet 990CXI with A4 format (french)
Thanks :)

great code

Posted: Fri Jun 23, 2006 2:17 pm
by z3phir2003
great code and it works :)

Posted: Fri Jun 23, 2006 5:36 pm
by Xombie
Thanks, z3phir2003 :)

@flaith - I'll have a debug version for you to test in a little bit. I'm afraid that printing is a really new area for me so I'm learning as I go.

One other thing I forgot to mention was that there is a very simple variable parser. Say you have a string variable called "FirstName". If you're going to print the report several times and the FirstName will change, you can use...

Code: Select all

"<@s"+str(@FirstName)+">"
And the code will replace that part with the value of FirstName. The first character after that '@' tells what kind of variable you're passing. In this case, 's' for 'string'. And then just pass the address to the variable. It's ugly but it works if needed.

Posted: Fri Jun 23, 2006 5:55 pm
by flaith
Thank you :)

Posted: Fri Jun 23, 2006 6:45 pm
by oryaaaaa
I am managing the PureBasic forum in Japan.
Recently, there was a question if the report was not able to be output
good quality for the print.
He was looking for FormPrint of VB.

This library might be the nearest the function to look for.

Thank you

Posted: Fri Jun 23, 2006 6:57 pm
by Xombie
oryaaaaa - you're welcome. I hope it works for him. Please don't hesitate to pass along any questions or suggestions that he may have. I'll do my best to answer them.

And speaking of forms, I forgot to mention some of the features I want to add in the future.
  • 1. The ability to print repeating information. Like rows from a query.
    2. The ability to print 'controls'. For example, to be able to print a 'checkbox control' that looks like a checkbox and even allows you to check or uncheck the box.
    3. An actual report designer so that you can create the report onscreen without having to use code.
    4. Header/Footer areas.
Number 3 is a little into the future but still something I'd like to do. I will have to fix the WYSIWYG part of the printing first.

@flaith - could you download http://www.seijin.net/Storage/Code/xPrint-Debug.zip ? Run it once and print to your HP printer. Email me the... hahah I misspelled the file in the code :oops: ... Well, pm me the text from 'xPring-Debug.txt'. I'll take a look to see if I can figure out what's happening.

Posted: Fri Jun 23, 2006 7:32 pm
by flaith
Thanks, i'll pm you the debug infos !

Posted: Fri Jun 23, 2006 7:46 pm
by Xombie
Oh, okay. I see what the problem is. It should have been very clear to me the first time >_<

I wrote the example report based on my own printer. Which is running at 600 DPI. I physically gave it x/y/width/height values based on an 8.5 inch x 11 inch paper (4900 x 6400 'pixels'). Your printer is at 300 DPI so my original values will show up twice as big on your printer.

Darn. So, okay, I'll just have to make the object dimensions independent of the current DPI and then just convert the dimensions properly when printing. I'll work on that next and should have something for you in the next few days.

However, I don't see why your image is being flipped. Normally that would be because your input or output dimenions are negative. Hummm... Well, I'll try the dimensions thing first and see how that impacts it.

Posted: Fri Jun 23, 2006 8:51 pm
by flaith
Great :D

Posted: Sat Jun 24, 2006 12:52 am
by oryaaaaa
He says. When the print form can be produced from displayed Gadget with the automatic operation, it is the best.

GadgetType()
GadgetX()
GadgetY()
GadgetWidth(#Gadget)
GadgetHeight(#Gadget)
GetGadgetFont(#Gadget)
GetGadgetColor(#Gadget, ColorType)
etc

Instead, if your concentration becomes interrupted, I make it. :D
What do you do?

Posted: Sat Jun 24, 2006 4:55 am
by oryaaaaa
I make it because the leave today and tomorrow.
I copy Gadget of the window onto the print form by one instruction.
I pass it to you and him if it completes it. 8)

Code: Select all

Procedure Window2xprint(WindowsID,Pages,FontName.s)
  Protected gadgetno.l
  If xp_CreatePrintJob(WindowsID, GetWindowTitle(WindowsID)) Or Pages>1
    If xp_AddPage(Pages)
      xp_SetTextDefaults(WindowsID, FontName.s,10 ,#Black,-1, #xp_TextAlign_Left,#xp_TextAlign_Top)
      
      For gadgetno=0 To 1000
        If IsGadget(gadgetno)
          Select GadgetType(gadgetno)
            Case #PB_GadgetType_Text
              Debug "TEXT"
              xp_AddText(gadgetno, GadgetX(gadgetno)*5, GadgetY(gadgetno)*5, GadgetWidth(gadgetno)*5, GadgetHeight(gadgetno)*5, GetGadgetText(gadgetno) )
              
            Case #PB_GadgetType_String
              xp_AddText(gadgetno, GadgetX(gadgetno)*5, GadgetY(gadgetno)*5, GadgetWidth(gadgetno)*5, GadgetHeight(gadgetno)*5, GetGadgetText(gadgetno) ,1)
              Debug "STRING"
            Case #PB_GadgetType_ListView
              Debug "ListVIEW"
            Case #PB_GadgetType_ComboBox
              Debug "COMBOBOX"
            Case #PB_GadgetType_Button
              Debug "BUTTON"
            Case #PB_GadgetType_ListIcon
              Debug "LISTICON"
            Case #PB_GadgetType_Image
              Debug "IMAGE"
            Case #PB_GadgetType_ButtonImage 
              Debug "BUTTONIMAGE"
          EndSelect
        EndIf
      Next  
    EndIf
  EndIf
  
EndProcedure
ADD::What capture fontdata??

Posted: Mon Jun 26, 2006 9:33 am
by LuckyLuke
Very nice !

Can't wait for header and footer support. :wink:

Posted: Mon Jun 26, 2006 7:10 pm
by Xombie
oryaaaaa wrote:ADD::What capture fontdata??
Do you mean how to change the font information for text? Use tags in the xp_AddText() string parameter. The first post in this topic shows all of them. For example, to change the font size and font for a text you could do ....

Code: Select all

xp_AddText(gadgetno, GadgetX(gadgetno)*5, GadgetY(gadgetno)*5, GadgetWidth(gadgetno)*5, GadgetHeight(gadgetno)*5, "<fnArial><fs28>"+GetGadgetText(gadgetno))
If you only wanted to change the font settings for a part of the text, you would need to close the tags at the right place. Just think of it as a kind of HTML tag system.

@flaith - could you try this new release to see if it's scaling things properly for your printer and the pdf printer?

http://www.seijin.net/Storage/Code/xPrint-Debug.zip

Let me know!

Oh, and thanks, LuckyLuke. I hope to have that in in a few days.

Posted: Mon Jun 26, 2006 8:13 pm
by flaith
Great work Xombie, both are ok (printer & PDF) !
Thanks :D