1. win32lib printing
- Posted by buzzo Dec 22, 2014
- 1538 views
Unable to print an image to Printer
Can "draw" stuff with out problems
this is a code snippet:
if havePhoto = True then db_select_table("photographs") recordNum = db_find_key(aKey) jpgImage = db_record_data(recordNum) l = length(jpgImage) if l > 0 then name = lower((slice(jpgImage,1,l-3))) name = name & "bmp" fileName = pathToPhoto & surName & "\\" & name bmp = loadBitmapFromFile(fileName) nexBox=nexBox+(topBox*2) setPenPos(Printer, xPos+10,nexBox) copyBlt(Printer,xPos+10,nexBox, bmp) end if end if
2. Re: win32lib printing
- Posted by ghaberek (admin) Dec 22, 2014
- 1516 views
Are you calling the necessary Win32Lib routines to manage a print job? The Printer control documentation for Win32Lib provides this example:
-- example of using printer sequence result -- select the printer result = getPrinter() -- did the user select a printer? if length( result ) then -- start a new document if not startDoc( sprintf( "My Job, Copy %s", {i} ) ) then exit end if -- start a new page if not startPage() then exit end if -- print on the page wPuts( Printer, "Hello, Printer!" ) -- close the page if not endPage() then exit end if -- close the document if not endDoc() then exit end if -- release the printer releasePrinter() end if
-Greg
3. Re: win32lib printing
- Posted by buzzo Dec 22, 2014
- 1519 views
Have no problem with text and lines..
But have no luck with printing bitmaps..
4. Re: win32lib printing
- Posted by ArthurCrump Dec 22, 2014
- 1505 views
It is some time since I used images with win32lib, but try:
copyBlt(Printer,xPos+10,nexBox, getHandle(bmp))
Arthur
5. Re: win32lib printing
- Posted by buzzo Dec 22, 2014
- 1507 views
getHandle did not work... gave an error
6. Re: win32lib printing
- Posted by ghaberek (admin) Dec 22, 2014
- 1554 views
What printing device are you using? I am testing with CutePDF Writer as my printer and my bitmap printing comes out fine. Maybe the printer driver has something to do with it?
Also, you do not need to call setPenPos() to position the bitmap, since copyBlt() takes its position directly. That is only for text functions that do not accept positioning parameters (e.g. wPuts()).
Here is the code I am using to test.
include Win32Lib.ew constant myWindow = create( Window, "Test", 0, Default, Default, 400, 300, 0 ), myButton = create( PushButton, "Print", myWindow, 10, 10, 90, 30, 0 ), $ procedure myButton_OnClick( integer self, integer event, sequence params ) sequence result = getPrinter() if length( result ) = 0 then -- user cancelled return end if if startDoc( "Test" ) then if startPage() then atom bmp = loadBitmapFromFile( "space.bmp" ) -- space.bmp is 300x225 (1.00" x 0.75"), so scale it up 8x to fill the page. -- N.B. we are assuming 300 DPI here, which may not be correct (it's probably not). stretchBlt( Printer, -- dest device 150, -- dest x = 0.5" 150, -- dest y = 0.5" 2400, -- dest width = 8" 1800, -- dest height = 6" bmp, -- src bitmap 0, -- src x 0, -- src y 300, -- src width 225, -- src height SRCCOPY -- operation ) endPage() end if endDoc() end if releasePrinter() end procedure setHandler( myButton, w32HClick, routine_id("myButton_OnClick") ) WinMain( myWindow, Normal )
-Greg
7. Re: win32lib printing
- Posted by buzzo Dec 22, 2014
- 1489 views
Greg,
Have my arms around image printing...
what units of measure are we using?
twips?
Buzzo
8. Re: win32lib printing
- Posted by ghaberek (admin) Dec 22, 2014
- 1490 views
what units of measure are we using?
twips?
Good question! I don't really know. I suppose we could consult the printer.
include Win32Lib.ew integer dpiX = queryDevice( Printer, LOGPIXELSX ) integer dpiY = queryDevice( Printer, LOGPIXELSY )
I am not really in a position to test this right now but that should do the trick.
-Greg
9. Re: win32lib printing
- Posted by ghaberek (admin) Dec 23, 2014
- 1476 views
I did some testing and I realized that queryDevice() in Win32Lib calls CreateIC to create an information context and returns only 96 DPI for the Printer.
According to the GetDeviceCaps documentation, it appears that 96 DPI is the "default" when it cannot figure out the actual DPI...
Note GetDeviceCaps reports info that the display driver provides. If the display driver declines to report any info, GetDeviceCaps calculates the info based on fixed calculations. If the display driver reports invalid info, GetDeviceCaps returns the invalid info. Also, if the display driver declines to report info, GetDeviceCaps might calculate incorrect info because it assumes either fixed DPI (96 DPI) or a fixed size (depending on the info that the display driver did and didn’t provide).
The trick then, is to just call GetDeviceCaps directly and provide it the proper device context using getDC() instead. Here is a function that will return one or more device values.
public function getDeviceCaps( integer device, object index ) object result atom dc = getDC( device ) if atom( index ) then -- just return one value result = w32Func( xGetDeviceCaps, {dc,index} ) else -- look up each value and return the list result = repeat( 0, length(index) ) for i = 1 to length(index) do result[i] = w32Func( xGetDeviceCaps, {dc,index[i]} ) end for end if return result end function
And now that we can get the DPI for any device, we can scale from one device to another, so an image appears the same size on both.
public function scaleDPI( sequence size, integer fromDevice, integer toDevice, atom factor = 1.0 ) -- use 'factor' to provide additional scaling if required -- get the DPI for each device sequence fromDPI = getDeviceCaps( fromDevice, {LOGPIXELSX,LOGPIXELSY} ) sequence toDPI = getDeviceCaps( toDevice, {LOGPIXELSX,LOGPIXELSY} ) -- calculate the scale ratio sequence scale = (toDPI / fromDPI) -- return the scaled size return floor( size * scale * factor ) end function
Now my click event handler looks like this. Notice I am taking nothing for granted and the bitmap appears the correct size on the page.
procedure myButton_OnClick( integer self, integer event, sequence params ) sequence result = getPrinter() if length( result ) = 0 then -- user cancelled return end if -- get the printer DPI values sequence printerDPI = getDeviceCaps( Printer, {LOGPIXELSX,LOGPIXELSY} ) if startDoc( "Test" ) then if startPage() then atom bmp = loadBitmapFromFile( "space.bmp" ) -- original bitmap size in pixels sequence screenSize = getCtlSize( bmp ) -- scale the bitmap from screen DPI to printer DPI (e.g. 96-to-600) sequence printSize = scaleDPI( screenSize, Screen, Printer ) -- calculate a decent page margin (1/2 inch) sequence margins = floor( printerDPI * 0.5 ) stretchBlt( Printer, -- dest device margins[1], -- dest x margins[2], -- dest y printSize[1], -- dest width printSize[2], -- dest height bmp, -- src bitmap 0, -- src x 0, -- src y screenSize[1], -- src width screenSize[2], -- src height SRCCOPY -- operation ) endPage() end if endDoc() end if releasePrinter() end procedure
-Greg
10. Re: win32lib printing
- Posted by buzzo Dec 23, 2014
- 1398 views
Greg,
Thanks for your guidance and help.
Buzzo