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 }
|