home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / YellowBox / Kits / MiscTableScroll-138.1 / Palettes / MiscTableScroll / Framework / MiscTableViewPrint.M < prev    next >
Encoding:
Text File  |  1998-03-31  |  20.2 KB  |  758 lines

  1. //=============================================================================
  2. //
  3. //    Copyright (C) 1996,1997,1998 by Paul S. McCarthy and Eric Sunshine.
  4. //        Written by Paul S. McCarthy and Eric Sunshine.
  5. //                All Rights Reserved.
  6. //
  7. //    This notice may not be removed from this source code.
  8. //
  9. //    This object is included in the MiscKit by permission from the authors
  10. //    and its use is governed by the MiscKit license, found in the file
  11. //    "License.rtf" in the MiscKit distribution.  Please refer to that file
  12. //    for a list of all applicable permissions and restrictions.
  13. //    
  14. //=============================================================================
  15. //-----------------------------------------------------------------------------
  16. // MiscTableViewPrint.M
  17. //
  18. //    Printing support for MiscTableScroll.
  19. //
  20. // FIXME: Move most of this junk up into table scroll.
  21. // FIXME: Separate computing the number of pages from doing all the
  22. //    other work, so that hopefully, we can do all the other work
  23. //    only if the user proceeds with a print operation.
  24. //-----------------------------------------------------------------------------
  25. //-----------------------------------------------------------------------------
  26. // $Id: MiscTableViewPrint.M,v 1.9 98/03/22 13:12:07 sunshine Exp $
  27. // $Log:    MiscTableViewPrint.M,v $
  28. // Revision 1.9  98/03/22  13:12:07  sunshine
  29. // v133.1: Now prints corner view.
  30. // 
  31. // Revision 1.8  97/11/24  01:48:34  sunshine
  32. // v131.1: Applied v131 NEXTSTEP 3.3 diffs to fix all printing problems.
  33. // 
  34. // Revision 1.7  97/06/18  09:56:31  sunshine
  35. // v125.9: Worked around Objective-C++ compiler crash in OPENSTEP 4.2 for NT
  36. // when sending message to 'super' from within a category.  Unified naming.
  37. //-----------------------------------------------------------------------------
  38. #import "MiscTableView.h"
  39. #import "MiscTableScrollPrivate.h"
  40. #import "MiscTableBorder.h"
  41. #import "MiscBorderView.h"
  42. #import "MiscGeometry.h"
  43.  
  44. extern "Objective-C" {
  45. #import    <AppKit/NSApplication.h>
  46. #import    <AppKit/NSImage.h>
  47. #import    <AppKit/NSPrintInfo.h>
  48. #import <AppKit/NSPrintOperation.h>
  49. #import    <AppKit/NSPrintPanel.h>
  50. #import <AppKit/psops.h>
  51. }
  52.  
  53. extern "C" {
  54. #import    <math.h>    // floor()
  55. }
  56.  
  57. @implementation MiscTableView(Print)
  58.  
  59. //-----------------------------------------------------------------------------
  60. // getPrintInfo
  61. //-----------------------------------------------------------------------------
  62. - (MiscTablePrintInfo const*)getPrintInfo
  63.     {
  64.     return (pages != 0) ? &(pages->info) : 0;
  65.     }
  66.  
  67.  
  68. //-----------------------------------------------------------------------------
  69. // getHeight:
  70. //-----------------------------------------------------------------------------
  71. - (float)getHeight:(id)obj
  72.     {
  73.     if (obj != 0)
  74.     {
  75.     if ([obj respondsToSelector:@selector(frame)])
  76.         return [obj frame].size.height;
  77.     else if ([obj respondsToSelector:@selector(size)])
  78.         return [obj size].height;
  79.     }
  80.     return 0;
  81.     }
  82.  
  83.  
  84. //-----------------------------------------------------------------------------
  85. // getWidth:
  86. //-----------------------------------------------------------------------------
  87. - (float)getWidth:(id)obj
  88.     {
  89.     if (obj != 0)
  90.     {
  91.     if ([obj respondsToSelector:@selector(frame:)])
  92.         return [obj frame].size.height;
  93.     else if ([obj respondsToSelector:@selector(size:)])
  94.         return [obj size].height;
  95.     }
  96.     return 0;
  97.     }
  98.  
  99.  
  100. //-----------------------------------------------------------------------------
  101. // numPagesForBorder:pageSize:
  102. //-----------------------------------------------------------------------------
  103. - (int)numPagesForBorder:(MiscBorderType)bt pageSize:(float)scaled_page_size
  104.     {
  105.     int npages = 0;
  106.  
  107.     // FIXME: Borders with uniform size slots should be much simpler
  108.     // than this.
  109.  
  110.     MiscPixels const page_size = (MiscPixels)floor(scaled_page_size);
  111.  
  112.     NSParameterAssert( page_size > 0 );
  113.  
  114.     MiscTableBorder* const border =
  115.         (bt == MISC_COL_BORDER ? colBorder : rowBorder);
  116.  
  117.     MiscPixels sz_sum = 0;
  118.     MiscCoord_V const numSlots = border->count();
  119.     for (MiscCoord_V vslot = 0; vslot < numSlots; vslot++)
  120.     {
  121.     MiscPixels sz = border->effectiveSize(vslot);
  122.     if (sz <= page_size)
  123.         {
  124.         sz_sum += sz;
  125.         if (sz_sum > page_size)
  126.         {
  127.         sz_sum = sz;
  128.         npages++;
  129.         }
  130.         }
  131.     else
  132.         {
  133.         if (sz_sum > 0)
  134.         npages++;
  135.         npages += sz / page_size;
  136.         sz_sum = sz % page_size;
  137.         }
  138.     }
  139.  
  140.     if (sz_sum >= 0)
  141.     npages++;
  142.  
  143.     return npages;
  144.     }
  145.  
  146.  
  147. //-----------------------------------------------------------------------------
  148. // append
  149. //-----------------------------------------------------------------------------
  150. static void append( MiscPixels w, MiscTSPageBreak& bk, MiscTSPageBreak bks[],
  151.             int n, int num_breaks )
  152.     {
  153.     NSCParameterAssert( n < num_breaks );
  154.     bk.size = w;
  155.     bks[ n ] = bk;
  156.     bk.offset += w;
  157.     }
  158.  
  159.  
  160. //-----------------------------------------------------------------------------
  161. // border:pageSize:numPages:calcBreaks:
  162. //-----------------------------------------------------------------------------
  163. - (void)border:(MiscBorderType)bt
  164.     pageSize:(float)pageSize
  165.     numPages:(int)nPages
  166.     clip:(BOOL)do_clip
  167.     calcBreaks:(MiscTSPageBreak*)bks
  168.     {
  169.     MiscPixels const page_size = (MiscPixels)floor(pageSize);
  170.  
  171.     // FIXME: Borders with uniform size slots should be much simpler
  172.     // than this.
  173.  
  174.     NSParameterAssert( page_size > 0 );
  175.  
  176.     MiscTableBorder* const border =
  177.         (bt == MISC_COL_BORDER ? colBorder : rowBorder);
  178.  
  179.     MiscTSPageBreak bk;
  180.     bk.offset = 0;
  181.     bk.size = 0;
  182.     bk.first = 0;
  183.     bk.last = 0;
  184.  
  185.     int pg = 0;
  186.     MiscPixels sz_sum = 0;
  187.  
  188.     MiscCoord_V const numSlots = border->count();
  189.     for (MiscCoord_V vslot = 0; vslot < numSlots; vslot++)
  190.     {
  191.     MiscPixels sz = border->effectiveSize(vslot);
  192.     if (sz <= page_size)
  193.         {
  194.         sz_sum += sz;
  195.         if (sz_sum > page_size)
  196.         {
  197.         bk.last = (vslot - 1);
  198.         append( sz_sum - sz, bk, bks, pg++, nPages );
  199.         if (do_clip) goto clip_exit;
  200.         bk.first = vslot;
  201.         sz_sum = sz;
  202.         }
  203.         }
  204.     else
  205.         {
  206.         if (sz_sum > 0)
  207.         {
  208.         bk.last = (vslot - 1);
  209.         append( sz_sum, bk, bks, pg++, nPages );
  210.         if (do_clip) goto clip_exit;
  211.         }
  212.         bk.first = vslot;
  213.         bk.last = ~vslot;
  214.         do  {
  215.         append( page_size, bk, bks, pg++, nPages );
  216.         if (do_clip) goto clip_exit;
  217.         bk.first = ~vslot;
  218.         sz -= page_size;
  219.         }
  220.         while (sz > page_size);
  221.         sz_sum = sz;
  222.         }
  223.     }
  224.  
  225.     if (sz_sum >= 0)
  226.     {
  227.     bk.last = numSlots - 1;
  228.     append( sz_sum, bk, bks, pg++, nPages );
  229.     }
  230.  
  231. clip_exit:
  232.  
  233.     NSParameterAssert( pg == nPages );
  234.     }
  235.  
  236.  
  237. //-----------------------------------------------------------------------------
  238. // - getImageForView:inRect:
  239. //-----------------------------------------------------------------------------
  240. - (NSImage*)getImageForView:(id)view inRect:(NSRect)rect
  241.     {
  242.     return [[[NSImage alloc] initWithData:
  243.         [view dataWithEPSInsideRect:rect]] autorelease];
  244.     }
  245.  
  246.  
  247. //-----------------------------------------------------------------------------
  248. // - getImageForView:
  249. //-----------------------------------------------------------------------------
  250. - (NSImage*)getImageForView:(id)view
  251.     {
  252.     return [self getImageForView:view inRect:[view bounds]];
  253.     }
  254.  
  255.  
  256. //-----------------------------------------------------------------------------
  257. // getImages:info:
  258. //-----------------------------------------------------------------------------
  259. - (void)getImages:(MiscTSPageImages*)img
  260.     info:(MiscTablePrintInfo const*)info
  261.     {
  262.     id delg;
  263.     id const scroll = [self scroll];
  264.  
  265.     img->page_header = 0;
  266.     img->page_footer = 0;
  267.     img->col_titles = 0;
  268.     img->row_titles = 0;
  269.     img->corner_view = 0;
  270.  
  271.     if (pages->pageHeader != 0)
  272.     {
  273.     delg = [scroll responsibleDelegate:
  274.             MiscDelegateFlags::DEL_PRINT_PAGE_HEADER];
  275.     if (delg != 0)
  276.         [delg tableScroll:scroll
  277.             willPrintPageHeader:pages->pageHeader
  278.             info:info];
  279.     // FIXME: Need to shrink/grow/center/position.
  280.     img->page_header = [[self getImageForView:pages->pageHeader] retain];
  281.     }
  282.  
  283.     if (pages->pageFooter != 0)
  284.     {
  285.     delg = [scroll responsibleDelegate:
  286.             MiscDelegateFlags::DEL_PRINT_PAGE_FOOTER];
  287.     if (delg != 0)
  288.         [delg tableScroll:scroll
  289.             willPrintPageFooter:pages->pageFooter
  290.             info:info];
  291.     // FIXME: Need to shrink/grow/center/position.
  292.     img->page_footer = [[self getImageForView:pages->pageFooter] retain];
  293.     }
  294.  
  295.     if (pages->colTitles != 0)
  296.     {
  297.     NSRect r = info->print_rect;
  298.     r.origin.y = 0;
  299.     r.size.height = pages->col_titles_height;
  300.     img->col_titles =
  301.         [[self getImageForView:pages->colTitles inRect:r] retain];
  302.     }
  303.  
  304.     if (pages->rowTitles != 0)
  305.     {
  306.     NSRect r = info->print_rect;
  307.     r.origin.x = 0;
  308.     r.size.width = pages->row_titles_width;
  309.     img->row_titles =
  310.         [[self getImageForView:pages->rowTitles inRect:r] retain];
  311.     }
  312.  
  313.     if (pages->cornerView != 0)
  314.     {
  315.     NSRect r;
  316.     r.origin.x = 0;
  317.     r.origin.y = 0;
  318.     r.size.width = pages->row_titles_width;
  319.     r.size.height = pages->col_titles_height;
  320.     img->corner_view =
  321.         [[self getImageForView:pages->cornerView inRect:r] retain];
  322.     }
  323.     }
  324.  
  325.  
  326. //-----------------------------------------------------------------------------
  327. // calcPages
  328. //-----------------------------------------------------------------------------
  329. - (BOOL)calcPages
  330.     {
  331.     BOOL ok = YES;    // FIXME: Deal with pages that are too small, etc.
  332.     id const scroll = [self scroll];
  333.  
  334.     pages = new MiscTablePages;
  335.  
  336.     pages->pageHeader = [scroll getPageHeader];
  337.     pages->pageFooter = [scroll getPageFooter];
  338.     pages->page_header_height = [self getHeight:pages->pageHeader];
  339.     pages->page_footer_height = [self getHeight:pages->pageFooter];
  340.  
  341.     pages->colTitles = [scroll colTitles];
  342.     pages->rowTitles = [scroll rowTitles];
  343.     if (pages->colTitles != 0 && pages->rowTitles != 0)
  344.     pages->cornerView = [scroll cornerView];
  345.     else
  346.     pages->cornerView = 0;
  347.     pages->col_titles_height = [scroll columnTitlesHeight];
  348.     pages->row_titles_width  = [scroll rowTitlesWidth ];
  349.  
  350.     float scroll_width = [scroll totalWidth];
  351.     float scroll_height = [scroll totalHeight];
  352.     float total_width  = scroll_width  + pages->row_titles_width;
  353.     float total_height = scroll_height + pages->col_titles_height;
  354.  
  355.     NSPrintInfo* printInfo = [NSPrintInfo sharedPrintInfo];
  356.     NSSize const paperSize = [printInfo paperSize];
  357.  
  358.     float page_width = paperSize.width -
  359.             [printInfo leftMargin] - [printInfo rightMargin];
  360.     float page_height = paperSize.height -
  361.             [printInfo topMargin] - [printInfo bottomMargin] -
  362.             pages->page_header_height -
  363.             pages->page_footer_height;
  364.  
  365.     int const hPagination = [printInfo horizontalPagination];
  366.     int const vPagination = [printInfo verticalPagination];
  367.  
  368.     BOOL hScaled = NO;    double hScaler = 1.0;
  369.     BOOL vScaled = NO;    double vScaler = 1.0;
  370.     BOOL isScaled = NO;    double scaleFactor = 1.0;
  371.  
  372.     if (hPagination == NSFitPagination && total_width > page_width)
  373.     {
  374.     hScaled = YES;
  375.     hScaler = double(page_width) / double(total_width);
  376.     }
  377.  
  378.     if (vPagination == NSFitPagination && total_height > page_height)
  379.     {
  380.     vScaled = YES;
  381.     vScaler = double(page_height) / double(total_height);
  382.     }
  383.  
  384.     if (hScaled || vScaled)
  385.     {
  386.     isScaled = YES;
  387.     if (vScaler < hScaler)
  388.         scaleFactor = vScaler;
  389.     else
  390.         scaleFactor = hScaler;
  391.     }
  392.  
  393.     float const EPSILON = 0.0001;
  394.     float const pScaler = [[[printInfo dictionary]
  395.     objectForKey:NSPrintScalingFactor] floatValue];
  396.     if (pScaler < (1.0 - EPSILON) || (1.0 + EPSILON) < pScaler)
  397.     {
  398.     if (isScaled)
  399.         scaleFactor *= pScaler;
  400.     else
  401.         {
  402.         scaleFactor = pScaler;
  403.         isScaled = YES;
  404.         }
  405.     }
  406.  
  407.     pages->info.is_scaled = isScaled;
  408.     pages->info.scale_factor = scaleFactor;
  409.  
  410.     float scaled_page_width = page_width;
  411.     float scaled_page_height = page_height;
  412.  
  413.     if (isScaled)
  414.     {
  415.     scaled_page_width = double(page_width) / scaleFactor;
  416.     scaled_page_height = double(page_height) / scaleFactor;
  417.     }
  418.  
  419.     scaled_page_width -= pages->row_titles_width;
  420.     scaled_page_height -= pages->col_titles_height;
  421.  
  422.  
  423.     //--- Calculate the number of rows/cols/pages -------------------------
  424.  
  425.     int ncols = 1;
  426.     int nrows = 1;
  427.  
  428.     if (hPagination != NSClipPagination && scroll_width > scaled_page_width)
  429.     ncols = [self numPagesForBorder:MISC_COL_BORDER
  430.             pageSize:scaled_page_width];
  431.  
  432.     if (vPagination != NSClipPagination && scroll_height > scaled_page_height)
  433.     nrows = [self numPagesForBorder:MISC_ROW_BORDER
  434.             pageSize:scaled_page_height];
  435.  
  436.     NSParameterAssert( nrows > 0 );  NSParameterAssert( ncols > 0 );
  437.  
  438.     int const npages = nrows * ncols;
  439.  
  440.  
  441.     //--- Allocate arrays -------------------------------------------------
  442.  
  443.     pages->col_breaks = (MiscTSPageBreak*)
  444.             malloc( (ncols + nrows) * sizeof(MiscTSPageBreak) );
  445.     pages->row_breaks = pages->col_breaks + ncols;
  446.  
  447.     MiscTSPageImages* images = (MiscTSPageImages*)
  448.             malloc( npages * sizeof(*images) );
  449.     pages->images = images;
  450.  
  451.  
  452.     //--- Prepare print rectangles and border images ----------------------
  453.  
  454.     [self border:MISC_COL_BORDER
  455.         pageSize:scaled_page_width
  456.         numPages:ncols
  457.         clip:(hPagination == NSClipPagination)
  458.         calcBreaks:pages->col_breaks];
  459.  
  460.     [self border:MISC_ROW_BORDER
  461.         pageSize:scaled_page_height
  462.         numPages:nrows
  463.         clip:(vPagination == NSClipPagination)
  464.         calcBreaks:pages->row_breaks];
  465.  
  466.  
  467.     MiscTablePrintInfo& info = pages->info;
  468.     info.page_size = paperSize;
  469.     info.num_print_pages = npages;
  470.     info.num_print_rows = nrows;
  471.     info.num_print_cols = ncols;
  472.     info.scale_factor = scaleFactor;
  473.     info.is_scaled = isScaled;
  474.  
  475.     int pg = 0;
  476.     MiscTSPageImages* img = images;
  477.     MiscTSPageBreak const* rbk = pages->row_breaks;
  478.     for (int r = 0; r < nrows; r++,rbk++)
  479.     {
  480.     info.print_rect.origin.y = rbk->offset;
  481.     info.print_rect.size.height = rbk->size;
  482.     info.first_print_row = rbk->first;
  483.     info.last_print_row = rbk->last;
  484.  
  485.     MiscTSPageBreak const* cbk = pages->col_breaks;
  486.     for (int c = 0; c < ncols; c++,cbk++,img++)
  487.         {
  488.         info.print_rect.origin.x = cbk->offset;
  489.         info.print_rect.size.width = cbk->size;
  490.         info.first_print_col = cbk->first;
  491.         info.last_print_col = cbk->last;
  492.         info.print_page = ++pg;
  493.  
  494.         [self getImages:img info:&info];
  495.         }
  496.     }
  497.  
  498.     return ok;
  499.     }
  500.  
  501.  
  502. //-----------------------------------------------------------------------------
  503. // freePages
  504. //-----------------------------------------------------------------------------
  505. - (void)freePages
  506.     {
  507.     if (pages->col_breaks != 0)
  508.     {
  509.     free( pages->col_breaks );
  510.     pages->col_breaks = 0;
  511.     }
  512.     if (pages->images != 0)
  513.     {
  514.     for (int i = pages->info.num_print_pages; i-- > 0; )
  515.         {
  516.         MiscTSPageImages const& img = pages->images[i];
  517.         if (img.page_header != 0) [img.page_header release];
  518.         if (img.page_footer != 0) [img.page_footer release];
  519.         if (img.col_titles  != 0) [img.col_titles  release];
  520.         if (img.row_titles  != 0) [img.row_titles  release];
  521.         if (img.corner_view != 0) [img.corner_view release];
  522.         }
  523.     free( pages->images );
  524.     pages->images = 0;
  525.     }
  526.     delete pages;
  527.     pages = 0;
  528.     }
  529.  
  530.  
  531. //-----------------------------------------------------------------------------
  532. // print:
  533. //-----------------------------------------------------------------------------
  534. - (void)print:(id)sender
  535.     {
  536.     id const scroll = [self scroll];
  537.     id del = [scroll responsibleDelegate:MiscDelegateFlags::DEL_WILL_PRINT];
  538.     if (del != 0)
  539.     [del tableScrollWillPrint:scroll];
  540.  
  541.     if ([self calcPages])
  542.     {
  543.     [self superPrint:sender];
  544.     [self freePages];
  545.     }
  546.  
  547.     del = [scroll responsibleDelegate:MiscDelegateFlags::DEL_DID_PRINT];
  548.     if (del != 0)
  549.     [del tableScrollDidPrint:scroll];
  550.     }
  551.  
  552.  
  553. //-----------------------------------------------------------------------------
  554. // knowsPagesFirst:last:
  555. //-----------------------------------------------------------------------------
  556. - (BOOL)knowsPagesFirst:(int*)first last:(int*)last
  557.     {
  558.     if (pages != 0)
  559.     {
  560.     *first = 1;
  561.     *last = pages->info.num_print_pages;
  562.     return YES;
  563.     }
  564.     return NO;
  565.     }
  566.  
  567.  
  568. //-----------------------------------------------------------------------------
  569. // rectForPage:
  570. //-----------------------------------------------------------------------------
  571. - (NSRect)rectForPage:(int)n
  572.     {
  573.     NSParameterAssert( pages != 0 );
  574.     MiscTablePrintInfo const& info = pages->info;
  575.     if (0 < n && n <= info.num_print_pages)
  576.     {
  577.     n--;
  578.     int const r = (n / info.num_print_cols);
  579.     int const c = (n % info.num_print_cols);
  580.     MiscTSPageBreak const& cbk = pages->col_breaks[c];
  581.     MiscTSPageBreak const& rbk = pages->row_breaks[r];
  582.     return NSMakeRect( cbk.offset, rbk.offset, cbk.size, rbk.size );
  583.     }
  584.     return NSZeroRect;
  585.     }
  586.  
  587.  
  588. //-----------------------------------------------------------------------------
  589. // locationOfPrintRect:
  590. //-----------------------------------------------------------------------------
  591. - (NSPoint)locationOfPrintRect:(NSRect)rect
  592.     {
  593.     NSPrintInfo* printInfo = [[NSPrintOperation currentOperation] printInfo];
  594.     NSSize const paperSize = [printInfo paperSize];
  595.     float ml = [printInfo leftMargin];
  596.     float mr = [printInfo rightMargin];
  597.     float mt = [printInfo topMargin];
  598.     float mb = [printInfo bottomMargin];
  599.  
  600.     float x = 0;
  601.     float y = 0;
  602.     float h = paperSize.height;
  603.     float w = paperSize.width;
  604.     float rh = rect.size.height;
  605.     float rw = rect.size.width;
  606.     float tw = pages->row_titles_width;
  607.     float th = pages->col_titles_height;
  608.     float hh = pages->page_header_height;
  609.  
  610.     NSParameterAssert( pages != 0 );
  611.  
  612.     MiscTablePrintInfo const& info = pages->info;
  613.     if (info.is_scaled)
  614.     {
  615.     float const k = info.scale_factor;
  616.     x /= k;
  617.     y /= k;
  618.     h /= k;
  619.     w /= k;
  620.     ml /= k;
  621.     mr /= k;
  622.     mt /= k;
  623.     mb /= k;
  624.     }
  625.  
  626.     NSPoint pt = NSMakePoint( x + ml + tw, y + h - mt - rh - hh - th );
  627.  
  628.     if ([printInfo isHorizontallyCentered])
  629.     {
  630.     float dx = w - ml - mr - tw - rw;
  631.     if (dx > 0)
  632.         pt.x += dx / 2;
  633.     }
  634.  
  635.     if ([printInfo isVerticallyCentered])
  636.     {
  637.     float dy = h - mt - mb - th - rh;
  638.     if (dy > 0)
  639.         pt.y -= dy / 2;
  640.     }
  641.  
  642.     return pt;
  643.     }
  644.  
  645.  
  646. //-----------------------------------------------------------------------------
  647. // drawImage:at:
  648. //-----------------------------------------------------------------------------
  649. - (void)drawImage:(NSImage*)img at:(NSPoint)pt
  650.     {
  651.     NSRect r;
  652.     r.size = [img size];
  653.     r.origin.x = pt.x;
  654.     r.origin.y = pt.y - r.size.height;
  655.     [img drawRepresentation:[[img representations] lastObject] inRect:r];
  656.     }
  657.  
  658.  
  659. //-----------------------------------------------------------------------------
  660. // drawPageBorderWithSize:
  661. //-----------------------------------------------------------------------------
  662. - (void)drawPageBorderWithSize:(NSSize)borderSize
  663.     {
  664.     NSParameterAssert( pages != 0 );
  665.     MiscTablePrintInfo const& info = pages->info;
  666.  
  667.     int n = [[NSPrintOperation currentOperation] currentPage] - 1;
  668.     NSParameterAssert( 0 <= n );
  669.     NSParameterAssert( n < info.num_print_pages );
  670.     MiscTSPageImages const& img = pages->images[n];
  671.  
  672.     NSPrintInfo* printInfo = [[NSPrintOperation currentOperation] printInfo];
  673.     float const ml = [printInfo leftMargin];
  674.     float const mr = [printInfo rightMargin];
  675.     float const mb = [printInfo bottomMargin];
  676.     float const mt = [printInfo topMargin];
  677.  
  678.     NSPoint const page_origin = NSZeroPoint;
  679.     NSSize const page_size = info.page_size;
  680.     float bottom = page_origin.y + mb;
  681.     float top = page_origin.y + page_size.height - mt;
  682.     float left = page_origin.x + ml;
  683.     float right = page_origin.x + page_size.width - mr;
  684.  
  685.     if (info.is_scaled)
  686.     {
  687.     float const k = info.scale_factor;
  688.     PSscale( k, k );
  689.     bottom /= k;
  690.     top /= k;
  691.     left /= k;
  692.     right /= k;
  693.     }
  694.  
  695.     if (img.page_header != 0)
  696.     {
  697.     [self drawImage:img.page_header at:NSMakePoint(top, left)];
  698.     top -= pages->page_header_height;
  699.     }
  700.  
  701.     if (img.page_footer != 0)
  702.     {
  703.     bottom += pages->page_footer_height;
  704.     [self drawImage:img.page_footer at:NSMakePoint(left, bottom)];
  705.     }
  706.  
  707.     float dx = 0;
  708.     float dy = 0;
  709.  
  710.     if ([printInfo isHorizontallyCentered])
  711.     {
  712.     int const c = (n % info.num_print_cols);
  713.     dx = right - left - pages->row_titles_width
  714.             - pages->col_breaks[c].size;
  715.     if (dx > 0)
  716.         dx /= 2;
  717.     else
  718.         dx = 0;
  719.     }
  720.  
  721.     if ([printInfo isVerticallyCentered])
  722.     {
  723.     int const r = (n / info.num_print_cols);
  724.     dy = top - bottom - pages->col_titles_height
  725.             - pages->row_breaks[r].size;
  726.     if (dy > 0)
  727.         dy /= 2;
  728.     else
  729.         dy = 0;
  730.     }
  731.  
  732.     if (img.corner_view != 0)
  733.     {
  734.     NSPoint pt;
  735.     pt.x = left + dx;
  736.     pt.y = top - dy;
  737.     [self drawImage:img.corner_view at:pt];
  738.     }
  739.  
  740.     if (img.row_titles != 0)
  741.     {
  742.     NSPoint pt;
  743.     pt.x = left + dx;
  744.     pt.y = top - pages->col_titles_height - dy;
  745.     [self drawImage:img.row_titles at:pt];
  746.     }
  747.  
  748.     if (img.col_titles != 0)
  749.     {
  750.     NSPoint pt;
  751.     pt.x = left + pages->row_titles_width + dx;
  752.     pt.y = top - dy;
  753.     [self drawImage:img.col_titles at:pt];
  754.     }
  755.     }
  756.  
  757. @end
  758.