Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7187834

[macosx] Usage of private API in macosx 2d implementation causes Apple Store rejection

XMLWordPrintable

    • 2d
    • b56
    • x86
    • os_x
    • Not verified

        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>

              skovatch Scott Kovatch (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: