/*
 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#import <Accelerate/Accelerate.h> // for vImage_Buffer
#import <JavaNativeFoundation/JavaNativeFoundation.h>

#import "CGGlyphImages.h"
#import "CoreTextSupport.h"
#import "fontscalerdefs.h" // contains the definition of GlyphInfo struct

#import "sun_awt_SunHints.h"
#import "LWCToolkit.h"

//#define USE_IMAGE_ALIGNED_MEMORY 1
//#define CGGI_DEBUG 1
//#define CGGI_DEBUG_DUMP 1
//#define CGGI_DEBUG_HIT_COUNT 1

#define PRINT_TX(x) \
    NSLog(@"(%f, %f, %f, %f, %f, %f)", x.a, x.b, x.c, x.d, x.tx, x.ty);

/*
 * The GlyphCanvas is a global shared CGContext that characters are struck into.
 * For each character, the glyph is struck, copied into a GlyphInfo struct, and
 * the canvas is cleared for the next glyph.
 *
 * If the necessary canvas is too large, the shared one will not be used and a
 * temporary one will be provided.
 */
@interface CGGI_GlyphCanvas : NSObject {
@public
    CGContextRef context;
    vImage_Buffer *image;
}
@end;

@implementation CGGI_GlyphCanvas
@end


#pragma mark --- Debugging Helpers ---

/*
 * These debug functions are only compiled when CGGI_DEBUG is activated.
 * They will print out a full UInt8 canvas and any pixels struck (assuming
 * the canvas is not too big).
 *
 * As another debug feature, the entire canvas will be filled with a light
 * alpha value so it is easy to see where the glyph painting regions are
 * at runtime.
 */

#ifdef CGGI_DEBUG_DUMP
static void
DUMP_PIXELS(const char msg[], const UInt8 pixels[],
            const size_t bytesPerPixel, const int width, const int height)
{
    printf("| %s: (%d, %d)\n", msg, width, height);

    if (width > 80 || height > 80) {
        printf("| too big\n");
        return;
    }

    size_t i, j = 0, k, size = width * height;
    for (i = 0; i < size; i++) {
        for (k = 0; k < bytesPerPixel; k++) {
            if (pixels[i * bytesPerPixel + k] > 0x80) j++;
        }
    }

    if (j == 0) {
        printf("| empty\n");
        return;
    }

    printf("|_");
    int x, y;
    for (x = 0; x < width; x++) {
        printf("__");
    }
    printf("_\n");

    for (y = 0; y < height; y++) {
        printf("| ");
        for (x = 0; x < width; x++) {
            int p = 0;
            for(k = 0; k < bytesPerPixel; k++) {
                p += pixels[(y * width + x) * bytesPerPixel + k];
            }

            if (p < 0x80) {
                printf("  ");
            } else {
                printf("[]");
            }
        }
        printf(" |\n");
    }
}

static void
DUMP_IMG_PIXELS(const char msg[], const vImage_Buffer *image)
{
    const void *pixels = image->data;
    const size_t pixelSize = image->rowBytes / image->width;
    const size_t width = image->width;
    const size_t height = image->height;

    DUMP_PIXELS(msg, pixels, pixelSize, width, height);
}

static void
PRINT_CGSTATES_INFO(const CGContextRef cgRef)
{
    // TODO(cpc): lots of SPI use in this method; remove/rewrite?
#if 0
    CGRect clip = CGContextGetClipBoundingBox(cgRef);
    fprintf(stderr, "    clip: ((%f, %f), (%f, %f))\n",
            clip.origin.x, clip.origin.y, clip.size.width, clip.size.height);

    CGAffineTransform ctm = CGContextGetCTM(cgRef);
    fprintf(stderr, "    ctm: (%f, %f, %f, %f, %f, %f)\n",
            ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);

    CGAffineTransform txtTx = CGContextGetTextMatrix(cgRef);
    fprintf(stderr, "    txtTx: (%f, %f, %f, %f, %f, %f)\n",
            txtTx.a, txtTx.b, txtTx.c, txtTx.d, txtTx.tx, txtTx.ty);

    if (CGContextIsPathEmpty(cgRef) == 0) {
        CGPoint pathpoint = CGContextGetPathCurrentPoint(cgRef);
        CGRect pathbbox = CGContextGetPathBoundingBox(cgRef);
        fprintf(stderr, "    [pathpoint: (%f, %f)] [pathbbox: ((%f, %f), (%f, %f))]\n",
                pathpoint.x, pathpoint.y, pathbbox.origin.x, pathbbox.origin.y,
                pathbbox.size.width, pathbbox.size.width);
    }

    CGFloat linewidth = CGContextGetLineWidth(cgRef);
    CGLineCap linecap = CGContextGetLineCap(cgRef);
    CGLineJoin linejoin = CGContextGetLineJoin(cgRef);
    CGFloat miterlimit = CGContextGetMiterLimit(cgRef);
    size_t dashcount = CGContextGetLineDashCount(cgRef);
    fprintf(stderr, "    [linewidth: %f] [linecap: %d] [linejoin: %d] [miterlimit: %f] [dashcount: %lu]\n",
            linewidth, linecap, linejoin, miterlimit, (unsigned long)dashcount);

    CGFloat smoothness = CGContextGetSmoothness(cgRef);
    bool antialias = CGContextGetShouldAntialias(cgRef);
    bool smoothfont = CGContextGetShouldSmoothFonts(cgRef);
    JRSFontRenderingStyle fRendMode = CGContextGetFontRenderingMode(cgRef);
    fprintf(stderr, "    [smoothness: %f] [antialias: %d] [smoothfont: %d] [fontrenderingmode: %d]\n",
            smoothness, antialias, smoothfont, fRendMode);
#endif
}
#endif

#ifdef CGGI_DEBUG

static void
DUMP_GLYPHINFO(const GlyphInfo *info)
{
    printf("size: (%d, %d) pixelSize: %d\n",
           info->width, info->height, info->rowBytes / info->width);
    printf("adv: (%f, %f) top: (%f, %f)\n",
           info->advanceX, info->advanceY, info->topLeftX, info->topLeftY);

#ifdef CGGI_DEBUG_DUMP
    DUMP_PIXELS("Glyph Info Struct",
                info->image, info->rowBytes / info->width,
                info->width, info->height);
#endif
}

#endif


#pragma mark --- Font Rendering Mode Descriptors ---
static Int32 reverseGamma = 0;

static UInt8 reverseGammaLut[256] = { 0 };

static inline UInt8* getReverseGammaLut() {
    if (reverseGamma == 0) {
        // initialize gamma lut
        double gamma;
        int i;
        const char* pGammaEnv = getenv("J2D_LCD_REVERSE_GAMMA");
        if (pGammaEnv != NULL) {
            reverseGamma = atol(pGammaEnv);
        }
        
        if (reverseGamma < 100 || reverseGamma > 250) {
            reverseGamma = 180;
        }
        
        gamma = 100.0 / reverseGamma;
        for (i = 0; i < 256; i++) {
            double x = ((double)i) / 255.0;
            reverseGammaLut[i] = (UInt8)(255 * pow(x, gamma));
        }
    }
    return reverseGammaLut;
}

static inline void
CGGI_CopyARGBPixelToRGBPixel(const UInt32 p, UInt8 *dst)
{
    UInt8* lut = getReverseGammaLut();
    
    *(dst + 0) = lut[0xFF - (p >> 16 & 0xFF)];  // red
    *(dst + 1) = lut[0xFF - (p >>  8 & 0xFF)];  // green
    *(dst + 2) = lut[0xFF - (p & 0xFF)];        // blue
}

static void
CGGI_CopyImageFromCanvasToRGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
{
    UInt32 *src = (UInt32 *)canvas->image->data;
    size_t srcRowWidth = canvas->image->width;

    UInt8 *dest = (UInt8 *)info->image;
    size_t destRowWidth = info->width;

    size_t height = info->height;

    size_t y;
    
    // fill empty glyph image with black-on-white glyph
    for (y = 0; y < height; y++) {
        size_t destRow = y * destRowWidth * 3;
        size_t srcRow = y * srcRowWidth;

        size_t x;
        for (x = 0; x < destRowWidth; x++) {
            CGGI_CopyARGBPixelToRGBPixel(src[srcRow + x],
                                         dest + destRow + x * 3);
        }
    }
}

//static void CGGI_copyImageFromCanvasToAlphaInfo
//(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
//{
//    vImage_Buffer infoBuffer;
//    infoBuffer.data = info->image;
//    infoBuffer.width = info->width;
//    infoBuffer.height = info->height;
//    infoBuffer.rowBytes = info->width; // three bytes per RGB pixel
//
//    UInt8 scrapPixel[info->width * info->height];
//    vImage_Buffer scrapBuffer;
//    scrapBuffer.data = &scrapPixel;
//    scrapBuffer.width = info->width;
//    scrapBuffer.height = info->height;
//    scrapBuffer.rowBytes = info->width;
//
//    vImageConvert_ARGB8888toPlanar8(canvas->image, &infoBuffer,
//        &scrapBuffer, &scrapBuffer, &scrapBuffer, kvImageNoFlags);
//}

static inline UInt8
CGGI_ConvertBWPixelToByteGray(UInt32 p)
{
    return 0xFF - (((p >> 24 & 0xFF) + (p >> 16 & 0xFF) + (p >> 8 & 0xFF)) / 3);
}

static void
CGGI_CopyImageFromCanvasToAlphaInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
{
    UInt32 *src = (UInt32 *)canvas->image->data;
    size_t srcRowWidth = canvas->image->width;

    UInt8 *dest = (UInt8 *)info->image;
    size_t destRowWidth = info->width;

    size_t height = info->height;

    size_t y;
    
    // fill empty glyph image with black-on-white glyph
    for (y = 0; y < height; y++) {
        size_t destRow = y * destRowWidth;
        size_t srcRow = y * srcRowWidth;
        size_t x;
        for (x = 0; x < destRowWidth; x++) {
            UInt32 p = src[srcRow + x];
            dest[destRow + x] = CGGI_ConvertBWPixelToByteGray(p);
        }
    }
}

static void
CGGI_CopyImageFromCanvasToARGBInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
{
    CGBitmapInfo bitmapInfo = CGBitmapContextGetBitmapInfo(canvas->context);
    bool littleEndian = (bitmapInfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Little;

    UInt32 *src = (UInt32 *)canvas->image->data;
    size_t srcRowWidth = canvas->image->width;

    UInt8 *dest = (UInt8 *)info->image;
    size_t destRowWidth = info->width;

    size_t height = info->height;

    size_t y;

    for (y = 0; y < height; y++) {
        size_t srcRow = y * srcRowWidth;
        if (littleEndian) {
            UInt16 destRowBytes = info->rowBytes;
            memcpy(dest, src + srcRow, destRowBytes);
            dest += destRowBytes;
        } else {
            size_t x;
            for (x = 0; x < destRowWidth; x++) {
                UInt32 p = src[srcRow + x];
                *dest++ = (p >> 24  & 0xFF); // blue  (alpha-premultiplied)
                *dest++ = (p >> 16 & 0xFF); // green (alpha-premultiplied)
                *dest++ = (p >> 8   & 0xFF); // red   (alpha-premultiplied)
                *dest++ = (p & 0xFF); // alpha
            }
        }
    }
}

#pragma mark --- Pixel Size, Modes, and Canvas Shaping Helper Functions ---

typedef struct CGGI_GlyphInfoDescriptor {
    size_t pixelSize;
    void (*copyFxnPtr)(CGGI_GlyphCanvas *canvas, GlyphInfo *info);
} CGGI_GlyphInfoDescriptor;

typedef struct CGGI_RenderingMode {
    CGGI_GlyphInfoDescriptor *glyphDescriptor;
    JRSFontRenderingStyle cgFontMode;
} CGGI_RenderingMode;

static CGGI_GlyphInfoDescriptor grey =
    { 1, &CGGI_CopyImageFromCanvasToAlphaInfo };
static CGGI_GlyphInfoDescriptor rgb =
    { 3, &CGGI_CopyImageFromCanvasToRGBInfo };
static CGGI_GlyphInfoDescriptor argb =
    { 4, &CGGI_CopyImageFromCanvasToARGBInfo };

static CFStringRef EMOJI_FONT_NAME = CFSTR("Apple Color Emoji");

bool CGGI_IsColorFont(CGFontRef font)
{
    CFStringRef name = CGFontCopyFullName(font);
    if (name == NULL) return false;
    bool isFixedColor = CFStringCompare(name, EMOJI_FONT_NAME, 0) == kCFCompareEqualTo;
    CFRelease(name);
    return isFixedColor;
}

static inline CGGI_GlyphInfoDescriptor*
CGGI_GetGlyphInfoDescriptor(const CGGI_RenderingMode *mode, CGFontRef font)
{
    bool isFixedColor = CGGI_IsColorFont(font);
    return isFixedColor ? &argb : mode->glyphDescriptor;
}

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_OFF:
    case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_ON:
        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:
        /* we expect that text antialiasing hint has been already
         * evaluated. Report an error if we get 'unevaluated' hint here.
         */
        e = [NSException
                exceptionWithName:@"IllegalArgumentException"
                reason:@"Invalid hint value"
                userInfo:nil];
        @throw e;
    }

    return mode;
}


#pragma mark --- Canvas Managment ---

/*
 * 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 CGGI_RenderingMode* mode)
{
    // our canvas is *always* 4-byte ARGB
    size_t bytesPerRow = width * sizeof(UInt32);
    size_t byteCount = bytesPerRow * height;

    canvas->image = malloc(sizeof(vImage_Buffer));
    canvas->image->width = width;
    canvas->image->height = height;
    canvas->image->rowBytes = bytesPerRow;

    canvas->image->data = (void *)calloc(byteCount, sizeof(UInt8));
    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(kCGColorSpaceSRGB);
    canvas->context = CGBitmapContextCreate(canvas->image->data,
                                            width, height, 8, bytesPerRow,
                                            colorSpace,
                                            bmpInfo);

    // set foreground color
    CGContextSetRGBFillColor(canvas->context, 0.0f, 0.0f, 0.0f, 1.0f);
    
    CGContextSetFontSize(canvas->context, 1);
    CGContextSaveGState(canvas->context);

    CGColorSpaceRelease(colorSpace);
}

/*
 * Releases the BitmapContext and the associated memory backing it.
 */
static inline void
CGGI_FreeCanvas(CGGI_GlyphCanvas *canvas)
{
    if (canvas->context != NULL) {
        CGContextRelease(canvas->context);
    }

    if (canvas->image != NULL) {
        if (canvas->image->data != NULL) {
            free(canvas->image->data);
        }
        free(canvas->image);
    }
}

/*
 * This is the slack space that is preallocated for the global GlyphCanvas
 * when it needs to be expanded. It has been set somewhat liberally to
 * avoid re-upsizing frequently.
 */
#define CGGI_GLYPH_CANVAS_SLACK 2.5

/*
 * 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 CGGI_RenderingMode* mode)
{
    if (canvas->image != NULL &&
        width  < canvas->image->width &&
        height < canvas->image->height)
    {
        return;
    }

    // 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,
                    mode);
    JRSFontSetRenderingStyleOnContext(canvas->context, mode->cgFontMode);
}

/*
 * Clear the canvas by blitting white (or transparent background for color glyphs) only into the region of interest
 * (the rect which we will copy out of once the glyph is struck).
 */
static inline void
CGGI_ClearCanvas(CGGI_GlyphCanvas *canvas, GlyphInfo *info, bool transparent)
{
    vImage_Buffer canvasRectToClear;
    canvasRectToClear.data = canvas->image->data;
    canvasRectToClear.height = info->height;
    canvasRectToClear.width = info->width;
    // use the row stride of the canvas, not the info
    canvasRectToClear.rowBytes = canvas->image->rowBytes;

    // clean the canvas
#ifdef CGGI_DEBUG
    Pixel_8888 background = { 0xE0, 0xE0, 0xE0, 0xE0 };
#else
    Pixel_8888 background = { transparent ? 0 : 0xFF,
                               transparent ? 0 : 0xFF,
                               transparent ? 0 : 0xFF,
                               transparent ? 0 : 0xFF };
#endif

    // clear canvas background
    vImageBufferFill_ARGB8888(&canvasRectToClear, background, kvImageNoFlags);
}


#pragma mark --- GlyphInfo Creation & Copy Functions ---

static inline CGSize CGGI_ScaleAdvance(CGSize advance, const AWTStrike *strike) {
    advance = CGSizeApplyAffineTransform(advance, strike->fFontTx);
    if (!JRSFontStyleUsesFractionalMetrics(strike->fStyle)) {
        advance.width = round(advance.width);
        advance.height = round(advance.height);
    }
    advance = CGSizeApplyAffineTransform(advance, strike->fDevTx);
    return advance;
}

/*
 * Creates a GlyphInfo with exactly the correct size image and measurements.
 */
#define CGGI_GLYPH_BBOX_PADDING 2.0f
static inline GlyphInfo *
CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
                            const AWTStrike *strike,
                            const CGGI_GlyphInfoDescriptor *glyphDescriptor)
{
    size_t pixelSize = glyphDescriptor->pixelSize;

    // adjust the bounding box to be 1px bigger on each side than what
    // CGFont-whatever suggests - because it gives a bounding box that
    // is too tight
    bbox.size.width += CGGI_GLYPH_BBOX_PADDING * 2.0f;
    bbox.size.height += CGGI_GLYPH_BBOX_PADDING * 2.0f;
    bbox.origin.x -= CGGI_GLYPH_BBOX_PADDING;
    bbox.origin.y -= CGGI_GLYPH_BBOX_PADDING;

    vImagePixelCount width = ceilf(bbox.size.width);
    vImagePixelCount height = ceilf(bbox.size.height);

    // if the glyph is larger than 1MB, don't even try...
    // the GlyphVector path should have taken over by now
    // and zero pixels is ok
    if (width * height > 1024 * 1024) {
        width = 1;
        height = 1;
    }
    advance = CGGI_ScaleAdvance(advance, strike);

    int imageBytes = height * width * pixelSize;
    int extraPixelStorage = (strike->fAAStyle == sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_HRGB &&
                             strike->fFmHint == sun_awt_SunHints_INTVAL_FRACTIONALMETRICS_ON) ? 3 : 0;

#ifdef USE_IMAGE_ALIGNED_MEMORY
    // create separate memory
    GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo));
    void *image = (void *)malloc(imageBytes + extraPixelStorage);
#else
    // create a GlyphInfo struct fused to the image it points to
    GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo) + imageBytes + extraPixelStorage);
#endif

    glyphInfo->advanceX = advance.width;
    glyphInfo->advanceY = advance.height;
    glyphInfo->topLeftX = round(bbox.origin.x);
    glyphInfo->topLeftY = round(bbox.origin.y);
    glyphInfo->width = width;
    glyphInfo->height = height;
    glyphInfo->rowBytes = width * pixelSize;
    glyphInfo->cellInfo = NULL;

#ifdef USE_IMAGE_ALIGNED_MEMORY
    glyphInfo->image = image;
#else
    glyphInfo->image = ((void *)glyphInfo) + sizeof(GlyphInfo);
#endif

    int i;
    for (i = 0; i < extraPixelStorage; i++) (glyphInfo->image)[imageBytes + i] = 0;

    return glyphInfo;
}


#pragma mark --- Glyph Striking onto Canvas ---

/*
 * Clears the canvas, strikes the glyph with CoreGraphics, and then
 * copies the struck pixels into the GlyphInfo image.
 */
static inline void
CGGI_CreateImageForGlyph
    (CGFontRef cgFont, CGGI_GlyphCanvas *canvas, const CGGlyph glyph,
     GlyphInfo *info, const CGGI_GlyphInfoDescriptor *glyphDescriptor, const AWTStrike *strike,
     const bool isCatalinaOrAbove)
{
    if (isnan(info->topLeftX) || isnan(info->topLeftY)) {
        // Explicitly set glyphInfo width/height to be 0 to ensure
        // zero length glyph image is copied into GlyphInfo from canvas
        info->width = 0;
        info->height = 0;

        // copy the "empty" glyph from the canvas into the info
        (*glyphDescriptor->copyFxnPtr)(canvas, info);
        return;
    }

    // clean the canvas
    CGGI_ClearCanvas(canvas, info, glyphDescriptor == &argb);

    // strike the glyph in the upper right corner
    CGFloat x = -info->topLeftX;
    CGFloat y = canvas->image->height + info->topLeftY;

    if (isCatalinaOrAbove || glyphDescriptor == &argb) {
        CGAffineTransform matrix = CGContextGetTextMatrix(canvas->context);
        CGFloat fontSize = sqrt(fabs(matrix.a * matrix.d - matrix.b * matrix.c));
        CTFontRef font = CTFontCreateWithGraphicsFont(cgFont, fontSize, NULL, NULL);

        CGFloat normFactor = 1.0 / fontSize;
        CGAffineTransform normMatrix = CGAffineTransformScale(matrix, normFactor, normFactor);
        CGContextSetTextMatrix(canvas->context, normMatrix);

        CGPoint userPoint = CGPointMake(x, y);
        CGAffineTransform invNormMatrix = CGAffineTransformInvert(normMatrix);
        CGPoint textPoint = CGPointApplyAffineTransform(userPoint, invNormMatrix);

        CTFontDrawGlyphs(font, &glyph, &textPoint, 1, canvas->context);

        // CTFontGetAdvancesForGlyphs returns rounded advance for emoji font, so it can be calculated only here
        // where CTFont instance with actual size is available
        CGSize advance;
        CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &glyph, &advance, 1);
        advance.width /= fontSize;
        advance.height /= fontSize;
        advance = CGGI_ScaleAdvance(advance, strike);
        info->advanceX = advance.width;
        info->advanceY = advance.height;

        CFRelease(font);
        // restore context's original state
        CGContextSetTextMatrix(canvas->context, matrix);
        CGContextSetFontSize(canvas->context, 1);
    } else {
        // old procedure is faster, so we use it by default
        CGContextShowGlyphsAtPoint(canvas->context, x, y, &glyph, 1);
    }

    // copy the glyph from the canvas into the info
    (*glyphDescriptor->copyFxnPtr)(canvas, info);
}

/*
 * CoreText path...
 */
static inline GlyphInfo *
CGGI_CreateImageForUnicode
    (CGGI_GlyphCanvas *canvas, const AWTStrike *strike,
     const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar,
     const bool isCatalinaOrAbove)
{
    // save the state of the world
    CGContextSaveGState(canvas->context);

    // get the glyph, measure it using CG
    CGGlyph glyph;
    CTFontRef fallback;
    if (uniChar > 0xFFFF) {
        UTF16Char charRef[2];
        CTS_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
        CGGlyph glyphTmp[2];
        fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
        glyph = glyphTmp[0];
    } else {
        UTF16Char charRef;
        charRef = (UTF16Char) uniChar; // truncate.
        fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
    }

    CGAffineTransform tx = strike->fTx;
    JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);

    CGRect bbox;
    JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &tx, style, &glyph, 1, &bbox);

    CGSize advance;
    CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);

    const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
    CGGI_GlyphInfoDescriptor *glyphDescriptor = CGGI_GetGlyphInfoDescriptor(mode, cgFallback);

    // create the Sun2D GlyphInfo we are going to strike into
    GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, glyphDescriptor);

    // fix the context size, just in case the substituted character is unexpectedly large
    CGGI_SizeCanvas(canvas, info->width, info->height, mode);

    // align the transform for the real CoreText strike
    CGContextSetTextMatrix(canvas->context, strike->fAltTx);

    CGContextSetFont(canvas->context, cgFallback);
    CFRelease(cgFallback);

    // clean the canvas - align, strike, and copy the glyph from the canvas into the info
    CGGI_CreateImageForGlyph(cgFallback, canvas, glyph, info, glyphDescriptor, strike, isCatalinaOrAbove);

    // restore the state of the world
    CGContextRestoreGState(canvas->context);

    CFRelease(fallback);
#ifdef CGGI_DEBUG
    DUMP_GLYPHINFO(info);
#endif

#ifdef CGGI_DEBUG_DUMP
    DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
#if 0
    PRINT_CGSTATES_INFO(NULL);
#endif
#endif

    return info;
}


#pragma mark --- GlyphInfo Filling and Canvas Managment ---

/*
 * Sets all the per-run properties for the canvas, and then iterates through
 * the character run, and creates images in the GlyphInfo structs.
 *
 * Not inlined because it would create two copies in the function below
 */
static void
CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
                                        const AWTStrike *strike,
                                        const CGGI_RenderingMode *mode,
                                        jlong glyphInfos[],
                                        const UnicodeScalarValue uniChars[],
                                        const CGGlyph glyphs[],
                                        const CFIndex len)
{
    CGContextSetTextMatrix(canvas->context, strike->fAltTx);

    CGContextSetFont(canvas->context, strike->fAWTFont->fNativeCGFont);
    JRSFontSetRenderingStyleOnContext(canvas->context, strike->fStyle);

    CGGI_GlyphInfoDescriptor* mainFontDescriptor = CGGI_GetGlyphInfoDescriptor(mode, strike->fAWTFont->fNativeCGFont);

    const bool isMojaveOrAbove = IS_OSX_GT10_13;
    CFIndex i;
    for (i = 0; i < len; i++) {
        GlyphInfo *info = (GlyphInfo *)jlong_to_ptr(glyphInfos[i]);
        if (info != NULL) {
            CGGI_CreateImageForGlyph(strike->fAWTFont->fNativeCGFont,
                                     canvas, glyphs[i], info, mainFontDescriptor, strike, isMojaveOrAbove);
        } else {
            info = CGGI_CreateImageForUnicode(canvas, strike, mode, uniChars[i], isMojaveOrAbove);
            glyphInfos[i] = ptr_to_jlong(info);
        }
#ifdef CGGI_DEBUG
        DUMP_GLYPHINFO(info);
#endif

#ifdef CGGI_DEBUG_DUMP
        DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
#endif
    }
#ifdef CGGI_DEBUG_DUMP
    DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
    PRINT_CGSTATES_INFO(canvas->context);
#endif
}

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.
 */
#define CGGI_GLYPH_CANVAS_MAX 100

/*
 * Based on the space needed to strike the largest character in the run,
 * either use the global shared canvas, or make one up on the spot, strike
 * the glyphs, and destroy it.
 */
static inline void
CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
                         const CGGI_RenderingMode *mode,
                         const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
                         const size_t maxWidth, const size_t maxHeight,
                         const CFIndex len)
{
    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, mode);
        CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
                mode, glyphInfos, uniChars,
                glyphs, len);
        CGGI_FreeCanvas(tmpCanvas);

        [tmpCanvas release];
        return;
    }
    NSMutableDictionary *threadDict =
        [[NSThread currentThread] threadDictionary];

    NSString* theKey = (mode->glyphDescriptor == &rgb) ?
        threadLocalLCDCanvasKey : threadLocalAACanvasKey;

    CGGI_GlyphCanvas *canvas = [threadDict objectForKey:theKey];
    if (canvas == nil) {
        canvas = [[CGGI_GlyphCanvas alloc] init];
        [threadDict setObject:canvas forKey:theKey];
    }

    CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
    CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
                                            glyphInfos, uniChars, glyphs, len);
}

/*
 * Finds the advances and bounding boxes of the characters in the run,
 * cycles through all the bounds and calculates the maximum canvas space
 * required by the largest glyph.
 *
 * Creates a GlyphInfo struct with a malloc that also encapsulates the
 * image the struct points to.  This is done to meet memory layout
 * expectations in the Sun text rasterizer memory managment code.
 * The image immediately follows the struct physically in memory.
 */
static inline void
CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
                      const CGGI_RenderingMode *mode,
                      const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
                      CGSize advances[], CGRect bboxes[], const CFIndex len)
{
    AWTFont *font = strike->fAWTFont;
    CGAffineTransform tx = strike->fTx;
    JRSFontRenderingStyle bboxCGMode = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);

    JRSFontGetBoundingBoxesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, bboxCGMode, glyphs, len, bboxes);
    CTFontGetAdvancesForGlyphs((CTFontRef)font->fFont, kCTFontDefaultOrientation, glyphs, advances, len);

    size_t maxWidth = 1;
    size_t maxHeight = 1;

    CGGI_GlyphInfoDescriptor* mainFontDescriptor = CGGI_GetGlyphInfoDescriptor(mode, strike->fAWTFont->fNativeCGFont);

    CFIndex i;
    for (i = 0; i < len; i++)
    {
        if (uniChars[i] != 0)
        {
            glyphInfos[i] = 0L;
            continue; // will be handled later
        }

        CGSize advance = advances[i];
        CGRect bbox = bboxes[i];

        GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mainFontDescriptor);

        if (maxWidth < glyphInfo->width)   maxWidth = glyphInfo->width;
        if (maxHeight < glyphInfo->height) maxHeight = glyphInfo->height;

        glyphInfos[i] = ptr_to_jlong(glyphInfo);
    }

    CGGI_FillImagesForGlyphs(glyphInfos, strike, mode, uniChars,
                             glyphs, maxWidth, maxHeight, len);
}


#pragma mark --- Temporary Buffer Allocations and Initialization ---

/*
 * This stage separates the already valid glyph codes from the unicode values
 * that need special handling - the rawGlyphCodes array is no longer used
 * after this stage.
 */
static void
CGGI_CreateGlyphsAndScanForComplexities(jlong *glyphInfos,
                                        const AWTStrike *strike,
                                        const CGGI_RenderingMode *mode,
                                        jint rawGlyphCodes[],
                                        UnicodeScalarValue uniChars[], CGGlyph glyphs[],
                                        CGSize advances[], CGRect bboxes[],
                                        const CFIndex len)
{
    CFIndex i;
    for (i = 0; i < len; i++) {
        jint code = rawGlyphCodes[i];
        if (code < 0) {
            glyphs[i] = 0;
            uniChars[i] = -code;
        } else {
            glyphs[i] = code;
            uniChars[i] = 0;
        }
    }

    CGGI_CreateGlyphInfos(glyphInfos, strike, mode,
                          uniChars, glyphs, advances, bboxes, len);

#ifdef CGGI_DEBUG_HIT_COUNT
    static size_t hitCount = 0;
    hitCount++;
    printf("%d\n", (int)hitCount);
#endif
}

/*
 * Conditionally stack allocates buffers for glyphs, bounding boxes,
 * and advances.  Unfortunately to use CG or CT in bulk runs (which is
 * faster than calling them per character), we have to copy into and out
 * of these buffers. Still a net win though.
 */
void
CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[],
                                const AWTStrike *strike,
                                jint rawGlyphCodes[], const CFIndex len)
{
    const CGGI_RenderingMode mode = CGGI_GetRenderingMode(strike);

    if (len < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE) {
        CGRect bboxes[len];
        CGSize advances[len];
        CGGlyph glyphs[len];
        UnicodeScalarValue uniChars[len];

        CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
                                                rawGlyphCodes, uniChars, glyphs,
                                                advances, bboxes, len);

        return;
    }

    // just do one malloc, and carve it up for all the buffers
    void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) *
                          sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len);
    if (buffer == NULL) {
        [[NSException exceptionWithName:NSMallocException
            reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise];
    }

    CGRect *bboxes = (CGRect *)(buffer);
    CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len);
    CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len);
    UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len);

    CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
                                            rawGlyphCodes, uniChars, glyphs,
                                            advances, bboxes, len);

    free(buffer);
}
