API  0.9.10
CGContextCanvas.j
Go to the documentation of this file.
1 /*
2  * CGContextCanvas.j
3  * AppKit
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 var CANVAS_LINECAP_TABLE = [ "butt", "round", "square" ],
24  CANVAS_LINEJOIN_TABLE = [ "miter", "round", "bevel" ],
25  CANVAS_COMPOSITE_TABLE = [ "source-over", "source-over", "source-over", "source-over", "darker",
26  "lighter", "source-over", "source-over", "source-over", "source-over",
27  "source-over", "source-over", "source-over", "source-over", "source-over",
28  "source-over", "source-over",
29  "copy", "source-in", "source-out", "source-atop",
30  "destination-over", "destination-in", "destination-out", "destination-atop",
31  "xor", "source-over", "source-over" ];
32 
33 #define _CGContextAddArcCanvas(aContext, x, y, radius, startAngle, endAngle, anticlockwise) aContext.arc(x, y, radius, startAngle, endAngle, anticlockwise)
34 #define _CGContextAddArcToPointCanvas(aContext, x1, y1, x2, y2, radius) aContext.arcTo(x1, y1, x2, y2, radius)
35 #define _CGContextAddCurveToPointCanvas(aContext, cp1x, cp1y, cp2x, cp2y, x, y) aContext.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
36 #define _CGContextAddQuadCurveToPointCanvas(aContext, cpx, cpy, x, y) aContext.quadraticCurveTo(cpx, cpy, x, y)
37 #define _CGContextAddLineToPointCanvas(aContext, x, y) aContext.lineTo(x, y)
38 #define _CGContextClosePathCanvas(aContext) aContext.closePath()
39 #define _CGContextMoveToPointCanvas(aContext, x, y) aContext.moveTo(x, y)
40 
41 #define _CGContextAddRectCanvas(aContext, aRect) aContext.rect(CGRectGetMinX(aRect), CGRectGetMinY(aRect), CGRectGetWidth(aRect), CGRectGetHeight(aRect))
42 #define _CGContextBeginPathCanvas(aContext) aContext.beginPath()
43 #define _CGContextFillRectCanvas(aContext, aRect) aContext.fillRect(CGRectGetMinX(aRect), CGRectGetMinY(aRect), CGRectGetWidth(aRect), CGRectGetHeight(aRect))
44 #define _CGContextClipCanvas(aContext) aContext.clip()
45 
46 // In Cocoa, all primitives excepts rects and arcs cannot be added to the context's path
47 // until a move to point has been done, because an empty path has no current point.
48 var hasPath = function(aContext, methodName)
49 {
50  if (!aContext.hasPath)
51  CPLog.error(methodName + ": no current point");
52 
53  return aContext.hasPath;
54 }
55 
56 function CGContextSaveGState(aContext)
57 {
58  aContext.save();
59 }
60 
61 function CGContextRestoreGState(aContext)
62 {
63  aContext.restore();
64 }
65 
66 function CGContextSetLineCap(aContext, aLineCap)
67 {
68  aContext.lineCap = CANVAS_LINECAP_TABLE[aLineCap];
69 }
70 
71 function CGContextSetLineDash(aContext, aPhase, someDashes)
72 {
73  if (aContext.setLineDash)
74  {
75  aContext.setLineDash(someDashes);
76  aContext.lineDashOffset = aPhase;
77  }
78  else if (typeof aContext['webkitLineDash'] !== 'undefined')
79  {
80  aContext.webkitLineDash = someDashes;
81  aContext.webkitLineDashOffset = aPhase;
82  }
83  else if (typeof aContext['mozDash'] !== 'undefined')
84  {
85  aContext.mozDash = someDashes;
86  aContext.mozDashOffset = aPhase;
87  }
88  else if (someDashes)
89  {
90  CPLog.warn("CGContextSetLineDash not implemented in this environment.")
91  }
92 }
93 
94 function CGContextSetLineJoin(aContext, aLineJoin)
95 {
96  aContext.lineJoin = CANVAS_LINEJOIN_TABLE[aLineJoin];
97 }
98 
99 function CGContextSetLineWidth(aContext, aLineWidth)
100 {
101  aContext.lineWidth = aLineWidth;
102 }
103 
104 function CGContextSetMiterLimit(aContext, aMiterLimit)
105 {
106  aContext.miterLimit = aMiterLimit;
107 }
108 
109 function CGContextSetBlendMode(aContext, aBlendMode)
110 {
111  aContext.globalCompositeOperation = CANVAS_COMPOSITE_TABLE[aBlendMode];
112 }
113 
114 function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise)
115 {
116  // Despite the documentation saying otherwise, the last parameter is anti-clockwise not clockwise.
117  // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes#Arcs
118  _CGContextAddArcCanvas(aContext, x, y, radius, startAngle, endAngle, !clockwise);
119 
120  // AddArc implicitly starts a path
121  aContext.hasPath = YES;
122 }
123 
124 function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
125 {
126  if (!hasPath(aContext, "CGContextAddArcToPoint"))
127  return;
128 
129  _CGContextAddArcToPointCanvas(aContext, x1, y1, x2, y2, radius);
130 }
131 
132 function CGContextAddCurveToPoint(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
133 {
134  if (!hasPath(aContext, "CGContextAddCurveToPoint"))
135  return;
136 
137  _CGContextAddCurveToPointCanvas(aContext, cp1x, cp1y, cp2x, cp2y, x, y);
138 }
139 
140 function CGContextAddLines(aContext, points, count)
141 {
142  // implementation mirrors that of CGPathAddLines()
143  if (count === null || count === undefined)
144  count = points.length;
145 
146  if (count < 1)
147  return;
148 
149  _CGContextMoveToPointCanvas(aContext, points[0].x, points[0].y);
150 
151  for (var i = 1; i < count; ++i)
152  _CGContextAddLineToPointCanvas(aContext, points[i].x, points[i].y);
153 
154  aContext.hasPath = YES;
155 }
156 
157 function CGContextAddLineToPoint(aContext, x, y)
158 {
159  if (!hasPath(aContext, "CGContextAddLineToPoint"))
160  return;
161 
162  _CGContextAddLineToPointCanvas(aContext, x, y);
163 }
164 
165 function CGContextAddPath(aContext, aPath)
166 {
167  if (!aContext || CGPathIsEmpty(aPath))
168  return;
169 
170  // If the context does not have a path, explicitly begin one
171  if (!aContext.hasPath)
172  _CGContextBeginPathCanvas(aContext);
173 
174  // We must implicitly move to the start of the path
175  _CGContextMoveToPointCanvas(aContext, aPath.start.x, aPath.start.y);
176 
177  var elements = aPath.elements,
178  i = 0,
179  count = aPath.count;
180 
181  for (; i < count; ++i)
182  {
183  var element = elements[i],
184  type = element.type;
185 
186  switch (type)
187  {
189  _CGContextMoveToPointCanvas(aContext, element.x, element.y);
190  break;
191 
193  _CGContextAddLineToPointCanvas(aContext, element.x, element.y);
194  break;
195 
197  _CGContextAddQuadCurveToPointCanvas(aContext, element.cpx, element.cpy, element.x, element.y);
198  break;
199 
201  _CGContextAddCurveToPointCanvas(aContext, element.cp1x, element.cp1y, element.cp2x, element.cp2y, element.x, element.y);
202  break;
203 
205  _CGContextClosePathCanvas(aContext);
206  break;
207 
209  _CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
210  break;
211 
213  _CGContextAddArcToPointCanvas(aContext, element.p1x, element.p1y, element.p2x, element.p2y, element.radius);
214  break;
215  }
216  }
217 
218  aContext.hasPath = YES;
219 }
220 
221 function CGContextAddRect(aContext, aRect)
222 {
223  _CGContextAddRectCanvas(aContext, aRect);
224  aContext.hasPath = YES;
225 }
226 
227 function CGContextAddQuadCurveToPoint(aContext, cpx, cpy, x, y)
228 {
229  if (!hasPath(aContext, "CGContextAddQuadCurveToPoint"))
230  return;
231 
232  _CGContextAddQuadCurveToPointCanvas(aContext, cpx, cpy, x, y);
233 }
234 
235 function CGContextAddRects(aContext, rects, count)
236 {
237  if (count === null || count === undefined)
238  count = rects.length;
239 
240  for (var i = 0; i < count; ++i)
241  {
242  var rect = rects[i];
243  _CGContextAddRectCanvas(aContext, rect);
244  }
245 
246  aContext.hasPath = YES;
247 }
248 
249 function CGContextBeginPath(aContext)
250 {
251  _CGContextBeginPathCanvas(aContext);
252  aContext.hasPath = NO;
253 }
254 
255 function CGContextClosePath(aContext)
256 {
257  _CGContextClosePathCanvas(aContext);
258 }
259 
260 function CGContextIsPathEmpty(aContext)
261 {
262  return !aContext.hasPath;
263 }
264 
265 function CGContextMoveToPoint(aContext, x, y)
266 {
267  _CGContextMoveToPointCanvas(aContext, x, y);
268  aContext.hasPath = YES;
269 }
270 
271 function CGContextClearRect(aContext, aRect)
272 {
273  aContext.clearRect(CGRectGetMinX(aRect), CGRectGetMinY(aRect), CGRectGetWidth(aRect), CGRectGetHeight(aRect));
274  aContext.hasPath = NO;
275 }
276 
277 function CGContextDrawPath(aContext, aMode)
278 {
279  if (!aContext.hasPath)
280  return;
281 
282  if (aMode === kCGPathFill || aMode === kCGPathFillStroke)
283  aContext.fill();
284  else if (aMode === kCGPathStroke || aMode === kCGPathFillStroke || aMode === kCGPathEOFillStroke)
285  aContext.stroke();
286  else if (aMode === kCGPathEOFill || aMode === kCGPathEOFillStroke)
287  CPLog.warn("Unimplemented fill mode in CGContextDrawPath: %d", aMode);
288 
289  aContext.hasPath = NO;
290 }
291 
292 function CGContextFillRect(aContext, aRect)
293 {
294  _CGContextFillRectCanvas(aContext, aRect);
295  aContext.hasPath = NO;
296 }
297 
298 function CGContextFillRects(aContext, rects, count)
299 {
300  if (count === null || count === undefined)
301  count = rects.length;
302 
303  for (var i = 0; i < count; ++i)
304  {
305  var rect = rects[i];
306  _CGContextFillRectCanvas(aContext, rect);
307  }
308 
309  aContext.hasPath = NO;
310 }
311 
312 function CGContextStrokeRect(aContext, aRect)
313 {
314  aContext.strokeRect(CGRectGetMinX(aRect), CGRectGetMinY(aRect), CGRectGetWidth(aRect), CGRectGetHeight(aRect));
315  aContext.hasPath = NO;
316 }
317 
318 function CGContextClip(aContext)
319 {
320  _CGContextClipCanvas(aContext);
321  aContext.hasPath = NO;
322 }
323 
324 function CGContextClipToRect(aContext, aRect)
325 {
326  _CGContextBeginPathCanvas(aContext);
327  _CGContextAddRectCanvas(aContext, aRect);
328  _CGContextClosePathCanvas(aContext);
329 
330  _CGContextClipCanvas(aContext);
331  aContext.hasPath = NO;
332 }
333 
334 function CGContextClipToRects(aContext, rects, count)
335 {
336  if (count === null || count === undefined)
337  count = rects.length;
338 
339  _CGContextBeginPathCanvas(aContext);
340  CGContextAddRects(aContext, rects, count);
341  _CGContextClipCanvas(aContext);
342  aContext.hasPath = NO;
343 }
344 
345 function CGContextSetAlpha(aContext, anAlpha)
346 {
347  aContext.globalAlpha = anAlpha;
348 }
349 
350 function CGContextSetFillColor(aContext, aColor)
351 {
352  var patternImage = [aColor patternImage];
353 
354  if ([patternImage isSingleImage])
355  {
356  var pattern = aContext.createPattern([patternImage image], "repeat");
357 
358  aContext.fillStyle = pattern;
359  }
360  else
361  aContext.fillStyle = [aColor cssString];
362 }
363 
370 function CGContextCreatePatternContext(aContext, aSize)
371 {
372  var pattern = document.createElement("canvas");
373 
374  pattern.width = aSize.width;
375  pattern.height = aSize.height;
376 
377  return pattern.getContext("2d");
378 }
379 
384 function CGContextSetFillPattern(aContext, aPatternContext)
385 {
386  var pattern = aContext.createPattern(aPatternContext.canvas, "repeat");
387  aContext.fillStyle = pattern;
388 }
389 
394 function CGContextSetStrokePattern(aContext, aPatternContext)
395 {
396  var pattern = aContext.createPattern(aPatternContext.canvas, "repeat");
397  aContext.strokeStyle = pattern;
398 }
399 
400 function CGContextSetStrokeColor(aContext, aColor)
401 {
402  var patternImage = [aColor patternImage];
403 
404  if ([patternImage isSingleImage])
405  {
406  var pattern = aContext.createPattern([patternImage image], "repeat");
407 
408  aContext.strokeStyle = pattern;
409  }
410  else
411  aContext.strokeStyle = [aColor cssString];
412 }
413 
414 function CGContextSetShadow(aContext, aSize, aBlur)
415 {
416  aContext.shadowOffsetX = aSize.width;
417  aContext.shadowOffsetY = aSize.height;
418  aContext.shadowBlur = aBlur;
419 }
420 
421 function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
422 {
423  aContext.shadowOffsetX = aSize.width;
424  aContext.shadowOffsetY = aSize.height;
425  aContext.shadowBlur = aBlur;
426  aContext.shadowColor = [aColor cssString];
427 }
428 
429 function CGContextRotateCTM(aContext, anAngle)
430 {
431  aContext.rotate(anAngle);
432 }
433 
434 function CGContextScaleCTM(aContext, sx, sy)
435 {
436  aContext.scale(sx, sy);
437 }
438 
439 function CGContextTranslateCTM(aContext, tx, ty)
440 {
441  aContext.translate(tx, ty);
442 }
443 
444 var scale_rotate = function(a, b, c, d)
445 {
446  var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0,
447  a2 = (ATAN2(b, d) + ATAN2(-sign * c, sign * a)) / 2.0,
448  cos = COS(a2),
449  sin = SIN(a2);
450 
451  if (cos === 0)
452  {
453  sx = -c / sin;
454  sy = b / sin;
455  }
456  else if (sin === 0)
457  {
458  sx = a / cos;
459  sy = d / cos;
460  }
461  else
462  {
463  abs_cos = ABS(cos);
464  abs_sin = ABS(sin);
465 
466  sx = (abs_cos * a / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);
467  sy = (abs_cos * d / cos + abs_sin * b / sin) / (abs_cos + abs_sin);
468  }
469 };
470 
471 var rotate_scale = function(a, b, c, d)
472 {
473  var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0,
474  a1 = (ATAN2(sign * b, sign * a) + ATAN2(-c, d)) / 2.0,
475  cos = COS(a1),
476  sin = SIN(a1);
477 
478  if (cos === 0)
479  {
480  sx = b / sin;
481  sy = -c / sin;
482  }
483  else if (sin === 0)
484  {
485  sx = a / cos;
486  sy = d / cos;
487  }
488  else
489  {
490  abs_cos = ABS(cos);
491  abs_sin = ABS(sin);
492 
493  sx = (abs_cos * a / cos + abs_sin * b / sin) / (abs_cos + abs_sin);
494  sy = (abs_cos * d / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);
495  }
496 };
497 
498 function eigen(anAffineTransform)
499 {
500  CPLog.warn("Unimplemented function: eigen");
501 }
502 
503 
505 {
506 
507 CGContextConcatCTM = function(aContext, anAffineTransform)
508 {
509  aContext.transform(anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty);
510 };
511 
512 }
513 else
514 {
515 
516 CGContextConcatCTM = function(aContext, anAffineTransform)
517 {
518  var a = anAffineTransform.a,
519  b = anAffineTransform.b,
520  c = anAffineTransform.c,
521  d = anAffineTransform.d,
522  tx = anAffineTransform.tx,
523  ty = anAffineTransform.ty,
524  sx = 1.0,
525  sy = 1.0,
526  a1 = 0.0,
527  a2 = 0.0;
528 
529  // Detect the simple case of just scaling.
530  if (b === 0.0 && c === 0.0)
531  {
532  sx = a;
533  sy = d;
534  }
535 
536  // a scale followed by a rotate
537  else if (a * b === -c * d)
538  {
539  scale_rotate(a, b, c, d)
540  }
541 
542  // rotate, then scale.
543  else if (a * c === -b * d)
544  {
545  rotate_scale(a, b, c, d)
546  }
547  else
548  {
549  var transpose = CGAffineTransformMake(a, c, b, d, 0.0, 0.0), // inline
550  u = eigen(CGAffineTransformConcat(anAffineTransform, transpose)),
551  v = eigen(CGAffineTransformConcat(transpose, anAffineTransform)),
552  U = CGAffineTransformMake(u.vector_1.x, u.vector_2.x, u.vector_1.y, u.vector_2.y, 0.0, 0.0), // inline
553  VT = CGAffineTransformMake(v.vector_1.x, v.vector_1.y, v.vector_2.x, v.vector_2.y, 0.0, 0.0),
555 
556  a = VT.a;
557  b = VT.b;
558  c = VT.c;
559  d = VT.d;
560  scale_rotate(a, b, c, d)
561  S.a *= sx;
562  S.d *= sy;
563  a = U.a;
564  b = U.b;
565  c = U.c;
566  d = U.d;
567  rotate_scale(a, b, c, d)
568  sx = S.a * sx;
569  sy = S.d * sy;
570  }
571 
572  if (tx != 0 || ty != 0)
573  CGContextTranslateCTM(aContext, tx, ty);
574  if (a1 != 0.0)
575  CGContextRotateCTM(aContext, a1);
576  if (sx != 1.0 || sy != 1.0)
577  CGContextScaleCTM(aContext, sx, sy);
578  if (a2 != 0.0)
579  CGContextRotateCTM(aContext, a2);
580 };
581 
582 }
583 
584 function CGContextDrawImage(aContext, aRect, anImage)
585 {
586  aContext.drawImage(anImage._image, CGRectGetMinX(aRect), CGRectGetMinY(aRect), CGRectGetWidth(aRect), CGRectGetHeight(aRect));
587  aContext.hasPath = NO;
588 }
589 
590 function to_string(aColor)
591 {
592  return "rgba(" + ROUND(aColor.components[0] * 255) + ", " + ROUND(aColor.components[1] * 255) + ", " + ROUND(255 * aColor.components[2]) + ", " + aColor.components[3] + ")";
593 }
594 
595 function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoint, options)
596 {
597  var colors = aGradient.colors,
598  count = colors.length,
599  linearGradient = aContext.createLinearGradient(aStartPoint.x, aStartPoint.y, anEndPoint.x, anEndPoint.y);
600 
601  while (count--)
602  linearGradient.addColorStop(aGradient.locations[count], to_string(colors[count]));
603 
604  aContext.fillStyle = linearGradient;
605  aContext.fill();
606  aContext.hasPath = NO;
607 }
608 
609 function CGContextDrawRadialGradient(aContext, aGradient, aStartCenter, aStartRadius, anEndCenter, anEndRadius, options)
610 {
611  var colors = aGradient.colors,
612  count = colors.length,
613  linearGradient = aContext.createRadialGradient(aStartCenter.x, aStartCenter.y, aStartRadius, anEndCenter.x, anEndCenter.y, anEndRadius);
614 
615  while (count--)
616  linearGradient.addColorStop(aGradient.locations[count], to_string(colors[count]));
617 
618  aContext.fillStyle = linearGradient;
619  aContext.fill();
620  aContext.hasPath = NO;
621 }
622 
624 {
625  var DOMElement = document.createElement("canvas"),
626  context = DOMElement.getContext("2d");
627 
628  context.DOMElement = DOMElement;
629 
630  // canvas gives us no way to query whether the path is empty or not, so we have to track it ourselves
631  context.hasPath = NO;
632 
633  return context;
634 }
function CGContextSetBlendMode(aContext, aBlendMode)
Definition: CGContext.j:187
function CGContextTranslateCTM(aContext, tx, ty)
Definition: CGContext.j:472
function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
Definition: CGContext.j:504
function CGBitmapGraphicsContextCreate()
var hasPath
function CGContextDrawImage(aContext, aRect, anImage)
function CGContextAddRects(aContext, rects, count)
Definition: CGContext.j:301
CGPath kCGPathElementMoveToPoint
Definition: CGPath.j:26
function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
Definition: CGContext.j:207
function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoint, options)
kCGPathEOFill
Definition: CGContext.j:35
function CGContextSetStrokeColor(aContext, aColor)
Definition: CGContext.j:675
function CGContextSetMiterLimit(aContext, aMiterLimit)
Definition: CGContext.j:182
function eigen(anAffineTransform)
function CGContextSetLineJoin(aContext, aLineJoin)
Definition: CGContext.j:172
function CGContextScaleCTM(aContext, sx, sy)
Definition: CGContext.j:458
function CGContextRestoreGState(aContext)
Definition: CGContext.j:156
function CGContextSetShadow(aContext, aSize, aBlur)
Definition: CGContext.j:487
function CGContextSetLineCap(aContext, aLineCap)
Definition: CGContext.j:161
function CGContextDrawRadialGradient(aContext, aGradient, aStartCenter, aStartRadius, anEndCenter, anEndRadius, options)
function CGContextDrawPath(aContext, aMode)
Definition: CGContextVML.j:119
function to_string(aColor)
function CGContextAddLineToPoint(aContext, x, y)
Definition: CGContext.j:247
kCGPathElementAddLineToPoint
Definition: CGPath.j:27
function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise)
Definition: CGContext.j:192
function CGContextSetLineWidth(aContext, aLineWidth)
Definition: CGContext.j:177
var CANVAS_LINECAP_TABLE
function CGContextClosePath(aContext)
Definition: CGContext.j:322
kCGPathFillStroke
Definition: CGContext.j:37
kCGPathElementAddArcToPoint
Definition: CGPath.j:33
function CGContextFillRects(aContext, rects, count)
Definition: CGContext.j:370
function CGContextSetLineDash(aContext, aPhase, someDashes)
Definition: CGContext.j:166
kCGPathEOFillStroke
Definition: CGContext.j:38
function CGContextAddPath(aContext, aPath)
Definition: CGContext.j:258
function CGContextSetAlpha(aContext, anAlpha)
Definition: CGContext.j:519
function CPFeatureIsCompatible(aFeature)
function CGPathIsEmpty(aPath)
Definition: CGPath.j:505
function CGContextSetFillColor(aContext, aColor)
Definition: CGContext.j:663
kCGPathElementAddArc
Definition: CGPath.j:32
var rotate_scale
function CGContextRotateCTM(aContext, anAngle)
Definition: CGContext.j:444
kCGPathElementCloseSubpath
Definition: CGPath.j:30
kCGPathStroke
Definition: CGContext.j:36
function CGContextBeginPath(aContext)
Definition: CGContext.j:311
function CGAffineTransformInvert(aTransform)
function CGContextClearRect(aContext, aRect)
Definition: CGContextVML.j:51
var CANVAS_LINEJOIN_TABLE
CGAffineTransform function CGAffineTransformMake(a, b, c, d, tx, ty)
function CGContextIsPathEmpty(aContext)
Definition: CGContext.j:332
function CGContextAddCurveToPoint(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
Definition: CGContext.j:223
CPJavaScriptCanvasTransformFeature
function CGContextStrokeRect(aContext, aRect)
Definition: CGContext.j:388
function CGContextSaveGState(aContext)
Definition: CGContext.j:146
var CANVAS_COMPOSITE_TABLE
kCGPathElementAddCurveToPoint
Definition: CGPath.j:29
function CGContextFillRect(aContext, aRect)
Definition: CGContext.j:358
function CGContextConcatCTM(aContext, aTransform)
Definition: CGContext.j:420
kCGPathElementAddQuadCurveToPoint
Definition: CGPath.j:28
function CGContextMoveToPoint(aContext, x, y)
Definition: CGContext.j:344
kCGPathFill
Definition: CGContext.j:34
function CGAffineTransformConcat(lhs, rhs)
function CGContextAddRect(aContext, aRect)
Definition: CGContext.j:289
function CGContextAddLines(aContext, points, count)
Definition: CGContext.j:235
function CGContextAddQuadCurveToPoint(aContext, cpx, cpy, x, y)
Definition: CGContext.j:278