< prev index next >
src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphImages.m
Print this page
@@ -198,14 +198,15 @@
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);
+ *(dst + 2) = 0xFF - (p >> 16 & 0xFF);
+ *(dst + 1) = 0xFF - (p >> 8 & 0xFF);
+ *(dst) = 0xFF - (p & 0xFF);
#else
+ // TODO: check whether do we need big endian case
*(dst) = 0xFF - (p >> 16 & 0xFF);
*(dst + 1) = 0xFF - (p >> 8 & 0xFF);
*(dst + 2) = 0xFF - (p & 0xFF);
#endif
}
@@ -316,23 +317,25 @@
{
CGGI_RenderingMode mode;
mode.cgFontMode = strike->fStyle;
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:
+ // TODO: generate an error?
+ break;
}
return mode;
}
@@ -343,11 +346,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 +364,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 +411,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 +425,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 +585,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 +661,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 +689,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 +701,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 >