00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 var CANVAS_LINECAP_TABLE = [ "butt", "round", "square" ],
00024 CANVAS_LINEJOIN_TABLE = [ "miter", "round", "bevel" ],
00025 CANVAS_COMPOSITE_TABLE = [ "source-over", "source-over", "source-over", "source-over", "darker",
00026 "lighter", "source-over", "source-over", "source-over", "source-over",
00027 "source-over", "source-over", "source-over", "source-over", "source-over",
00028 "source-over", "source-over",
00029 "copy", "source-in", "source-out", "source-atop",
00030 "destination-over", "destination-in", "destination-out", "destination-atop",
00031 "xor", "source-over", "source-over" ];
00032
00033 #define _CGContextAddArcCanvas(aContext, x, y, radius, startAngle, endAngle, anticlockwise) aContext.arc(x, y, radius, startAngle, endAngle, anticlockwise)
00034 #define _CGContextAddArcToPointCanvas(aContext, x1, y1, x2, y2, radius) aContext.arcTo(x1, y1, x2, y2, radius)
00035 #define _CGContextAddCurveToPointCanvas(aContext, cp1x, cp1y, cp2x, cp2y, x, y) aContext.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
00036 #define _CGContextAddQuadCurveToPointCanvas(aContext, cpx, cpy, x, y) aContext.quadraticCurveTo(cpx, cpy, x, y)
00037 #define _CGContextAddLineToPointCanvas(aContext, x, y) aContext.lineTo(x, y)
00038 #define _CGContextClosePathCanvas(aContext) aContext.closePath()
00039 #define _CGContextMoveToPointCanvas(aContext, x, y) aContext.moveTo(x, y)
00040
00041 #define _CGContextAddRectCanvas(aContext, aRect) aContext.rect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect))
00042 #define _CGContextBeginPathCanvas(aContext) aContext.beginPath()
00043 #define _CGContextFillRectCanvas(aContext, aRect) aContext.fillRect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect))
00044 #define _CGContextClipCanvas(aContext) aContext.clip()
00045
00046 function CGContextSaveGState(aContext)
00047 {
00048 aContext.save();
00049 }
00050
00051 function CGContextRestoreGState(aContext)
00052 {
00053 aContext.restore();
00054 }
00055
00056 function CGContextSetLineCap(aContext, aLineCap)
00057 {
00058 aContext.lineCap = CANVAS_LINECAP_TABLE[aLineCap];
00059 }
00060
00061 function CGContextSetLineJoin(aContext, aLineJoin)
00062 {
00063 aContext.lineJoin = CANVAS_LINEJOIN_TABLE[aLineJoin];
00064 }
00065
00066 function CGContextSetLineWidth(aContext, aLineWidth)
00067 {
00068 aContext.lineWidth = aLineWidth;
00069 }
00070
00071 function CGContextSetMiterLimit(aContext, aMiterLimit)
00072 {
00073 aContext.miterLimit = aMiterLimit;
00074 }
00075
00076 function CGContextSetBlendMode(aContext, aBlendMode)
00077 {
00078 aContext.globalCompositeOperation = CANVAS_COMPOSITE_TABLE[aBlendMode];
00079 }
00080
00081 function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise)
00082 {
00083
00084
00085 _CGContextAddArcCanvas(aContext, x, y, radius, startAngle, endAngle, !clockwise);
00086 }
00087
00088 function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
00089 {
00090 _CGContextAddArcToPointCanvas(aContext, x1, y1, x2, y2, radius);
00091 }
00092
00093 function CGContextAddCurveToPoint(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
00094 {
00095 _CGContextAddCurveToPointCanvas(aContext, cp1x, cp1y, cp2x, cp2y, x, y);
00096 }
00097
00098 function CGContextAddLineToPoint(aContext, x, y)
00099 {
00100 _CGContextAddLineToPointCanvas(aContext, x, y);
00101 }
00102
00103 function CGContextAddPath(aContext, aPath)
00104 {
00105 if (!aContext || CGPathIsEmpty(aPath))
00106 return;
00107
00108 var elements = aPath.elements,
00109
00110 i = 0,
00111 count = aPath.count;
00112
00113 for (; i < count; ++i)
00114 {
00115 var element = elements[i],
00116 type = element.type;
00117
00118 switch (type)
00119 {
00120 case kCGPathElementMoveToPoint: _CGContextMoveToPointCanvas(aContext, element.x, element.y);
00121 break;
00122 case kCGPathElementAddLineToPoint: _CGContextAddLineToPointCanvas(aContext, element.x, element.y);
00123 break;
00124 case kCGPathElementAddQuadCurveToPoint: _CGContextAddQuadCurveToPointCanvas(aContext, element.cpx, element.cpy, element.x, element.y);
00125 break;
00126 case kCGPathElementAddCurveToPoint: _CGContextAddCurveToPointCanvas(aContext, element.cp1x, element.cp1y, element.cp2x, element.cp2y, element.x, element.y);
00127 break;
00128 case kCGPathElementCloseSubpath: _CGContextClosePathCanvas(aContext);
00129 break;
00130 case kCGPathElementAddArc: _CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
00131 break;
00132 case kCGPathElementAddArcTo:
00133 break;
00134 }
00135 }
00136 }
00137
00138 function CGContextAddRect(aContext, aRect)
00139 {
00140 _CGContextAddRectCanvas(aContext, aRect);
00141 }
00142
00143 function CGContextAddRects(aContext, rects, count)
00144 {
00145 var i = 0;
00146
00147 if (arguments["count"] == NULL)
00148 var count = rects.length;
00149
00150 for (; i < count; ++i)
00151 {
00152 var rect = rects[i];
00153 _CGContextAddRectCanvas(aContext, rect);
00154 }
00155 }
00156
00157 function CGContextBeginPath(aContext)
00158 {
00159 _CGContextBeginPathCanvas(aContext);
00160 }
00161
00162 function CGContextClosePath(aContext)
00163 {
00164 _CGContextClosePathCanvas(aContext);
00165 }
00166
00167 function CGContextMoveToPoint(aContext, x, y)
00168 {
00169 _CGContextMoveToPointCanvas(aContext, x, y);
00170 }
00171
00172 function CGContextClearRect(aContext, aRect)
00173 {
00174 aContext.clearRect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
00175 }
00176
00177 function CGContextDrawPath(aContext, aMode)
00178 {
00179 if (aMode == kCGPathFill || aMode == kCGPathFillStroke)
00180 aContext.fill();
00181 else if (aMode == kCGPathEOFill || aMode == kCGPathEOFillStroke)
00182 alert("not implemented!!!");
00183
00184 if (aMode == kCGPathStroke || aMode == kCGPathFillStroke || aMode == kCGPathEOFillStroke)
00185 aContext.stroke();
00186 }
00187
00188 function CGContextFillRect(aContext, aRect)
00189 {
00190 _CGContextFillRectCanvas(aContext, aRect);
00191 }
00192
00193 function CGContextFillRects(aContext, rects, count)
00194 {
00195 var i = 0;
00196
00197 if (arguments["count"] == NULL)
00198 var count = rects.length;
00199
00200 for (; i < count; ++i)
00201 {
00202 var rect = rects[i];
00203 _CGContextFillRectCanvas(aContext, rect);
00204 }
00205 }
00206
00207 function CGContextStrokeRect(aContext, aRect)
00208 {
00209 aContext.strokeRect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
00210 }
00211
00212 function CGContextClip(aContext)
00213 {
00214 _CGContextClipCanvas(aContext);
00215 }
00216
00217 function CGContextClipToRect(aContext, aRect)
00218 {
00219 _CGContextBeginPathCanvas(aContext);
00220 _CGContextAddRectCanvas(aContext, aRect);
00221 _CGContextClosePathCanvas(aContext);
00222
00223 _CGContextClipCanvas(aContext);
00224 }
00225
00226 function CGContextClipToRects(aContext, rects, count)
00227 {
00228 if (arguments["count"] == NULL)
00229 var count = rects.length;
00230
00231 _CGContextBeginPathCanvas(aContext);
00232 CGContextAddRects(aContext, rects, count);
00233 _CGContextClipCanvas(aContext);
00234 }
00235
00236 function CGContextSetAlpha(aContext, anAlpha)
00237 {
00238 aContext.globalAlpha = anAlpha;
00239 }
00240
00241 function CGContextSetFillColor(aContext, aColor)
00242 {
00243 aContext.fillStyle = [aColor cssString];
00244 }
00245
00246 function CGContextSetStrokeColor(aContext, aColor)
00247 {
00248 aContext.strokeStyle = [aColor cssString];
00249 }
00250
00251 function CGContextSetShadow(aContext, aSize, aBlur)
00252 {
00253 aContext.shadowOffsetX = aSize.width;
00254 aContext.shadowOffsetY = aSize.height;
00255 aContext.shadowBlur = aBlur;
00256 }
00257
00258 function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
00259 {
00260 aContext.shadowOffsetX = aSize.width;
00261 aContext.shadowOffsetY = aSize.height;
00262 aContext.shadowBlur = aBlur;
00263 aContext.shadowColor = [aColor cssString];
00264 }
00265
00266 function CGContextRotateCTM(aContext, anAngle)
00267 {
00268 aContext.rotate(anAngle);
00269 }
00270
00271 function CGContextScaleCTM(aContext, sx, sy)
00272 {
00273 aContext.scale(sx, sy);
00274 }
00275
00276 function CGContextTranslateCTM(aContext, tx, ty)
00277 {
00278 aContext.translate(tx, ty);
00279 }
00280
00281 #define scale_rotate(a, b, c, d) \
00282 var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0, \
00283 a2 = (ATAN2(b, d) + ATAN2(-sign * c, sign * a)) / 2.0, \
00284 cos = COS(a2),\
00285 sin = SIN(a2);\
00286 \
00287 if (cos == 0)\
00288 {\
00289 sx = -c / sin;\
00290 sy = b / sin;\
00291 }\
00292 else if (sin == 0)\
00293 {\
00294 sx = a / cos;\
00295 sy = d / cos;\
00296 }\
00297 else\
00298 {\
00299 abs_cos = ABS(cos);\
00300 abs_sin = ABS(sin);\
00301 \
00302 sx = (abs_cos * a / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);\
00303 sy = (abs_cos * d / cos + abs_sin * b / sin) / (abs_cos + abs_sin);\
00304 }\
00305
00306 #define rotate_scale(a, b, c, d) \
00307 var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0;\
00308 a1 = (Math.atan2(sign * b, sign * a) + Math.atan2(-c, d)) / 2.0,\
00309 cos = COS(a1),\
00310 sin = SIN(a1);\
00311 \
00312 if (cos == 0)\
00313 {\
00314 sx = b / sin;\
00315 sy = -c / sin;\
00316 }\
00317 else if (sin == 0)\
00318 {\
00319 sx = a / cos;\
00320 sy = d / cos;\
00321 }\
00322 else\
00323 {\
00324 abs_cos = ABS(cos);\
00325 abs_sin = ABS(sin);\
00326 \
00327 sx = (abs_cos * a / cos + abs_sin * b / sin) / (abs_cos + abs_sin);\
00328 sy = (abs_cos * d / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);\
00329 }\
00330
00331 function eigen(anAffineTransform)
00332 {
00333 alert("IMPLEMENT ME!");
00334 }
00335
00336
00337 if (CPFeatureIsCompatible(CPJavaScriptCanvasTransformFeature))
00338 {
00339
00340 CGContextConcatCTM = function(aContext, anAffineTransform)
00341 {
00342 aContext.transform(anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty);
00343 }
00344
00345 }
00346 else
00347 {
00348
00349 CGContextConcatCTM = function(aContext, anAffineTransform)
00350 {
00351 var a = anAffineTransform.a,
00352 b = anAffineTransform.b,
00353 c = anAffineTransform.c,
00354 d = anAffineTransform.d,
00355 tx = anAffineTransform.tx,
00356 ty = anAffineTransform.ty,
00357 sx = 1.0,
00358 sy = 1.0,
00359 a1 = 0.0,
00360 a2 = 0.0;
00361
00362
00363 if (b == 0.0 && c == 0.0)
00364 {
00365 sx = a;
00366 sy = d;
00367 }
00368
00369
00370 else if (a * b == -c * d)
00371 {
00372 scale_rotate(a, b, c, d)
00373 }
00374
00375
00376 else if (a * c == -b * d)
00377 {
00378 rotate_scale(a, b, c, d)
00379 }
00380 else
00381 {
00382 var transpose = CGAffineTransformMake(a, c, b, d, 0.0, 0.0),
00383 u = eigen(CGAffineTransformConcat(anAffineTransform, transpose)),
00384 v = eigen(CGAffineTransformConcat(transpose, anAffineTransform)),
00385 U = CGAffineTransformMake(u.vector_1.x, u.vector_2.x, u.vector_1.y, u.vector_2.y, 0.0, 0.0),
00386 VT = CGAffineTransformMake(v.vector_1.x, v.vector_1.y, v.vector_2.x, v.vector_2.y, 0.0, 0.0),
00387 S = CGAffineTransformConcat(CGAffineTransformConcat(CGAffineTransformInvert(U), anAffineTransform), CGAffineTransformInvert(VT));
00388
00389 a = VT.a;
00390 b = VT.b;
00391 c = VT.c;
00392 d = VT.d;
00393 scale_rotate(a, b, c, d)
00394 S.a *= sx;
00395 S.d *= sy;
00396 a = U.a;
00397 b = U.b;
00398 c = U.c;
00399 d = U.d;
00400 rotate_scale(a, b, c, d)
00401 sx = S.a * sx;
00402 sy = S.d * sy;
00403 }
00404
00405 if (tx != 0 || ty != 0)
00406 CGContextTranslateCTM(aContext, tx, ty);
00407 if (a1 != 0.0)
00408 CGContextRotateCTM(aContext, a1);
00409 if (sx != 1.0 || sy != 1.0)
00410 CGContextScaleCTM(aContext, sx, sy);
00411 if (a2 != 0.0)
00412 CGContextRotateCTM(aContext, a2);
00413 }
00414
00415 }
00416
00417 function CGContextDrawImage(aContext, aRect, anImage)
00418 {
00419 aContext.drawImage(anImage._image, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
00420 }
00421
00422 function to_string(aColor)
00423 {
00424 return "rgba(" + ROUND(aColor.components[0] * 255) + ", " + ROUND(aColor.components[1] * 255) + ", " + ROUND(255 * aColor.components[2]) + ", " + aColor.components[3] + ")";
00425 }
00426
00427 function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoint, options)
00428 {
00429 var colors = aGradient.colors,
00430 count = colors.length,
00431
00432 linearGradient = aContext.createLinearGradient(aStartPoint.x, aStartPoint.y, anEndPoint.x, anEndPoint.y);
00433
00434 while (count--)
00435 linearGradient.addColorStop(aGradient.locations[count], to_string(colors[count]));
00436
00437 aContext.fillStyle = linearGradient;
00438 aContext.fill();
00439 }
00440
00441 function CGBitmapGraphicsContextCreate()
00442 {
00443 var DOMElement = document.createElement("canvas"),
00444 context = DOMElement.getContext("2d");
00445
00446 context.DOMElement = DOMElement;
00447
00448 return context;
00449 }