stardot / b-em

An opensource BBC Micro emulator for Win32 and Linux
http://stardot.org.uk/forums/viewtopic.php?f=4&t=10823
GNU General Public License v2.0
112 stars 56 forks source link

Provide a "virtual printer" output to image/PDF or some modern format... #66

Open afarlie opened 5 years ago

afarlie commented 5 years ago

Per a StarDot thread, I felt I should formally open an issue here..

What is the concern:
Most software written for the BBC micro uses an obsolete printer control method, using Escape sequences which were available on Centronics or Serial interfaced printers of their era. Current printers connected to Mac or PC systems are more likely to be USB based, and use entirely different printer control languages such as PostScript or HP-PCL.

What is desired:

A "virtual printer" that can emulate the control seqeunces translating them into an appropriate modern format, should be implemented. The output format of this could be PDF, or a suitable bitmpa image format for graphics.. If no specialist sequences are used then a plain text file could also be generated.

IIRC a "Virtual Printer" was implemented in some experimental builds of DosBox, but I have no further details at present...

SteveFosdick commented 5 years ago

This is a good idea but it is not completely straightforward.

The most promising converter so far mentioned in the stardot thread at https://stardot.org.uk/forums/viewtopic.php?f=4&t=15516, epsonps, could be integrated as it is otherwise self contained but it outputs in PostScript rather than PDF.

No-one has yet identified a ESC/P to PDF converter that is suitable in its current form. One possibility would be to use the state machine from epsonps but replace the PostScript output with calls to a PDF library. Ideally this also needs to be done in a way that is cross-platform, i.e. the PDF library needs to be cross-platform.

For the moment, to make it easier to experiment with external converters I have implemented a print to file option in B-Em. From the File menu one chooses "Print to file" whereupon a "Save file" prompts for the name of the file. After a file has been chosen (i.e. the dialog wasn't cancelled) a checkbox will appear alongside the "Print to file" menu item indicating the printer output is being sent to the file. When the output is complete one chooses "Print to file" again which closes the file and the checkbox disappears. Contents of the file will be exact what was send to the parallel port. This output can then be transformed by an external program.

afarlie commented 5 years ago

Ghostscript I think can handle either Postscript or PDF, but I'm not sure it's 'embeddable' (and there may be licensing considerations.).

There is also the issue of handling different 'print-job' managers... Linux, Windows etc all have different API. (sigh)

SteveFosdick commented 5 years ago

When it comes to the possibility of embedding a converter the main part that could usefully live inside an emulator such as B-Em but currently doesn't is an ESC/P converter.

So far the best offerings have had PostScript (PS) as their output format.

Last did anything with printing on Linux, in common with other Unix-like systems, PostScript was the defacto standard for fancy printing, i.e. anything except basic monospace text in the old lineprinter style. That means if an emulator embedded an ESC/P to PS converter it would be able to feed the output of that straight into the print queue.

Of course, GhostScript still often features in that if the attached printer does not understand PS natively, the print manager (CUPS seems to be latest fashion) would usually use GhostScript internally to convert that to a raster image to be send in the printer's own proprietary protocol.

By comparison, on Windows, last I looked one requested a drawing context from the printing system and then used normal GDI calls to drawn upon. The job of converting GDI to a raster to send to the printer was then the job of the printer driver.

I am toying with the idea of dividing the ESC/P conversion into three layers. One layer implements parsing the control codes by using a finite state machine in the way epsonps does but, unlike epsonps, rather than having output operations embedded in it, it would issue method calls to a renderer. The renderer would implement the page model for the ESC/P printers, i.e. it would deal with such things as, page sizes, margins, line spacing, font choices and movement rate etc. That could then make calls to a further layer to generate some output. That third layer could be PS or PDF output or even calls to Windows GDI (on a Windows build on B-Em).

Even with that flexibility I am not sure that one size fits all because in the existing converters we see two completely different approaches. Epsonps goes for translating as directly as possible into PS so text remains text in PS and is drawn in modern, high quality PS fonts, whereas the ukncbtl-utils ESCParser models the printer down to individual pins so the output is always a bitmap, and hence can't have text copied from it, but does look very much like the output from a real printer.

nzeemin commented 5 years ago

Don't know helps it or not, ukncbtl-utils ESCParser supports PS, SVG and PDF output.

fordp2002 commented 3 years ago

Be careful with this as b-e has a feature/bug in the way it processes the '£' to the printer as it transforms it to a different value. This will not work for graphics output!

SteveFosdick commented 3 years ago

I think that was a feature originally for 'print to clipboard' where I think Allegro is working with UTF-8. It has probably sneaked into print to file as a result of re-use.

SteveFosdick commented 3 years ago

I have removed the pound sign translation from the print to file path (which will enabled uncorrupted graphics) but left it in print to clipboard (which I assume will be used for text).

SteveFosdick commented 3 years ago

I have also had another idea - does Windows have a reasonable implementation of the popen library function? If so, it would be possible to have b-em automatically start and command to receive the print output and that command could be anything of the user's choosing.

fordp2002 commented 3 years ago

Thanks Steve, good work!

SteveFosdick commented 3 years ago

OK, there is a branch that implements this: https://github.com/stardot/b-em/tree/sf/issue66

I've tested it on Linux and it works. I have also tested cross-compiling for Windows and it gets at least that far. I have yet to test running it on Windows and I don't know if native MingW or Visual Studio compilation would work.