| /* |
| * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #import "PrinterView.h" |
| |
| #import "java_awt_print_Pageable.h" |
| #import "java_awt_print_PageFormat.h" |
| |
| #import <JavaNativeFoundation/JavaNativeFoundation.h> |
| |
| #import "ThreadUtilities.h" |
| #import "GeomUtilities.h" |
| |
| |
| static JNF_CLASS_CACHE(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob"); |
| static JNF_CLASS_CACHE(sjc_PageFormat, "java/awt/print/PageFormat"); |
| |
| @implementation PrinterView |
| |
| - (id)initWithFrame:(NSRect)aRect withEnv:(JNIEnv*)env withPrinterJob:(jobject)printerJob |
| { |
| self = [super initWithFrame:aRect]; |
| if (self) |
| { |
| fPrinterJob = JNFNewGlobalRef(env, printerJob); |
| fCurPageFormat = NULL; |
| fCurPainter = NULL; |
| fCurPeekGraphics = NULL; |
| } |
| return self; |
| } |
| |
| - (void)releaseReferences:(JNIEnv*)env |
| { |
| if (fCurPageFormat != NULL) |
| { |
| JNFDeleteGlobalRef(env, fCurPageFormat); |
| fCurPageFormat = NULL; |
| } |
| if (fCurPainter != NULL) |
| { |
| JNFDeleteGlobalRef(env, fCurPainter); |
| fCurPainter = NULL; |
| } |
| if (fCurPeekGraphics != NULL) |
| { |
| JNFDeleteGlobalRef(env, fCurPeekGraphics); |
| fCurPeekGraphics = NULL; |
| } |
| } |
| |
| - (void)setFirstPage:(jint)firstPage lastPage:(jint)lastPage { |
| fFirstPage = firstPage; |
| fLastPage = lastPage; |
| } |
| |
| - (void)drawRect:(NSRect)aRect |
| { |
| AWT_ASSERT_NOT_APPKIT_THREAD; |
| |
| static JNF_MEMBER_CACHE(jm_printToPathGraphics, sjc_CPrinterJob, "printToPathGraphics", "(Lsun/print/PeekGraphics;Ljava/awt/print/PrinterJob;Ljava/awt/print/Printable;Ljava/awt/print/PageFormat;IJ)V"); |
| |
| // Create and draw into a new CPrinterGraphics with the current Context. |
| assert(fCurPageFormat != NULL); |
| assert(fCurPainter != NULL); |
| assert(fCurPeekGraphics != NULL); |
| |
| JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; |
| |
| if ([self cancelCheck:env]) |
| { |
| [self releaseReferences:env]; |
| return; |
| } |
| |
| NSPrintOperation* printLoop = [NSPrintOperation currentOperation]; |
| jint jPageIndex = [printLoop currentPage] - 1; |
| |
| jlong context = ptr_to_jlong([printLoop context]); |
| CGContextRef cgRef = (CGContextRef)[[printLoop context] graphicsPort]; |
| CGContextSaveGState(cgRef); //04/28/2004: state needs to be saved here due to addition of lazy state management |
| |
| JNFCallVoidMethod(env, fPrinterJob, jm_printToPathGraphics, fCurPeekGraphics, fPrinterJob, fCurPainter, fCurPageFormat, jPageIndex, context); // AWT_THREADING Safe (AWTRunLoop) |
| |
| CGContextRestoreGState(cgRef); |
| |
| [self releaseReferences:env]; |
| } |
| |
| - (NSString*)printJobTitle |
| { |
| AWT_ASSERT_NOT_APPKIT_THREAD; |
| |
| static JNF_MEMBER_CACHE(jm_getJobName, sjc_CPrinterJob, "getJobName", "()Ljava/lang/String;"); |
| |
| JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; |
| |
| jobject o = JNFCallObjectMethod(env, fPrinterJob, jm_getJobName); // AWT_THREADING Safe (known object) |
| id result = JNFJavaToNSString(env, o); |
| (*env)->DeleteLocalRef(env, o); |
| return result; |
| } |
| |
| - (BOOL)knowsPageRange:(NSRangePointer)aRange |
| { |
| AWT_ASSERT_NOT_APPKIT_THREAD; |
| |
| JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; |
| if ([self cancelCheck:env]) |
| { |
| return NO; |
| } |
| |
| aRange->location = fFirstPage + 1; |
| |
| if (fLastPage == java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES) |
| { |
| aRange->length = NSIntegerMax; |
| } |
| else |
| { |
| aRange->length = (fLastPage + 1) - fFirstPage; |
| } |
| |
| return YES; |
| } |
| |
| - (NSRect)rectForPage:(NSInteger)pageNumber |
| { |
| AWT_ASSERT_NOT_APPKIT_THREAD; |
| |
| static JNF_MEMBER_CACHE(jm_getPageformatPrintablePeekgraphics, sjc_CPrinterJob, "getPageformatPrintablePeekgraphics", "(I)[Ljava/lang/Object;"); |
| static JNF_MEMBER_CACHE(jm_printAndGetPageFormatArea, sjc_CPrinterJob, "printAndGetPageFormatArea", "(Ljava/awt/print/Printable;Ljava/awt/Graphics;Ljava/awt/print/PageFormat;I)Ljava/awt/geom/Rectangle2D;"); |
| static JNF_MEMBER_CACHE(jm_getOrientation, sjc_PageFormat, "getOrientation", "()I"); |
| |
| // Assertions removed, and corresponding JNFDeleteGlobalRefs added, for radr://3962543 |
| // Actual fix that will keep these assertions from being true is radr://3205462 , |
| // which will hopefully be fixed by the blocking AppKit bug radr://3056694 |
| //assert(fCurPageFormat == NULL); |
| //assert(fCurPainter == NULL); |
| //assert(fCurPeekGraphics == NULL); |
| |
| JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; |
| if(fCurPageFormat != NULL) { |
| JNFDeleteGlobalRef(env, fCurPageFormat); |
| } |
| if(fCurPainter != NULL) { |
| JNFDeleteGlobalRef(env, fCurPainter); |
| } |
| if(fCurPeekGraphics != NULL) { |
| JNFDeleteGlobalRef(env, fCurPeekGraphics); |
| } |
| |
| //+++gdb Check the pageNumber for validity (PageAttrs) |
| |
| jint jPageNumber = pageNumber - 1; |
| |
| NSRect result; |
| |
| if ([self cancelCheck:env]) |
| { |
| return NSZeroRect; |
| } |
| |
| jobjectArray objectArray = JNFCallObjectMethod(env, fPrinterJob, jm_getPageformatPrintablePeekgraphics, jPageNumber); // AWT_THREADING Safe (AWTRunLoopMode) |
| if (objectArray != NULL) { |
| // Get references to the return objects -> PageFormat, Printable, PeekGraphics |
| // Cheat - we know we either got NULL or a 3 element array |
| jobject pageFormat = (*env)->GetObjectArrayElement(env, objectArray, 0); |
| fCurPageFormat = JNFNewGlobalRef(env, pageFormat); |
| (*env)->DeleteLocalRef(env, pageFormat); |
| |
| jobject painter = (*env)->GetObjectArrayElement(env, objectArray, 1); |
| fCurPainter = JNFNewGlobalRef(env, painter); |
| (*env)->DeleteLocalRef(env, painter); |
| |
| jobject peekGraphics = (*env)->GetObjectArrayElement(env, objectArray, 2); |
| fCurPeekGraphics = JNFNewGlobalRef(env, peekGraphics); |
| (*env)->DeleteLocalRef(env, peekGraphics); |
| |
| // Actually print and get the PageFormatArea |
| jobject pageFormatArea = JNFCallObjectMethod(env, fPrinterJob, jm_printAndGetPageFormatArea, fCurPainter, fCurPeekGraphics, fCurPageFormat, jPageNumber); // AWT_THREADING Safe (AWTRunLoopMode) |
| if (pageFormatArea != NULL) { |
| NSPrintingOrientation currentOrientation = |
| [[[NSPrintOperation currentOperation] printInfo] orientation]; |
| // set page orientation |
| switch (JNFCallIntMethod(env, fCurPageFormat, jm_getOrientation)) { |
| case java_awt_print_PageFormat_PORTRAIT: |
| default: |
| if (currentOrientation != NSPortraitOrientation) { |
| [[[NSPrintOperation currentOperation] printInfo] |
| setOrientation:NSPortraitOrientation]; |
| } |
| break; |
| |
| case java_awt_print_PageFormat_LANDSCAPE: |
| case java_awt_print_PageFormat_REVERSE_LANDSCAPE: |
| if (currentOrientation != NSLandscapeOrientation) { |
| [[[NSPrintOperation currentOperation] printInfo] |
| setOrientation:NSLandscapeOrientation]; |
| } |
| break; |
| } |
| result = JavaToNSRect(env, pageFormatArea); |
| (*env)->DeleteLocalRef(env, pageFormatArea); |
| } else { |
| [self releaseReferences:env]; |
| result = NSZeroRect; |
| } |
| |
| (*env)->DeleteLocalRef(env, objectArray); |
| } else { |
| [self releaseReferences:env]; |
| result = NSZeroRect; |
| } |
| |
| return result; |
| } |
| |
| - (BOOL)cancelCheck:(JNIEnv*)env |
| { |
| AWT_ASSERT_NOT_APPKIT_THREAD; |
| |
| static JNF_MEMBER_CACHE(jm_cancelCheck, sjc_CPrinterJob, "cancelCheck", "()Z"); |
| |
| return JNFCallBooleanMethod(env, fPrinterJob, jm_cancelCheck); // AWT_THREADING Safe (known object) |
| } |
| |
| // This is called by -[PrintModel safePrintLoop] |
| - (void)complete:(JNIEnv*)env |
| { |
| AWT_ASSERT_NOT_APPKIT_THREAD; |
| |
| static JNF_MEMBER_CACHE(jf_completePrintLoop, sjc_CPrinterJob, "completePrintLoop", "()V"); |
| JNFCallVoidMethod(env, fPrinterJob, jf_completePrintLoop); |
| |
| // Clean up after ourselves |
| // Can't put these into -dealloc since that happens (potentially) after the JNIEnv is stale |
| [self releaseReferences:env]; |
| if (fPrinterJob != NULL) |
| { |
| JNFDeleteGlobalRef(env, fPrinterJob); |
| fPrinterJob = NULL; |
| } |
| } |
| |
| - (BOOL)isFlipped |
| { |
| return TRUE; |
| } |
| |
| @end |