258 *out++ = c1 + ((c2-c1)*range); 259 } 260 } 261 } 262 } 263 264 // this function MUST NOT be inlined! 265 void gradientPaintReleaseFunction(void *info) 266 { 267 PRINT(" gradientPaintReleaseFunction") 268 free(info); 269 } 270 271 static inline void contextQuartzLinearGradientPath(QuartzSDOps* qsdo) 272 { 273 274 PRINT(" contextQuartzLinearGradientPath"); 275 276 CGContextRef cgRef = qsdo->cgRef; 277 StateGradientInfo *gradientInfo = qsdo->gradientInfo; 278 279 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 280 size_t num_locations = gradientInfo->fractionsLength; 281 CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); 282 int i = 0; 283 size_t component_size = num_locations * 4; 284 CGFloat components[component_size]; 285 CGGradientRef gradient = NULL; 286 287 for (i = 0; i < num_locations; i++) { 288 locations[i] = gradientInfo->fractionsdata[i]; 289 } 290 for (i = 0; i < component_size; i++) { 291 components[i] = gradientInfo->colordata[i]; 292 } 293 CGContextSaveGState(cgRef); 294 gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); 295 if (qsdo->isEvenOddFill) { 296 CGContextEOClip(cgRef); 297 } else { 298 CGContextClip(cgRef); 299 } 300 CGContextDrawLinearGradient(cgRef, gradient, gradientInfo->start, gradientInfo->end, kCGGradientDrawsAfterEndLocation); 301 302 CGContextRestoreGState(cgRef); 303 CGColorSpaceRelease(colorspace); 304 CGGradientRelease(gradient); 305 free(locations); 306 free(gradientInfo->colordata); 307 free(gradientInfo->fractionsdata); 308 } 309 310 static inline void contextQuartzRadialGradientPath(QuartzSDOps* qsdo) 311 { 312 313 PRINT(" contextQuartzRadialGradientPath"); 314 315 CGContextRef cgRef = qsdo->cgRef; 316 StateGradientInfo *gradientInfo = qsdo->gradientInfo; 317 318 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 319 size_t num_locations = gradientInfo->fractionsLength; 320 CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); 321 int i = 0; 322 size_t component_size = num_locations * 4; 323 CGFloat components[component_size]; 324 CGGradientRef gradient = NULL; 325 CGFloat startRadius = gradientInfo->radius; 326 CGFloat endRadius = gradientInfo->radius; 327 328 for (i = 0; i < num_locations; i++) { 329 locations[i] = gradientInfo->fractionsdata[i]; 330 } 331 for (i = 0; i < component_size; i++) { 332 components[i] = gradientInfo->colordata[i]; 333 } 334 CGContextSaveGState(cgRef); 335 gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); 336 if (qsdo->isEvenOddFill) { 337 CGContextEOClip(cgRef); 338 } else { 339 CGContextClip(cgRef); 340 } 341 CGContextDrawRadialGradient(cgRef, gradient, gradientInfo->start, 0, gradientInfo->end, endRadius, kCGGradientDrawsAfterEndLocation); 342 343 CGContextRestoreGState(cgRef); 344 CGColorSpaceRelease(colorspace); 345 CGGradientRelease(gradient); 346 free(locations); 347 free(gradientInfo->colordata); 348 free(gradientInfo->fractionsdata); 349 } 350 351 static inline void contextGradientPath(QuartzSDOps* qsdo) 352 { 353 PRINT(" ContextGradientPath") 354 355 CGContextRef cgRef = qsdo->cgRef; 356 StateShadingInfo* shadingInfo = qsdo->shadingInfo; 357 358 CGRect bounds = CGContextGetClipBoundingBox(cgRef); 359 360 static const CGFloat domain[2] = {0.0f, 1.0f}; 361 static const CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f}; 362 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 363 CGFunctionRef shadingFunc = NULL; 364 CGShadingRef shading = NULL; 365 if (shadingInfo->cyclic == NO) 366 { 367 static const CGFunctionCallbacks callbacks = {0, &gradientLinearPaintEvaluateFunction, &gradientPaintReleaseFunction}; 368 shadingFunc = CGFunctionCreate((void *)shadingInfo, 1, domain, 4, range, &callbacks); 369 shading = CGShadingCreateAxial(colorspace, shadingInfo->start, shadingInfo->end, shadingFunc, 1, 1); 370 } 371 else 372 { 373 //fprintf(stderr, "BOUNDING BOX x1=%f, y1=%f x2=%f, y2=%f\n", bounds.origin.x, bounds.origin.y, bounds.origin.x+bounds.size.width, bounds.origin.y+bounds.size.height); 374 // need to extend the line start-end 908 qsdo->renderType = renderType; 909 } 910 911 void setupGradient(JNIEnv *env, QuartzSDOps* qsdo, jfloat* javaFloatGraphicsStates) 912 { 913 static const CGFloat kColorConversionMultiplier = 1.0f/255.0f; 914 qsdo->gradientInfo = (StateGradientInfo*)malloc(sizeof(StateGradientInfo)); 915 if (qsdo->gradientInfo == NULL) 916 { 917 [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for gradient paint"]; 918 } 919 920 qsdo->graphicsStateInfo.simpleStroke = NO; 921 qsdo->graphicsStateInfo.simpleColor = NO; 922 923 qsdo->gradientInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; 924 qsdo->gradientInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; 925 qsdo->gradientInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; 926 qsdo->gradientInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; 927 928 jobject colorArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kColorArrayIndex)); 929 if (colorArray != NULL) 930 { 931 jint length = (*env)->GetArrayLength(env, colorArray); 932 933 jint* jcolorData = (jint*)(*env)->GetPrimitiveArrayCritical(env, colorArray, NULL); 934 qsdo->gradientInfo->colordata = (CGFloat*)malloc(sizeof(CGFloat)*4*length); 935 memset(qsdo->gradientInfo->colordata, 0, sizeof(CGFloat)*4*length); 936 if (jcolorData != NULL) 937 { 938 int i; 939 for (i=0; i<length; i++) 940 { 941 qsdo->gradientInfo->colordata[i*4] = ((jcolorData[i]>>16)&0xff)*kColorConversionMultiplier; 942 943 qsdo->gradientInfo->colordata[i*4+1] = ((jcolorData[i]>>8)&0xff)*kColorConversionMultiplier; 944 945 qsdo->gradientInfo->colordata[i*4+2] = ((jcolorData[i]>>0)&0xff)*kColorConversionMultiplier; 946 947 qsdo->gradientInfo->colordata[i*4+3] = ((jcolorData[i]>>24)&0xff)*kColorConversionMultiplier; 948 } 949 } 950 (*env)->ReleasePrimitiveArrayCritical(env, colorArray, jcolorData, 0); 951 } 952 jobject fractionsArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kFractionsArrayIndex)); 953 if (fractionsArray != NULL) 954 { 955 jint length = (*env)->GetArrayLength(env, fractionsArray); 956 qsdo->gradientInfo->fractionsLength = length; 957 958 jfloat* jfractionsData = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL); 959 if (jfractionsData != NULL) 960 { 961 int i; 962 qsdo->gradientInfo->fractionsdata = (CGFloat *)malloc(sizeof(CGFloat) *length); 963 memset(qsdo->gradientInfo->fractionsdata, 0, sizeof(CGFloat)*length); 964 for (i=0; i<length; i++) 965 { 966 qsdo->gradientInfo->fractionsdata[i] = jfractionsData[i]; 967 } 968 (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, jfractionsData, 0); 969 } 970 } 971 } 972 973 SDRenderType SetUpPaint(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType) 974 { 975 CGContextRef cgRef = qsdo->cgRef; 976 977 jint *javaGraphicsStates = qsdo->javaGraphicsStates; 978 jfloat *javaFloatGraphicsStates = (jfloat*)(qsdo->javaGraphicsStates); 979 980 static const CGFloat kColorConversionMultiplier = 1.0f/255.0f; 981 jint colorState = javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorStateIndex]; 982 983 switch (colorState) 984 { 985 case sun_java2d_OSXSurfaceData_kColorSimple: 986 { 987 if (qsdo->graphicsStateInfo.simpleColor == NO) 988 { 989 setDefaultColorSpace(cgRef); 990 } | 258 *out++ = c1 + ((c2-c1)*range); 259 } 260 } 261 } 262 } 263 264 // this function MUST NOT be inlined! 265 void gradientPaintReleaseFunction(void *info) 266 { 267 PRINT(" gradientPaintReleaseFunction") 268 free(info); 269 } 270 271 static inline void contextQuartzLinearGradientPath(QuartzSDOps* qsdo) 272 { 273 274 PRINT(" contextQuartzLinearGradientPath"); 275 276 CGContextRef cgRef = qsdo->cgRef; 277 StateGradientInfo *gradientInfo = qsdo->gradientInfo; 278 279 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 280 size_t num_locations = gradientInfo->fractionsLength; 281 CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); 282 int i = 0; 283 size_t component_size = num_locations * 4; 284 CGFloat components[component_size]; 285 CGGradientRef gradient = NULL; 286 287 for (i = 0; i < num_locations; i++) { 288 locations[i] = gradientInfo->fractionsdata[i]; 289 } 290 for (i = 0; i < component_size; i++) { 291 components[i] = gradientInfo->colordata[i]; 292 } 293 CGContextSaveGState(cgRef); 294 gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); 295 if (qsdo->isEvenOddFill) { 296 CGContextEOClip(cgRef); 297 } else { 298 CGContextClip(cgRef); 299 } 300 CGContextDrawLinearGradient(cgRef, gradient, gradientInfo->start, gradientInfo->end, kCGGradientDrawsAfterEndLocation); 301 302 CGContextRestoreGState(cgRef); 303 CGColorSpaceRelease(colorspace); 304 CGGradientRelease(gradient); 305 free(locations); 306 free(gradientInfo->colordata); 307 free(gradientInfo->fractionsdata); 308 } 309 310 static inline void contextQuartzRadialGradientPath(QuartzSDOps* qsdo) 311 { 312 313 PRINT(" contextQuartzRadialGradientPath"); 314 315 CGContextRef cgRef = qsdo->cgRef; 316 StateGradientInfo *gradientInfo = qsdo->gradientInfo; 317 318 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 319 size_t num_locations = gradientInfo->fractionsLength; 320 CGFloat *locations = (CGFloat *) malloc(sizeof(CGFloat) * num_locations); 321 int i = 0; 322 size_t component_size = num_locations * 4; 323 CGFloat components[component_size]; 324 CGGradientRef gradient = NULL; 325 CGFloat startRadius = gradientInfo->radius; 326 CGFloat endRadius = gradientInfo->radius; 327 328 for (i = 0; i < num_locations; i++) { 329 locations[i] = gradientInfo->fractionsdata[i]; 330 } 331 for (i = 0; i < component_size; i++) { 332 components[i] = gradientInfo->colordata[i]; 333 } 334 CGContextSaveGState(cgRef); 335 gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); 336 if (qsdo->isEvenOddFill) { 337 CGContextEOClip(cgRef); 338 } else { 339 CGContextClip(cgRef); 340 } 341 CGContextDrawRadialGradient(cgRef, gradient, gradientInfo->start, 0, gradientInfo->end, endRadius, kCGGradientDrawsAfterEndLocation); 342 343 CGContextRestoreGState(cgRef); 344 CGColorSpaceRelease(colorspace); 345 CGGradientRelease(gradient); 346 free(locations); 347 free(gradientInfo->colordata); 348 free(gradientInfo->fractionsdata); 349 } 350 351 static inline void contextGradientPath(QuartzSDOps* qsdo) 352 { 353 PRINT(" ContextGradientPath") 354 355 CGContextRef cgRef = qsdo->cgRef; 356 StateShadingInfo* shadingInfo = qsdo->shadingInfo; 357 358 CGRect bounds = CGContextGetClipBoundingBox(cgRef); 359 360 static const CGFloat domain[2] = {0.0f, 1.0f}; 361 static const CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f}; 362 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 363 CGFunctionRef shadingFunc = NULL; 364 CGShadingRef shading = NULL; 365 if (shadingInfo->cyclic == NO) 366 { 367 static const CGFunctionCallbacks callbacks = {0, &gradientLinearPaintEvaluateFunction, &gradientPaintReleaseFunction}; 368 shadingFunc = CGFunctionCreate((void *)shadingInfo, 1, domain, 4, range, &callbacks); 369 shading = CGShadingCreateAxial(colorspace, shadingInfo->start, shadingInfo->end, shadingFunc, 1, 1); 370 } 371 else 372 { 373 //fprintf(stderr, "BOUNDING BOX x1=%f, y1=%f x2=%f, y2=%f\n", bounds.origin.x, bounds.origin.y, bounds.origin.x+bounds.size.width, bounds.origin.y+bounds.size.height); 374 // need to extend the line start-end 908 qsdo->renderType = renderType; 909 } 910 911 void setupGradient(JNIEnv *env, QuartzSDOps* qsdo, jfloat* javaFloatGraphicsStates) 912 { 913 static const CGFloat kColorConversionMultiplier = 1.0f/255.0f; 914 qsdo->gradientInfo = (StateGradientInfo*)malloc(sizeof(StateGradientInfo)); 915 if (qsdo->gradientInfo == NULL) 916 { 917 [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for gradient paint"]; 918 } 919 920 qsdo->graphicsStateInfo.simpleStroke = NO; 921 qsdo->graphicsStateInfo.simpleColor = NO; 922 923 qsdo->gradientInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; 924 qsdo->gradientInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; 925 qsdo->gradientInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; 926 qsdo->gradientInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; 927 928 jobject colorArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kColorArrayIndex)); 929 if (colorArray != NULL) 930 { 931 jint length = (*env)->GetArrayLength(env, colorArray); 932 933 jint* jcolorData = (jint*)(*env)->GetPrimitiveArrayCritical(env, colorArray, NULL); 934 qsdo->gradientInfo->colordata = (CGFloat*)malloc(sizeof(CGFloat)*4*length); 935 memset(qsdo->gradientInfo->colordata, 0, sizeof(CGFloat)*4*length); 936 if (jcolorData != NULL) 937 { 938 int i; 939 for (i=0; i<length; i++) 940 { 941 qsdo->gradientInfo->colordata[i*4] = ((jcolorData[i]>>16)&0xff)*kColorConversionMultiplier; 942 943 qsdo->gradientInfo->colordata[i*4+1] = ((jcolorData[i]>>8)&0xff)*kColorConversionMultiplier; 944 945 qsdo->gradientInfo->colordata[i*4+2] = ((jcolorData[i]>>0)&0xff)*kColorConversionMultiplier; 946 947 qsdo->gradientInfo->colordata[i*4+3] = ((jcolorData[i]>>24)&0xff)*kColorConversionMultiplier; 948 } 949 } 950 (*env)->ReleasePrimitiveArrayCritical(env, colorArray, jcolorData, 0); 951 } 952 jobject fractionsArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kFractionsArrayIndex)); 953 if (fractionsArray != NULL) 954 { 955 jint length = (*env)->GetArrayLength(env, fractionsArray); 956 qsdo->gradientInfo->fractionsLength = length; 957 958 jfloat* jfractionsData = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL); 959 if (jfractionsData != NULL) 960 { 961 int i; 962 qsdo->gradientInfo->fractionsdata = (CGFloat *)malloc(sizeof(CGFloat) *length); 963 memset(qsdo->gradientInfo->fractionsdata, 0, sizeof(CGFloat)*length); 964 for (i=0; i<length; i++) 965 { 966 qsdo->gradientInfo->fractionsdata[i] = jfractionsData[i]; 967 } 968 (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, jfractionsData, 0); 969 } 970 } 971 } 972 973 SDRenderType SetUpPaint(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType) 974 { 975 CGContextRef cgRef = qsdo->cgRef; 976 977 jint *javaGraphicsStates = qsdo->javaGraphicsStates; 978 jfloat *javaFloatGraphicsStates = (jfloat*)(qsdo->javaGraphicsStates); 979 980 static const CGFloat kColorConversionMultiplier = 1.0f/255.0f; 981 jint colorState = javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorStateIndex]; 982 983 switch (colorState) 984 { 985 case sun_java2d_OSXSurfaceData_kColorSimple: 986 { 987 if (qsdo->graphicsStateInfo.simpleColor == NO) 988 { 989 setDefaultColorSpace(cgRef); 990 } |