Current work and challenges.

56 views
Skip to first unread message

luserdroog

unread,
Jan 17, 2014, 4:36:02 AM1/17/14
to
We're doing lots of stuff with the code base at the moment, but they do fall under a few broad categories.
 
Source Portability.
I'm routinely checking the program under Mingw, Cygwin, and Ubuntu (Virtualbox), and Vincent has mentioned checking it with OpenIndiana (OpenSolaris), FreeBSD, and Visual Studio. These last few still need some work, I understand; for FreeBSD, there are certain calls (like mremap) which take different arguments than other Unices; for Visual Studio, it needs to be clean C89 (so we're also removing //comments for completeness, first from the library). But the code was ready for a lot of that. I had already removed designated initializers, compound literals, and VLAs. No bitfields. But I was using <stdbool.h> all over the place, even in header files, requiring them all over the place even where not specifically used. Bools are all ints now.
 
Interoperability.
We are also working to unravel my tangled web of inter-module dependencies, and to migrate most of the program into the library. We haven't hammered out all the details yet, but Vincent is firmly against ghostscript's (argc, argv) initialization. He says (compellingly) that the initialization should be more "library" like. And, put that way, I can't disagree.
 
A big hurdle for me is removing the setjmp/longjmp mechanism that I've long used for error recovery. It's not appropriate behavior for a library. So I've been slowly replacing return values with pass-by-pointer, and void functions with int functions. Once the last call to error() is removed, then there won't be any more longjmps. But there won't be a backup error handler, either. Which feels weird. But /good/ weird, you know? Instead it has a powerful logging system for tracking internal errors and messages. One that I'm only beginning to put to proper use.
 
Update: setjmp/longjmp have been removed. This removes the bulk of bin/xpost_error.c, so xpost_error is pretty much ready to migrate to the library, then xpost_save, and then maybe context. With context, then the rest of the data types can come over, dict, array, string, file. Then finally, xpost_interpreter. And the garbage collector still needs a lot of work.
 
Graphics.
I'm missing a big algorithm in the middle of the chain: shape-reduction. Oh, and operations using the even-odd winding-number rule. I don't know how to do those (yet).
 
I think my device structure is workable, although still quite primitive. The prototype is based around generating a pgm file, but it can be made to work with any byte-map format by replacing the /Emit procedure.
 
Here's the description from the image.ps file which implements the device.
 
% PGMIMAGE device handles 8bit images.
%
% It uses the full range 0-255 of values and does not calculate
% the actual maximum value in the data before transmitting. MaxVal
% is always 255.
%
% In the list of procedures below, PGMIMAGE is the Class dictionary,
% IMAGE is an instance returned by Create.
%
% procedures:
%           width height PGMIMAGE  Create  ->  IMAGE
%                   val x y IMAGE  PutPix  ->  -
%                       x y IMAGE  GetPix  ->  val
%           val x1 y1 x2 y2 IMAGE  DrawLine  ->  -
%      val x y width height IMAGE  DrawRect  ->  -
%      val x y width height IMAGE  FillRect  ->  -
%               val polygon IMAGE  FillPoly  ->  -
%                           IMAGE  Emit  ->  -
% eg:
% PS> /dev 40 20 newPGMIMAGEdevice def
% PS> 55 1 1 38 17 dev dup /DrawLine get exec
% PS> 77 9 14 3 3 dev dup /FillRect get exec
% PS> dev dup /Emit get exec
%
So this is the basis upon which I next need (want) to implement an X11 device. I'm planning to write this in C. ... Long ago there was a silly idea to add network client functions and implement the X protocol itself in postscript (Xlib /in/ ps). But ... ick. :P :)
 
So, the X11 device will inherit the above class dictionary, and overload Create, PutPix, GetPix, and Emit. These will be implemented by operator functions defined in the X11DEVICE dict.
 
I think it'll work. We'll see. Being able to see the output dynamically is going to make implementing the rest of the graphics algorithms much easier, I think.
 
PPM images, xcb windows, win32 windows, and much of the graphics and font functionality has been implemented and is being refined and optimized.
 
Vincent really wants a BGRA device, so that's very high on the list. It would be second for sure, except I've got this nagging desire to do the bitmap device next so I can start playing with caching bitmaps and masks and other mysterious parts of the font machinery. If I've got a color device, then I also have to bring in hsb and cmyk. They have to be there sooner or later. Excuses, excuses. I think the X11 device will show nicely how to get the postscript values /back/ into C.
 
Bitmaps have been implemented in the `image` operator, but not yet as an output device.
 
There's also, in DPS and NeWS, a new object type to encapsulate a color value explicitly tied to a color space. If a color value is passed as a single object, then color devices can use the same interface defined above, I think. There's room at the moment for 15 more types before we have to rearrange the flags.
 
We've put Cairo to one side because of the desire to make Xpost self-contained so that it can be included in LibreOffice and used for EPS rendering. LibreOffice only uses Cairo on Linux, so it's not guaranteed to be present in all the configurations where xpost is wanted. It would also match unfavorably with the current code which uses float for real numbers, whereas cairo uses double. This would require conversions at every function call. There is some (untested) support in the design for using doubles; this would require reworking the dictionary hash function, for starters.
 
 

luserdroog

unread,
Jan 17, 2014, 4:38:27 AM1/17/14
to
With window devices, and now fonts to worry about, both bitmap and BGRA devices have been backburnered.
 
There are quite a few open issues on the project page, and if anyone wants to do some tests, we'd love to have more cases to guide the improvements. You can attach files to an issue.
 
There is a planned overhaul of the memory layout, pending eradication of a nasty bug which would certain get obscured by any radical change in memory.
 
The memory bugs seem mostly to have been discovered and eradicated. The most recent was a predicted problem, where a pointer was used after a call which grew (and moved) the memory (which invalidates all memory pointers).
 
 
 

luserdroog

unread,
Jan 10, 2014, 5:07:46 PM1/10/14
to xpost-...@googlegroups.com
BGRA doesn't seem so far off anymore. I've got the siggraph with Porter/Duff and the A-buffer. So, yeah, we can do that. Sub-pixel sampling. Anti-aliasing. Fuck yeah!

luserdroog

unread,
Feb 9, 2014, 2:26:01 AM2/9/14
to xpost-...@googlegroups.com
Well, we're going to lead-in to that with a simpler BGR device which will then be the basis for png, jpg, what-have-you.
 
There are a couple of different ways this device could be made. I could take either the win32 or xcb device implementations and remove all the window stuff. This would have an ancillary benefit of providing a device implementation "template" as an intermediate step.
 
Or it could derive from the ppmimage device (the RGB base class) and just override the /Emit method (called by `showpage`). This would be much simpler to do, and perhaps all that's needed.

luserdroog

unread,
Feb 17, 2014, 3:56:34 AM2/17/14
to xpost-...@googlegroups.com
After some discussion with the LibreOffice guys, I think Vincent and I have planned our work in the correct direction. It is conceivable to fork+exec to xpost, but there are strong reasons to aim for a different method: put the entire application into the library. We've already been doing this, because Vincent already knew it was the correct choice for many reasons. And I think I knew it too (not so strongly), because I knew I wanted main() to be a very small function, basically just cracking the command-line arguments.
 
So for the "application end", we've got this rough top-level API:
 
    /* 3 simple top-level functions */
    int xpost_create(const char *device, const char *outfile, char *exedir, int is_installed);
    void xpost_run(const char *ps_file);
    void xpost_destroy(void);
 
So, we'll need to supplement xpost_create(), either with additional parameters, or a new variant of the function.
 
For the "back end", I've been pointed to http://sourceforge.net/p/libwpg/code/ci/STABLE-0-2-0/tree/inc/libwpg/WPGPaintInterface.h as one possibility. We'd need to implement a device that calls these functions to implement its member functions. So, roughly the same level of work that xcb and windows were, separately, I think. Still the C|C++ interface to grapple. I think I'm going to have to use some mangled function names. If that's the extent of it, it won't be so terrible, and I should stop worrying.
 
Another possibility is to contruct an SVG file. And that's a possibility that's somewhat in the same line as our (longer-term) plan to produce PDF output. Both could (conceivably) share a common document model (display-list) internally, so work spent making one device file really nice would reap benefits on the other, I think.
 
 
Reply all
Reply to author
Forward
0 new messages