1

We have an app that has many reports, and some of those reports have complex print loops.

Back in the day (IE PowerPlant , Carbon, Core Printing) we used to create print loops that had some sort of BeginPage() / EndPage() pair. Frequently, those pairs were embedded in the report print loop logic.

The net effect was that many reports were not paginated prior to printing, but paginated AS they printed. These reports iterated through thousands of objects and filled up as much of the page as possible, then called EndPage(), and then continued on with the next page by calling BeginPage(), all while maintaining the complex “state” of the in-progress printed report.

With most of Core Printing deprecated, It SEEMS that with NSPrint’s logic, the approach of the printed report driving the pagination isn’t possible. NSPrintOperation pretty much wants to be able to request a full page for a custom NSView’s drawRect to draw, and that custom NSView had better be able to start at ANY page. Does that mean that EVERY report has to be pre-paginated?

There seems to be a different method that is part of the “automatic” pagination:

 - (void)adjustPageHeightNew:(CGFloat *)newBottom top:(CGFloat)oldTop bottom:(CGFloat)oldBottom limit:(CGFloat)bottomLimit;

If I'm reading the documentation correctly, say I had a 10-page report where I needed to find suitable places to divide. It LOOKS like I can treat that report as one long view, then call the above method while I’m in my drawRect, causing the page I’m drawing to become SHORTER, and thus pushing the material off to the next page.

The documentation doesn't give much detail about how such adjustments would propagate across dozens (or hundreds) of pages.

Are there any other methods to drive the printing and pagination from report-generation code, rather than the passive approaches described above?

SMGreenfield
  • 1,680
  • 19
  • 35

1 Answers1

1

If I'm reading the documentation correctly, say I had a 10-page report where I needed to find suitable places to divide. It LOOKS like I can treat that report as one long view,

Yes,

 - (void)adjustPageHeightNew:(CGFloat *)newBottom top:(CGFloat)oldTop bottom:(CGFloat)oldBottom limit:(CGFloat)bottomLimit;

then call the above method while I’m in my drawRect

No, the documentation says:

Overridden by subclasses to adjust page height during automatic pagination. This method is invoked by print:. The view can raise the bottom edge and return the new value in newBottom, allowing it to prevent items such as lines of text from being divided across pages.

 

The documentation doesn't give much detail about how such adjustments would propagate across dozens (or hundreds) of pages.

I assume the following pages shift up.

Are there any other methods to drive the printing and pagination from report-generation code, rather than the passive approaches described above?

Yes, override

- (BOOL)knowsPageRange:(NSRangePointer)range;

and

- (NSRect)rectForPage:(NSInteger)page;

This requires that the report is pre-paginated.

See Selecting the Page Bounds for Content That Exceed a Single Page

in Printing Programming Guide for Mac.

Willeke
  • 14,578
  • 4
  • 19
  • 47
  • Here's what's odd: When the docs say, "This method is invoked by print:. The view can raise the bottom edge and return the new value in newBottom", what this doesn't say is HOW would adjustPageHeightNew pass in WHICH page it is asking about? – SMGreenfield Apr 17 '20 at 23:41
  • The page number doesn't matter. `adjustPageHeightNew` asks "Is this bottom edge at a convenient position?". – Willeke Apr 18 '20 at 00:43
  • So that's the whole point of pagination, "Is the bottom edge [of a SPECIFIC PAGE] at a convenient position". Otherwise, "convenient position" has no meaning whatsoever... – SMGreenfield Apr 18 '20 at 01:29
  • If a specific y-location must be on a specific page then automatic pagination can't be used. – Willeke Apr 18 '20 at 03:48