< prev index next >

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

Print this page




 191 #endif
 192 }
 193 
 194 #endif
 195 
 196 
 197 #pragma mark --- Font Rendering Mode Descriptors ---
 198 static Int32 reverseGamma = 0;
 199 
 200 static UInt8 reverseGammaLut[256] = { 0 };
 201 
 202 static inline UInt8* getReverseGammaLut() {
 203     if (reverseGamma == 0) {
 204         // initialize gamma lut
 205         double gamma;
 206         int i;
 207         const char* pGammaEnv = getenv("J2D_LCD_REVERSE_GAMMA");
 208         if (pGammaEnv != NULL) {
 209             reverseGamma = atol(pGammaEnv);
 210         }
 211         
 212         if (reverseGamma < 100 || reverseGamma > 250) {
 213             reverseGamma = 180;
 214         }
 215         
 216         gamma = 100.0 / reverseGamma;
 217         for (i = 0; i < 256; i++) {
 218             double x = ((double)i) / 255.0;
 219             reverseGammaLut[i] = (UInt8)(255 * pow(x, gamma));
 220         }
 221     }
 222     return reverseGammaLut;
 223 }
 224 
 225 static inline void
 226 CGGI_CopyARGBPixelToRGBPixel(const UInt32 p, UInt8 *dst)
 227 {
 228     UInt8* lut = getReverseGammaLut();
 229     
 230     *(dst + 0) = lut[0xFF - (p >> 16 & 0xFF)];  // red
 231     *(dst + 1) = lut[0xFF - (p >>  8 & 0xFF)];  // green
 232     *(dst + 2) = lut[0xFF - (p & 0xFF)];        // blue
 233 }
 234 
 235 static void
 236 CGGI_CopyImageFromCanvasToRGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 237 {
 238     UInt32 *src = (UInt32 *)canvas->image->data;
 239     size_t srcRowWidth = canvas->image->width;
 240 
 241     UInt8 *dest = (UInt8 *)info->image;
 242     size_t destRowWidth = info->width;
 243 
 244     size_t height = info->height;
 245 
 246     size_t y;
 247     
 248     // fill empty glyph image with black-on-white glyph
 249     for (y = 0; y < height; y++) {
 250         size_t destRow = y * destRowWidth * 3;
 251         size_t srcRow = y * srcRowWidth;
 252 
 253         size_t x;
 254         for (x = 0; x < destRowWidth; x++) {
 255             CGGI_CopyARGBPixelToRGBPixel(src[srcRow + x],
 256                                          dest + destRow + x * 3);
 257         }
 258     }
 259 }
 260 
 261 //static void CGGI_copyImageFromCanvasToAlphaInfo
 262 //(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 263 //{
 264 //    vImage_Buffer infoBuffer;
 265 //    infoBuffer.data = info->image;
 266 //    infoBuffer.width = info->width;
 267 //    infoBuffer.height = info->height;


 279 //}
 280 
 281 static inline UInt8
 282 CGGI_ConvertBWPixelToByteGray(UInt32 p)
 283 {
 284     return 0xFF - (((p >> 24 & 0xFF) + (p >> 16 & 0xFF) + (p >> 8 & 0xFF)) / 3);
 285 }
 286 
 287 static void
 288 CGGI_CopyImageFromCanvasToAlphaInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 289 {
 290     UInt32 *src = (UInt32 *)canvas->image->data;
 291     size_t srcRowWidth = canvas->image->width;
 292 
 293     UInt8 *dest = (UInt8 *)info->image;
 294     size_t destRowWidth = info->width;
 295 
 296     size_t height = info->height;
 297 
 298     size_t y;
 299     
 300     // fill empty glyph image with black-on-white glyph
 301     for (y = 0; y < height; y++) {
 302         size_t destRow = y * destRowWidth;
 303         size_t srcRow = y * srcRowWidth;
 304         size_t x;
 305         for (x = 0; x < destRowWidth; x++) {
 306             UInt32 p = src[srcRow + x];
 307             dest[destRow + x] = CGGI_ConvertBWPixelToByteGray(p);
 308         }
 309     }
 310 }
 311 
 312 
 313 #pragma mark --- Pixel Size, Modes, and Canvas Shaping Helper Functions ---
 314 
 315 typedef struct CGGI_GlyphInfoDescriptor {
 316     size_t pixelSize;
 317     void (*copyFxnPtr)(CGGI_GlyphCanvas *canvas, GlyphInfo *info);
 318 } CGGI_GlyphInfoDescriptor;
 319 


 384 
 385     canvas->image->data = (void *)calloc(byteCount, sizeof(UInt8));
 386     if (canvas->image->data == NULL) {
 387         [[NSException exceptionWithName:NSMallocException
 388             reason:@"Failed to allocate memory for the buffer which backs the CGContext for glyph strikes." userInfo:nil] raise];
 389     }
 390 
 391     uint32_t bmpInfo = kCGImageAlphaPremultipliedFirst;
 392     if (mode->glyphDescriptor == &rgb) {
 393         bmpInfo |= kCGBitmapByteOrder32Host;
 394     }
 395 
 396     CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
 397     canvas->context = CGBitmapContextCreate(canvas->image->data,
 398                                             width, height, 8, bytesPerRow,
 399                                             colorSpace,
 400                                             bmpInfo);
 401 
 402     // set foreground color
 403     CGContextSetRGBFillColor(canvas->context, 0.0f, 0.0f, 0.0f, 1.0f);
 404     
 405     CGContextSetFontSize(canvas->context, 1);
 406     CGContextSaveGState(canvas->context);
 407 
 408     CGColorSpaceRelease(colorSpace);
 409 }
 410 
 411 /*
 412  * Releases the BitmapContext and the associated memory backing it.
 413  */
 414 static inline void
 415 CGGI_FreeCanvas(CGGI_GlyphCanvas *canvas)
 416 {
 417     if (canvas->context != NULL) {
 418         CGContextRelease(canvas->context);
 419     }
 420 
 421     if (canvas->image != NULL) {
 422         if (canvas->image->data != NULL) {
 423             free(canvas->image->data);
 424         }


 725                          const CFIndex len)
 726 {
 727     if (maxWidth*maxHeight*CGGI_GLYPH_CANVAS_SLACK*CGGI_GLYPH_CANVAS_SLACK >
 728         CGGI_GLYPH_CANVAS_MAX*CGGI_GLYPH_CANVAS_MAX*CGGI_GLYPH_CANVAS_SLACK*CGGI_GLYPH_CANVAS_SLACK)
 729     {
 730         CGGI_GlyphCanvas *tmpCanvas = [[CGGI_GlyphCanvas alloc] init];
 731         CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight, mode);
 732         CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
 733                 mode, glyphInfos, uniChars,
 734                 glyphs, len);
 735         CGGI_FreeCanvas(tmpCanvas);
 736 
 737         [tmpCanvas release];
 738         return;
 739     }
 740     NSMutableDictionary *threadDict =
 741         [[NSThread currentThread] threadDictionary];
 742 
 743     NSString* theKey = (mode->glyphDescriptor == &rgb) ?
 744         threadLocalLCDCanvasKey : threadLocalAACanvasKey;
 745     
 746     CGGI_GlyphCanvas *canvas = [threadDict objectForKey:theKey];
 747     if (canvas == nil) {
 748         canvas = [[CGGI_GlyphCanvas alloc] init];
 749         [threadDict setObject:canvas forKey:theKey];
 750     }
 751 
 752     CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
 753     CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
 754                                             glyphInfos, uniChars, glyphs, len);
 755 }
 756 
 757 /*
 758  * Finds the advances and bounding boxes of the characters in the run,
 759  * cycles through all the bounds and calculates the maximum canvas space
 760  * required by the largest glyph.
 761  *
 762  * Creates a GlyphInfo struct with a malloc that also encapsulates the
 763  * image the struct points to.  This is done to meet memory layout
 764  * expectations in the Sun text rasterizer memory managment code.
 765  * The image immediately follows the struct physically in memory.




 191 #endif
 192 }
 193 
 194 #endif
 195 
 196 
 197 #pragma mark --- Font Rendering Mode Descriptors ---
 198 static Int32 reverseGamma = 0;
 199 
 200 static UInt8 reverseGammaLut[256] = { 0 };
 201 
 202 static inline UInt8* getReverseGammaLut() {
 203     if (reverseGamma == 0) {
 204         // initialize gamma lut
 205         double gamma;
 206         int i;
 207         const char* pGammaEnv = getenv("J2D_LCD_REVERSE_GAMMA");
 208         if (pGammaEnv != NULL) {
 209             reverseGamma = atol(pGammaEnv);
 210         }
 211 
 212         if (reverseGamma < 100 || reverseGamma > 250) {
 213             reverseGamma = 180;
 214         }
 215 
 216         gamma = 100.0 / reverseGamma;
 217         for (i = 0; i < 256; i++) {
 218             double x = ((double)i) / 255.0;
 219             reverseGammaLut[i] = (UInt8)(255 * pow(x, gamma));
 220         }
 221     }
 222     return reverseGammaLut;
 223 }
 224 
 225 static inline void
 226 CGGI_CopyARGBPixelToRGBPixel(const UInt32 p, UInt8 *dst)
 227 {
 228     UInt8* lut = getReverseGammaLut();
 229 
 230     *(dst + 0) = lut[0xFF - (p >> 16 & 0xFF)];  // red
 231     *(dst + 1) = lut[0xFF - (p >>  8 & 0xFF)];  // green
 232     *(dst + 2) = lut[0xFF - (p & 0xFF)];        // blue
 233 }
 234 
 235 static void
 236 CGGI_CopyImageFromCanvasToRGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 237 {
 238     UInt32 *src = (UInt32 *)canvas->image->data;
 239     size_t srcRowWidth = canvas->image->width;
 240 
 241     UInt8 *dest = (UInt8 *)info->image;
 242     size_t destRowWidth = info->width;
 243 
 244     size_t height = info->height;
 245 
 246     size_t y;
 247 
 248     // fill empty glyph image with black-on-white glyph
 249     for (y = 0; y < height; y++) {
 250         size_t destRow = y * destRowWidth * 3;
 251         size_t srcRow = y * srcRowWidth;
 252 
 253         size_t x;
 254         for (x = 0; x < destRowWidth; x++) {
 255             CGGI_CopyARGBPixelToRGBPixel(src[srcRow + x],
 256                                          dest + destRow + x * 3);
 257         }
 258     }
 259 }
 260 
 261 //static void CGGI_copyImageFromCanvasToAlphaInfo
 262 //(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 263 //{
 264 //    vImage_Buffer infoBuffer;
 265 //    infoBuffer.data = info->image;
 266 //    infoBuffer.width = info->width;
 267 //    infoBuffer.height = info->height;


 279 //}
 280 
 281 static inline UInt8
 282 CGGI_ConvertBWPixelToByteGray(UInt32 p)
 283 {
 284     return 0xFF - (((p >> 24 & 0xFF) + (p >> 16 & 0xFF) + (p >> 8 & 0xFF)) / 3);
 285 }
 286 
 287 static void
 288 CGGI_CopyImageFromCanvasToAlphaInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
 289 {
 290     UInt32 *src = (UInt32 *)canvas->image->data;
 291     size_t srcRowWidth = canvas->image->width;
 292 
 293     UInt8 *dest = (UInt8 *)info->image;
 294     size_t destRowWidth = info->width;
 295 
 296     size_t height = info->height;
 297 
 298     size_t y;
 299 
 300     // fill empty glyph image with black-on-white glyph
 301     for (y = 0; y < height; y++) {
 302         size_t destRow = y * destRowWidth;
 303         size_t srcRow = y * srcRowWidth;
 304         size_t x;
 305         for (x = 0; x < destRowWidth; x++) {
 306             UInt32 p = src[srcRow + x];
 307             dest[destRow + x] = CGGI_ConvertBWPixelToByteGray(p);
 308         }
 309     }
 310 }
 311 
 312 
 313 #pragma mark --- Pixel Size, Modes, and Canvas Shaping Helper Functions ---
 314 
 315 typedef struct CGGI_GlyphInfoDescriptor {
 316     size_t pixelSize;
 317     void (*copyFxnPtr)(CGGI_GlyphCanvas *canvas, GlyphInfo *info);
 318 } CGGI_GlyphInfoDescriptor;
 319 


 384 
 385     canvas->image->data = (void *)calloc(byteCount, sizeof(UInt8));
 386     if (canvas->image->data == NULL) {
 387         [[NSException exceptionWithName:NSMallocException
 388             reason:@"Failed to allocate memory for the buffer which backs the CGContext for glyph strikes." userInfo:nil] raise];
 389     }
 390 
 391     uint32_t bmpInfo = kCGImageAlphaPremultipliedFirst;
 392     if (mode->glyphDescriptor == &rgb) {
 393         bmpInfo |= kCGBitmapByteOrder32Host;
 394     }
 395 
 396     CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
 397     canvas->context = CGBitmapContextCreate(canvas->image->data,
 398                                             width, height, 8, bytesPerRow,
 399                                             colorSpace,
 400                                             bmpInfo);
 401 
 402     // set foreground color
 403     CGContextSetRGBFillColor(canvas->context, 0.0f, 0.0f, 0.0f, 1.0f);
 404 
 405     CGContextSetFontSize(canvas->context, 1);
 406     CGContextSaveGState(canvas->context);
 407 
 408     CGColorSpaceRelease(colorSpace);
 409 }
 410 
 411 /*
 412  * Releases the BitmapContext and the associated memory backing it.
 413  */
 414 static inline void
 415 CGGI_FreeCanvas(CGGI_GlyphCanvas *canvas)
 416 {
 417     if (canvas->context != NULL) {
 418         CGContextRelease(canvas->context);
 419     }
 420 
 421     if (canvas->image != NULL) {
 422         if (canvas->image->data != NULL) {
 423             free(canvas->image->data);
 424         }


 725                          const CFIndex len)
 726 {
 727     if (maxWidth*maxHeight*CGGI_GLYPH_CANVAS_SLACK*CGGI_GLYPH_CANVAS_SLACK >
 728         CGGI_GLYPH_CANVAS_MAX*CGGI_GLYPH_CANVAS_MAX*CGGI_GLYPH_CANVAS_SLACK*CGGI_GLYPH_CANVAS_SLACK)
 729     {
 730         CGGI_GlyphCanvas *tmpCanvas = [[CGGI_GlyphCanvas alloc] init];
 731         CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight, mode);
 732         CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
 733                 mode, glyphInfos, uniChars,
 734                 glyphs, len);
 735         CGGI_FreeCanvas(tmpCanvas);
 736 
 737         [tmpCanvas release];
 738         return;
 739     }
 740     NSMutableDictionary *threadDict =
 741         [[NSThread currentThread] threadDictionary];
 742 
 743     NSString* theKey = (mode->glyphDescriptor == &rgb) ?
 744         threadLocalLCDCanvasKey : threadLocalAACanvasKey;
 745 
 746     CGGI_GlyphCanvas *canvas = [threadDict objectForKey:theKey];
 747     if (canvas == nil) {
 748         canvas = [[CGGI_GlyphCanvas alloc] init];
 749         [threadDict setObject:canvas forKey:theKey];
 750     }
 751 
 752     CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
 753     CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
 754                                             glyphInfos, uniChars, glyphs, len);
 755 }
 756 
 757 /*
 758  * Finds the advances and bounding boxes of the characters in the run,
 759  * cycles through all the bounds and calculates the maximum canvas space
 760  * required by the largest glyph.
 761  *
 762  * Creates a GlyphInfo struct with a malloc that also encapsulates the
 763  * image the struct points to.  This is done to meet memory layout
 764  * expectations in the Sun text rasterizer memory managment code.
 765  * The image immediately follows the struct physically in memory.


< prev index next >