Cutting paper ("feed and cut") with GDI? - printing

Many printers have a "feed and cut" or "cut paper" command (I'm talking about POS - printers here).
Since using POS.NET is not always possible (horrific driver incompatibilities) and GDI can do so much more, we would like to utilize the paper cutter also when printing using GDI.
Is there a way to do so? Possibly when issuing EndDocument()?
Or maybe even from .NET?

GDI and even the abstract Windows printing model are probably not going to help you here. You're going to have to send the feed and cut command to the printer in the language that it expects to typically receive data.
For example, an Epson TM-T88III thermal receipt printer speaks the ESC/POS language natively, not a sequence of GDI or PCL commands. However, most of these printers do come with printer drivers that make Windows see them as regular GDI printers. The way these drivers typically work is that they rasterize all of the GDI commands into one big bitmap in software, and then dole out the bitmap to the printer for printing via its native-language "print the bit-image" command. This usually has less-than-desirable effects:
It is much less efficient (in sense of time required and data transmitted) to send a lot of bitmap data to the printer than a sequence of binary commands that it knows how to interpret. (Would you rather send an image of text to print, or just the actual text and a font size specification? Analogies with HTML/CSS vs. an image of text.)
These printers typically have low resolutions and are monochrome (that is, all black or all white, no grayscale or color). Their pre-loaded fonts are designed to work well under these limitations for crisp, clear rendering. By rasterizing to a bitmap, we lose this careful design as pixels are snapped and rounded off of the grid, resulting in jagged text rendering on the actual printout. If you're trying to draw something that's really sensitive to this kind of rounding, like a barcode, you're SOL, unless you're painstakingly keeping the DPI of the printer device context in mind while working with GDI.
For example, here is a snippet of code from an extensive example on my usually-irrelevant blog. You can see near the end how I fill the BinaryWriter with the necessary sequence of bytes that equals the "feed paper and cut" command on our Epson thermal receipt printer (AsciiControlChars is just a static class with constants):
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
// Reset the printer bws (NV images are not cleared)
bw.Write(AsciiControlChars.Escape);
bw.Write('#');
// Render the logo
RenderLogo(bw);
// Feed 3 vertical motion units and cut the paper with a 1 point cut
bw.Write(AsciiControlChars.GroupSeparator);
bw.Write('V');
bw.Write((byte)66);
bw.Write((byte)3);
bw.Flush();
return ms.ToArray();
}
You can then just send the bytes directly to the printer as a RAW document, either using the code at the end of that article, which works against various Win32 printer functions, or Microsoft's RawPrinterHelper class.
You'll need to look up the commands specific for your printer. Chances are that its not too different from the one that you see here: POS languages are beginning to standardize, but that's also like saying SQL is a standard--mutually intelligible by humans but not really interoperable without some adjustments.
If you really still want to use GDI, you can print the GDI document in the usual way to the printer (again, assuming that a GDI printer driver exists, which it probably does), and then issue a second, small, RAW document to the printer that contains the native feed and cut command. (Alternatively, some of the GDI printer drivers let you specify "always cut after printing a document" right in the Printers control panel--but good luck accessing that driver feature in a well-documented fashion programmatically!)
Hope this helps to paint a picture of GDI's relationship to POS printers.

Related

what is Printer-based Barcodes,How is it implemented?

How is this technique implemented?
I noticed that they(like Bartender) don't directly concatenate commands like ZPL (etc.).
And also they don't use bitmap(GDI,GDI+ images) transfer to printer-driver.
Printer-based Serialization In print jobs that include serial numbers, many printers can accept a starting value and the incremental
step size. When you use this printer-based serialization, you can
print a large number of serialized items without having to send any
data after the first label.
Printer-based Barcodes Printers that have built-in barcode functionality make it possible for software programs to request
complex barcodes by using simple text strings (such as “1234”). This
process is much faster than sending bitmap images (or pictures) of
barcodes that consume hundreds or thousands of extra bytes per printed
item. (When you use software other than BarTender, our driver fonts
give you some limited functionality.)
Printer-based barcodes are, as you mention, barcodes that have the symbology / definition stored in the printer firmware. Much like a DLL that you give "12345" and as a result gets a bitmap, an SVG file etc etc.
Many modern label printers know a bunch of common symbologies such as EAN, DM, QR, UPC and similar.
The benefit is obviously that it makes transfer of data much more efficient. Instead of sending a (large) image for every print, the software just sends initial definition (layout, symbology choice and options, ..) + the value needed. Taken to the next level, the printer could receive metadata such as "take this layout, make 500 labels, and in the barcode start at 1, increase 1 every label".
Some disadvantages are
is that the appearance is left to the firmware designer of the printer firmware
There may be less coordination between what's being designed and what's being printed, although typically the driver for the printer should adress this.
The printer firmware may not be updated if the barcode symbology specifications has been updated
The printer firmware may contain only a subset of the barcode definition
In short, simplificy vs freedom of parameters and appearance.
How it is technically implemented (at printer end, from receiving the number to drawing the actual barcode) is probably out of scope for this forum.
Example specification (in newer printer model)
Looking at a random Zebra Printer (ZT600) the built-in barcodes covers nearly every use:
1D symbologies
Code11, Code39, Code93, Code128 (all subsets),
UCC, ISBT, UPC, EAN 8 / 13, UPC/EAN extensions,
Plessey, Postnet, 2of5, Logmars, MSI, Codabar and Planet Code
2D symbologies
codablock, PDF417, Code49, Datamatrix,
QR, TLC39, MicroPDF, RSS14 +composite and Aztec.
When you print an element on a label (barcode or text) you can do that by sending a graphic field or by instructing the printer to pick up the element internally and build the element with the configuration you need.
For example, in case you want to print a text, the ZPL command will include the font you want to use, vertical and horizontal size, position of the text and so on.
In the case of a barcode, the barcode selector contained in the ZPL command, will automatically recall the .BAR file stored in the Z memory, which contains the instructions for the printer to build the barcode, then, in the same command and likewise for the text, you have also provide the size of the barcode (usually it's a ratio between the narrow and the bold line), the position, the human readable line and so on.
The graphic method is used for example when a font which is not stored on the printer memory is used: the printer doesn't recognize the font and so it can't build the text, so the print can happen only after a conversion of the text field into a graphic field. This works well with text fields, but the barcodes can have quality issues as, due to how a thermal printers physicall works, the lines of a barcode can be printed like a sort of saw. Moreover you can't see or edit the data since the code is basically unreadable, that's why it's impossible to send serialized data, unless you use a software.
The element printing is not affected by this type of quality issues and allows you to edit the data.
If you want to see the difference, try to use zebradesigner and print to file a label with a barocode. When you select a barcode, you can choose to print it as a graphic or to use the printer element and you'll see that the .prn files will contains different data.
This is what you get using the printer element (128 barcode containing 123456789012)
https://justpaste.it/66gvp
and this is the same barcode printed as graphic field
https://justpaste.it/27abu

How to change screening (halftone pattern) of my printer Cups driver?

I am using CUPS with the printer driver which use "application/vnd.cups-raster 10 rastertopj" and i am trying to get the look of dither 4x4 print/output but i am clueless where to change the setting for choosing different dithering/halftoning pattern..
i also contacted the cups and they said dithering is done by the driver and also told that If the driver is Ghostscript-based you may be able to change the dither as you’d like, and yes this is indeed Ghostscript-based printer driver/filter cause when i open .PPD file i see *Product: "(ESP Ghostscript)".
Can you please guide me on how or where to change the dither of the printer filter/driver?
Edited:
this is the halftone output its printing: https://imgur.com/a/18hkC1H or https://imgur.com/download/7pTksX4
this is the output i am looking for: https://imgur.com/a/KZTQrkp or https://imgur.com/download/5FnpKEM
Thankyou
Ghostscript supports the full range of halftoning defined in the PostScript Language Reference Manual. It also has its own stochastic screening code.
To change the screening, you put the relevant commands in the PostScript file. If you are starting with a PostScript program, then that's where you put the screening. Otherwise you'll have to inject it into the PostScript, which is where you modify the PPD file.
I can't tell you how to do that (because its a CUPS thing, not Ghostscript), nor can I tell you what the PostScript you need is (because I have no idea what the screen you want looks like), you'll have to experiment to match the output you want (note that halftoning is not the same as dithering). Worst case you can use a type 3 halftone dictionary which should produce something similar to what you want, at the cost of needing a lot of data to set it up.
<<
/HalftoneType 1
/Frequency 37
/Angle 45
/SpotFunction {180 mul cos
exch 180 mul cos
add 2 div}
>> sethalftone
For what its worth, the above is a type 1 halftone dictionary defining a round spot shape and with what I beleive are 'reasonable' values for a 300 dpi monochrome output device.
As to how you get that into the PostScript that Cups sends to Ghostscript, or onto the Ghostscript command line, I can't tell you.

Star TSP700 TSP743U using OPOS prints line-by-line

We have a POS application we have developed that can use any ESC/POS printer via MS POS.Net v1.12. Our application runs fine with Epson printers, but with a Star TSP700 it prints correctly, but it "stutters"/line-by-line (think calling PrintNormal repeatedly rather than using a StringBuilder and dumping it all at once into the queue). Setting the dip switch to what should be ESCPOS emulation does nothing, as I don't think the USB interface supports that according to the docs found on page 98 of https://www.star-m.jp/eng/service/usermanual/tsp700um.pdf. I am building a string and dumping it all at once using Transaction printing in OPOS. The print speed to the customer is unacceptable and replacing 100 printers is also not acceptable. There is another mode we use to connect to the printer aside from OPOS, and that is setting up the printer as a "Generic / Text Only" printer and then I send the escape codes to the printer, but it doesn't print everything out correctly at all - I imagine this is because the printer is expecting Star Line commands.
Phew. Anyone have any input on what to try? Worst case scenario I build in printing via Star commands, so all is not lost, and I'm going to try HexDump mode first to see if I am missing anything, but I would much prefer to not write out a whole library just to handle Star printers if I can avoid it.
ESC + | + N on an Epson printer resets the font to normal after setting it to big, bold, etc. However, this causes the Star to stutter to the point of shaking violently. I was able to remove that escape sequence from my code and have it not affect the output from Epson printers, so now the Star stutters less. Note, it doesn't stop stuttering, it prints 50 lines, flips out for 2 or 3 lines, and repeats. It's really a huge improvement if you are able to see the printer print before and after the fix.

Set printer driver specific data

We have an application that prints 2 invoice copies - 1 on white (for the cust) and 1 on blue (for us).
We print a LOT of these so we are getting a printer with 3 big trays. One tray (tray 5) holds 4000 sheets and the other two (trays 3 and 4) are a tandem set holding 1600 and 2000 sheets. The application automatically generates the invoice and sends one document to the tray with the white paper and one to the tray with the blue paper.
The user has no input in this process.
Now, my problem is this - if I specifically send the blue copy to tray 3 and there is no paper in tray 3, the job will go on hold until someone loads it up even though tray 4 has 2000 more sheets ready to go. On the other hand, if I tell the printer to print on Blue 8 1/2x11" paper, it is smart enough to know that that type of paper is in both trays and to pull from either one until they are both empty. So, I want to change our application to select a paper type/size and color instead of a specific tray.
The program is written in Delphi and I have been looking at the DEVMODE structure returned by TPrinter.GetPrinter. The DEVMODE structure has a memory size in dmDriverExtra that indicates how much extra data the print driver is adding to the structure for its own storage.
Does anyone know of anyway to access this data and make changes to it? If you have examples in other languages, I can probably adapt it to Delphi so anything will help.
There are actually two different items in the questions:
How to set the pater size and type:
PaperSize would be stored in dmPaperSize (value DMPAPER_LETTER)
PaperType is a bit more difficult. I'd guess that it's in dmMediaType (use DeviceCapabilities to retrieve available media types and their names)
How to access / edit "DriverExtra" data:
In short: don't!
A bit longer: dmDriverExtra is described as "Contains the number of bytes of private driver-data that follow this structure". So this data is private to the driver (which means that you need very good documentation for the driver to actually know the format and content of this data. It's not guaranteed that different versions of the driver use the same format).
So the only thing you can do is to use a print dialog, retrieve the DevMode structure and store it for further use (however as I said: If the driver changes, this data may become invalid...)

How do I choose a pixel format when creating a new Texture2D?

I'm using the SharpDX Toolkit, and I'm trying to create a Texture2D programmatically, so I can manually specify all the pixel values. And I'm not sure what pixel format to create it with.
SharpDX doesn't even document the toolkit's PixelFormat type (they have documentation for another PixelFormat class but it's for WIC, not the toolkit). I did find the DirectX enum it wraps, DXGI_FORMAT, but its documentation doesn't give any useful guidance on how I would choose a format.
I'm used to plain old 32-bit bitmap formats with 8 bits per color channel plus 8-bit alpha, which is plenty good enough for me. So I'm guessing the simplest choices will be R8G8B8A8 or B8G8R8A8. Does it matter which I choose? Will they both be fully supported on all hardware?
And even once I've chosen one of those, I then need to further specify whether it's SInt, SNorm, Typeless, UInt, UNorm, or UNormSRgb. I don't need the sRGB colorspace. I don't understand what Typeless is supposed to be for. UInt seems like the simplest -- just a plain old unsigned byte -- but it turns out it doesn't work; I don't get an error, but my texture won't draw anything to the screen. UNorm works, but there's nothing in the documentation that explains why UInt doesn't. So now I'm paranoid that UNorm might not work on some other video card.
Here's the code I've got, if anyone wants to see it. Download the SharpDX full package, open the SharpDXToolkitSamples project, go to the SpriteBatchAndFont.WinRTXaml project, open the SpriteBatchAndFontGame class, and add code where indicated:
// Add new field to the class:
private Texture2D _newTexture;
// Add at the end of the LoadContent method:
_newTexture = Texture2D.New(GraphicsDevice, 8, 8, PixelFormat.R8G8B8A8.UNorm);
var colorData = new Color[_newTexture.Width*_newTexture.Height];
_newTexture.GetData(colorData);
for (var i = 0; i < colorData.Length; ++i)
colorData[i] = (i%3 == 0) ? Color.Red : Color.Transparent;
_newTexture.SetData(colorData);
// Add inside the Draw method, just before the call to spriteBatch.End():
spriteBatch.Draw(_newTexture, new Vector2(0, 0), Color.White);
This draws a small rectangle with diagonal lines in the top left of the screen. It works on the laptop I'm testing it on, but I have no idea how to know whether that means it's going to work everywhere, nor do I have any idea whether it's going to be the most performant.
What pixel format should I use to make sure my app will work on all hardware, and to get the best performance?
The formats in the SharpDX Toolkit map to the underlying DirectX/DXGI formats, so you can, as usual with Microsoft products, get your info from the MSDN:
DXGI_FORMAT enumeration (Windows)
32-bit-textures are a common choice for most texture scenarios and have a good performance on older hardware. UNorm means, as already answered in the comments, "in the range of 0.0 .. 1.0" and is, again, a common way to access color data in textures.
If you look at the Hardware Support for Direct3D 10Level9 Formats (Windows) page you will see, that DXGI_FORMAT_R8G8B8A8_UNORM as well as DXGI_FORMAT_B8G8R8A8_UNORM are supported on DirectX 9 hardware. You will not run into compatibility-problems with both of them.
Performance is up to how your Device is initialized (RGBA/BGRA?) and what hardware (=supported DX feature level) and OS you are running your software on. You will have to run your own tests to find it out (though in case of these common and similar formats the difference should be a single digit percentage at most).

Resources