/*
 * 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.
 */

//  Native side of the Quartz text pipe, paints on Quartz Surface Datas.
//  Interesting Docs : /Developer/Documentation/Cocoa/TasksAndConcepts/ProgrammingTopics/FontHandling/FontHandling.html

#import "sun_awt_SunHints.h"
#import "sun_lwawt_macosx_CTextPipe.h"
#import "sun_java2d_OSXSurfaceData.h"

#import <JavaNativeFoundation/JavaNativeFoundation.h>

#import "CoreTextSupport.h"
#import "QuartzSurfaceData.h"
#include "AWTStrike.h"

/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
    #define THIS_FILE __FILE__
#endif

static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };


#pragma mark --- CoreText Support ---


// Translates a Unicode into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyphRef"
CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForUnicode
(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
    CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, charRef, count);
    if (fallback == NULL)
    {
        // use the original font if we somehow got duped into trying to fallback something we can't
        fallback = (CTFontRef)font->fFont;
        CFRetain(fallback);
    }

    CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
    return fallback;
}

// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyph"
CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForJavaGlyphCode
(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
{
    // negative glyph codes are really unicodes, which were placed there by the mapper
    // to indicate we should use CoreText to substitute the character
    if (glyphCode >= 0)
    {
        *glyphRef = glyphCode;
        CFRetain(font->fFont);
        return (CTFontRef)font->fFont;
    }

    UTF16Char character = -glyphCode;
    return JavaCT_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
}

// Breakup a 32 bit unicode value into the component surrogate pairs
void JavaCT_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
    int value = uniChar - 0x10000;
    UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
    UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
    charRef[0] = high_surrogate;
    charRef[1] = low_surrogate;
}



/*
 * Callback for CoreText which uses the CoreTextProviderStruct to feed CT UniChars
 * We only use it for one-off lines, and don't attempt to fragment our strings
 */
const UniChar *Java_CTProvider
(CFIndex stringIndex, CFIndex *charCount, CFDictionaryRef *attributes, void *refCon)
{
    // if we have a zero length string we can just return NULL for the string
    // or if the index anything other than 0 we are not using core text
    // correctly since we only have one run.
    if (stringIndex != 0)
    {
        return NULL;
    }

    CTS_ProviderStruct *ctps = (CTS_ProviderStruct *)refCon;
    *charCount = ctps->length;
    *attributes = ctps->attributes;
    return ctps->unicodes;
}


/*
 *    Gets a Dictionary filled with common details we want to use for CoreText when we are interacting
 *    with it from Java.
 */
static NSDictionary* ctsDictionaryFor(const NSFont *font, BOOL useFractionalMetrics)
{
    NSNumber *gZeroNumber = [NSNumber numberWithInt:0];
    NSNumber *gOneNumber = [NSNumber numberWithInt:1];

    return [NSDictionary dictionaryWithObjectsAndKeys:
             font, NSFontAttributeName,
             gOneNumber,  (id)kCTForegroundColorFromContextAttributeName,
             useFractionalMetrics ? gZeroNumber : gOneNumber, @"CTIntegerMetrics", // force integer hack in CoreText to help with Java's integer assumptions
             gZeroNumber, NSLigatureAttributeName,
             gZeroNumber, NSKernAttributeName,
             nil];
}

// Itterates though each glyph, and if a transform is present for that glyph, apply it to the CGContext, and strike the glyph.
// If there is no per-glyph transform, just strike the glyph. Advances must also be transformed on-the-spot as well.
void JavaCT_DrawGlyphVector
(const QuartzSDOps *qsdo, const AWTStrike *strike, const BOOL useSubstituion, const int uniChars[], const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
{
    CGPoint pt = { 0, 0 };

    // get our baseline transform and font
    CGContextRef cgRef = qsdo->cgRef;
    CGAffineTransform ctmText = CGContextGetTextMatrix(cgRef);

    BOOL saved = false;

    CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);

    NSInteger i;
    for (i = 0; i < length; i++)
    {
        CGGlyph glyph = glyphs[i];
        int uniChar = uniChars[i];
        // if we found a unichar instead of a glyph code, get the fallback font,
        // find the glyph code for the fallback font, and set the font on the current context
        if (uniChar != 0)
        {
            CTFontRef fallback;
            if (uniChar > 0xFFFF) {
                UTF16Char charRef[2];
                JavaCT_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
                CGGlyph glyphTmp[2];
                fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
                glyph = glyphTmp[0];
            } else {
                const UTF16Char u = uniChar;
                fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, &u, (CGGlyph *)&glyph, 1);
            }
            if (fallback) {
                const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
                CFRelease(fallback);

                if (cgFallback) {
                    if (!saved) {
                        CGContextSaveGState(cgRef);
                        saved = true;
                    }
                    CGContextSetFont(cgRef, cgFallback);
                    CFRelease(cgFallback);
                }
            }
        } else {
            if (saved) {
                CGContextRestoreGState(cgRef);
                saved = false;
            }
        }

        // if we have per-glyph transformations
        int tin = (g_gvTXIndicesAsInts == NULL) ? -1 : (g_gvTXIndicesAsInts[i] - 1) * 6;
        if (tin < 0)
        {
            CGContextShowGlyphsAtPoint(cgRef, pt.x, pt.y, &glyph, 1);
        }
        else
        {
            CGAffineTransform tx = CGAffineTransformMake(
                                                         (CGFloat)g_gvTransformsAsDoubles[tin + 0], (CGFloat)g_gvTransformsAsDoubles[tin + 2],
                                                         (CGFloat)g_gvTransformsAsDoubles[tin + 1], (CGFloat)g_gvTransformsAsDoubles[tin + 3],
                                                         0, 0);

            CGPoint txOffset = { (CGFloat)g_gvTransformsAsDoubles[tin + 4], (CGFloat)g_gvTransformsAsDoubles[tin + 5] };

            txOffset = CGPointApplyAffineTransform(txOffset, invTx);

            // apply the transform, strike the glyph, can change the transform back
            CGContextSetTextMatrix(cgRef, CGAffineTransformConcat(ctmText, tx));
            CGContextShowGlyphsAtPoint(cgRef, txOffset.x + pt.x, txOffset.y + pt.y, &glyph, 1);
            CGContextSetTextMatrix(cgRef, ctmText);

            // transform the measured advance for this strike
            advances[i] = CGSizeApplyAffineTransform(advances[i], tx);
            advances[i].width += txOffset.x;
            advances[i].height += txOffset.y;
        }

        // move our next x,y
        pt.x += advances[i].width;
        pt.y += advances[i].height;

    }
    // reset the font on the context after striking a unicode with CoreText
    if (saved) {
        CGContextRestoreGState(cgRef);
    }
}

// Using the Quartz Surface Data context, draw a hot-substituted character run
void JavaCT_DrawTextUsingQSD(JNIEnv *env, const QuartzSDOps *qsdo, const AWTStrike *strike, const jchar *chars, const jsize length)
{
    CGContextRef cgRef = qsdo->cgRef;

    AWTFont *awtFont = strike->fAWTFont;
    CGFloat ptSize = strike->fSize;
    CGAffineTransform tx = strike->fFontTx;

    NSFont *nsFont = [NSFont fontWithName:[awtFont->fFont fontName] size:ptSize];

    if (ptSize != 0) {
        CGFloat invScale = 1 / ptSize;
        tx = CGAffineTransformConcat(tx, CGAffineTransformMakeScale(invScale, invScale));
        CGContextConcatCTM(cgRef, tx);
    }

    CGContextSetTextMatrix(cgRef, CGAffineTransformIdentity); // resets the damage from CoreText

    NSString *string = [NSString stringWithCharacters:chars length:length];
    /*
       The calls below were used previously but for unknown reason did not 
       render using the right font (see bug 7183516) when attribString is not 
       initialized with font dictionary attributes.  It seems that "options" 
       in CTTypesetterCreateWithAttributedStringAndOptions which contains the 
       font dictionary is ignored.

    NSAttributedString *attribString = [[NSAttributedString alloc] initWithString:string];

    CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedStringAndOptions((CFAttributedStringRef) attribString, (CFDictionaryRef) ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle)));
    */
    NSAttributedString *attribString = [[NSAttributedString alloc]
        initWithString:string
        attributes:ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle))];
    
    CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedString((CFAttributedStringRef) attribString);

    CFRange range = {0, length};
    CTLineRef lineRef = CTTypesetterCreateLine(typeSetterRef, range);

    CTLineDraw(lineRef, cgRef);

    [attribString release];
    CFRelease(lineRef);
    CFRelease(typeSetterRef);
}


/*----------------------
    DrawTextContext is the funnel for all of our CoreText drawing.
    All three JNI apis call through this method.
 ----------------------*/
static void DrawTextContext
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, const jchar *chars, const jsize length, const jdouble x, const jdouble y)
{
    if (length == 0)
    {
        return;
    }

    qsdo->BeginSurface(env, qsdo, SD_Text);
    if (qsdo->cgRef == NULL)
    {
        qsdo->FinishSurface(env, qsdo);
        return;
    }

    CGContextRef cgRef = qsdo->cgRef;


    CGContextSaveGState(cgRef);
    JRSFontSetRenderingStyleOnContext(cgRef, strike->fStyle);

    // we want to translate before we transform (scale or rotate) <rdar://4042541> (vm)
    CGContextTranslateCTM(cgRef, x, y);

    AWTFont *awtfont = strike->fAWTFont; //(AWTFont *)(qsdo->fontInfo.awtfont);
    NSCharacterSet *charSet = [awtfont->fFont coveredCharacterSet];

    JavaCT_DrawTextUsingQSD(env, qsdo, strike, chars, length);   // Draw with CoreText

    CGContextRestoreGState(cgRef);

    qsdo->FinishSurface(env, qsdo);
}

#pragma mark --- Glyph Vector Pipeline ---

/*-----------------------------------
    Glyph Vector Pipeline

    doDrawGlyphs() has been separated into several pipelined functions to increase performance,
    and improve accountability for JNI resources, malloc'd memory, and error handling.

    Each stage of the pipeline is responsible for doing only one major thing, like allocating buffers,
    aquiring transform arrays from JNI, filling buffers, or striking glyphs. All resources or memory
    acquired at a given stage, must be released in that stage. Any error that occurs (like a failed malloc)
    is to be handled in the stage it occurs in, and is to return immediatly after freeing it's resources.

-----------------------------------*/

static JNF_CLASS_CACHE(jc_StandardGlyphVector, "sun/font/StandardGlyphVector");

// Checks the GlyphVector Java object for any transforms that were applied to individual characters. If none are present,
// strike the glyphs immediately in Core Graphics. Otherwise, obtain the arrays, and defer to above.
static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, BOOL useSubstituion, int *uniChars, CGGlyph *glyphs, CGSize *advances, size_t length)
{
    // if we have no character substitution, and no per-glyph transformations - strike now!
    static JNF_MEMBER_CACHE(jm_StandardGlyphVector_gti, jc_StandardGlyphVector, "gti", "Lsun/font/StandardGlyphVector$GlyphTransformInfo;");
    jobject gti = JNFGetObjectField(env, gVector, jm_StandardGlyphVector_gti);
    if (gti == 0)
    {
        if (useSubstituion)
        {
            // quasi-simple case, substitution, but no per-glyph transforms
            JavaCT_DrawGlyphVector(qsdo, strike, TRUE, uniChars, glyphs, advances, NULL, NULL, length);
        }
        else
        {
            // fast path, straight to CG without per-glyph transforms
            CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
        }
        return;
    }

    static JNF_CLASS_CACHE(jc_StandardGlyphVector_GlyphTransformInfo, "sun/font/StandardGlyphVector$GlyphTransformInfo");
    static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_transforms, jc_StandardGlyphVector_GlyphTransformInfo, "transforms", "[D");
    jdoubleArray g_gtiTransformsArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_transforms); //(*env)->GetObjectField(env, gti, g_gtiTransforms);
    if (g_gtiTransformsArray == NULL) {
        return;
    } 
    jdouble *g_gvTransformsAsDoubles = (*env)->GetPrimitiveArrayCritical(env, g_gtiTransformsArray, NULL);
    if (g_gvTransformsAsDoubles == NULL) {
        (*env)->DeleteLocalRef(env, g_gtiTransformsArray);
        return;
    } 

    static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_indices, jc_StandardGlyphVector_GlyphTransformInfo, "indices", "[I");
    jintArray g_gtiTXIndicesArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_indices);
    jint *g_gvTXIndicesAsInts = (*env)->GetPrimitiveArrayCritical(env, g_gtiTXIndicesArray, NULL);
    if (g_gvTXIndicesAsInts == NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT);
        (*env)->DeleteLocalRef(env, g_gtiTransformsArray);
        (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
        return;
    }
    // slowest case, we have per-glyph transforms, and possibly glyph substitution as well
    JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);

    (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT);
    (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT);

    (*env)->DeleteLocalRef(env, g_gtiTransformsArray);
    (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
}

// Retrieves advances for translated unicodes
// Uses "glyphs" as a temporary buffer for the glyph-to-unicode translation
void JavaCT_GetAdvancesForUnichars
(const NSFont *font, const int uniChars[], CGGlyph glyphs[], const size_t length, CGSize advances[])
{
    // cycle over each spot, and if we discovered a unicode to substitute, we have to calculate the advance for it
    size_t i;
    for (i = 0; i < length; i++)
    {
        UniChar uniChar = uniChars[i];
        if (uniChar == 0) continue;

        CGGlyph glyph = 0;
        const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font, &uniChar, 1);
        if (fallback) {
            CTFontGetGlyphsForCharacters(fallback, &uniChar, &glyph, 1);
            CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &(advances[i]), 1);
            CFRelease(fallback);
        }

        glyphs[i] = glyph;
    }
}

// Fills the glyph buffer with glyphs from the GlyphVector object. Also checks to see if the glyph's positions have been
// already caculated from GlyphVector, or we simply ask Core Graphics to make some advances for us. Pre-calculated positions
// are translated into advances, since CG only understands advances.
static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, int *uniChars, CGSize *advances, size_t length, jintArray glyphsArray)
{
    // fill the glyph buffer
    jint *glyphsAsInts = (*env)->GetPrimitiveArrayCritical(env, glyphsArray, NULL);
    if (glyphsAsInts == NULL) {
        return;
    }

    // if a glyph code from Java is negative, that means it is really a unicode value
    // which we can use in CoreText to strike the character in another font
    size_t i;
    BOOL complex = NO;
    for (i = 0; i < length; i++)
    {
        jint code = glyphsAsInts[i];
        if (code < 0)
        {
            complex = YES;
            uniChars[i] = -code;
            glyphs[i] = 0;
        }
        else
        {
            uniChars[i] = 0;
            glyphs[i] = code;
        }
    }

    (*env)->ReleasePrimitiveArrayCritical(env, glyphsArray, glyphsAsInts, JNI_ABORT);

    // fill the advance buffer
    static JNF_MEMBER_CACHE(jm_StandardGlyphVector_positions, jc_StandardGlyphVector, "positions", "[F");
    jfloatArray posArray = JNFGetObjectField(env, gVector, jm_StandardGlyphVector_positions);
    jfloat *positions = NULL;
    if (posArray != NULL) {
        // in this case, the positions have already been pre-calculated for us on the Java side
        positions = (*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
        if (positions == NULL) {
            (*env)->DeleteLocalRef(env, posArray);
        }
    }
    if (positions != NULL) {
        CGPoint prev;
        prev.x = positions[0];
        prev.y = positions[1];

        // <rdar://problem/4294061> take the first point, and move the context to that location
        CGContextTranslateCTM(qsdo->cgRef, prev.x, prev.y);

        CGAffineTransform invTx = CGAffineTransformInvert(strike->fFontTx);

        // for each position, figure out the advance (since CG won't take positions directly)
        size_t i;
        for (i = 0; i < length - 1; i++)
        {
            size_t i2 = (i+1) * 2;
            CGPoint pt;
            pt.x = positions[i2];
            pt.y = positions[i2+1];
            pt = CGPointApplyAffineTransform(pt, invTx);
            advances[i].width = pt.x - prev.x;
            advances[i].height = -(pt.y - prev.y); // negative to translate to device space
            prev.x = pt.x;
            prev.y = pt.y;
        }

        (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, JNI_ABORT);
        (*env)->DeleteLocalRef(env, posArray);
    }
    else
    {
        // in this case, we have to go and calculate the positions ourselves
        // there were no pre-calculated positions from the glyph buffer on the Java side
        AWTFont *awtFont = strike->fAWTFont;
        CTFontGetAdvancesForGlyphs((CTFontRef)awtFont->fFont, kCTFontDefaultOrientation, glyphs, advances, length);

        if (complex)
        {
            JavaCT_GetAdvancesForUnichars(awtFont->fFont, uniChars, glyphs, length, advances);
        }
    }

    // continue on to the next stage of the pipe
    doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, complex, uniChars, glyphs, advances, length);
}

// Obtains the glyph array to determine the number of glyphs we are dealing with. If we are dealing a large number of glyphs,
// we malloc a buffer to hold the glyphs and their advances, otherwise we use stack allocated buffers.
static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector)
{
    static JNF_MEMBER_CACHE(jm_StandardGlyphVector_glyphs, jc_StandardGlyphVector, "glyphs", "[I");
    jintArray glyphsArray = JNFGetObjectField(env, gVector, jm_StandardGlyphVector_glyphs);
    jsize length = (*env)->GetArrayLength(env, glyphsArray);

    if (length == 0)
    {
        // nothing to draw
        (*env)->DeleteLocalRef(env, glyphsArray);
        return;
    }

    if (length < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE)
    {
        // if we are small enough, fit everything onto the stack
        CGGlyph glyphs[length];
        int uniChars[length];
        CGSize advances[length];
        doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
    }
    else
    {
        // otherwise, we should malloc and free buffers for this large run
        CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * length);
        int *uniChars = (int *)malloc(sizeof(int) * length);
        CGSize *advances = (CGSize *)malloc(sizeof(CGSize) * length);

        if (glyphs == NULL || uniChars == NULL || advances == NULL)
        {
            (*env)->DeleteLocalRef(env, glyphsArray);
            [NSException raise:NSMallocException format:@"%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__];
            if (glyphs)
            {
                free(glyphs);
            }
            if (uniChars)
            {
                free(uniChars);
            }
            if (advances)
            {
                free(advances);
            }
            return;
        }

        doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);

        free(glyphs);
        free(uniChars);
        free(advances);
    }

    (*env)->DeleteLocalRef(env, glyphsArray);
}

// Setup and save the state of the CGContext, and apply any java.awt.Font transforms to the context.
static inline void doDrawGlyphsPipe_applyFontTransforms
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, const jfloat x, const jfloat y)
{
    CGContextRef cgRef = qsdo->cgRef;
    CGContextSetFontSize(cgRef, 1.0);
    CGContextSetFont(cgRef, strike->fAWTFont->fNativeCGFont);
    CGContextSetTextMatrix(cgRef, CGAffineTransformIdentity);

    CGAffineTransform tx = strike->fFontTx;
    tx.tx += x;
    tx.ty += y;
    CGContextConcatCTM(cgRef, tx);

    doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc(env, qsdo, strike, gVector);
}


#pragma mark --- CTextPipe JNI ---


/*
 * Class:     sun_lwawt_macosx_CTextPipe
 * Method:    doDrawString
 * Signature: (Lsun/java2d/SurfaceData;JLjava/lang/String;DD)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CTextPipe_doDrawString
(JNIEnv *env, jobject jthis, jobject jsurfacedata, jlong awtStrikePtr, jstring str, jdouble x, jdouble y)
{
    QuartzSDOps *qsdo = (QuartzSDOps *)SurfaceData_GetOps(env, jsurfacedata);
    AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);

JNF_COCOA_ENTER(env);

    jsize len = (*env)->GetStringLength(env, str);

    if (len < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE) // optimized for stack allocation <rdar://problem/4285041>
    {
        jchar unichars[len];
        (*env)->GetStringRegion(env, str, 0, len, unichars);
        JNF_CHECK_AND_RETHROW_EXCEPTION(env);

        // Draw the text context
        DrawTextContext(env, qsdo, awtStrike, unichars, len, x, y);
    }
    else
    {
        // Get string to draw and the length
        const jchar *unichars = JNFGetStringUTF16UniChars(env, str);

        // Draw the text context
        DrawTextContext(env, qsdo, awtStrike, unichars, len, x, y);

        JNFReleaseStringUTF16UniChars(env, str, unichars);
    }

JNF_COCOA_RENDERER_EXIT(env);
}


/*
 * Class:     sun_lwawt_macosx_CTextPipe
 * Method:    doUnicodes
 * Signature: (Lsun/java2d/SurfaceData;J[CIIFF)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CTextPipe_doUnicodes
(JNIEnv *env, jobject jthis, jobject jsurfacedata, jlong awtStrikePtr, jcharArray unicodes, jint offset, jint length, jfloat x, jfloat y)
{
    QuartzSDOps *qsdo = (QuartzSDOps *)SurfaceData_GetOps(env, jsurfacedata);
    AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);

JNF_COCOA_ENTER(env);

    // Setup the text context
    if (length < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE) // optimized for stack allocation
    {
        jchar copyUnichars[length];
        (*env)->GetCharArrayRegion(env, unicodes, offset, length, copyUnichars);
        JNF_CHECK_AND_RETHROW_EXCEPTION(env);
        DrawTextContext(env, qsdo, awtStrike, copyUnichars, length, x, y);
    }
    else
    {
        jchar *copyUnichars = malloc(length * sizeof(jchar));
        if (!copyUnichars) {
            [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory to create the glyphs for string drawing"];
        }

        @try {
            (*env)->GetCharArrayRegion(env, unicodes, offset, length, copyUnichars);
            JNF_CHECK_AND_RETHROW_EXCEPTION(env);
            DrawTextContext(env, qsdo, awtStrike, copyUnichars, length, x, y);
        } @finally {
            free(copyUnichars);
        }
    }

JNF_COCOA_RENDERER_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CTextPipe
 * Method:    doOneUnicode
 * Signature: (Lsun/java2d/SurfaceData;JCFF)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CTextPipe_doOneUnicode
(JNIEnv *env, jobject jthis, jobject jsurfacedata, jlong awtStrikePtr, jchar aUnicode, jfloat x, jfloat y)
{
    QuartzSDOps *qsdo = (QuartzSDOps *)SurfaceData_GetOps(env, jsurfacedata);
    AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);

JNF_COCOA_ENTER(env);

    DrawTextContext(env, qsdo, awtStrike, &aUnicode, 1, x, y);

JNF_COCOA_RENDERER_EXIT(env);
}

/*
 * Class: sun_lwawt_macosx_CTextPipe
 * Method: doDrawGlyphs
 * Signature: (Lsun/java2d/SurfaceData;JLjava/awt/font/GlyphVector;FF)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CTextPipe_doDrawGlyphs
(JNIEnv *env, jobject jthis, jobject jsurfacedata, jlong awtStrikePtr, jobject gVector, jfloat x, jfloat y)
{
    QuartzSDOps *qsdo = (QuartzSDOps *)SurfaceData_GetOps(env, jsurfacedata);
    AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);

JNF_COCOA_ENTER(env);

    qsdo->BeginSurface(env, qsdo, SD_Text);
    if (qsdo->cgRef == NULL)
    {
        qsdo->FinishSurface(env, qsdo);
        return;
    }

    CGContextSaveGState(qsdo->cgRef);
    JRSFontSetRenderingStyleOnContext(qsdo->cgRef, JRSFontGetRenderingStyleForHints(sun_awt_SunHints_INTVAL_FRACTIONALMETRICS_ON, sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_ON));

    doDrawGlyphsPipe_applyFontTransforms(env, qsdo, awtStrike, gVector, x, y);

    CGContextRestoreGState(qsdo->cgRef);

    qsdo->FinishSurface(env, qsdo);

JNF_COCOA_RENDERER_EXIT(env);
}
