225 void JavaCT_DrawTextUsingQSD(JNIEnv *env, const QuartzSDOps *qsdo, const AWTStrike *strike, const jchar *chars, const jsize length) 226 { 227 CGContextRef cgRef = qsdo->cgRef; 228 229 AWTFont *awtFont = strike->fAWTFont; 230 CGFloat ptSize = strike->fSize; 231 CGAffineTransform tx = strike->fFontTx; 232 233 NSFont *nsFont = [NSFont fontWithName:[awtFont->fFont fontName] size:ptSize]; 234 235 if (ptSize != 0) { 236 CGFloat invScale = 1 / ptSize; 237 tx = CGAffineTransformConcat(tx, CGAffineTransformMakeScale(invScale, invScale)); 238 CGContextConcatCTM(cgRef, tx); 239 } 240 241 CGContextSetTextMatrix(cgRef, CGAffineTransformIdentity); // resets the damage from CoreText 242 243 NSString *string = [NSString stringWithCharacters:chars length:length]; 244 /* 245 The calls below were used previously but for unknown reason did not 246 render using the right font (see bug 7183516) when attribString is not 247 initialized with font dictionary attributes. It seems that "options" 248 in CTTypesetterCreateWithAttributedStringAndOptions which contains the 249 font dictionary is ignored. 250 251 NSAttributedString *attribString = [[NSAttributedString alloc] initWithString:string]; 252 253 CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedStringAndOptions((CFAttributedStringRef) attribString, (CFDictionaryRef) ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle))); 254 */ 255 NSAttributedString *attribString = [[NSAttributedString alloc] 256 initWithString:string 257 attributes:ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle))]; 258 259 CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedString((CFAttributedStringRef) attribString); 260 261 CFRange range = {0, length}; 262 CTLineRef lineRef = CTTypesetterCreateLine(typeSetterRef, range); 263 264 CTLineDraw(lineRef, cgRef); 265 266 [attribString release]; 267 CFRelease(lineRef); 268 CFRelease(typeSetterRef); 269 } 270 271 272 /*---------------------- 273 DrawTextContext is the funnel for all of our CoreText drawing. 274 All three JNI apis call through this method. 275 ----------------------*/ 276 static void DrawTextContext 277 (JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, const jchar *chars, const jsize length, const jdouble x, const jdouble y) 278 { 335 if (gti == 0) 336 { 337 if (useSubstituion) 338 { 339 // quasi-simple case, substitution, but no per-glyph transforms 340 JavaCT_DrawGlyphVector(qsdo, strike, TRUE, uniChars, glyphs, advances, NULL, NULL, length); 341 } 342 else 343 { 344 // fast path, straight to CG without per-glyph transforms 345 CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length); 346 } 347 return; 348 } 349 350 static JNF_CLASS_CACHE(jc_StandardGlyphVector_GlyphTransformInfo, "sun/font/StandardGlyphVector$GlyphTransformInfo"); 351 static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_transforms, jc_StandardGlyphVector_GlyphTransformInfo, "transforms", "[D"); 352 jdoubleArray g_gtiTransformsArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_transforms); //(*env)->GetObjectField(env, gti, g_gtiTransforms); 353 if (g_gtiTransformsArray == NULL) { 354 return; 355 } 356 jdouble *g_gvTransformsAsDoubles = (*env)->GetPrimitiveArrayCritical(env, g_gtiTransformsArray, NULL); 357 if (g_gvTransformsAsDoubles == NULL) { 358 (*env)->DeleteLocalRef(env, g_gtiTransformsArray); 359 return; 360 } 361 362 static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_indices, jc_StandardGlyphVector_GlyphTransformInfo, "indices", "[I"); 363 jintArray g_gtiTXIndicesArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_indices); 364 jint *g_gvTXIndicesAsInts = (*env)->GetPrimitiveArrayCritical(env, g_gtiTXIndicesArray, NULL); 365 if (g_gvTXIndicesAsInts == NULL) { 366 (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT); 367 (*env)->DeleteLocalRef(env, g_gtiTransformsArray); 368 (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray); 369 return; 370 } 371 // slowest case, we have per-glyph transforms, and possibly glyph substitution as well 372 JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length); 373 374 (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT); 375 (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT); 376 377 (*env)->DeleteLocalRef(env, g_gtiTransformsArray); 378 (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray); 379 } 380 | 225 void JavaCT_DrawTextUsingQSD(JNIEnv *env, const QuartzSDOps *qsdo, const AWTStrike *strike, const jchar *chars, const jsize length) 226 { 227 CGContextRef cgRef = qsdo->cgRef; 228 229 AWTFont *awtFont = strike->fAWTFont; 230 CGFloat ptSize = strike->fSize; 231 CGAffineTransform tx = strike->fFontTx; 232 233 NSFont *nsFont = [NSFont fontWithName:[awtFont->fFont fontName] size:ptSize]; 234 235 if (ptSize != 0) { 236 CGFloat invScale = 1 / ptSize; 237 tx = CGAffineTransformConcat(tx, CGAffineTransformMakeScale(invScale, invScale)); 238 CGContextConcatCTM(cgRef, tx); 239 } 240 241 CGContextSetTextMatrix(cgRef, CGAffineTransformIdentity); // resets the damage from CoreText 242 243 NSString *string = [NSString stringWithCharacters:chars length:length]; 244 /* 245 The calls below were used previously but for unknown reason did not 246 render using the right font (see bug 7183516) when attribString is not 247 initialized with font dictionary attributes. It seems that "options" 248 in CTTypesetterCreateWithAttributedStringAndOptions which contains the 249 font dictionary is ignored. 250 251 NSAttributedString *attribString = [[NSAttributedString alloc] initWithString:string]; 252 253 CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedStringAndOptions((CFAttributedStringRef) attribString, (CFDictionaryRef) ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle))); 254 */ 255 NSAttributedString *attribString = [[NSAttributedString alloc] 256 initWithString:string 257 attributes:ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle))]; 258 259 CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedString((CFAttributedStringRef) attribString); 260 261 CFRange range = {0, length}; 262 CTLineRef lineRef = CTTypesetterCreateLine(typeSetterRef, range); 263 264 CTLineDraw(lineRef, cgRef); 265 266 [attribString release]; 267 CFRelease(lineRef); 268 CFRelease(typeSetterRef); 269 } 270 271 272 /*---------------------- 273 DrawTextContext is the funnel for all of our CoreText drawing. 274 All three JNI apis call through this method. 275 ----------------------*/ 276 static void DrawTextContext 277 (JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, const jchar *chars, const jsize length, const jdouble x, const jdouble y) 278 { 335 if (gti == 0) 336 { 337 if (useSubstituion) 338 { 339 // quasi-simple case, substitution, but no per-glyph transforms 340 JavaCT_DrawGlyphVector(qsdo, strike, TRUE, uniChars, glyphs, advances, NULL, NULL, length); 341 } 342 else 343 { 344 // fast path, straight to CG without per-glyph transforms 345 CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length); 346 } 347 return; 348 } 349 350 static JNF_CLASS_CACHE(jc_StandardGlyphVector_GlyphTransformInfo, "sun/font/StandardGlyphVector$GlyphTransformInfo"); 351 static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_transforms, jc_StandardGlyphVector_GlyphTransformInfo, "transforms", "[D"); 352 jdoubleArray g_gtiTransformsArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_transforms); //(*env)->GetObjectField(env, gti, g_gtiTransforms); 353 if (g_gtiTransformsArray == NULL) { 354 return; 355 } 356 jdouble *g_gvTransformsAsDoubles = (*env)->GetPrimitiveArrayCritical(env, g_gtiTransformsArray, NULL); 357 if (g_gvTransformsAsDoubles == NULL) { 358 (*env)->DeleteLocalRef(env, g_gtiTransformsArray); 359 return; 360 } 361 362 static JNF_MEMBER_CACHE(jm_StandardGlyphVector_GlyphTransformInfo_indices, jc_StandardGlyphVector_GlyphTransformInfo, "indices", "[I"); 363 jintArray g_gtiTXIndicesArray = JNFGetObjectField(env, gti, jm_StandardGlyphVector_GlyphTransformInfo_indices); 364 jint *g_gvTXIndicesAsInts = (*env)->GetPrimitiveArrayCritical(env, g_gtiTXIndicesArray, NULL); 365 if (g_gvTXIndicesAsInts == NULL) { 366 (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT); 367 (*env)->DeleteLocalRef(env, g_gtiTransformsArray); 368 (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray); 369 return; 370 } 371 // slowest case, we have per-glyph transforms, and possibly glyph substitution as well 372 JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length); 373 374 (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT); 375 (*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT); 376 377 (*env)->DeleteLocalRef(env, g_gtiTransformsArray); 378 (*env)->DeleteLocalRef(env, g_gtiTXIndicesArray); 379 } 380 |