FULL PRODUCT VERSION : openjdk version "1.7.0" OpenJDK Runtime Environment (build 1.7.0-2012_06_18_15_16-b00) OpenJDK 64-Bit Server VM (build 23.2-b05, mixed mode) ADDITIONAL OS VERSION INFORMATION : OSX 10.7 A DESCRIPTION OF THE PROBLEM : Our application has been rejected on the Apple Store because some native awt files in jdk/src/macosx/native/sun/awt/ use private calls like CGPointApplyInverseAffineTransform from the framework '/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices'. Other private calls I found are CGContextSetCTM and the usage of a constant called CTIntegerMetrics in CoreTextSupport.m and CTextPipe.m. REPRODUCIBILITY : This bug can be reproduced always. CUSTOMER SUBMITTED WORKAROUND : The following patch against OpenJDK 7u rev 243717d7fe95 attempts to replace the private calls CGPointApplyInverseAffineTransform and CGContextSetCTM with public ones. # HG changeset patch # User Marco Dinacci <###@###.###> # Date 1343648968 -3600 # Node ID d873b027d78564ad237f98a0cb5a327c5c740354 # Parent 2ebb564fd0a1267491b6a13bf7ff35b9894ebdba Replaced CGContextSetCTM and CGPointApplyInverseAffineTransform with public API calls. diff -r 2ebb564fd0a1 -r d873b027d785 src/macosx/native/sun/awt/ImageSurfaceData.m --- a/src/macosx/native/sun/awt/ImageSurfaceData.m Thu Jun 28 10:13:16 2012 +0100 +++ b/src/macosx/native/sun/awt/ImageSurfaceData.m Mon Jul 30 12:49:28 2012 +0100 @@ -48,20 +48,16 @@ #endif // same value as defined in Sun's own code #define XOR_ALPHA_CUTOFF 128 // for vImage framework headers #include <Accelerate/Accelerate.h> - -// private Quartz routines needed here -CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); - static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] = { {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case {YES, YES, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_RGB {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_ARGB {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_ARGB_PRE {YES, YES, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_BGR {YES, NO, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_3BYTE_BGR // use the default ARGB_PRE context synce we have to sync by hand anyway @@ -937,17 +933,16 @@ PRINT("createContext") if (qsdo->cgRef == NULL) { fprintf(stderr, "ERROR: (qsdo->cgRef == NULL) in createContext!\n"); } // intitalize the context to match the Java coordinate system // BG, since the context is created above, we can just concat - //CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height)); CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height)); CGContextSaveGState(qsdo->cgRef); // this will make sure we don't go pass device context settings CGContextSaveGState(qsdo->cgRef); // this will put user settings on top, used by LazyStateManagement code qsdo->newContext = YES; } IMAGE_SURFACE_INLINE void holdJavaPixels(JNIEnv* env, ImageSDOps* isdo) @@ -1109,17 +1104,17 @@ PRINT("syncFromJavaPixels") if (qsdo->cgRef == NULL) { createContext(env, isdo); } if (qsdo->cgRef != NULL) { CGContextSaveGState(qsdo->cgRef); - CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0)); + CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0)); CGContextSetBlendMode(qsdo->cgRef, kCGBlendModeCopy); CGContextSetAlpha(qsdo->cgRef, 1.0f); CGContextDrawImage(qsdo->cgRef, CGRectMake(0, 0, width, height), javaImg); CGContextFlush(qsdo->cgRef); CGContextRestoreGState(qsdo->cgRef); CGImageRelease(javaImg); } else diff -r 2ebb564fd0a1 -r d873b027d785 src/macosx/native/sun/awt/QuartzRenderer.m --- a/src/macosx/native/sun/awt/QuartzRenderer.m Thu Jun 28 10:13:16 2012 +0100 +++ b/src/macosx/native/sun/awt/QuartzRenderer.m Mon Jul 30 12:49:28 2012 +0100 @@ -45,19 +45,16 @@ // Copied the following from Math.java #define PI 3.14159265358979323846f #define BATCHED_POINTS_SIZE 1024 // same value as defined in Sun's own code #define XOR_ALPHA_CUTOFF 128 -// private Quartz routines needed here -CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); - static CGFloat gRoundRectCtrlpts[10][12] = { {0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f}, {1.0f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f}, @@ -532,31 +529,33 @@ QUARTZ_RENDERER_INLINE void doImageCG(JN { a = -1.0f; tx += dw; } makeSureImageIsCreated(isdo); CGAffineTransform ctm = CGContextGetCTM(cgRef); - CGContextConcatCTM(cgRef, CGAffineTransformMake(a, b, c, d, tx, ty)); + CGAffineTransform newTm = CGAffineTransformMake(a, b, c, d, tx, ty); + CGContextConcatCTM(cgRef, newTm); jint alphaInfo = isdo->contextInfo.alphaInfo & kCGBitmapAlphaInfoMask; if ((sx == 0) && (sy == 0) && (sw == w) && (sh == h)) // no subimages allowed here { CGContextDrawImage(cgRef, CGRectMake(0, 0, dw, dh), isdo->imgRef); } else // handle subimages { CGImageRef subImg = CGImageCreateWithImageInRect(isdo->imgRef, CGRectMake(sx, sy, sw, sh)); CGContextDrawImage(cgRef, CGRectMake(0.0f, 0.0f, dw, dh), subImg); CGImageRelease(subImg); } - CGContextSetCTM(cgRef, ctm); + CGAffineTransform inverse = CGAffineTransformInvert(newRef); + CGContextConcatCTM(cgRef, inverse); UnlockImage(env, isdo); } QUARTZ_RENDERER_INLINE void doImage(JNIEnv *env, QuartzSDOps *qsdo, jobject imageSurfaceData, jboolean fliph, jboolean flipv, jint w, jint h, jint sx, jint sy, jint sw, jint sh, jint dx, jint dy, jint dw, jint dh) { if ((w > 0) && (h > 0) && (sw > 0) && (sh > 0) && (dw > 0) && (dh > 0)) { diff -r 2ebb564fd0a1 -r d873b027d785 src/macosx/native/sun/awt/QuartzSurfaceData.m --- a/src/macosx/native/sun/awt/QuartzSurfaceData.m Thu Jun 28 10:13:16 2012 +0100 +++ b/src/macosx/native/sun/awt/QuartzSurfaceData.m Mon Jul 30 12:49:28 2012 +0100 @@ -35,29 +35,23 @@ #import "sun_lwawt_macosx_CPrinterSurfaceData.h" #import "ImageSurfaceData.h" #import <JavaNativeFoundation/JavaNativeFoundation.h> #import <AppKit/AppKit.h> #import "ThreadUtilities.h" -// private Quartz routines needed here -CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx); - //#define DEBUG #if defined DEBUG #define PRINT(msg) {fprintf(stderr, "%s\n", msg);} #else #define PRINT(msg) {} #endif -// from CGAffineTransformPrivate.h -extern CGPoint CGPointApplyInverseAffineTransform(CGPoint point, CGAffineTransform t); - #define kOffset (0.5f) BOOL gAdjustForJavaDrawing; #pragma mark #pragma mark --- Color Cache --- // Creating and deleting CGColorRefs can be expensive, therefore we have a color cache. @@ -603,17 +597,21 @@ PRINT(" SetUpCGContext") (qsdo->graphicsStateInfo.ctm.c != ctm.c) || (qsdo->graphicsStateInfo.ctm.d != ctm.d)) { qsdo->graphicsStateInfo.ctm = ctm; // In CG affine xforms y' = bx+dy+ty // We need to flip both y coefficeints to flip the offset point into the java coordinate system. ctm.b = -ctm.b; ctm.d = -ctm.d; ctm.tx = 0.0f; ctm.ty = 0.0f; CGPoint offsets = {kOffset, kOffset}; - offsets = CGPointApplyInverseAffineTransform(offsets, ctm); + + + CGAffineTransform inverse = CGAffineTransformInvert(ctm); + offsets = CGPointApplyAffineTransform(offsets, inverse); + //offsets = CGPointApplyInverseAffineTransform(offsets, ctm); qsdo->graphicsStateInfo.offsetX = offsets.x; qsdo->graphicsStateInfo.offsetY = offsets.y; } } else { qsdo->graphicsStateInfo.offsetX = 0.0f; qsdo->graphicsStateInfo.offsetY = 0.0f; exporting patch: <fdopen>
|