PrintingLibEx-an enhanced printing lib with preview option

Developed or developing a new product in PureBasic? Tell the world about it.
Fraiser72
New User
New User
Posts: 3
Joined: Sat Mar 11, 2006 10:36 am
Location: Kiel (Germany)

PrintingLibEx-an enhanced printing lib with preview option

Post by Fraiser72 »

Hi,

for an application, that i developed at the moment, i need some
special printing functions, that was not included inPB at the moment.
So i make my own priting lib with some of the following function:
  • easy preview on an ListIconGadget()
  • printer setup and printing dialog
  • set the page orientation, size and color
  • all used koordinates in 1/10mm
  • frame, box, circle, ellipse and line function
  • formatted text output (multiline support)
  • image printing with keeping the pic aspect
  • an some other stuff
Download PrintingLibEx for PB 3.9x

Download PrintingLibEx for PB 4

Fraiser
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

Really good, i'm interested in using it.

Some questions :

1/
Any chance to implement anti-aliased drawing stuff, like in PurePDF ?

2/
And is it possible to save in a file the output ?

3/
What are the supported image formats (bmp,png,jpg,...) ?

4/
Do you planned to release the source code ?

5/
Is it possible to add the possibilty to manually set the printer device.
Something like PrintingExSetPrinterByName("Lexmark 730 series")

Thanks for sharing.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Droopy
Enthusiast
Enthusiast
Posts: 658
Joined: Thu Sep 16, 2004 9:50 pm
Location: France
Contact:

Post by Droopy »

Nice and useful
User avatar
HAnil
User
User
Posts: 87
Joined: Thu Feb 26, 2004 5:42 pm
Location: 28:58E 41:01N

Post by HAnil »

for 3.94 examples not working.

PrintingLibInitEx()
and
ClosePrintingLibEx()

are unknown procedure.
When I remark this functions, program works.
do you control ?
Fraiser72
New User
New User
Posts: 3
Joined: Sat Mar 11, 2006 10:36 am
Location: Kiel (Germany)

Post by Fraiser72 »

Hi,

@HAnil
sorry, i removed this two functions because they are not needed
any more! The first call of any function will init the lib.

@Flype
1/
Any chance to implement anti-aliased drawing stuff, like in PurePDF ?
I will see.
2/
And is it possible to save in a file the output ?
Why would you save it to a file? For a printing lib, i think, it make no sense.
3/
What are the supported image formats (bmp,png,jpg,...) ?
At the moment bmp and jpeg are full supportet.
4/
Do you planned to release the source code ?
Yes.
5/
Is it possible to add the possibilty to manually set the printer device.
Something like PrintingExSetPrinterByName("Lexmark 730 series")
Yes, it is posible. I will try to include it in the next versions.

Fraiser
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Nice Lib :)

If you use the "PrintingTextBoxEx" command and the text does not fit in the box (height-wise), is there any way to see how much of the text has printed?

It could return the number of characters into the string that were used?

This way the programmer could remove that amount from the front of the string and carry on from where he/she left off in another box?

Bookmarks are also a nice idea that I've seen in other print preview systems, could you add those?
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
ABBKlaus
Addict
Addict
Posts: 1143
Joined: Sat Apr 10, 2004 1:20 pm
Location: Germany

Post by ABBKlaus »

could it be possible to include the following routines :

Code: Select all

ProcedureDLL.l Printing_GetFontAscent(DC)
  GetTextMetrics_(DC,TM.TEXTMETRIC)
  ;Debug "tmHeight="+Str(TM\tmHeight)
  ;Debug "tmAscent="+Str(TM\tmAscent)
  ;Debug "tmDescent="+Str(TM\tmDescent)
  ProcedureReturn TM\tmAscent
EndProcedure

ProcedureDLL.l Printing_TextHeight(DC,Text$)
  GetTextExtentPoint32_(DC,Text$,Len(Text$),TextH.SIZE)
  Debug Text$+"="+Str(TextH\cy)
  ProcedureReturn TextH\cy
EndProcedure

ProcedureDLL.l Printing_TextWidth(DC,Text$)
  GetTextExtentPoint32_(DC,Text$,Len(Text$),TextL.SIZE)
  Debug Text$+"="+Str(TextL\cx)
  ProcedureReturn TextL\cx
EndProcedure

ProcedureDLL.s Printing_GetDefaultPrinter()
  PrinterName$=""
  If OSVersion()<#PB_OS_Windows_2000
    Len=260
    PrinterName$=Space(Len)
    GetPrivateProfileString_("WINDOWS","DEVICE","",@PrinterName$,Len,"Win.Ini")
    PrinterName$=StringField(PrinterName$,1,",")
  Else
    winspool=OpenLibrary(#PB_Any,"WINSPOOL.DRV")
    If winspool
      Len=260
      PrinterName$=Space(260)
      CallFunction(winspool,"GetDefaultPrinterA",@PrinterName$,@Len)
      If GetLastError_()=#ERROR_FILE_NOT_FOUND
        PrinterName$=""
      EndIf
    EndIf
    CloseLibrary(winspool)
  EndIf
  ProcedureReturn PrinterName$
EndProcedure
Please make your lib more API compatible :wink:
ABBKlaus
Addict
Addict
Posts: 1143
Joined: Sat Apr 10, 2004 1:20 pm
Location: Germany

Post by ABBKlaus »

no reply :?:
ok than i put down my trousers :oops:
i am currently workin on a barcode library (for the PurePDF - lib its almost done) but for printing directly to a printer i need some more commands :
GetFontSize()
GetStringWidth()
Klaus

Code: Select all

#PDF_BARCODE_FULL_CODE39      = $001 ; included
#PDF_BARCODE_REGULAR_CODE39   = $002 ; included
#PDF_BARCODE_CODE93           = $003 ; included
#PDF_BARCODE_CODE128          = $004 ; included
#PDF_BARCODE_CODABAR          = $005 ; included
#PDF_BARCODE_DATAMATRIX       = $006
#PDF_BARCODE_MAXICODE         = $007
#PDF_BARCODE_PDF417           = $008
#PDF_BARCODE_QRCODE           = $009
#PDF_BARCODE_INTERLEAVED2OF5  = $00A ; included
#PDF_BARCODE_MSIPLESSEY       = $00B
#PDF_BARCODE_UPC_A            = $00C ; included
#PDF_BARCODE_UPC_E            = $00D ; included
#PDF_BARCODE_EAN13            = $00E ; included
#PDF_BARCODE_EAN8             = $00F ; included
#PDF_BARCODE_2DIGIT_SUPP      = $010 ; included
#PDF_BARCODE_5DIGIT_SUPP      = $011 ; included
#PDF_BARCODE_USPOSTNET        = $012
#PDF_BARCODE_AUSTRALIAPOST    = $013
#PDF_BARCODE_KIX              = $014
#PDF_BARCODE_ROYAL_MAIL       = $015

#PDF_BARCODE_CODE128_CODEA    = $001
#PDF_BARCODE_CODE128_CODEB    = $002
#PDF_BARCODE_CODE128_CODEC    = $003
#PDF_BARCODE_CODE128_AUTO     = $004
#PDF_BARCODE_CODE128_AUTOA    = $005

#PDF_TEXT_NOTEXT              = $000
#PDF_TEXT_CENTER              = $001
#PDF_TEXT_RIGHT               = $002
#PDF_TEXT_TOP                 = $004
#PDF_TEXT_BOTTOM              = $008

Procedure ipf_Barcode_Text_EAN(x.f,y.f,h.f,w.f,offsety.f,barpos.l,align.b,text.s)
  fontsize.f
  textx.f
  texty.f
  
  ;fontsize=ipf_GetFontSize()*0.70
  ; GetFontSize() not available in PrintingLibEx !!
  fontsize=10*0.70
  
  If Align<>#PDF_TEXT_NOTEXT
    If Align&#PDF_TEXT_TOP
      texty=y-(offsety)
    Else
      texty=y+offsety+fontsize+h
    EndIf
    ;textx=x+(barpos+1)*w+(((barpos+7)*w-barpos*w)/2-pdf_GetStringWidth(text)/2)
    ; GetStringWidth() not available in PrintingLibEx !!
    textx=x+(barpos+1)*w+(((barpos+7)*w-barpos*w)/2)
    ;pdf_Text(textx,texty,text)
    PrintingTextEx(text,textx,texty,0)
  EndIf
EndProcedure

Procedure ipf_Barcode_Print_Bar(x.f,y.f,h.f,w.f,code$)
  first.l
  last.l
  
  For i=1 To Len(code$)
    a$=Mid(code$,i,1)
    If a$="1" And first=0
      first=i
    EndIf
    If (a$="0" Or i=Len(code$)) And first<>0
      last=i-first
      If i=Len(code$) And a$<>"0"
        last+1
      EndIf
      ;pdf_Rect(x+first*w,y,last*w,h, #PDF_STYLE_FILL)
      PrintingBoxEx((x+first*w),y,((x+first*w)+(last*w)),(y+h),0)
      first=0
    EndIf
  Next
EndProcedure

Procedure ipf_Barcode_DrawEdgebar(x.f,y.f,h.f,w.f,barpos.l,edgebar.f,align.b,code.s)
  If Align&#PDF_TEXT_TOP
    ipf_Barcode_Print_Bar(x+barpos*w,y-edgebar,h+edgebar,w,code.s)
  Else
    ipf_Barcode_Print_Bar(x+barpos*w,y,h+edgebar,w,code.s)
  EndIf
EndProcedure

Procedure.s ipf_Check_Number(String.s)
  temp$=""
  For i=1 To Len(String)
    char$=Mid(String,i,1)
    If char$>="0" And char$=<"9"
      temp$+char$
    EndIf
  Next
  ProcedureReturn String
EndProcedure

Procedure.b ipf_Barcode_GetCheckDigit_EAN(barcode.s)
  ;Compute the check digit
  wSum.w=0
  res.b = 0
  For i = 0 To Len(barcode)-1
    If (Len(barcode)%2<>1 And i&1) Or (Len(barcode)%2 And i&1<>1)
      wSum + 3 * Val(Mid(barcode,i+1,1))
    Else
      wSum + 1 * Val(Mid(barcode,i+1,1))
    EndIf
  Next
  
  res = wSum % 10
  If (res>0)
    res =10 - res
  EndIf
  ProcedureReturn res  
EndProcedure

Procedure.s ipf_Barcode_GetBarcode_EAN(Type,index.l,barcode.s)
  parity.b
  adr.l
  
  If Type=#PDF_BARCODE_EAN13 Or Type=#PDF_BARCODE_UPC_A
    If index<7
      adr=(index-1) + Val( Mid(barcode,1,1) ) * 6
      If adr>59
        Debug "Address out of range ("+Str(adr)+")"
        parity=0
      Else
        parity=PeekB(?pdf_barcode_parities + adr)
      EndIf
    Else
      parity=2
    EndIf
    adr=Val(Mid(barcode,index+1,1))*8
    If adr>72
      Debug "Address out of range ("+Str(adr)+")"
      adr=0
    EndIf
  ElseIf Type=#PDF_BARCODE_EAN8
    If index<5
      parity=0
    Else
      parity=2
    EndIf
    adr=Val(Mid(barcode,index,1))*8
    If adr>72
      Debug "Address out of range ("+Str(adr)+")"
      adr=0
    EndIf
  EndIf
  
  ProcedureReturn PeekS(?pdf_barcode_codes + parity*80 + adr, 7)
EndProcedure

Procedure ipf_Barcode_EAN8(x.f,y.f,barcode.s,h.f,w.f,Align.b,offsety.f,edgebar.f,checkdigit.b)
; http://www.barcodeisland.com/ean8.phtml
  
  barcode=ipf_Check_Number(barcode)
  If Len(barcode)<7
    barcode=RSet(barcode,7,"0") ; Padding
  EndIf
  If Len(barcode)=7
    barcode+Str(ipf_Barcode_GetCheckDigit_EAN(barcode))
  EndIf
  ;If ipf_Barcode_TestCheckDigit_EAN(barcode)=#False
  ;  Debug "Incorrect check digit"
  ;EndIf
  ;Debug "EAN8:"+barcode
  
  ;Draw Bars
  
  barpos=1
  
  ;Left-hand guard bars
  ipf_Barcode_DrawEdgebar(x,y,h,w,barpos,edgebar,align,"101")
  barpos+3
  
  For i = 1 To Len(barcode)
    ; Center guard bars
    If i=5
      ipf_Barcode_DrawEdgebar(x,y,h,w,barpos,edgebar,align,"01010")
      barpos+5
    EndIf
    
    ;Convert digits To bars
    a$=ipf_Barcode_GetBarcode_EAN(#PDF_BARCODE_EAN8,i,barcode)
    ;print barcode
    ipf_Barcode_Print_Bar(x+barpos*w,y,h,w,a$)
    If i<8 Or (i=8 And checkdigit=#True)
      ipf_Barcode_Text_EAN(x,y,h,w,offsety,barpos,align,Mid(barcode,i,1))
    EndIf
    barpos+7
  Next
  
  ;Right-hand guard bars
  ipf_Barcode_DrawEdgebar(x,y,h,w,barpos,edgebar,align,"101")
  barpos+3
EndProcedure

DataSection
  pdf_barcode_parities:
  Data.b 0,0,0,0,0,0 ; 0
  Data.b 0,0,1,0,1,1 ; 1
  Data.b 0,0,1,1,0,1 ; 2
  Data.b 0,0,1,1,1,0 ; 3
  Data.b 0,1,0,0,1,1 ; 4
  Data.b 0,1,1,0,0,1 ; 5
  Data.b 0,1,1,1,0,0 ; 6
  Data.b 0,1,0,1,0,1 ; 7
  Data.b 0,1,0,1,1,0 ; 8
  Data.b 0,1,1,0,1,0 ; 9
  pdf_barcode_codes:
  Data.s "0001101" ; 0,0 left hand odd parity
  Data.s "0011001" ; 0,1
  Data.s "0010011" ; 0,2
  Data.s "0111101" ; 0,3
  Data.s "0100011" ; 0,4
  Data.s "0110001" ; 0,5
  Data.s "0101111" ; 0,6
  Data.s "0111011" ; 0,7
  Data.s "0110111" ; 0,8
  Data.s "0001011" ; 0,9
  Data.s "0100111" ; 1,0 left hand even parity
  Data.s "0110011" ; 1,1
  Data.s "0011011" ; 1,2
  Data.s "0100001" ; 1,3
  Data.s "0011101" ; 1,4
  Data.s "0111001" ; 1,5
  Data.s "0000101" ; 1,6
  Data.s "0010001" ; 1,7
  Data.s "0001001" ; 1,8
  Data.s "0010111" ; 1,9
  Data.s "1110010" ; 2,0 
  Data.s "1100110" ; 2,1
  Data.s "1101100" ; 2,2
  Data.s "1000010" ; 2,3
  Data.s "1011100" ; 2,4
  Data.s "1001110" ; 2,5
  Data.s "1010000" ; 2,6
  Data.s "1000100" ; 2,7
  Data.s "1001000" ; 2,8
  Data.s "1110100" ; 2,9
EndDataSection

ProcedureDLL print_Barcode_EAN8(x.f, y.f, barcode.s, h.f, w.f,Align.b,offsety.f, edgebar.f, checkdigit.b)
  ipf_Barcode_EAN8(x,y,barcode,h,w,Align,offsety,edgebar,checkdigit)
EndProcedure

;
;**** Demo App for the PrintingLibEx 
;**** (c) 2006 bei Fraiser (Gunnar Lühr)
;

Enumeration
  #MainWindow
  #BtnPrintDlg
  #BtnSetupDlg
  #BtnPrint
  #BtnPreview
  #BtnInfo
  #EditorInfo
  #CkdWidth
  #ListPreview
EndEnumeration

;*** Infos about printer an page
Procedure PrinterInfo()
    ClearGadgetItemList(#EditorInfo)
    AddGadgetItem(#EditorInfo, -1, "Width:   "+Str(GetPrintingCapsEx(#PL_PageSize_X))+"mm")
    AddGadgetItem(#EditorInfo, -1, "Height:  "+Str(GetPrintingCapsEx(#PL_PageSize_Y))+"mm")
    AddGadgetItem(#EditorInfo, -1, "Pixel X: "+Str(GetPrintingCapsEx(#PL_PhysicalSize_X)))
    AddGadgetItem(#EditorInfo, -1, "Pixel Y: "+Str(GetPrintingCapsEx(#PL_PhysicalSize_Y)))
    AddGadgetItem(#EditorInfo, -1, "DPI X:   "+Str(GetPrintingCapsEx(#PL_DPI_X)))
    AddGadgetItem(#EditorInfo, -1, "DPI Y:   "+Str(GetPrintingCapsEx(#PL_DPI_Y)))
    AddGadgetItem(#EditorInfo, -1, "Offset X:"+Str(GetPrintingCapsEx(#PL_Offset_X)))
    AddGadgetItem(#EditorInfo, -1, "Offset Y:"+Str(GetPrintingCapsEx(#PL_Offset_Y)))
    AddGadgetItem(#EditorInfo, -1, "Copies  :"+Str(GetPrintingCapsEx(#PL_PrintingCopies)))
    AddGadgetItem(#EditorInfo, -1, "Pages   :"+Str(GetPrintingCapsEx(#PL_PrintingPages)))
    AddGadgetItem(#EditorInfo, -1, "From    :"+Str(GetPrintingCapsEx(#PL_StartPage)))
    AddGadgetItem(#EditorInfo, -1, "To      :"+Str(GetPrintingCapsEx(#PL_EndPage)))
EndProcedure


;*** print loop with or without preview
Procedure PrintPreview(Preview)
  
  If Preview 
    ;*** start preview
    If GetGadgetState(#CkdWidth)
      ;*** set optional preview width
      RetStart.l = StartPrintingPreviewEx(#ListPreview, #True, 450)
    Else
      ;*** normal preview width with 72dpi
      RetStart.l = StartPrintingPreviewEx(#ListPreview, #True, 0)
    EndIf
  Else
    ;*** start printing
    RetStart.l = StartPrintingEx("Test Printing")
  EndIf
 
height.f=140
width.f=4.445
edgebar.f=15
xoffset.f=0
yoffset.f=0

  If RetStart.l
    PrintingFontEx("Arial", 60, #True)
    
    print_Barcode_EAN8(50,20,"5512345",height,width,#PDF_TEXT_BOTTOM,yoffset,edgebar,#True)
    ;print_Barcode_Code128(50,220,"12345678",height,width,#PDF_TEXT_BOTTOM,xoffset,yoffset,#PDF_BARCODE_CODE128_AUTO)
    
    If Preview
      ;*** end preview
      StopPrintingPreviewEx()
    Else
      ;*** end printing
      StopPrintingEx()
    EndIf
  Else
    MessageRequester("FEHLER", "Init Start Printing")
  EndIf
EndProcedure


;*** page setting
;If InitPrintingPageEx(#DMPAPER_A4, #DMORIENT_LANDSCAPE, #DMCOLOR_COLOR) = 0
If InitPrintingPageEx(#DMPAPER_A4, #DMORIENT_PORTRAIT, #DMCOLOR_COLOR) = 0
  MessageRequester("FEHLER", "Init PrintingPagebEx")
  End
EndIf

;** create window
If OpenWindow(#MainWindow, 50,50, 800, 800, #PB_Window_SystemMenu|#PB_Window_MaximizeGadget, "PrintingLibEx Test Application")
  If CreateGadgetList(WindowID(#MainWindow))
    ButtonGadget(#BtnPrintDlg, 20,20, 200, 24, "Open Print Dialog")
    ButtonGadget(#BtnSetupDlg, 20,60, 200, 24, "Open Print Setup")
    ButtonGadget(#BtnPrint, 20,100, 200, 24, "Print")
    ButtonGadget(#BtnPreview, 20,140, 200, 24, "Preview")    
    ButtonGadget(#BtnInfo, 20,420, 200, 24, "Info")
    EditorGadget(#EditorInfo, 20, 190, 200, 200)
    CheckBoxGadget(#CkdWidth, 20, 450, 200, 24, " - Preview breite begrenzen")
    
    ;*** IMPORTANT!! this gadget is used for the preview output
    ListIconGadget(#ListPreview, 240, 20, 540, 760, "", 0)
    ChangeListIconGadgetDisplay(#ListPreview, 0)  

    ;*** show info
    PrinterInfo()
         
    ;*** Main Loop
    Repeat
      Event.l = WaitWindowEvent()
  
      If Event.l = #PB_Event_Gadget
        Gadget.l = EventGadgetID()
      
        ;*** Print Dialog
        If Gadget.l = #BtnPrintDlg
          If PrintingDlgEx(WindowID(#MainWindow))
            PrintPreview(#False)
            PrinterInfo()   
          EndIf
       
        ;*** Printer Setup Dialog
        ElseIf Gadget.l = #BtnSetupDlg
          If PrinterSetupEx(WindowID(#MainWindow))
            PrinterInfo()
          EndIf
          
        ;*** print
        ElseIf Gadget.l = #BtnPrint
          PrinterInfo()
          PrintPreview(#False)
        
        ;*** preview
        ElseIf Gadget.l = #btnPreview
          PrintPreview(#True)
          
        ;*** show info
        ElseIf Gadget.l = #BtnInfo
          PrinterInfo()
          
        EndIf
      EndIf
    Until Event.l = #PB_Event_CloseWindow

  EndIf
  
EndIf
User avatar
Droopy
Enthusiast
Enthusiast
Posts: 658
Joined: Thu Sep 16, 2004 9:50 pm
Location: France
Contact:

Post by Droopy »

Very nice
Fraiser72
New User
New User
Posts: 3
Joined: Sat Mar 11, 2006 10:36 am
Location: Kiel (Germany)

Post by Fraiser72 »

Hi,

@ABBKlaus
Sorry, but at the moment i have much to do at the job so that i havent
so much time to work at the PrintingLibEx. What do you mean with
'Please make your lib more API compatible' ?
I didn't know if you see it, but a german version is also available
(http://www.purebasic.fr/german/viewtopi ... sc&start=0

Here is a little update with three new functions.

-GetPrintingFontMetricEx(Type) to get ascent,desent and height of the actual font
-GetPrintingTextHeightEx(Text$) to get the height of the given TEXT$
-GetPrintingTextWidthEx(Text$) to get the width of the given TEXT$

I hope this will help you a little bit. The function for the default printer name
is still in work.

Download PrintingLibEx for PB 3.9x

Download PrintingLibEx for PB 4

Fraiser
ABBKlaus
Addict
Addict
Posts: 1143
Joined: Sat Apr 10, 2004 1:20 pm
Location: Germany

Post by ABBKlaus »

Thanks that was fast :D
API compatible means :
when opening a printer return a 'PrinterHandle'
when opening a DC return a 'DCHandle'

Klaus
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Post by QuimV »

Hi,

I'm using this library and I need to know the units to use in the different types of GetPrintingCapsEx(Type) function.

Types are:

#PL_PageSize_X - Pagewidth in mm -> OK, clear!

#PL_PageSize_Y - Pageheight in mm -> OK, clear!

#PL_PhysicalSize_X - Physical pagewidth in dots (depends on the DPI resolution of the printer) -> Is the same dots and pixels?

#PL_PhysicalSize_Y - Physical pageheight in dots (depends on the DPI resolution of the printer) -> Is the same dots and pixels?

#PL_DPI_X - DPI resolution of the printer (horizontal) -> dots, OK!
#PL_DPI_Y - DPI resolution of the printer (vertikal) -> dots, OK!


#PL_Offset_X - non printable area ( left & right ) -> Units???

#PL_Offset_Y - non printable area ( top & bottom ) -> Units??


#PL_PrintingCopies - copies the user selected -> Number of copies, OK!

#PL_StartPage - start page -> Number of page to start printing, OK!

#PL_EndPage - end page -> Number of page to end printing, OK!

#PL_PrintingPages - amount of total pages ( available after preview) -> Number of total pages to print, OK!


I need to know the relation between dots and pixels?

Could anybody help me?

Thanks in advanced ...




QuimV
Post Reply