mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-20 21:56:27 +00:00
Simple printint implementation
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@11341 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
81915f4a3c
commit
04a3436aff
119 changed files with 4892 additions and 3621 deletions
|
@ -45,6 +45,9 @@ static BOOL boldSystemCacheNeedsRecomputing = NO;
|
|||
static BOOL userCacheNeedsRecomputing = NO;
|
||||
static BOOL userFixedCacheNeedsRecomputing = NO;
|
||||
|
||||
/* Set used to keep track of fonts we are using */
|
||||
static NSMutableSet *usedFonts = nil;
|
||||
|
||||
@interface NSFont (Private)
|
||||
- (id) initWithName: (NSString*)name
|
||||
matrix: (const float*)fontMatrix;
|
||||
|
@ -394,9 +397,21 @@ setNSFont(NSString* key, NSFont* font)
|
|||
|
||||
+ (void) useFont: (NSString*)name
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
if (usedFonts == nil)
|
||||
usedFonts = RETAIN([NSMutableSet setWithCapacity: 2]);
|
||||
|
||||
[ctxt useFont: name];
|
||||
[usedFonts addObject: name];
|
||||
}
|
||||
|
||||
+ (void) resetUsedFonts
|
||||
{
|
||||
if (usedFonts)
|
||||
[usedFonts removeAllObjects];
|
||||
}
|
||||
|
||||
+ (NSSet *) usedFonts
|
||||
{
|
||||
return usedFonts;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -497,7 +512,7 @@ setNSFont(NSString* key, NSFont* font)
|
|||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
|
||||
[ctxt setFont: self];
|
||||
[ctxt useFont: fontName];
|
||||
[NSFont useFont: fontName];
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -111,18 +111,6 @@ NSGraphicsContext *GSCurrentContext()
|
|||
defaultNSGraphicsContextClass = defaultContextClass;
|
||||
}
|
||||
|
||||
+ defaultContextWithInfo: (NSDictionary *)info;
|
||||
{
|
||||
NSGraphicsContext *ctxt;
|
||||
|
||||
NSAssert(defaultNSGraphicsContextClass,
|
||||
@"Internal Error: No default NSGraphicsContext set\n");
|
||||
ctxt = [[defaultNSGraphicsContextClass allocWithZone: _globalGSZone]
|
||||
initWithContextInfo: info];
|
||||
AUTORELEASE(ctxt);
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
+ (void) setCurrentContext: (NSGraphicsContext *)context
|
||||
{
|
||||
#ifdef GNUSTEP_BASE_LIBRARY
|
||||
|
@ -149,10 +137,25 @@ NSGraphicsContext *GSCurrentContext()
|
|||
return [GSCurrentContext() isDrawingToScreen];
|
||||
}
|
||||
|
||||
+ (NSGraphicsContext *) graphicsContextWithAttributes: (NSDictionary *)attributes
|
||||
+ defaultContextWithInfo: (NSDictionary *)info;
|
||||
{
|
||||
// FIXME: The attributes should determine the concrete class
|
||||
return [self defaultContextWithInfo: attributes];
|
||||
return [self graphicsContextWithAttributes: info];
|
||||
}
|
||||
|
||||
+ (NSGraphicsContext *) graphicsContextWithAttributes: (NSDictionary *)info
|
||||
{
|
||||
NSGraphicsContext *ctxt;
|
||||
if (self == [NSGraphicsContext class])
|
||||
{
|
||||
NSAssert(defaultNSGraphicsContextClass,
|
||||
@"Internal Error: No default NSGraphicsContext set\n");
|
||||
ctxt = [[defaultNSGraphicsContextClass allocWithZone: _globalGSZone]
|
||||
initWithContextInfo: info];
|
||||
AUTORELEASE(ctxt);
|
||||
}
|
||||
else
|
||||
ctxt = [[self allocWithZone: _globalGSZone] initWithContextInfo: info];
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
+ (NSGraphicsContext *) graphicsContextWithWindow: (NSWindow *)aWindow
|
||||
|
@ -1170,16 +1173,6 @@ NSGraphicsContext *GSCurrentContext()
|
|||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) useFont: (NSString*) name
|
||||
{
|
||||
/*
|
||||
* Do nothing here, printing subclasses will have to register all
|
||||
* the fonts used by the current print operation to be able to
|
||||
* dump the %%DocumentFonts comment required by the Adobe Document
|
||||
* Structuring Convention (see the red book).
|
||||
*/
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* Gstate operations */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
|
|
@ -194,7 +194,6 @@ static NSPageLayout *shared_instance;
|
|||
|
||||
result = [NSApp runModalForWindow: self];
|
||||
[self orderOut: self];
|
||||
NSLog(@"Model Page Layout ended with code %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -486,8 +485,7 @@ static NSPageLayout *shared_instance;
|
|||
[_printInfo setOrientation: [control selectedColumn]+NSPortraitOrientation];
|
||||
|
||||
/* Write Size */
|
||||
/* FIXME: Currently don't allow writing size. What does that mean
|
||||
anyway? Shouldn't we set margins instead? */
|
||||
/* FIXME: Currently don't allow writing custom size. */
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSEnumerator.h>
|
||||
|
@ -47,6 +49,10 @@
|
|||
#define NSPrintInfo_DEFAULTSTABLE @"PrintDefaults"
|
||||
#endif
|
||||
|
||||
#define NSNUMBER(val) [NSNumber numberWithInt: val]
|
||||
#define DICTSET(dict, obj, key) \
|
||||
[dict setObject: obj forKey: key]
|
||||
|
||||
// FIXME: retain/release of dictionary with retain/release of printInfo?
|
||||
|
||||
// Class variables:
|
||||
|
@ -58,6 +64,16 @@ NSDictionary *paperSizes = nil;
|
|||
+ initPrintInfoDefaults;
|
||||
@end
|
||||
|
||||
/**
|
||||
<unit>
|
||||
<heading>Class Description</heading>
|
||||
<p>
|
||||
NSPrintInfo is a storage object that stores information that describes
|
||||
how a view is to printed and the destination information for printing.
|
||||
</p>
|
||||
</unit>
|
||||
*/
|
||||
|
||||
@implementation NSPrintInfo
|
||||
|
||||
//
|
||||
|
@ -98,28 +114,6 @@ NSDictionary *paperSizes = nil;
|
|||
+ (NSSize)sizeForPaperName:(NSString *)name
|
||||
{
|
||||
return [[self defaultPrinter] pageSizeForPaper:name];
|
||||
// Alternatively:
|
||||
// NSBundle *adminBundle;
|
||||
// NSString *path;
|
||||
// NSValue *size;
|
||||
// if (!paperSizes)
|
||||
// {
|
||||
// adminBundle = [NSBundle bundleWithPath:NSPrinterAdmin_PATH];
|
||||
// path = [adminBundle pathForResource:NSPrintInfo_PAPERFILE ofType:nil];
|
||||
// // If not found
|
||||
// if (path == nil || [path length] == 0)
|
||||
// {
|
||||
// [NSException raise:NSGenericException
|
||||
// format:@"Could not find paper size index, file %s",
|
||||
// [NSPrintInfo_PAPERFILE cString]];
|
||||
// // NOT REACHED
|
||||
// }
|
||||
// paperSizes = RETAIN([NSDictionary dictionaryWithContentsOfFile:path]);
|
||||
// }
|
||||
// size = [paperSizes objectForKey:name];
|
||||
// if (!size)
|
||||
// return NSZeroSize;
|
||||
// return [size sizeValue];
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -214,19 +208,41 @@ NSDictionary *paperSizes = nil;
|
|||
|
||||
- (void)setOrientation:(NSPrintingOrientation)mode
|
||||
{
|
||||
NSSize size;
|
||||
[_info setObject:[NSNumber numberWithInt:mode]
|
||||
forKey:NSPrintOrientation];
|
||||
/* Set the paper size accordingly */
|
||||
size = [self paperSize];
|
||||
if ((mode == NSPortraitOrientation && size.width > size.height)
|
||||
|| (mode == NSLandscapeOrientation && size.width < size.height))
|
||||
{
|
||||
float tmp = size.width;
|
||||
size.width = size.height;
|
||||
size.height = tmp;
|
||||
[_info setObject: [NSValue valueWithSize: size]
|
||||
forKey: NSPrintPaperSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setPaperName:(NSString *)name
|
||||
{
|
||||
[_info setObject:name forKey:NSPrintPaperName];
|
||||
DICTSET(_info, name, NSPrintPaperName);
|
||||
DICTSET(_info,
|
||||
[NSValue valueWithSize: [NSPrintInfo sizeForPaperName: name]],
|
||||
NSPrintPaperSize);
|
||||
}
|
||||
|
||||
- (void)setPaperSize:(NSSize)size
|
||||
{
|
||||
NSPrintingOrientation orient;
|
||||
[_info setObject:[NSValue valueWithSize:size]
|
||||
forKey:NSPrintPaperSize];
|
||||
/* Set orientation accordingly */
|
||||
if (size.width <= size.height)
|
||||
orient = NSPortraitOrientation;
|
||||
else
|
||||
orient = NSLandscapeOrientation;
|
||||
DICTSET(_info, NSNUMBER(orient), NSPrintOrientation);
|
||||
}
|
||||
|
||||
- (void)setRightMargin:(float)value
|
||||
|
@ -369,38 +385,62 @@ NSDictionary *paperSizes = nil;
|
|||
//
|
||||
+ initPrintInfoDefaults
|
||||
{
|
||||
NSString *defPrinter, *str;
|
||||
NSBundle *adminBundle;
|
||||
NSString *path;
|
||||
NSPrinter *printer;
|
||||
adminBundle = [NSBundle bundleWithPath:NSPrinterAdmin_PATH];
|
||||
path = [adminBundle pathForResource:NSPrintInfo_DEFAULTSTABLE ofType:nil];
|
||||
// If not found
|
||||
defPrinter = nil;
|
||||
if (path != nil && [path length] != 0)
|
||||
{
|
||||
printInfoDefaults = RETAIN([NSMutableDictionary dictionaryWithContentsOfFile:path]);
|
||||
// NOT REACHED
|
||||
printInfoDefaults = [NSMutableDictionary dictionaryWithContentsOfFile:path];
|
||||
RETAIN(printInfoDefaults);
|
||||
defPrinter = [printInfoDefaults objectForKey:NSPrintPrinter];
|
||||
printer = [NSPrinter printerWithName: defPrinter];
|
||||
if (printer == nil)
|
||||
defPrinter = nil;
|
||||
}
|
||||
if (printInfoDefaults == nil)
|
||||
{
|
||||
NSLog(@"Could not find printing defaults table, file %s",
|
||||
[NSPrintInfo_DEFAULTSTABLE cString]);
|
||||
// FIXME: As a replacement we add a very simple definition
|
||||
printInfoDefaults = RETAIN(([NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
@"Unknown", NSPrintPrinter,
|
||||
@"A4", NSPrintPaperName,
|
||||
NULL]));
|
||||
NSDebugLog(@"NSPrinter", @"Could not find printing defaults table, file %@",
|
||||
NSPrintInfo_DEFAULTSTABLE);
|
||||
printInfoDefaults = RETAIN([NSMutableDictionary dictionary]);
|
||||
}
|
||||
if (defPrinter == nil)
|
||||
{
|
||||
defPrinter = [[NSPrinter printerNames] objectAtIndex: 0];
|
||||
DICTSET(printInfoDefaults, defPrinter, NSPrintPrinter);
|
||||
}
|
||||
|
||||
// The loaded dictionary contains the name of the printer for NSPrintPrinter
|
||||
// Load the real NSPrinter object...
|
||||
[printInfoDefaults
|
||||
setObject:[NSPrinter printerWithName:[printInfoDefaults
|
||||
objectForKey:NSPrintPrinter]]
|
||||
forKey:NSPrintPrinter];
|
||||
[printInfoDefaults
|
||||
setObject:[NSValue valueWithSize:
|
||||
[NSPrintInfo sizeForPaperName:
|
||||
[printInfoDefaults objectForKey:NSPrintPaperName]]]
|
||||
forKey:NSPrintPaperSize];
|
||||
/* Replace the printer name with a real NSPrinter object */
|
||||
printer = [NSPrinter printerWithName: defPrinter];
|
||||
DICTSET(printInfoDefaults, [NSPrinter printerWithName: defPrinter], NSPrintPrinter);
|
||||
|
||||
/* Set up other defaults from the printer object */
|
||||
str = [printer stringForKey:@"DefaultPageSize" inTable: @"PPD"];
|
||||
/* FIXME: Need to check for AutoSelect and probably a million other things... */
|
||||
if (str == nil)
|
||||
str = @"A4";
|
||||
DICTSET(printInfoDefaults, str, NSPrintPaperName);
|
||||
DICTSET(printInfoDefaults,
|
||||
[NSValue valueWithSize: [NSPrintInfo sizeForPaperName: str]],
|
||||
NSPrintPaperSize);
|
||||
|
||||
/* Set default margins. FIXME: Probably should check ImageableArea */
|
||||
DICTSET(printInfoDefaults, NSNUMBER(36), NSPrintRightMargin);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(36), NSPrintLeftMargin);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(72), NSPrintTopMargin);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(72), NSPrintBottomMargin);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(NSPortraitOrientation),
|
||||
NSPrintOrientation);
|
||||
//DICTSET(printInfoDefaults, NSNUMBER(NSClipPagination),
|
||||
// NSPrintHorizontalPagination);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(NSAutoPagination),
|
||||
NSPrintVerticalPagination);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(1), NSPrintHorizontallyCentered);
|
||||
DICTSET(printInfoDefaults, NSNUMBER(1), NSPrintVerticallyCentered);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,27 +29,46 @@
|
|||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <gnustep/gui/config.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSThread.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <AppKit/AppKitExceptions.h>
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSGraphicsContext.h>
|
||||
#include <AppKit/NSView.h>
|
||||
#include <AppKit/NSPrintPanel.h>
|
||||
#include <AppKit/NSPrintInfo.h>
|
||||
#include <AppKit/NSPrintOperation.h>
|
||||
#include <AppKit/PSOperators.h>
|
||||
|
||||
#include <gnustep/base/GSLocale.h>
|
||||
|
||||
@interface NSGraphicsContext (Printing)
|
||||
#define NSNUMBER(a) [NSNumber numberWithInt: (a)]
|
||||
#define NSFNUMBER(a) [NSNumber numberWithFloat: (a)]
|
||||
|
||||
+ (NSGraphicsContext*) postscriptContextWithInfo: (NSDictionary*)info;
|
||||
|
||||
@end
|
||||
/* Local pagination variables needed while printing */
|
||||
typedef struct _page_info_t {
|
||||
NSRect scaledBounds; /* View's rect scaled by the user specified scale
|
||||
and page fitting */
|
||||
NSRect paperBounds; /* Print area of a page in default user space, possibly
|
||||
rotated if printing Landscape */
|
||||
NSRect sheetBounds; /* Print are of a page in default user space */
|
||||
NSSize paperSize; /* Size of the paper */
|
||||
int xpages, ypages;
|
||||
int first, last;
|
||||
double pageScale; /* Scaling determined from page fitting */
|
||||
double printScale; /* User specified scaling */
|
||||
double nupScale; /* Scale required to fit nup pages on the sheet */
|
||||
int nup; /* Number up pages to print on a sheet */
|
||||
double lastWidth, lastHeight;
|
||||
NSPrintingOrientation orient;
|
||||
} page_info_t;
|
||||
|
||||
@interface NSPrintOperation (Private)
|
||||
|
||||
|
@ -62,6 +81,13 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface NSView (NSPrintOperation)
|
||||
- (void) _displayPageInRect: (NSRect)pageRect
|
||||
atPlacement: (NSPoint)location
|
||||
withInfo: (page_info_t)info;
|
||||
- (void) _endSheet;
|
||||
@end
|
||||
|
||||
// Subclass for the regular printing
|
||||
@interface GSPrintOperation: NSPrintOperation
|
||||
{
|
||||
|
@ -99,6 +125,21 @@
|
|||
|
||||
static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
||||
|
||||
/**
|
||||
<unit>
|
||||
<heading>Class Description</heading>
|
||||
<p>
|
||||
NSPrintOperation controls printing of an NSView. When invoked normally
|
||||
it will (optionally) display a standard print panel (NSPrintPanel), and
|
||||
based on the information entered by the user here as well as information
|
||||
about page layout (see NSPageLayout) tells the NSView to print it's
|
||||
contents. NSPrintOperation works with the NSView to paginate the output
|
||||
into appropriately sized and oriented pages and finally delivers the result
|
||||
to the appropriate place, whether it be a printer, and PostScript file,
|
||||
or another output.
|
||||
</p>
|
||||
</unit>
|
||||
*/
|
||||
@implementation NSPrintOperation
|
||||
|
||||
//
|
||||
|
@ -196,6 +237,9 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Setting the Print Operation
|
||||
//
|
||||
/** Returns the NSPrintOperation object that is currently performing
|
||||
a print operation (if any).
|
||||
*/
|
||||
+ (NSPrintOperation *)currentOperation
|
||||
{
|
||||
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
||||
|
@ -203,6 +247,12 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
return (NSPrintOperation*)[dict objectForKey: NSPrintOperationThreadKey];
|
||||
}
|
||||
|
||||
/** Set the current NSPrintOperation to the supplied operation
|
||||
object. As this is currently implemented, if a NSPrintOperation
|
||||
is currently running, that operation is lost (along with any
|
||||
associated context), so be careful to call this only when there is
|
||||
no current operation.
|
||||
*/
|
||||
+ (void)setCurrentOperation:(NSPrintOperation *)operation
|
||||
{
|
||||
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
|
||||
|
@ -258,6 +308,9 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Determining the Type of Operation
|
||||
//
|
||||
/** Returns YES if the receiver is performing an operation whose output
|
||||
is EPS format.
|
||||
*/
|
||||
- (BOOL)isEPSOperation
|
||||
{
|
||||
return NO;
|
||||
|
@ -271,6 +324,8 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Controlling the User Interface
|
||||
//
|
||||
/** Returns the NSPrintPanel associated with the receiver.
|
||||
*/
|
||||
- (NSPrintPanel *)printPanel
|
||||
{
|
||||
if (_printPanel == nil)
|
||||
|
@ -279,26 +334,42 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
return _printPanel;
|
||||
}
|
||||
|
||||
/** Returns YES if the reciever display an NSPrintPanel and other information
|
||||
when running a print operation. */
|
||||
- (BOOL)showPanels
|
||||
{
|
||||
return _showPanels;
|
||||
}
|
||||
|
||||
/** Sets the NSPrintPanel used by the receiver obtaining and displaying
|
||||
printing information from/to the user.
|
||||
*/
|
||||
- (void)setPrintPanel:(NSPrintPanel *)panel
|
||||
{
|
||||
ASSIGN(_printPanel, panel);
|
||||
}
|
||||
|
||||
/** Use this to set whether a print panel is displayed during a printing
|
||||
operation. If set to NO, then the receiver uses information that
|
||||
was previously set and does not display any status information about the
|
||||
progress of the printing operation.
|
||||
*/
|
||||
- (void)setShowPanels:(BOOL)flag
|
||||
{
|
||||
_showPanels = flag;
|
||||
}
|
||||
|
||||
/** Returns the accessory view used by the NSPrintPanel associated with
|
||||
the receiver.
|
||||
*/
|
||||
- (NSView *)accessoryView
|
||||
{
|
||||
return _accessoryView;
|
||||
}
|
||||
|
||||
/** Set the accessory view used by the NSPrintPanel associated with the
|
||||
receiver.
|
||||
*/
|
||||
- (void)setAccessoryView:(NSView *)aView
|
||||
{
|
||||
ASSIGN(_accessoryView, aView);
|
||||
|
@ -307,17 +378,25 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Managing the drawing Context
|
||||
//
|
||||
/** This method is used by the print operation to create a special
|
||||
graphics context for use while running the print operation.
|
||||
*/
|
||||
- (NSGraphicsContext*)createContext
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/** Returns the graphic contexts used by the print operation.
|
||||
*/
|
||||
- (NSGraphicsContext *)context
|
||||
{
|
||||
return _context;
|
||||
}
|
||||
|
||||
/** This method is used by the print operation to destroy the special
|
||||
graphic context used while running the print operation.
|
||||
*/
|
||||
- (void)destroyContext
|
||||
{
|
||||
[_context destroyContext];
|
||||
|
@ -327,16 +406,23 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Page Information
|
||||
//
|
||||
/** Returns the page currently being printing. Returns 0 if no page
|
||||
is currently being printed
|
||||
*/
|
||||
- (int)currentPage
|
||||
{
|
||||
return _currentPage;
|
||||
}
|
||||
|
||||
/** Returns the page order of printing.
|
||||
*/
|
||||
- (NSPrintingPageOrder)pageOrder
|
||||
{
|
||||
return _pageOrder;
|
||||
}
|
||||
|
||||
/** Set the page order used when printing.
|
||||
*/
|
||||
- (void)setPageOrder:(NSPrintingPageOrder)order
|
||||
{
|
||||
_pageOrder = order;
|
||||
|
@ -345,18 +431,26 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Running a Print Operation
|
||||
//
|
||||
/** Called by the print operation and it has finished running a printing
|
||||
operation.
|
||||
*/
|
||||
- (void)cleanUpOperation
|
||||
{
|
||||
_currentPage = 0;
|
||||
[NSPrintOperation setCurrentOperation: nil];
|
||||
}
|
||||
|
||||
/** Called by the print operation to deliver the results of the printing
|
||||
operation. This might include sending the output to a printer, a file
|
||||
or a previewing program. Returns YES if the output was delivered
|
||||
sucessfully.
|
||||
*/
|
||||
- (BOOL)deliverResult
|
||||
{
|
||||
// FIXME
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* Private method to run the printing operation */
|
||||
- (BOOL) _runOperation
|
||||
{
|
||||
BOOL result;
|
||||
|
@ -367,23 +461,53 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
return NO;
|
||||
|
||||
result = NO;
|
||||
if (_pageOrder == NSUnknownPageOrder)
|
||||
{
|
||||
if ([[[_printInfo dictionary] objectForKey: NSPrintReversePageOrder]
|
||||
boolValue] == YES)
|
||||
_pageOrder = NSDescendingPageOrder;
|
||||
else
|
||||
_pageOrder = NSAscendingPageOrder;
|
||||
}
|
||||
|
||||
[NSGraphicsContext setCurrentContext: _context];
|
||||
NS_DURING
|
||||
{
|
||||
[self _print];
|
||||
result = YES;
|
||||
[NSGraphicsContext setCurrentContext: oldContext];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
[NSGraphicsContext setCurrentContext: oldContext];
|
||||
NSRunAlertPanel(@"Error", @"Printing error: %@",
|
||||
@"OK", NULL, NULL, localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
[NSGraphicsContext setCurrentContext: oldContext];
|
||||
[self destroyContext];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) _setupPrintInfo
|
||||
{
|
||||
BOOL knowsPageRange;
|
||||
NSRange viewPageRange;
|
||||
NSMutableDictionary *dict = [_printInfo dictionary];
|
||||
|
||||
knowsPageRange = [_view knowsPageRange: &viewPageRange];
|
||||
if (knowsPageRange == YES)
|
||||
{
|
||||
int first = viewPageRange.location;
|
||||
int last = NSMaxRange(viewPageRange) - 1;
|
||||
[dict setObject: NSNUMBER(first) forKey: NSPrintFirstPage];
|
||||
[dict setObject: NSNUMBER(last) forKey: NSPrintLastPage];
|
||||
}
|
||||
}
|
||||
|
||||
/** Call this message to run the print operation on a view. This includes
|
||||
(optionally) displaying a print panel and working with the NSView to
|
||||
paginate and draw the contents of the view.
|
||||
*/
|
||||
- (BOOL)runOperation
|
||||
{
|
||||
BOOL result;
|
||||
|
@ -394,6 +518,7 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
int button;
|
||||
|
||||
[panel setAccessoryView: _accessoryView];
|
||||
[self _setupPrintInfo];
|
||||
[panel updateFromPrintInfo];
|
||||
button = [panel runModal];
|
||||
[panel setAccessoryView: nil];
|
||||
|
@ -438,6 +563,8 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
withObject: contextInfo];
|
||||
}
|
||||
|
||||
/** Run a print operation modally with respect to a window.
|
||||
*/
|
||||
- (void)runOperationModalForWindow: (NSWindow *)docWindow
|
||||
delegate: (id)delegate
|
||||
didRunSelector: (SEL)didRunSelector
|
||||
|
@ -457,6 +584,7 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
of _showPanels
|
||||
*/
|
||||
[panel setAccessoryView: _accessoryView];
|
||||
[self _setupPrintInfo];
|
||||
[panel updateFromPrintInfo];
|
||||
[panel beginSheetWithPrintInfo: _printInfo
|
||||
modalForWindow: docWindow
|
||||
|
@ -470,11 +598,15 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Getting the NSPrintInfo Object
|
||||
//
|
||||
/** Returns the NSPrintInfo object associated with the receiver.
|
||||
*/
|
||||
- (NSPrintInfo *)printInfo
|
||||
{
|
||||
return _printInfo;
|
||||
}
|
||||
|
||||
/** Set the NSPrintInfo object associated with the receiver.
|
||||
*/
|
||||
- (void)setPrintInfo:(NSPrintInfo *)aPrintInfo
|
||||
{
|
||||
if (aPrintInfo == nil)
|
||||
|
@ -486,6 +618,8 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
//
|
||||
// Getting the NSView Object
|
||||
//
|
||||
/** Return the view that is the being printed.
|
||||
*/
|
||||
- (NSView *)view
|
||||
{
|
||||
return _view;
|
||||
|
@ -520,11 +654,246 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
return self;
|
||||
}
|
||||
|
||||
static NSSize
|
||||
scaleSize(NSSize size, double scale)
|
||||
{
|
||||
size.height *= scale;
|
||||
size.width *= scale;
|
||||
return size;
|
||||
}
|
||||
|
||||
static NSRect
|
||||
scaleRect(NSRect rect, double scale)
|
||||
{
|
||||
return NSMakeRect(NSMinX(rect) * scale,
|
||||
NSMinY(rect) * scale,
|
||||
NSWidth(rect) * scale,
|
||||
NSHeight(rect) * scale);
|
||||
}
|
||||
|
||||
/* Pagination - guess how many pages we need to print. This could be off
|
||||
by one in both X and Y because of the view's ability to adjust the
|
||||
width and height of the printRect during printing. Also set up a bunch
|
||||
of other information needed for printing.
|
||||
*/
|
||||
- (void) _printPaginateWithInfo: (page_info_t *)info knowsRange: (BOOL)knowsRange
|
||||
{
|
||||
NSMutableDictionary *dict;
|
||||
dict = [_printInfo dictionary];
|
||||
|
||||
info->paperSize = [_printInfo paperSize];
|
||||
info->orient = [_printInfo orientation];
|
||||
info->printScale = [[dict objectForKey: NSPrintScalingFactor] doubleValue];
|
||||
info->nup = [[dict objectForKey: NSPrintPagesPerSheet] intValue];
|
||||
info->nupScale = 1;
|
||||
if (info->nup < 1 || (info->nup > 1 && (((info->nup) & 0x1) == 1)))
|
||||
{
|
||||
/* Bad nup value */
|
||||
info->nup = 1;
|
||||
[dict setObject: NSNUMBER(1) forKey: NSPrintPagesPerSheet];
|
||||
}
|
||||
|
||||
/* Subtract the margins from the paper size to get print boundary */
|
||||
info->paperBounds.size = info->paperSize;
|
||||
info->paperBounds.origin.x = [_printInfo leftMargin];
|
||||
info->paperBounds.origin.y = [_printInfo bottomMargin];
|
||||
info->paperBounds.size.width -=
|
||||
([_printInfo rightMargin]+[_printInfo leftMargin]);
|
||||
info->paperBounds.size.height -=
|
||||
([_printInfo topMargin]+[_printInfo bottomMargin]);
|
||||
|
||||
info->sheetBounds = info->paperBounds;
|
||||
if (info->orient == NSLandscapeOrientation)
|
||||
{
|
||||
/* Bounding box needs to be in default user space, but the bbox
|
||||
we get is rotated */
|
||||
info->sheetBounds = NSMakeRect(NSMinY(info->paperBounds),
|
||||
NSMinX(info->paperBounds),
|
||||
NSHeight(info->paperBounds),
|
||||
NSWidth(info->paperBounds));
|
||||
}
|
||||
/* Save this for the view to look at */
|
||||
[dict setObject: [NSValue valueWithRect: info->paperBounds]
|
||||
forKey: @"NSPrintPaperBounds"];
|
||||
[dict setObject: [NSValue valueWithRect: info->sheetBounds]
|
||||
forKey: @"NSPrintSheetBounds"];
|
||||
|
||||
/* Scale bounds by the user specified scaling */
|
||||
info->scaledBounds = scaleRect(_rect, info->printScale);
|
||||
|
||||
if (knowsRange == NO)
|
||||
{
|
||||
/* Now calculate page fitting to get page scale */
|
||||
info->pageScale = 1;
|
||||
if ([_printInfo horizontalPagination] == NSFitPagination)
|
||||
info->pageScale = info->paperBounds.size.width
|
||||
/ NSWidth(info->scaledBounds);
|
||||
if ([_printInfo verticalPagination] == NSFitPagination)
|
||||
info->pageScale = MIN(info->pageScale,
|
||||
NSHeight(info->paperBounds)/NSHeight(info->scaledBounds));
|
||||
/* Scale bounds by pageScale */
|
||||
info->scaledBounds = scaleRect(info->scaledBounds, info->pageScale);
|
||||
|
||||
/* Now find out how many pages */
|
||||
info->xpages = ceil(NSWidth(info->scaledBounds)/NSWidth(info->paperBounds));
|
||||
info->ypages = ceil(NSHeight(info->scaledBounds)/NSHeight(info->paperBounds));
|
||||
if ([_printInfo horizontalPagination] == NSClipPagination)
|
||||
info->xpages = 1;
|
||||
if ([_printInfo verticalPagination] == NSClipPagination)
|
||||
info->ypages = 1;
|
||||
}
|
||||
|
||||
/* Calculate nup. If nup is an odd multiple of two, secretly change the
|
||||
page orientation to it's complement to make pages fit better.
|
||||
*/
|
||||
if (((int)(info->nup / 2) & 0x1) == 1)
|
||||
{
|
||||
float tmp;
|
||||
if (info->orient == NSLandscapeOrientation)
|
||||
info->nupScale =
|
||||
info->paperSize.width/(2*info->paperSize.height);
|
||||
else
|
||||
info->nupScale =
|
||||
info->paperSize.height/(2*info->paperSize.width);
|
||||
info->nupScale /= (info->nup / 2);
|
||||
info->orient = (info->orient == NSPortraitOrientation) ?
|
||||
NSLandscapeOrientation : NSPortraitOrientation;
|
||||
tmp = info->paperSize.width;
|
||||
info->paperSize.width = info->paperSize.height;
|
||||
info->paperSize.height = tmp;
|
||||
[dict setObject: NSNUMBER(info->orient) forKey: NSPrintOrientation];
|
||||
}
|
||||
else if (info->nup > 1)
|
||||
{
|
||||
info->nupScale = 2.0 / (float)info->nup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Our personnel method to calculate the print rect for the specified page.
|
||||
Note, we assume this function is called in order from our first to last
|
||||
page. The returned pageRect is in the view's coordinate system
|
||||
*/
|
||||
- (NSRect) _rectForPage: (int)page info: (page_info_t *)info
|
||||
{
|
||||
int xpage, ypage;
|
||||
NSRect pageRect;
|
||||
|
||||
xpage = (page - 1) % info->xpages;
|
||||
ypage = (page - 1) % info->ypages;
|
||||
if (xpage == 0)
|
||||
info->lastWidth = 0;
|
||||
if (ypage == 0)
|
||||
info->lastHeight = 0;
|
||||
pageRect = NSMakeRect(info->lastWidth, info->lastHeight,
|
||||
NSWidth(info->paperBounds), NSHeight(info->paperBounds));
|
||||
pageRect = NSIntersectionRect(pageRect, info->scaledBounds);
|
||||
/* Scale to view's coordinate system */
|
||||
return scaleRect(pageRect, 1/(info->pageScale*info->printScale));
|
||||
|
||||
}
|
||||
|
||||
/* Let the view adjust the page rect we calculated. See assumptions for
|
||||
_rectForPage:
|
||||
*/
|
||||
- (NSRect) _adjustPagesFirst: (int)first
|
||||
last: (int)last
|
||||
info: (page_info_t *)info
|
||||
{
|
||||
int i;
|
||||
double hlimit, wlimit;
|
||||
NSRect pageRect;
|
||||
hlimit = [_view heightAdjustLimit];
|
||||
wlimit = [_view widthAdjustLimit];
|
||||
for (i = first; i <= last; i++)
|
||||
{
|
||||
float newVal, limitVal;
|
||||
pageRect = [self _rectForPage: i info: info];
|
||||
limitVal = NSMaxY(pageRect) - hlimit * NSHeight(pageRect);
|
||||
[_view adjustPageHeightNew: &newVal
|
||||
top: NSMinY(pageRect)
|
||||
bottom: NSMaxY(pageRect)
|
||||
limit: limitVal];
|
||||
if (newVal < NSMaxY(pageRect))
|
||||
pageRect.size.height = MAX(newVal, limitVal) - NSMinY(pageRect);
|
||||
limitVal = NSMaxX(pageRect) - wlimit * NSWidth(pageRect);
|
||||
[_view adjustPageWidthNew: &newVal
|
||||
left: NSMinX(pageRect)
|
||||
right: NSMaxX(pageRect)
|
||||
limit: limitVal];
|
||||
if (newVal < NSMaxX(pageRect))
|
||||
pageRect.size.width = MAX(newVal, limitVal) - NSMinX(pageRect);
|
||||
info->lastWidth = NSMaxX(pageRect)*(info->pageScale*info->printScale);
|
||||
info->lastHeight = NSMaxY(pageRect)*(info->pageScale*info->printScale);
|
||||
}
|
||||
return pageRect;
|
||||
}
|
||||
|
||||
- (void) _print
|
||||
{
|
||||
BOOL knowsPageRange;
|
||||
int i, dir;
|
||||
BOOL knowsPageRange, allPages;
|
||||
NSRange viewPageRange;
|
||||
NSString *clocale;
|
||||
NSMutableDictionary *dict;
|
||||
page_info_t info;
|
||||
|
||||
dict = [_printInfo dictionary];
|
||||
|
||||
/* Setup pagination */
|
||||
allPages = [[dict objectForKey: NSPrintAllPages] boolValue];
|
||||
knowsPageRange = [_view knowsPageRange: &viewPageRange];
|
||||
[self _printPaginateWithInfo: &info knowsRange: knowsPageRange];
|
||||
if (knowsPageRange == NO)
|
||||
{
|
||||
viewPageRange = NSMakeRange(1, (info.xpages * info.ypages));
|
||||
}
|
||||
[dict setObject: NSNUMBER(NSMaxRange(viewPageRange) )
|
||||
forKey: @"NSPrintTotalPages"];
|
||||
if (allPages == YES)
|
||||
{
|
||||
info.first = viewPageRange.location;
|
||||
info.last = NSMaxRange(viewPageRange) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.first = [[dict objectForKey: NSPrintFirstPage] intValue];
|
||||
info.last = [[dict objectForKey: NSPrintLastPage] intValue];
|
||||
info.first = MAX(info.first, viewPageRange.location);
|
||||
info.first = MIN(info.first, NSMaxRange(viewPageRange) - 1);
|
||||
info.last = MAX(info.last, info.first);
|
||||
info.last = MIN(info.last, NSMaxRange(viewPageRange) - 1);
|
||||
viewPageRange = NSMakeRange(info.first, (info.last-info.first)+1);
|
||||
}
|
||||
info.lastWidth = info.lastHeight = 0;
|
||||
[dict setObject: NSFNUMBER(info.nupScale) forKey: @"NSNupScale"];
|
||||
[dict setObject: NSNUMBER(info.first) forKey: NSPrintFirstPage];
|
||||
if (allPages == YES && knowsPageRange == NO)
|
||||
[dict setObject: NSNUMBER(info.first-1) forKey: NSPrintLastPage];
|
||||
else
|
||||
[dict setObject: NSNUMBER(info.last) forKey: NSPrintLastPage];
|
||||
NSDebugLLog(@"NSPrinting", @"Printing pages %d to %d",
|
||||
info.first, info.last);
|
||||
NSDebugLLog(@"NSPrinting", @"Printing rect %@, scaled %@",
|
||||
NSStringFromRect(_rect),
|
||||
NSStringFromRect(info.scaledBounds));
|
||||
|
||||
_currentPage = info.first;
|
||||
dir = 1;
|
||||
if (_pageOrder == NSDescendingPageOrder)
|
||||
{
|
||||
_currentPage = info.last;
|
||||
dir = -1;
|
||||
}
|
||||
if (dir > 0 && _currentPage != 1)
|
||||
{
|
||||
/* Calculate page rects we aren't processing to catch up to the
|
||||
first page we are */
|
||||
NSRect pageRect;
|
||||
pageRect = [self _adjustPagesFirst: 1
|
||||
last: _currentPage-1
|
||||
info: &info];
|
||||
}
|
||||
|
||||
/* Reset the current locale to a generic C locale so numbers
|
||||
get printed correctly for PostScript (maybe we should only
|
||||
set the numeric locale?). Save the current locale for later. */
|
||||
|
@ -534,18 +903,180 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
/* Print the header information */
|
||||
[_view beginDocument];
|
||||
|
||||
/* Setup pagination */
|
||||
knowsPageRange = [_view knowsPageRange: &viewPageRange];
|
||||
/* Print each page */
|
||||
i = 0;
|
||||
while (i < (info.last-info.first+1))
|
||||
{
|
||||
NSPoint location;
|
||||
NSRect pageRect, scaledPageRect;
|
||||
if (knowsPageRange == YES)
|
||||
{
|
||||
pageRect = [_view rectForPage: _currentPage];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir < 0)
|
||||
pageRect = [self _adjustPagesFirst: 1
|
||||
last: _currentPage
|
||||
info: &info];
|
||||
else
|
||||
pageRect = [self _adjustPagesFirst: _currentPage
|
||||
last: _currentPage
|
||||
info: &info];
|
||||
}
|
||||
NSDebugLLog(@"NSPrinting", @" current page %d, rect %@",
|
||||
_currentPage, NSStringFromRect(pageRect));
|
||||
if (NSIsEmptyRect(pageRect))
|
||||
break;
|
||||
|
||||
[_view beginPageInRect: _rect atPlacement: NSMakePoint(0,0)];
|
||||
[_view displayRectIgnoringOpacity: _rect];
|
||||
scaledPageRect = scaleRect(pageRect, info.printScale*info.pageScale);
|
||||
location = [_view locationOfPrintRect: scaledPageRect];
|
||||
|
||||
/* Draw using our special view routine */
|
||||
[_view _displayPageInRect: pageRect
|
||||
atPlacement: location
|
||||
withInfo: info];
|
||||
|
||||
if (dir > 0 && _currentPage == info.last && allPages == YES)
|
||||
{
|
||||
/* Check if adjust pages forced part of the bounds onto
|
||||
another page */
|
||||
if (NSMaxX(pageRect) < NSMaxX(_rect)
|
||||
&& [_printInfo horizontalPagination] != NSClipPagination)
|
||||
{
|
||||
info.xpages++;
|
||||
}
|
||||
if (NSMaxY(pageRect) < NSMaxY(_rect)
|
||||
&& [_printInfo verticalPagination] != NSClipPagination)
|
||||
{
|
||||
info.ypages++;
|
||||
}
|
||||
viewPageRange = NSMakeRange(1, (info.xpages * info.ypages));
|
||||
info.last = NSMaxRange(viewPageRange) - 1;
|
||||
}
|
||||
i++;
|
||||
_currentPage += dir;
|
||||
} /* Print each page */
|
||||
|
||||
/* Make sure we end the sheet */
|
||||
if ( info.nup > 1 && (info.last - info.first) % info.nup != info.nup - 1 )
|
||||
{
|
||||
[_view drawSheetBorderWithSize: info.paperBounds.size];
|
||||
[_view _endSheet];
|
||||
}
|
||||
[_view endDocument];
|
||||
|
||||
GSSetLocale(clocale);
|
||||
|
||||
/* Setup/reset for next time */
|
||||
[dict setObject: NSNUMBER(info.last) forKey: NSPrintLastPage];
|
||||
if (((int)(info.nup / 2) & 0x1) == 1)
|
||||
{
|
||||
info.orient = (info.orient == NSPortraitOrientation) ?
|
||||
NSLandscapeOrientation : NSPortraitOrientation;
|
||||
[dict setObject: NSNUMBER(info.orient) forKey: NSPrintOrientation];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSView (NSPrintOperation)
|
||||
- (void) _displayPageInRect: (NSRect)pageRect
|
||||
atPlacement: (NSPoint)location
|
||||
withInfo: (page_info_t)info
|
||||
{
|
||||
int currentPage;
|
||||
float xoffset, yoffset, scale;
|
||||
NSString *label;
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
|
||||
currentPage = [printOp currentPage];
|
||||
|
||||
label = nil;
|
||||
if (info.nup == 1)
|
||||
label = [NSString stringWithFormat: @"%d", currentPage];
|
||||
|
||||
/* Begin a sheet (i.e. a physical page in Postscript terms). If
|
||||
nup > 1 then this occurs only once every nup pages */
|
||||
if ((currentPage - info.first) % info.nup == 0)
|
||||
{
|
||||
[self beginPage: floor((currentPage - info.first)/info.nup)+1
|
||||
label: label
|
||||
bBox: info.sheetBounds
|
||||
fonts: nil];
|
||||
DPSPrintf(ctxt, "/__GSsheetsaveobject save def\n");
|
||||
if (info.orient == NSLandscapeOrientation)
|
||||
{
|
||||
DPSrotate(ctxt, 90);
|
||||
DPStranslate(ctxt, 0, -info.paperSize.height);
|
||||
}
|
||||
/* Also offset by margins */
|
||||
DPStranslate(ctxt, NSMinX(info.paperBounds), NSMinY(info.paperBounds));
|
||||
}
|
||||
|
||||
/* Begin a logical page */
|
||||
[self beginPageInRect: pageRect atPlacement: location];
|
||||
scale = info.pageScale * info.printScale;
|
||||
if (scale != 1.0)
|
||||
DPSscale(ctxt, scale, scale);
|
||||
if ([self isFlipped])
|
||||
{
|
||||
NSAffineTransformStruct ats = { 1, 0, 0, -1, 0, 1 };
|
||||
NSAffineTransform *matrix, *flip;
|
||||
flip = [NSAffineTransform new];
|
||||
matrix = [NSAffineTransform new];
|
||||
[matrix makeIdentityMatrix];
|
||||
[matrix appendTransform: _boundsMatrix];
|
||||
/*
|
||||
* The flipping process must result in a coordinate system that
|
||||
* exactly overlays the original. To do that, we must translate
|
||||
* the origin by the height of the view.
|
||||
*/
|
||||
[flip setTransformStruct: ats];
|
||||
flip->matrix.ty = NSHeight(_bounds);
|
||||
[matrix appendTransform: flip];
|
||||
[matrix concat];
|
||||
yoffset = NSHeight(_frame) - NSMaxY(pageRect);
|
||||
}
|
||||
else
|
||||
yoffset = 0 - NSMinY(pageRect);
|
||||
|
||||
/* Translate so the rect we're printing is on the page */
|
||||
xoffset = 0 - NSMinX(pageRect);
|
||||
DPStranslate(ctxt, xoffset, yoffset);
|
||||
|
||||
if ((currentPage - info.first) % info.nup == 0)
|
||||
[self endPageSetup];
|
||||
|
||||
/* Do the actual drawing */
|
||||
[self displayRectIgnoringOpacity: pageRect];
|
||||
|
||||
/* End a logical page */
|
||||
DPSgrestore(ctxt); // Balance gsave in beginPageInRect:
|
||||
[self drawPageBorderWithSize:
|
||||
scaleSize(info.paperBounds.size, info.nupScale)];
|
||||
[self endPage];
|
||||
|
||||
/* End a physical page */
|
||||
if ( ((currentPage - info.first) % info.nup == info.nup-1) )
|
||||
{
|
||||
[self drawSheetBorderWithSize: info.paperBounds.size];
|
||||
[self _endSheet];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _endSheet
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
if ([printOp isEPSOperation] == NO)
|
||||
DPSPrintf(ctxt, "showpage\n");
|
||||
DPSPrintf(ctxt, "__GSsheetsaveobject restore\n");
|
||||
DPSPrintf(ctxt, "%%%%PageTrailer\n");
|
||||
DPSPrintf(ctxt, "\n");
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation GSPrintOperation
|
||||
|
||||
|
@ -581,7 +1112,9 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
}
|
||||
|
||||
[info setObject: _path forKey: @"NSOutputFile"];
|
||||
_context = RETAIN([NSGraphicsContext postscriptContextWithInfo: info]);
|
||||
[info setObject: NSGraphicsContextPSFormat
|
||||
forKey: NSGraphicsContextRepresentationFormatAttributeName];
|
||||
_context = RETAIN([NSGraphicsContext graphicsContextWithAttributes: info]);
|
||||
|
||||
return _context;
|
||||
}
|
||||
|
@ -642,6 +1175,10 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
clocale = GSSetLocale(nil);
|
||||
GSSetLocale(@"C");
|
||||
|
||||
/* Save this for the view to look at. Seems like there should
|
||||
be a better way to pass it to beginDocument */
|
||||
[[_printInfo dictionary] setObject: [NSValue valueWithRect: _rect]
|
||||
forKey: @"NSPrintSheetBounds"];
|
||||
[_view beginDocument];
|
||||
[_view beginPageInRect: _rect atPlacement: NSMakePoint(0,0)];
|
||||
[_view displayRectIgnoringOpacity: _rect];
|
||||
|
@ -650,6 +1187,11 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
GSSetLocale(clocale);
|
||||
}
|
||||
|
||||
- (BOOL)isEPSOperation
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)deliverResult
|
||||
{
|
||||
if (_data != nil && _path != nil)
|
||||
|
@ -663,6 +1205,22 @@ static NSString *NSPrintOperationThreadKey = @"NSPrintOperationThreadKey";
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (NSGraphicsContext*)createContext
|
||||
{
|
||||
NSMutableDictionary *info;
|
||||
if (_context)
|
||||
return _context;
|
||||
|
||||
info = [_printInfo dictionary];
|
||||
|
||||
[info setObject: _path forKey: @"NSOutputFile"];
|
||||
[info setObject: NSGraphicsContextPSFormat
|
||||
forKey: NSGraphicsContextRepresentationFormatAttributeName];
|
||||
_context = RETAIN([NSGraphicsContext graphicsContextWithAttributes: info]);
|
||||
|
||||
return _context;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSPDFPrintOperation
|
||||
|
|
|
@ -144,7 +144,8 @@ static NSPrintPanel *shared_instance;
|
|||
|
||||
/* Setup the layout popup */
|
||||
control = CONTROL(self, NSPPLayoutButton);
|
||||
list = [NSArray arrayWithObjects: @"1up", @"2up", @"3up", @"4up", nil];
|
||||
list = [NSArray arrayWithObjects: @"1 up", @"2 up", @"4 up", @"6 up",
|
||||
@"8 up", nil];
|
||||
[control removeAllItems];
|
||||
for (i = 0; i < [list count]; i++)
|
||||
{
|
||||
|
@ -239,11 +240,15 @@ static NSPrintPanel *shared_instance;
|
|||
else if (tag == NSPPPreviewButton)
|
||||
{
|
||||
_picked = NSPPPreviewButton;
|
||||
NSRunAlertPanel(@"Sorry", @"Previewing of print file not implemented",
|
||||
@"OK", NULL, NULL);
|
||||
/* Don't stop the modal session */
|
||||
return;
|
||||
}
|
||||
else if (tag ==NSFaxButton )
|
||||
{
|
||||
_picked = NSFaxButton;
|
||||
NSRunAlertPanel(@"Warning", @"Fax of print file not implemented",
|
||||
NSRunAlertPanel(@"Sorry", @"Faxing of print file not implemented",
|
||||
@"OK", NULL, NULL);
|
||||
/* Don't stop the modal session */
|
||||
return;
|
||||
|
@ -293,7 +298,7 @@ static NSPrintPanel *shared_instance;
|
|||
NSString *str;
|
||||
str = [NSString stringWithFormat: @"%d", _pages.location];
|
||||
[[fromRangeForm cellAtIndex: 0] setStringValue: str];
|
||||
str = [NSString stringWithFormat: @"%d", NSMaxRange(_pages)];
|
||||
str = [NSString stringWithFormat: @"%d", NSMaxRange(_pages)-1];
|
||||
[[toRangeForm cellAtIndex: 0] setStringValue: str];
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +366,7 @@ static NSPrintPanel *shared_instance;
|
|||
|
||||
|
||||
dict = [info dictionary];
|
||||
NSDebugLLog(@"NSPrintPanel",
|
||||
NSDebugLLog(@"NSPrinting",
|
||||
@"Update PrintInfo dictionary\n %@ \n --------------", dict);
|
||||
_pages = NSMakeRange([[dict objectForKey: NSPrintFirstPage] intValue],
|
||||
[[dict objectForKey: NSPrintLastPage] intValue]);
|
||||
|
@ -375,7 +380,7 @@ static NSPrintPanel *shared_instance;
|
|||
if (layout > 4)
|
||||
layout = 4;
|
||||
control = CONTROL(self, NSPPLayoutButton);
|
||||
[control selectItemAtIndex: layout-1];
|
||||
[control selectItemAtIndex: (int)(layout/2)];
|
||||
|
||||
/* Setup the resolution popup */
|
||||
control = CONTROL(_optionPanel, NSPPResolutionButton);
|
||||
|
@ -508,7 +513,7 @@ static NSPrintPanel *shared_instance;
|
|||
|
||||
/* Scale */
|
||||
control = CONTROL(self, NSPPScaleField);
|
||||
scale = [control intValue]/100;
|
||||
scale = [control doubleValue]/100.0;
|
||||
if (scale <= 0)
|
||||
scale = .1;
|
||||
if (scale >= 10)
|
||||
|
@ -518,7 +523,9 @@ static NSPrintPanel *shared_instance;
|
|||
forKey: NSPrintScalingFactor];
|
||||
|
||||
/* Layout */
|
||||
layout = [CONTROL(self, NSPPLayoutButton) indexOfSelectedItem] + 1;
|
||||
layout = [CONTROL(self, NSPPLayoutButton) indexOfSelectedItem] * 2;
|
||||
if (layout == 0)
|
||||
layout = 1;
|
||||
[dict setObject: NSNUMBER(layout) forKey: NSPrintPagesPerSheet];
|
||||
|
||||
/* Resolution */
|
||||
|
@ -611,7 +618,7 @@ static NSPrintPanel *shared_instance;
|
|||
}
|
||||
[info setJobDisposition: sel];
|
||||
|
||||
NSDebugLLog(@"NSPrintPanel",
|
||||
NSDebugLLog(@"NSPrinting",
|
||||
@"Final info dictionary ----\n %@ \n --------------", dict);
|
||||
|
||||
}
|
||||
|
|
306
Source/NSView.m
306
Source/NSView.m
|
@ -37,6 +37,7 @@
|
|||
#include <float.h>
|
||||
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSCalendarDate.h>
|
||||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSThread.h>
|
||||
|
@ -46,18 +47,24 @@
|
|||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
|
||||
#include <AppKit/NSView.h>
|
||||
#include <AppKit/NSWindow.h>
|
||||
#include <AppKit/GSTrackingRect.h>
|
||||
#include <AppKit/NSGraphics.h>
|
||||
#include <AppKit/PSOperators.h>
|
||||
#include <AppKit/GSVersion.h>
|
||||
#include <AppKit/NSAffineTransform.h>
|
||||
#include <AppKit/NSScrollView.h>
|
||||
#include <AppKit/NSDocumentController.h>
|
||||
#include <AppKit/NSDocument.h>
|
||||
#include <AppKit/NSClipView.h>
|
||||
#include <AppKit/NSFont.h>
|
||||
#include <AppKit/NSGraphics.h>
|
||||
#include <AppKit/NSPasteboard.h>
|
||||
#include <AppKit/NSPrintInfo.h>
|
||||
#include <AppKit/NSPrintOperation.h>
|
||||
#include <AppKit/NSScrollView.h>
|
||||
#include <AppKit/NSView.h>
|
||||
#include <AppKit/NSWindow.h>
|
||||
#include <AppKit/PSOperators.h>
|
||||
|
||||
/* Variable tells this view and subviews that we're printing. Not really
|
||||
a class variable because we want it visible to subviews also
|
||||
|
@ -69,6 +76,11 @@ struct NSWindow_struct
|
|||
@defs(NSWindow)
|
||||
};
|
||||
|
||||
@interface NSFont (NSViewFonts)
|
||||
+ (void) resetUsedFonts;
|
||||
+ (NSSet *) usedFonts;
|
||||
@end
|
||||
|
||||
@implementation NSView
|
||||
|
||||
/*
|
||||
|
@ -1352,7 +1364,6 @@ GSSetDragTypes(NSView* obj, NSArray *types)
|
|||
a superview so we get printed correctly */
|
||||
[self _matrixToWindow];
|
||||
[_matrixToWindow makeIdentityMatrix];
|
||||
_visibleRect = _bounds;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1418,11 +1429,7 @@ GSSetDragTypes(NSView* obj, NSArray *types)
|
|||
if ([_window gState] == 0)
|
||||
return;
|
||||
|
||||
if (viewIsPrinting != nil)
|
||||
{
|
||||
_coordinates_valid = NO;
|
||||
}
|
||||
else
|
||||
if (viewIsPrinting == nil)
|
||||
{
|
||||
/* Restore our original gstate */
|
||||
DPSgrestore(ctxt);
|
||||
|
@ -2450,16 +2457,10 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
{
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
/* Inform ourselves and subviews that we're printing so we adjust
|
||||
the PostScript accordingly. Perhaps this could be in the thread
|
||||
dictionary, but that's probably overkill and slow */
|
||||
viewIsPrinting = self;
|
||||
|
||||
[[NSPrintOperation EPSOperationWithView: self
|
||||
insideRect: aRect
|
||||
toData: data] runOperation];
|
||||
|
||||
viewIsPrinting = nil;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -2495,7 +2496,15 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
|
||||
- (NSString *)printJobTitle
|
||||
{
|
||||
return nil;
|
||||
id doc;
|
||||
NSString *title;
|
||||
doc = [[NSDocumentController sharedDocumentController] documentForWindow:
|
||||
[self window]];
|
||||
if (doc)
|
||||
title = [doc displayName];
|
||||
else
|
||||
title = [[self window] title];
|
||||
return title;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2624,8 +2633,31 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
|
||||
- (NSPoint) locationOfPrintRect: (NSRect)aRect
|
||||
{
|
||||
// FIXME: Should depend on the print info
|
||||
return NSZeroPoint;
|
||||
int pages;
|
||||
NSPoint location;
|
||||
NSRect bounds;
|
||||
NSMutableDictionary *dict;
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
NSPrintInfo *printInfo = [printOp printInfo];
|
||||
dict = [printInfo dictionary];
|
||||
|
||||
pages = [[dict objectForKey: @"NSPrintTotalPages"] intValue];
|
||||
if ([dict objectForKey: @"NSPrintPaperBounds"])
|
||||
bounds = [[dict objectForKey: @"NSPrintPaperBounds"] rectValue];
|
||||
else
|
||||
bounds = aRect;
|
||||
location = NSMakePoint(0, NSHeight(bounds)-NSHeight(aRect));
|
||||
/* FIXME: I can't figure out how the location for a multi-page document
|
||||
is computed. Just ignore centering? */
|
||||
if (pages == 1)
|
||||
{
|
||||
if ([printInfo isHorizontallyCentered])
|
||||
location.x = (NSWidth(bounds) - NSWidth(aRect))/2;
|
||||
if ([printInfo isVerticallyCentered])
|
||||
location.y = (NSHeight(bounds) - NSHeight(aRect))/2;
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
- (NSRect) rectForPage: (int)page
|
||||
|
@ -2646,13 +2678,26 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
bBox: (NSRect)pageRect
|
||||
fonts: (NSString*)fontNames
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
|
||||
if (aString == nil)
|
||||
aString = [[NSNumber numberWithInt: ordinalNum] description];
|
||||
DPSPrintf(ctxt, "%%%%Page: %s %d\n", [aString cString], ordinalNum);
|
||||
if (NSIsEmptyRect(pageRect) == NO)
|
||||
DPSPrintf(ctxt, "%%%%PageBoundingBox: %d %d %d %d\n",
|
||||
(int)NSMinX(pageRect), (int)NSMinY(pageRect),
|
||||
(int)NSMaxX(pageRect), (int)NSMaxY(pageRect));
|
||||
if (fontNames)
|
||||
DPSPrintf(ctxt, "%%%%PageFonts: %s\n", [fontNames cString]);
|
||||
DPSPrintf(ctxt, "%%%%BeginPageSetup\n");
|
||||
}
|
||||
|
||||
- (void) beginPageSetupRect: (NSRect)aRect placement: (NSPoint)location
|
||||
{
|
||||
[self beginPageInRect: aRect atPlacement: location];
|
||||
}
|
||||
|
||||
- (void) beginPrologueBBox: (NSRect)boundingBox
|
||||
- (void) beginPrologueBBox: (NSRect)bBox
|
||||
creationDate: (NSString*)dateCreated
|
||||
createdBy: (NSString*)anApplication
|
||||
fonts: (NSString*)fontNames
|
||||
|
@ -2660,6 +2705,57 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
pages: (int)numPages
|
||||
title: (NSString*)aTitle
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
NSPrintingOrientation orient;
|
||||
BOOL epsOp;
|
||||
|
||||
epsOp = [printOp isEPSOperation];
|
||||
orient = [[printOp printInfo] orientation];
|
||||
|
||||
if (epsOp)
|
||||
DPSPrintf(ctxt, "%%!PS-Adobe-3.0 EPSF-3.0\n");
|
||||
else
|
||||
DPSPrintf(ctxt, "%%!PS-Adobe-3.0\n");
|
||||
DPSPrintf(ctxt, "%%%%Title: %s\n", [aTitle cString]);
|
||||
DPSPrintf(ctxt, "%%%%Creator: %s\n", [anApplication cString]);
|
||||
DPSPrintf(ctxt, "%%%%CreationDate: %s\n",
|
||||
[[dateCreated description] cString]);
|
||||
DPSPrintf(ctxt, "%%%%For: %s\n", [user cString]);
|
||||
if (fontNames)
|
||||
DPSPrintf(ctxt, "%%%%DocumentFonts: %s\n", [fontNames cString]);
|
||||
else
|
||||
DPSPrintf(ctxt, "%%%%DocumentFonts: (atend)\n");
|
||||
|
||||
if (NSIsEmptyRect(bBox) == NO)
|
||||
DPSPrintf(ctxt, "%%%%BoundingBox: %d %d %d %d\n",
|
||||
(int)NSMinX(bBox), (int)NSMinY(bBox),
|
||||
(int)NSMaxX(bBox), (int)NSMaxY(bBox));
|
||||
else
|
||||
DPSPrintf(ctxt, "%%%%BoundingBox: (atend)\n");
|
||||
|
||||
if (epsOp == NO)
|
||||
{
|
||||
if (numPages)
|
||||
DPSPrintf(ctxt, "%%%%Pages: %d\n", numPages);
|
||||
else
|
||||
DPSPrintf(ctxt, "%%%%Pages: (atend)\n");
|
||||
if ([printOp pageOrder] == NSDescendingPageOrder)
|
||||
DPSPrintf(ctxt, "%%%%PageOrder: Descend\n");
|
||||
else if ([printOp pageOrder] == NSAscendingPageOrder)
|
||||
DPSPrintf(ctxt, "%%%%PageOrder: Ascend\n");
|
||||
else if ([printOp pageOrder] == NSSpecialPageOrder)
|
||||
DPSPrintf(ctxt, "%%%%PageOrder: Special\n");
|
||||
|
||||
if (orient == NSPortraitOrientation)
|
||||
DPSPrintf(ctxt, "%%%%Orientation: Portrait\n");
|
||||
else
|
||||
DPSPrintf(ctxt, "%%%%Orientation: Landscape\n");
|
||||
}
|
||||
|
||||
DPSPrintf(ctxt, "%%%%GNUstepVersion: %d.%d.%d\n",
|
||||
GNUSTEP_GUI_MAJOR_VERSION, GNUSTEP_GUI_MINOR_VERSION,
|
||||
GNUSTEP_GUI_SUBMINOR_VERSION);
|
||||
}
|
||||
|
||||
- (void) addToPageSetup
|
||||
|
@ -2668,10 +2764,14 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
|
||||
- (void) beginSetup
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%BeginSetup\n");
|
||||
}
|
||||
|
||||
- (void) beginTrailer
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%Trailer\n");
|
||||
}
|
||||
|
||||
- (void) drawPageBorderWithSize: (NSSize)borderSize
|
||||
|
@ -2684,39 +2784,203 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
|
||||
- (void) endHeaderComments
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%EndComments\n\n");
|
||||
}
|
||||
|
||||
- (void) endPrologue
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%EndProlog\n\n");
|
||||
}
|
||||
|
||||
- (void) endSetup
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%EndSetup\n\n");
|
||||
}
|
||||
|
||||
- (void) endPageSetup
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%EndPageSetup\n");
|
||||
}
|
||||
|
||||
- (void) endPage
|
||||
{
|
||||
int nup;
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
NSDictionary *dict = [[printOp printInfo] dictionary];
|
||||
|
||||
nup = [[dict objectForKey: NSPrintPagesPerSheet] intValue];
|
||||
if (nup > 1)
|
||||
{
|
||||
DPSPrintf(ctxt, "__GSpagesaveobject restore\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
- (void) endTrailer
|
||||
{
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
DPSPrintf(ctxt, "%%%%EOF\n");
|
||||
}
|
||||
|
||||
/**
|
||||
Writes header and job information for the PostScript document. This
|
||||
includes at a minimum, PostScript header information. It may also
|
||||
include job setup information if the output is intended for a printer
|
||||
(i.e. not an EPS file). Most of the information for writing the
|
||||
header comes from the NSPrintOperation and NSPrintInfo objects
|
||||
associated with the current print operation.
|
||||
|
||||
There isn't normally anything that the program needs to override
|
||||
at the beginning of a document, although if there is additional
|
||||
setup that needs to be done, you can override the NSView's methods
|
||||
endHeaderComments, endPrologue, beginSetup, and/or endSetup.
|
||||
|
||||
This method calls the above methods in the listed order before
|
||||
or after writing the required information. For an EPS operation, the
|
||||
beginSetup and endSetup methods aren't used. */
|
||||
- (void)beginDocument
|
||||
{
|
||||
int first, last, pages, nup;
|
||||
NSRect bbox;
|
||||
NSDictionary *dict;
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
dict = [[printOp printInfo] dictionary];
|
||||
if (printOp == nil)
|
||||
{
|
||||
NSLog(@"[NSView -beginDocument] called without a current print op");
|
||||
return;
|
||||
}
|
||||
/* Inform ourselves and subviews that we're printing so we adjust
|
||||
the PostScript accordingly. Perhaps this could be in the thread
|
||||
dictionary, but that's probably overkill and slow */
|
||||
viewIsPrinting = self;
|
||||
|
||||
/* Get pagination information */
|
||||
nup = [[dict objectForKey: NSPrintPagesPerSheet] intValue];
|
||||
bbox = NSZeroRect;
|
||||
if ([dict objectForKey: @"NSPrintSheetBounds"])
|
||||
bbox = [[dict objectForKey: @"NSPrintSheetBounds"] rectValue];
|
||||
first = [[dict objectForKey: NSPrintFirstPage] intValue];
|
||||
last = [[dict objectForKey: NSPrintLastPage] intValue];
|
||||
pages = last - first + 1;
|
||||
if (nup > 1)
|
||||
pages = ceil((float)pages / nup);
|
||||
|
||||
/* Begin document structure */
|
||||
[self beginPrologueBBox: bbox
|
||||
creationDate: [[NSCalendarDate calendarDate] description]
|
||||
createdBy: [[NSProcessInfo processInfo] processName]
|
||||
fonts: nil
|
||||
forWhom: NSUserName()
|
||||
pages: pages
|
||||
title: [self printJobTitle]];
|
||||
[self endHeaderComments];
|
||||
|
||||
DPSPrintf(ctxt, "%%%%BeginProlog\n");
|
||||
// Prolog goes here !
|
||||
[self endPrologue];
|
||||
if ([printOp isEPSOperation] == NO)
|
||||
{
|
||||
[self beginSetup];
|
||||
// Setup goes here !
|
||||
[self endSetup];
|
||||
}
|
||||
|
||||
[NSFont resetUsedFonts];
|
||||
/* Make sure we set the visible rect so everything is printed. */
|
||||
[self _rebuildCoordinates];
|
||||
_visibleRect = _bounds;
|
||||
}
|
||||
|
||||
- (void)beginPageInRect:(NSRect)aRect
|
||||
atPlacement:(NSPoint)location
|
||||
{
|
||||
int nup;
|
||||
float scale;
|
||||
NSRect bounds;
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
NSDictionary *dict = [[printOp printInfo] dictionary];
|
||||
|
||||
if ([dict objectForKey: @"NSPrintPaperBounds"])
|
||||
bounds = [[dict objectForKey: @"NSPrintPaperBounds"] rectValue];
|
||||
else
|
||||
bounds = aRect;
|
||||
|
||||
nup = [[dict objectForKey: NSPrintPagesPerSheet] intValue];
|
||||
if (nup > 1)
|
||||
{
|
||||
int page;
|
||||
float xoff, yoff;
|
||||
DPSPrintf(ctxt, "/__GSpagesaveobject save def\n");
|
||||
page = [printOp currentPage]
|
||||
- [[dict objectForKey: NSPrintFirstPage] intValue];
|
||||
page = page % nup;
|
||||
scale = [[dict objectForKey: @"NSNupScale"] floatValue];
|
||||
if (nup == 2)
|
||||
xoff = page;
|
||||
else
|
||||
xoff = (page % (nup/2));
|
||||
xoff *= NSWidth(bounds) * scale;
|
||||
if (nup == 2)
|
||||
yoff = 0;
|
||||
else
|
||||
yoff = (int)((nup-page-1) / (nup/2));
|
||||
yoff *= NSHeight(bounds) * scale;
|
||||
DPStranslate(ctxt, xoff, yoff);
|
||||
DPSgsave(ctxt);
|
||||
DPSscale(ctxt, scale, scale);
|
||||
}
|
||||
else
|
||||
DPSgsave(ctxt);
|
||||
|
||||
/* Translate to placement */
|
||||
if (location.x != 0 || location.y != 0)
|
||||
DPStranslate(ctxt, location.x, location.y);
|
||||
}
|
||||
|
||||
- (void)endDocument
|
||||
{
|
||||
int first, last, current, pages;
|
||||
NSSet *fontNames;
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSPrintOperation *printOp = [NSPrintOperation currentOperation];
|
||||
NSDictionary *dict = [[printOp printInfo] dictionary];
|
||||
|
||||
first = [[dict objectForKey: NSPrintFirstPage] intValue];
|
||||
last = [[dict objectForKey: NSPrintLastPage] intValue];
|
||||
pages = last - first + 1;
|
||||
[self beginTrailer];
|
||||
|
||||
if (pages == 0)
|
||||
{
|
||||
int nup = [[dict objectForKey: NSPrintPagesPerSheet] intValue];
|
||||
current = [printOp currentPage];
|
||||
pages = current - first; // Current is 1 more than the last page
|
||||
if (nup > 1)
|
||||
pages = ceil((float)pages / nup);
|
||||
DPSPrintf(ctxt, "%%%%Pages: %d\n", pages);
|
||||
}
|
||||
fontNames = [NSFont usedFonts];
|
||||
if (fontNames && [fontNames count])
|
||||
{
|
||||
NSString *name;
|
||||
NSEnumerator *e = [fontNames objectEnumerator];
|
||||
DPSPrintf(ctxt, "%%%%DocumentFonts: %@\n", [e nextObject]);
|
||||
while ((name = [e nextObject]))
|
||||
{
|
||||
DPSPrintf(ctxt, "%%%%+ %@\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
[self endTrailer];
|
||||
[self _invalidateCoordinates];
|
||||
viewIsPrinting = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -158,6 +158,21 @@ NSString *NSDrawerWillOpenNotification =
|
|||
NSString *_NSFormCellDidChangeTitleWidthNotification
|
||||
= @"_NSFormCellDidChangeTitleWidthNotification";
|
||||
|
||||
// NSGraphicContext constants
|
||||
NSString *NSGraphicsContextDestinationAttributeName =
|
||||
@"NSGraphicsContextDestinationAttributeName";
|
||||
NSString *NSGraphicsContextPDFFormat =
|
||||
@"NSGraphicsContextPDFFormat";
|
||||
NSString *NSGraphicsContextPSFormat =
|
||||
@"NSGraphicsContextPSFormat";
|
||||
NSString *NSGraphicsContextRepresentationFormatAttributeName =
|
||||
@"NSGraphicsContextRepresentationFormatAttributeName";
|
||||
|
||||
NSString *NSImageInterpolationDefault = @"NSImageInterpolationDefault";
|
||||
NSString *NSImageInterpolationNone = @"NSImageInterpolationNone";
|
||||
NSString *NSImageInterpolationLow = @"NSImageInterpolationLow";
|
||||
NSString *NSImageInterpolationHigh = @"NSImageInterpolationHigh";
|
||||
|
||||
// NSHelpManager notifications;
|
||||
NSString *NSContextHelpModeDidActivateNotification =
|
||||
@"NSContextHelpModeDidActivateNotification";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue