Printing with delphi - delphi

I am facing some difficulties while printing, when I print my reports to physical printer the texts are perfectly centred but when I print the same report to PDF printer (e.g. cutePDF) or XPS document writer the left margin becomes 0. Meanwhile when I am trying to adjust the margin it works fine in PDF and XPS but the physical printing prints the pages with some extra left margin. I am not able to find out this difference also I tried to set the margin only for non-physical printing but could not able to do this.
It would be great if it will possible to set the marige according to printer selection e.g. if I will select PDF printer or XPS writer the margin gets changed. I am using Printer.canvas.textout(), procedure to print the text.
Can anybody please help me for this.

Some points which are worth be highligted:
From the Windows (and Delphi's TPrinter.Canvas) POV, there is no such concept as margins during drawing: the whole paper size is available to the canvas - for instance, X=0 will point to the absolute leftmost part of the paper;
There are so called "hardware margins" or "physical margins", depending on the printer capability: this is the non printable area around the paper; that is, if you draw something in this area, it won't be painted - these margins depend on the technology and model of printer used, and in some cases, it is possible to retrieve those "margins" values from the printer driver via GetDeviceCaps API calls;
But, from my experiment, do not trust those "physical margins" as retrieved by the printer driver - it is better (and more esthetical) to use some software defined margins, and let your user change it if necessary (like the "Page layout" options of MS Word);
PDF printers usually are virtual printers, so they do not have any "physical margin";
When you print a PDF document, Acrobat Reader is able to "fit" the page content to the "physical margins" of the physical printer.
So here are some possible solutions:
From Acrobat Reader, if your PDF has no margin, click on Print, then select "Fit to Printable Area" in the "Page Handling / Page Scaling" option - I guess you have "None " as settings here so the result is truncated by the printer;
From your Delphi application, set some "logical" margins (e.g. 1 cm around your paper) when drawing your report - that is, do not start at X=0 and Y=0, but with some offsets, and let the width and height of your drawing area be smaller (see for instance how is implemented our Open Source Report engine);
From your Delphi application, if you use a Report component, there should be some properties to set the margins.
See this article about general printing using Delphi (some info is old, but most is still accurate), or set up properly your report engine.

If you use TextOut (and not DrawText) you have the x and y coordinate where you are going to put the string(s) you need to print. You can follow the calculations in the debugger (or log them if the application runs without a debugger present). Perhaps something goes wrong in determining the coordinates (eg TextExtend fails to measure the text before centering, eg the resolution is different from what you expect, you get the Printer Canvas with a transformation so the coordinates are not 1:1 with the pixels.
If you are unsure about the coordinates / font issues: try drawing some boxes at expected coordinates so you can leave all font related errors out of the equation. If they exhibit the same problems it's a coordinate problem, if not it's font problem somehow.
As Ken said, we cannot know anything more if you do not show the code... so many possibilities..

Related

C# Newbie - Vector Printing of Visio Document using AxVisioViewer ActiveX control

I am using VS2013Express to create a windows form based application which will display and eventually print Visio documents, rather than relying on the browser based Visio Viewer. Needless to say this is a very specific requirement, so really don't need anyone telling me to use the MS Visio Viewer!
So far, I can open the Visio document, display it using the AxVisioViewer.dll control. I can even print... to a degree.
The issue is that I can only print currently using a PrintFromScreen method which basically captures the image of the form as displayed on screen and creates a Raster BitMap of it.
I copy the BitMap image to a hidden panel on the form (to remove toolbars etc), then print the contents of the panel. Simple (ish)!
Here's a link to the page I used to create the panel and print the image.
What I want to be able to do is resize (Vector not Raster to retain scale) and centre the image as required to ensure the document prints properly.
You'll want to center the drawing in the control.
Check the following link.
https://msdn.microsoft.com/en-us/vba/visio-vba/articles/viewer-zoomtorect-method-visio-viewer
You may also check the zoom and pan methods.

How to make TSaveDialog customization dpi aware / scaleable?

Using Delphi 2010 I have customized a TSaveDialog using the resource template approach as shown in TOpenPictureDialog in Delpi's ExtDlgs.
The template approach allows me to successfully insert a form containing several controls in the system save dialog. This works fine as long as the Windows DPI setting is 96. With user defined (text) scaling or hdpi monitors the inserted form is only partly visible. This is of course due to Form.Scaled = True which causes the form plus containing controls to scale (become larger). Currently the template file ( the default as used in for example TOpenPictureDialog ) contains fixed size dialog and static text elements that define the space that will be taken up by the inserted form.
I can think of several workarounds:
No form scaling (not really a solution for hdpi monitors)
Provide different templates based on Screen.PixelsPerInch/96: 100% 125%, 150%
200% etc).
Using the IFileDialogCustomize interface, but that's not really expressive enough for what I want.
The best solution would probably be a way to resize that template (based on Screen.PixelsPerInch/ 96) in memory before it gets loaded by the dialog.
Is something like that available?

Ghostscript and page margin

I have a HP Deskjet 5150 PCL compatible printer and I need to print down a PostScript file. If I view the file with gv, its margins are fine. When I try to print it with: gs -dSAFER -dNOPAUSE -dBATCH -q -sDEVICE=hpdjportable -sOutputFile=/dev/usb/lp0 file.ps the left margin is shifted to the right by approximately 6 mm. As a consequence, the rightmost 6 mm of the page are cropped off. I know this flaw is barely noticeable, but I dislike it. The print is otherwise more than fair.
Any help is greatly appreciated.
Sounds like your printer has a hardware margin, an area where it simply cannot print, often due to paper handling hardware.
This can mean that the printable area of the paper is less than the size of the media, so if you try to print right to the edges then bits 'drop off'. Screen displays obviously don't suffer from this problem....
Generally PostScript consuming printers will either use a PPD which includes the printable area, or they will rescale the input slightly to fit.
Now, I suspect that the PCL output from Ghostscript is nothing more than a bitmap wrapped up with just enough PCL to make it print, which means that it will be assuming it can print right to the edges. So your solution will be to rescale the output slightly and probably shift it on the media a bit as well.
You can use any of several different command line options to select a different Media size such as DEVICEWIDTHPOINTS and DEVICEHEIGHTPOINTS or -g you will also need to select -dFIXEDMEDIA (so the PostScript can't change the media size) and -dFitPage to make GS scale the contents to fit the new size. Finally you will need to write a little PostScript to move the output around a little:
-c "<</PageOffset [-18 0]>> setpagedevice" -f
You should put that as the last option, just before the input filename. You will almost certainly need to meddle with the numbers in there to make it come out right.

Can ligatures be used within Delphi PaintBox when writing to Canvas using TextOut or DrawTextW?

I am currently trying to implement the Bravada OTF Font from http://www.smufl.org/fonts/ in a Delphi music application. While I can easily render the private extended unicode characters to a TPaintBox using either TextOut or DrawTextW, it appears OpenType ligatures may not be handled within Delphi.
Specifically, certain unicode characters serve as modifiers ... per the README for Bravada:
"In Bravura Text, ligatures are used to adjust the vertical position of individual symbols. First, you enter the code point corresponding to the amount by which you want to change the vertical position, and then you enter the code point for the symbol itself. Provided the application you are using supports OpenType ligatures, you should see the symbol appear at the desired vertical position."
"So to position, say, a black notehead at the G4 staff position, you would first enter U+EB89 (lower by two staff positions) followed immediately by U+E0A4 (the black notehead)."
My rudimentary attempts like this:
Canvas.TextOut(10,10, #$EB89+#$E0A4);
Only reveal two characters, not moving E084 by the vertical offset desired. Knowing that clients are responsible for understanding the ligature rules and responding accordingly, are there any workable options available in Delphi for OTF features? I'd love to raw draw to the canvas but even if there is a more advanced canvas VCL out there... I'll take it.
VCL's TCanvas class is a thin wrapper around Microsoft's GDI API. GDI by itself does not support what you are asking for. However, you can use Microsoft's DirectWrite API (part of DirectX), which does support OpenType and its advanced features.
Introducing DirectWrite
DirectWrite takes advantage of the advances in OpenType Font technology to enable high quality typography within a Windows application...
...
The OpenType support provided by DirectWrite enables developers to add to their applications advanced typographic features and support for international text.
It is possible to have DirectWrite render to a GDI surface. It would first render to an in-memory bitmap HDC, which you could then draw onto the TPaintBox afterwards, by either:
wrapping the rendered HDC in a temp TCanvas object and then copying it to the TPaintBox.Canvas using the TCanvas.CopyRect() or TCanvas.Draw() method.
copying it directly to the HDC provided by TPaintBox.Canvas.Handle using GDI's BitBlt() or StretchBlt() function.

What is the proper font for printing on thermal paper?

I have a program that prints every client's order, like restaurants tickets, but I made it with times new roman. The result wasn't a quality print. I believe that the font is not the best for this tech and I have to convince my client the owner, cause he loves that font.
Would sans serif or similar be the better choice?
Also, is there a standard procedure for printing direct to those thermal printers and choose the internal fonts, whatever the manufacturer is?
I am using QuickReports to create the printing. The result is king of blur. I will put the pictures to compare as soon as I put my hands on a scanner.
Selecting the optimal print font is both subjective and technical. Not all fonts are suitable to small-dpi mediums; Some fonts use highly variable line width when painting the letters and that will "smudge" easily when used with smudge-prone mediums; I guess the thermal printer fits into both "small dpi" and "easily smudged" areas.
In my opinion the selected font should be, based on priority:
The device fonts: don't print graphics to tiny printers, use the on-board fonts and learn the "escape" language. Results will be outstanding, and there's enough flexibility to also get beautiful results. The only time I had to deal with a thermal printer I used this method and the results really are great. The device allows font scaling, drawing lines, almost everything you'd need. But it is hard work and you'll be outside of the "comfort zone". The printer driver is not helping you at all and you end up writing device-specific routines.
Next option would be BITMAP fonts. That is, don't use True Type Fonts. On today's computers bitmap fonts only serve one purpose: look good at small pixels count. That's perfect for a small-dpi printer.
Invest millions in developing a special purpose font that's easy to read on paper and behaves good printed on whatever device. Or use the font others have spent millions in developing: open your favorite version of Ms Word, type a few words and see what font is used. Right now I get Calibri.
Use a font that doesn't have fancy strokes that need many pixels to paint OR make smudges more obvious. Write something in Times New Roman in very large font. See the fancy lines, the narrow segments, the elegant design? That's not a good choice for a small-dpi, smudge-prone printer. Now do the same for Arial, Verdana, Tahoma.
Let the user choose. This decision is only partly technical, there might be subjective reasons to use one thing or the other.

Resources