251 } 252 else if (c1 > c2) 253 { 254 *out++ = c1 - ((c1-c2)*range); 255 } 256 else// if (c1 < c2) 257 { 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 contextGradientPath(QuartzSDOps* qsdo) 272 { 273 PRINT(" ContextGradientPath") 274 CGContextRef cgRef = qsdo->cgRef; 275 StateShadingInfo* shadingInfo = qsdo->shadingInfo; 276 277 CGRect bounds = CGContextGetClipBoundingBox(cgRef); 278 279 static const CGFloat domain[2] = {0.0f, 1.0f}; 280 static const CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f}; 281 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 282 CGFunctionRef shadingFunc = NULL; 283 CGShadingRef shading = NULL; 284 if (shadingInfo->cyclic == NO) 285 { 286 static const CGFunctionCallbacks callbacks = {0, &gradientLinearPaintEvaluateFunction, &gradientPaintReleaseFunction}; 287 shadingFunc = CGFunctionCreate((void *)shadingInfo, 1, domain, 4, range, &callbacks); 288 shading = CGShadingCreateAxial(colorspace, shadingInfo->start, shadingInfo->end, shadingFunc, 1, 1); 289 } 290 else 291 { 292 //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); 293 // need to extend the line start-end 881 renderType = SD_Shade; 882 883 qsdo->shadingInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; 884 qsdo->shadingInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; 885 qsdo->shadingInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; 886 qsdo->shadingInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; 887 jint c1 = javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorRGBValue1Index]; 888 qsdo->shadingInfo->colors[0] = ((c1>>16)&0xff)*kColorConversionMultiplier; 889 qsdo->shadingInfo->colors[1] = ((c1>>8)&0xff)*kColorConversionMultiplier; 890 qsdo->shadingInfo->colors[2] = ((c1>>0)&0xff)*kColorConversionMultiplier; 891 qsdo->shadingInfo->colors[3] = ((c1>>24)&0xff)*kColorConversionMultiplier; 892 jint c2 = javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorRGBValue2Index]; 893 qsdo->shadingInfo->colors[4] = ((c2>>16)&0xff)*kColorConversionMultiplier; 894 qsdo->shadingInfo->colors[5] = ((c2>>8)&0xff)*kColorConversionMultiplier; 895 qsdo->shadingInfo->colors[6] = ((c2>>0)&0xff)*kColorConversionMultiplier; 896 qsdo->shadingInfo->colors[7] = ((c2>>24)&0xff)*kColorConversionMultiplier; 897 qsdo->shadingInfo->cyclic = (javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorIsCyclicIndex] == sun_java2d_OSXSurfaceData_kColorCyclic); 898 899 break; 900 } 901 case sun_java2d_OSXSurfaceData_kColorTexture: 902 { 903 qsdo->patternInfo = (StatePatternInfo*)malloc(sizeof(StatePatternInfo)); 904 if (qsdo->patternInfo == NULL) 905 { 906 [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for texture paint"]; 907 } 908 909 qsdo->graphicsStateInfo.simpleStroke = NO; 910 qsdo->graphicsStateInfo.simpleColor = NO; 911 912 renderType = SD_Pattern; 913 914 qsdo->patternInfo->tx = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColortxIndex]; 915 qsdo->patternInfo->ty = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColortyIndex]; 916 qsdo->patternInfo->sx = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorsxIndex]; 917 if (qsdo->patternInfo->sx == 0.0f) 918 { 919 return SD_Fill; // 0 is an invalid value, fill argb rect 920 } 1053 switch (qsdo->renderType) 1054 { 1055 case SD_Nothing: 1056 break; 1057 1058 case SD_Stroke: 1059 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1060 { 1061 CGContextStrokePath(qsdo->cgRef); 1062 } 1063 break; 1064 1065 case SD_Fill: 1066 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1067 { 1068 CGContextFillPath(qsdo->cgRef); 1069 } 1070 break; 1071 1072 case SD_Shade: 1073 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1074 { 1075 contextGradientPath(qsdo); 1076 } 1077 break; 1078 1079 case SD_Pattern: 1080 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1081 { 1082 //TODO:BG 1083 //contextTexturePath(env, qsdo); 1084 } 1085 break; 1086 1087 case SD_EOFill: 1088 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1089 { 1090 CGContextEOFillPath(qsdo->cgRef); 1091 } 1092 break; 1093 1094 case SD_Image: 1095 break; 1096 1097 case SD_Text: 1098 break; 1099 1100 case SD_CopyArea: 1101 break; 1102 1103 case SD_Queue: 1104 break; 1105 1106 case SD_External: 1107 break; 1108 } 1109 1110 if (qsdo->shadingInfo != NULL) { 1111 gradientPaintReleaseFunction(qsdo->shadingInfo); 1112 qsdo->shadingInfo = NULL; 1113 } 1114 } | 251 } 252 else if (c1 > c2) 253 { 254 *out++ = c1 - ((c1-c2)*range); 255 } 256 else// if (c1 < c2) 257 { 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 contextQuartzGradientPath(QuartzSDOps* qsdo) 272 { 273 274 PRINT(" contextQuartzGradientPath"); 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 (int i = 0; i < num_locations; i++) { 288 locations[i] = gradientInfo->fractionsdata[i]; 289 //fprintf(stderr, "locations[%d] %f\n", i, locations[i]); 290 } 291 for (i = 0; i < component_size; i++) { 292 components[i] = gradientInfo->colordata[i]; 293 //fprintf(stderr, "components[%d] %f, gradientInfo->colordata[%d] %f\n", 294 // i, components[i], i, gradientInfo->colordata[i]); 295 } 296 CGContextSaveGState(cgRef); 297 gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations); 298 //fprintf(stderr, "gradientInfo->start.x %f, gradientInfo->start.y %f\n", 299 // gradientInfo->start.x, gradientInfo->start.y); 300 //fprintf(stderr, "gradientInfo->end.x %f, gradientInfo->end.y %f\n", 301 // gradientInfo->end.x, gradientInfo->end.y); 302 if (qsdo->isEvenOddFill) { 303 CGContextEOClip(cgRef); 304 } else { 305 CGContextClip(cgRef); 306 } 307 CGContextDrawLinearGradient(cgRef, gradient, gradientInfo->start, gradientInfo->end, 0); 308 309 CGContextRestoreGState(cgRef); 310 CGColorSpaceRelease(colorspace); 311 CGGradientRelease(gradient); 312 free(locations); 313 free(gradientInfo->colordata); 314 free(gradientInfo->fractionsdata); 315 } 316 317 static inline void contextGradientPath(QuartzSDOps* qsdo) 318 { 319 PRINT(" ContextGradientPath") 320 321 CGContextRef cgRef = qsdo->cgRef; 322 StateShadingInfo* shadingInfo = qsdo->shadingInfo; 323 324 CGRect bounds = CGContextGetClipBoundingBox(cgRef); 325 326 static const CGFloat domain[2] = {0.0f, 1.0f}; 327 static const CGFloat range[8] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f}; 328 CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 329 CGFunctionRef shadingFunc = NULL; 330 CGShadingRef shading = NULL; 331 if (shadingInfo->cyclic == NO) 332 { 333 static const CGFunctionCallbacks callbacks = {0, &gradientLinearPaintEvaluateFunction, &gradientPaintReleaseFunction}; 334 shadingFunc = CGFunctionCreate((void *)shadingInfo, 1, domain, 4, range, &callbacks); 335 shading = CGShadingCreateAxial(colorspace, shadingInfo->start, shadingInfo->end, shadingFunc, 1, 1); 336 } 337 else 338 { 339 //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); 340 // need to extend the line start-end 928 renderType = SD_Shade; 929 930 qsdo->shadingInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; 931 qsdo->shadingInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; 932 qsdo->shadingInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; 933 qsdo->shadingInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; 934 jint c1 = javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorRGBValue1Index]; 935 qsdo->shadingInfo->colors[0] = ((c1>>16)&0xff)*kColorConversionMultiplier; 936 qsdo->shadingInfo->colors[1] = ((c1>>8)&0xff)*kColorConversionMultiplier; 937 qsdo->shadingInfo->colors[2] = ((c1>>0)&0xff)*kColorConversionMultiplier; 938 qsdo->shadingInfo->colors[3] = ((c1>>24)&0xff)*kColorConversionMultiplier; 939 jint c2 = javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorRGBValue2Index]; 940 qsdo->shadingInfo->colors[4] = ((c2>>16)&0xff)*kColorConversionMultiplier; 941 qsdo->shadingInfo->colors[5] = ((c2>>8)&0xff)*kColorConversionMultiplier; 942 qsdo->shadingInfo->colors[6] = ((c2>>0)&0xff)*kColorConversionMultiplier; 943 qsdo->shadingInfo->colors[7] = ((c2>>24)&0xff)*kColorConversionMultiplier; 944 qsdo->shadingInfo->cyclic = (javaGraphicsStates[sun_java2d_OSXSurfaceData_kColorIsCyclicIndex] == sun_java2d_OSXSurfaceData_kColorCyclic); 945 946 break; 947 } 948 case sun_java2d_OSXSurfaceData_kColorLinearOrRadialGradient: 949 { 950 qsdo->gradientInfo = (StateGradientInfo*)malloc(sizeof(StateGradientInfo)); 951 if (qsdo->gradientInfo == NULL) 952 { 953 [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for gradient paint"]; 954 } 955 956 qsdo->graphicsStateInfo.simpleStroke = NO; 957 qsdo->graphicsStateInfo.simpleColor = NO; 958 959 renderType = SD_Gradient; 960 961 qsdo->gradientInfo->start.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx1Index]; 962 qsdo->gradientInfo->start.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory1Index]; 963 qsdo->gradientInfo->end.x = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorx2Index]; 964 qsdo->gradientInfo->end.y = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColory2Index]; 965 966 jobject colorArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kColorArrayIndex)); 967 if (colorArray != NULL) 968 { 969 jint length = (*env)->GetArrayLength(env, colorArray); 970 //fprintf(stderr, "length %d\n", length); 971 972 jint* jcolorData = (jint*)(*env)->GetPrimitiveArrayCritical(env, colorArray, NULL); 973 CGFloat* colors= (CGFloat*)calloc(0, sizeof(CGFloat)*length); 974 if (jcolorData != NULL) 975 { 976 jint i; 977 for (i=0; i<length; i++) 978 { 979 colors[i] = (CGFloat)jcolorData[i]; 980 } 981 } 982 for (int i = 0; i < length; i++) 983 { 984 jint c1 = colors[i]; 985 //fprintf(stderr, "c1 %x\n", c1); 986 qsdo->gradientInfo->colordata = (CGFloat*)calloc(0, sizeof(CGFloat)*4*length); 987 qsdo->gradientInfo->colordata[i*4] = ((c1>>16)&0xff)*kColorConversionMultiplier; 988 //fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4, qsdo->gradientInfo->colordata[i*4]); 989 990 qsdo->gradientInfo->colordata[i*4+1] = ((c1>>8)&0xff)*kColorConversionMultiplier; 991 //fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+1, qsdo->gradientInfo->colordata[i*4+1]); 992 993 qsdo->gradientInfo->colordata[i*4+2] = ((c1>>0)&0xff)*kColorConversionMultiplier; 994 //fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+2, qsdo->gradientInfo->colordata[i*4+2]); 995 996 qsdo->gradientInfo->colordata[i*4+3] = ((c1>>24)&0xff)*kColorConversionMultiplier; 997 //fprintf(stderr, "qsdo->gradientInfo->colordata[%d] %f\n", i*4+3, qsdo->gradientInfo->colordata[i*4+3]); 998 } 999 (*env)->ReleasePrimitiveArrayCritical(env, colorArray, jcolorData, 0); 1000 free(colors); 1001 } 1002 jobject fractionsArray = ((*env)->GetObjectArrayElement(env, qsdo->javaGraphicsStatesObjects, sun_java2d_OSXSurfaceData_kFractionsArrayIndex)); 1003 if (fractionsArray != NULL) 1004 { 1005 jint length = (*env)->GetArrayLength(env, fractionsArray); 1006 //fprintf(stderr, "fractions length %d\n", length); 1007 qsdo->gradientInfo->fractionsLength = length; 1008 1009 jfloat* jfractionsData = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL); 1010 if (jfractionsData != NULL) 1011 { 1012 qsdo->gradientInfo->fractionsdata = (CGFloat *)malloc(sizeof(CGFloat) *length); 1013 jint i; 1014 for (i=0; i<length; i++) 1015 { 1016 qsdo->gradientInfo->fractionsdata[i] = jfractionsData[i]; 1017 //fprintf(stderr, "jfrationsData[%d] %f, qsdo->gradientInfo->fractionsdata[%d] = %f\n", i, jfractionsData[i], i, qsdo->gradientInfo->fractionsdata[i]); 1018 } 1019 (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, jfractionsData, 0); 1020 } 1021 } 1022 break; 1023 } 1024 case sun_java2d_OSXSurfaceData_kColorTexture: 1025 { 1026 qsdo->patternInfo = (StatePatternInfo*)malloc(sizeof(StatePatternInfo)); 1027 if (qsdo->patternInfo == NULL) 1028 { 1029 [JNFException raise:env as:kOutOfMemoryError reason:"Failed to malloc memory for texture paint"]; 1030 } 1031 1032 qsdo->graphicsStateInfo.simpleStroke = NO; 1033 qsdo->graphicsStateInfo.simpleColor = NO; 1034 1035 renderType = SD_Pattern; 1036 1037 qsdo->patternInfo->tx = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColortxIndex]; 1038 qsdo->patternInfo->ty = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColortyIndex]; 1039 qsdo->patternInfo->sx = javaFloatGraphicsStates[sun_java2d_OSXSurfaceData_kColorsxIndex]; 1040 if (qsdo->patternInfo->sx == 0.0f) 1041 { 1042 return SD_Fill; // 0 is an invalid value, fill argb rect 1043 } 1176 switch (qsdo->renderType) 1177 { 1178 case SD_Nothing: 1179 break; 1180 1181 case SD_Stroke: 1182 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1183 { 1184 CGContextStrokePath(qsdo->cgRef); 1185 } 1186 break; 1187 1188 case SD_Fill: 1189 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1190 { 1191 CGContextFillPath(qsdo->cgRef); 1192 } 1193 break; 1194 1195 case SD_Shade: 1196 fprintf(stderr, "SD_Shade\n"); 1197 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1198 { 1199 contextGradientPath(qsdo); 1200 } 1201 break; 1202 1203 case SD_Gradient: 1204 fprintf(stderr, "SD_Gradient\n"); 1205 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1206 { 1207 contextQuartzGradientPath(qsdo); 1208 } 1209 break; 1210 1211 case SD_Pattern: 1212 fprintf(stderr, "SD_Pattern\n"); 1213 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1214 { 1215 //TODO:BG 1216 //contextTexturePath(env, qsdo); 1217 } 1218 break; 1219 1220 case SD_EOFill: 1221 if (CGContextIsPathEmpty(qsdo->cgRef) == 0) 1222 { 1223 CGContextEOFillPath(qsdo->cgRef); 1224 } 1225 break; 1226 1227 case SD_Image: 1228 break; 1229 1230 case SD_Text: 1231 break; 1232 1233 case SD_CopyArea: 1234 break; 1235 1236 case SD_Queue: 1237 break; 1238 1239 case SD_External: 1240 break; 1241 } 1242 1243 if (qsdo->shadingInfo != NULL) { 1244 gradientPaintReleaseFunction(qsdo->shadingInfo); 1245 qsdo->shadingInfo = NULL; 1246 } 1247 if (qsdo->gradientInfo != NULL) { 1248 gradientPaintReleaseFunction(qsdo->gradientInfo); 1249 qsdo->gradientInfo = NULL; 1250 } 1251 } |