< prev index next >

src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m

Print this page

        

@@ -197,19 +197,13 @@
 #pragma mark --- Font Rendering Mode Descriptors ---
 
 static inline void
 CGGI_CopyARGBPixelToRGBPixel(const UInt32 p, UInt8 *dst)
 {
-#if __LITTLE_ENDIAN__
-    *(dst + 2) = 0xFF - (p >> 24 & 0xFF);
-    *(dst + 1) = 0xFF - (p >> 16 & 0xFF);
-    *(dst) = 0xFF - (p >> 8 & 0xFF);
-#else
-    *(dst) = 0xFF - (p >> 16 & 0xFF);
-    *(dst + 1) = 0xFF - (p >> 8 & 0xFF);
-    *(dst + 2) = 0xFF - (p & 0xFF);
-#endif
+    *(dst + 0) = 0xFF - (p >> 16 & 0xFF);  // red
+    *(dst + 1) = 0xFF - (p >>  8 & 0xFF);  // green
+    *(dst + 2) = 0xFF - (p & 0xFF);        // blue
 }
 
 static void
 CGGI_CopyImageFromCanvasToRGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 {

@@ -314,25 +308,31 @@
 static inline CGGI_RenderingMode
 CGGI_GetRenderingMode(const AWTStrike *strike)
 {
     CGGI_RenderingMode mode;
     mode.cgFontMode = strike->fStyle;
+    NSException *e = nil;
 
     switch (strike->fAAStyle) {
-    case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_DEFAULT:
     case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_OFF:
     case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_ON:
-    case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_GASP:
-    default:
         mode.glyphDescriptor = &grey;
         break;
     case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
     case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_HBGR:
     case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
     case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_VBGR:
         mode.glyphDescriptor = &rgb;
         break;
+    case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_GASP:
+    case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_DEFAULT:
+    default:
+        e = [NSException
+                exceptionWithName:@"IllegalArgumentException"
+                reason:@"Invalid hint value"
+                userInfo:nil];
+        @throw e;
     }
 
     return mode;
 }
 

@@ -343,11 +343,12 @@
  * Creates a new canvas of a fixed size, and initializes the CGContext as
  * an 32-bit ARGB BitmapContext with some generic RGB color space.
  */
 static inline void
 CGGI_InitCanvas(CGGI_GlyphCanvas *canvas,
-                const vImagePixelCount width, const vImagePixelCount height)
+                const vImagePixelCount width, const vImagePixelCount height,
+                const CGGI_RenderingMode* mode)
 {
     // our canvas is *always* 4-byte ARGB
     size_t bytesPerRow = width * sizeof(UInt32);
     size_t byteCount = bytesPerRow * height;
 

@@ -360,15 +361,20 @@
     if (canvas->image->data == NULL) {
         [[NSException exceptionWithName:NSMallocException
             reason:@"Failed to allocate memory for the buffer which backs the CGContext for glyph strikes." userInfo:nil] raise];
     }
 
+    uint32_t bmpInfo = kCGImageAlphaPremultipliedFirst;
+    if (mode->glyphDescriptor == &rgb) {
+        bmpInfo |= kCGBitmapByteOrder32Host;
+    }
+
     CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
     canvas->context = CGBitmapContextCreate(canvas->image->data,
                                             width, height, 8, bytesPerRow,
                                             colorSpace,
-                                            kCGImageAlphaPremultipliedFirst);
+                                            bmpInfo);
 
     CGContextSetRGBFillColor(canvas->context, 0.0f, 0.0f, 0.0f, 1.0f);
     CGContextSetFontSize(canvas->context, 1);
     CGContextSaveGState(canvas->context);
 

@@ -402,11 +408,11 @@
 
 /*
  * Quick and easy inline to check if this canvas is big enough.
  */
 static inline void
-CGGI_SizeCanvas(CGGI_GlyphCanvas *canvas, const vImagePixelCount width, const vImagePixelCount height, const JRSFontRenderingStyle style)
+CGGI_SizeCanvas(CGGI_GlyphCanvas *canvas, const vImagePixelCount width, const vImagePixelCount height, const CGGI_RenderingMode* mode)
 {
     if (canvas->image != NULL &&
         width  < canvas->image->width &&
         height < canvas->image->height)
     {

@@ -416,12 +422,13 @@
     // if we don't have enough space to strike the largest glyph in the
     // run, resize the canvas
     CGGI_FreeCanvas(canvas);
     CGGI_InitCanvas(canvas,
                     width * CGGI_GLYPH_CANVAS_SLACK,
-                    height * CGGI_GLYPH_CANVAS_SLACK);
-    JRSFontSetRenderingStyleOnContext(canvas->context, style);
+                    height * CGGI_GLYPH_CANVAS_SLACK,
+                    mode);
+    JRSFontSetRenderingStyleOnContext(canvas->context, mode->cgFontMode);
 }
 
 /*
  * Clear the canvas by blitting white only into the region of interest
  * (the rect which we will copy out of once the glyph is struck).

@@ -575,11 +582,11 @@
 
     // create the Sun2D GlyphInfo we are going to strike into
     GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mode);
 
     // fix the context size, just in case the substituted character is unexpectedly large
-    CGGI_SizeCanvas(canvas, info->width, info->height, mode->cgFontMode);
+    CGGI_SizeCanvas(canvas, info->width, info->height, mode);
 
     // align the transform for the real CoreText strike
     CGContextSetTextMatrix(canvas->context, strike->fAltTx);
 
     const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);

@@ -651,12 +658,15 @@
     DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
     PRINT_CGSTATES_INFO(canvas->context);
 #endif
 }
 
-static NSString *threadLocalCanvasKey =
-    @"Java CoreGraphics Text Renderer Cached Canvas";
+static NSString *threadLocalAACanvasKey =
+    @"Java CoreGraphics Text Renderer Cached Canvas for AA";
+
+static NSString *threadLocalLCDCanvasKey =
+        @"Java CoreGraphics Text Renderer Cached Canvas for LCD";
 
 /*
  * This is the maximum length and height times the above slack squared
  * to determine if we go with the global canvas, or malloc one on the spot.
  */

@@ -676,11 +686,11 @@
 {
     if (maxWidth*maxHeight*CGGI_GLYPH_CANVAS_SLACK*CGGI_GLYPH_CANVAS_SLACK >
         CGGI_GLYPH_CANVAS_MAX*CGGI_GLYPH_CANVAS_MAX*CGGI_GLYPH_CANVAS_SLACK*CGGI_GLYPH_CANVAS_SLACK)
     {
         CGGI_GlyphCanvas *tmpCanvas = [[CGGI_GlyphCanvas alloc] init];
-        CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight);
+        CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight, mode);
         CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
                                                 mode, glyphInfos, uniChars,
                                                 glyphs, len);
         CGGI_FreeCanvas(tmpCanvas);
 

@@ -688,17 +698,26 @@
         return;
     }
 
     NSMutableDictionary *threadDict =
         [[NSThread currentThread] threadDictionary];
-    CGGI_GlyphCanvas *canvas = [threadDict objectForKey:threadLocalCanvasKey];
+
+    NSString* theKey;
+
+    if (mode->glyphDescriptor == &rgb) {
+        theKey = threadLocalLCDCanvasKey;
+    } else {
+        theKey = threadLocalAACanvasKey;
+    }
+
+    CGGI_GlyphCanvas *canvas = [threadDict objectForKey:theKey];
     if (canvas == nil) {
         canvas = [[CGGI_GlyphCanvas alloc] init];
-        [threadDict setObject:canvas forKey:threadLocalCanvasKey];
+        [threadDict setObject:canvas forKey:theKey];
     }
 
-    CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode->cgFontMode);
+    CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
     CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
                                             glyphInfos, uniChars, glyphs, len);
 }
 
 /*
< prev index next >