There was one annoying complexity that one could view as a design limitation. When printing, Java calls you page by page. If at the end of a page you have more to print, you return PAGE_EXISTS, else you return NO_SUCH_PAGE. But this means that when you reach the end of a page, your application must remember its exact state before it exits, so when Java calls it for the next page, it picks up right where it left off.
On the surface, this seems to require the application to be reentrant. Java calls you, you print to the end of the page, you exit. Java calls you again, you pick up right where you left off before. An Icon or Ruby type "suspend" capability would have been very useful here. But no such capability exists in Java, so I came up with a different (and simpler solution).
I created an abstract model of the stuff being printed. At the root is a PrintBatch, which is a list of PrintLines, each of which is a list of PrintItems. When the print is first requested, the system "prints" the entire document by creating and filling in an instance of this abstract model. When it's done, we have defined the document that will be printed. Its definiton is abstract and entirely independent of the print system. During printing we will render it to the print system's graphics space (the printed page).
When printing, when we get to the end of a page all we have to remember is:
Now to make matters worse, when printing, Java may call your app multiple times for the same page. For example I found it usually (but not always) calls for each page twice. I found that doing the same thing each time satisfied Java - no duplicate pages or missing data. However, this added a bit of complexity to the print program. To handle this I created a simple Map with integer keys & values. Keys are page numbers, values are the starting line for that page.
So the algorithm became:
Printing in OS/2 was easier. The system calls you one time, giving you the graphics space representing the printed page. You print away and when you reach the end of a page, you make one of two calls: