Cappuccino  1.0.0
 All Classes Files Functions Variables Typedefs Macros Groups Pages
CGContext.j
Go to the documentation of this file.
1 /*
2  * CGContext.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 
24 @typedef CGContext
25 
29 
33 
39 
72 
83 function CGContextRelease()
84 {
85 }
86 
93 function CGContextRetain(aContext)
94 {
95  return aContext;
96 }
97 
101 // BEGIN CANVAS IF
103 {
112 function CGGStateCreate()
113 {
114  return { alpha:1.0, strokeStyle:"#000", fillStyle:"#ccc", lineWidth:1.0, lineJoin:kCGLineJoinMiter, lineCap:kCGLineCapButt, miterLimit:10.0, globalAlpha:1.0,
115  blendMode:kCGBlendModeNormal,
116  shadowOffset:CGSizeMakeZero(), shadowBlur:0.0, shadowColor:NULL, CTM:CGAffineTransformMakeIdentity() };
117 }
118 
124 function CGGStateCreateCopy(aGState)
125 {
126  return { alpha:aGState.alpha, strokeStyle:aGState.strokeStyle, fillStyle:aGState.fillStyle, lineWidth:aGState.lineWidth,
127  lineJoin:aGState.lineJoin, lineCap:aGState.lineCap, miterLimit:aGState.miterLimit, globalAlpha:aGState.globalAlpha,
128  blendMode:aGState.blendMode,
129  shadowOffset:CGSizeMakeCopy(aGState.shadowOffset), shadowBlur:aGState.shadowBlur, shadowColor:aGState.shadowColor, CTM:CGAffineTransformMakeCopy(aGState.CTM) };
130 }
131 
137 {
138  return { DOMElement:document.createElement("div"), path:NULL, gState:CGGStateCreate(), gStateStack:[] };
139 }
140 
146 function CGContextSaveGState(aContext)
147 {
148  aContext.gStateStack.push(CGGStateCreateCopy(aContext.gState));
149 }
150 
156 function CGContextRestoreGState(aContext)
157 {
158  aContext.gState = aContext.gStateStack.pop();
159 }
160 
161 function CGContextSetLineCap(aContext, aLineCap)
162 {
163  aContext.gState.lineCap = aLineCap;
164 }
165 
166 function CGContextSetLineDash(aContext, aPhase, someDashes)
167 {
168  aContext.gState.lineDashes = someDashes;
169  aContext.gState.lineDashesPhase = aPhase;
170 }
171 
172 function CGContextSetLineJoin(aContext, aLineJoin)
173 {
174  aContext.gState.lineJoin = aLineJoin;
175 }
176 
177 function CGContextSetLineWidth(aContext, aLineWidth)
178 {
179  aContext.gState.lineWidth = aLineWidth;
180 }
181 
182 function CGContextSetMiterLimit(aContext, aMiterLimit)
183 {
184  aContext.gState.miterLimit = aMiterLimit;
185 }
186 
187 function CGContextSetBlendMode(aContext, aBlendMode)
188 {
189  aContext.gState.blendMode = aBlendMode;
190 }
191 
192 function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise)
193 {
194  CGPathAddArc(aContext.path, aContext.gState.CTM, x, y, radius, startAngle, endAngle, clockwise);
195 }
196 
207 function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
208 {
209  CGPathAddArcToPoint(aContext.path, aContext.gState.CTM, x1, y1, x2, y2, radius);
210 }
211 
223 function CGContextAddCurveToPoint(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
224 {
225  CGPathAddCurveToPoint(aContext.path, aContext.gState.CTM, cp1x, cp1y, cp2x, cp2y, x, y);
226 }
227 
235 function CGContextAddLines(aContext, points, count)
236 {
237  CGPathAddLines(aContext.path, aContext.gState.CTM, points, count);
238 }
239 
247 function CGContextAddLineToPoint(aContext, x, y)
248 {
249  CGPathAddLineToPoint(aContext.path, aContext.gState.CTM, x, y);
250 }
251 
258 function CGContextAddPath(aContext, aPath)
259 {
260  if (!aContext || CGPathIsEmpty(aPath))
261  return;
262 
263  if (!aContext.path)
264  aContext.path = CGPathCreateMutable();
265 
266  CGPathAddPath(aContext.path, aContext.gState.CTM, aPath);
267 }
268 
278 function CGContextAddQuadCurveToPoint(aContext, cpx, cpy, x, y)
279 {
280  CGPathAddQuadCurveToPoint(aContext.path, aContext.gState.CTM, cpx, cpy, x, y);
281 }
282 
289 function CGContextAddRect(aContext, aRect)
290 {
291  CGPathAddRect(aContext.path, aContext.gState.CTM, aRect);
292 }
293 
301 function CGContextAddRects(aContext, rects, count)
302 {
303  CGPathAddRects(aContext.path, aContext.gState.CTM, rects, count);
304 }
305 
311 function CGContextBeginPath(aContext)
312 {
313  // This clears any previous path.
314  aContext.path = CGPathCreateMutable();
315 }
316 
322 function CGContextClosePath(aContext)
323 {
324  CGPathCloseSubpath(aContext.path);
325 }
326 
332 function CGContextIsPathEmpty(aContext)
333 {
334  return (!aContext.path || CGPathIsEmpty(aContext.path));
335 }
336 
344 function CGContextMoveToPoint(aContext, x, y)
345 {
346  if (!aContext.path)
347  aContext.path = CGPathCreateMutable();
348 
349  CGPathMoveToPoint(aContext.path, aContext.gState.CTM, x, y);
350 }
351 
358 function CGContextFillRect(aContext, aRect)
359 {
360  CGContextFillRects(aContext, [aRect], 1);
361 }
362 
370 function CGContextFillRects(aContext, rects, count)
371 {
372  if (arguments[2] === undefined)
373  var count = rects.length;
374 
375  CGContextBeginPath(aContext);
376  CGContextAddRects(aContext, rects, count);
377  CGContextClosePath(aContext);
378 
379  CGContextDrawPath(aContext, kCGPathFill);
380 }
381 
388 function CGContextStrokeRect(aContext, aRect)
389 {
390  CGContextBeginPath(aContext);
391  CGContextAddRect(aContext, aRect);
392  CGContextClosePath(aContext);
393 
394  CGContextDrawPath(aContext, kCGPathStroke);
395 }
396 
404 function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
405 {
406  CGContextSaveGState(aContext);
407 
408  CGContextSetLineWidth(aContext, aWidth);
409  CGContextStrokeRect(aContext, aRect);
410 
411  CGContextRestoreGState(aContext);
412 }
413 
420 function CGContextConcatCTM(aContext, aTransform)
421 {
422  var CTM = aContext.gState.CTM;
423 
424  CGAffineTransformConcatTo(CTM, aTransform, CTM);
425 }
426 
432 function CGContextGetCTM(aContext)
433 {
434  return aContext.gState.CTM;
435 }
436 
444 function CGContextRotateCTM(aContext, anAngle)
445 {
446  var gState = aContext.gState;
447 
448  gState.CTM = CGAffineTransformRotate(gState.CTM, anAngle);
449 }
450 
458 function CGContextScaleCTM(aContext, sx, sy)
459 {
460  var gState = aContext.gState;
461 
462  gState.CTM = CGAffineTransformScale(gState.CTM, sx, sy);
463 }
464 
472 function CGContextTranslateCTM(aContext, tx, ty)
473 {
474  var gState = aContext.gState;
475 
476  gState.CTM = CGAffineTransformTranslate(gState.CTM, tx, ty);
477 }
478 
487 function CGContextSetShadow(aContext, aSize, aBlur)
488 {
489  var gState = aContext.gState;
490 
491  gState.shadowOffset = CGSizeMakeCopy(aSize);
492  gState.shadowBlur = aBlur;
493  gState.shadowColor = [CPColor shadowColor];
494 }
495 
504 function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
505 {
506  var gState = aContext.gState;
507 
508  gState.shadowOffset = CGSizeMakeCopy(aSize);
509  gState.shadowBlur = aBlur;
510  gState.shadowColor = aColor;
511 }
512 
519 function CGContextSetAlpha(aContext, anAlpha)
520 {
521  aContext.gState.alpha = MAX(MIN(anAlpha, 1.0), 0.0);
522 }
523 
527 } // END CANVAS IF
532 // GOOD.
538 function CGContextEOFillPath(aContext)
539 {
540  CGContextDrawPath(aContext, kCGPathEOFill);
541 }
542 
548 function CGContextFillPath(aContext)
549 {
550  CGContextDrawPath(aContext, kCGPathFill);
551  CGContextClosePath(aContext);
552 }
553 
561 function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
562 {
563  CGContextSaveGState(aContext);
564 
565  CGContextSetLineWidth(aContext, aWidth);
566  CGContextStrokeRect(aContext, aRect);
567 
568  CGContextRestoreGState(aContext);
569 }
570 
571 var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
572 
579 function CGContextAddEllipseInRect(aContext, aRect)
580 {
581  CGContextBeginPath(aContext);
582  CGContextAddPath(aContext, CGPathWithEllipseInRect(aRect));
583  CGContextClosePath(aContext);
584 }
585 
592 function CGContextFillEllipseInRect(aContext, aRect)
593 {
594  CGContextBeginPath(aContext);
595  CGContextAddEllipseInRect(aContext, aRect);
596  CGContextClosePath(aContext);
597  CGContextFillPath(aContext);
598 }
599 
606 function CGContextStrokeEllipseInRect(aContext, aRect)
607 {
608  CGContextBeginPath(aContext);
609  CGContextAddEllipseInRect(aContext, aRect);
610  CGContextClosePath(aContext);
611  CGContextStrokePath(aContext);
612 }
613 
619 function CGContextStrokePath(aContext)
620 {
621  CGContextDrawPath(aContext, kCGPathStroke);
622  CGContextClosePath(aContext);
623 }
624 
635 function CGContextStrokeLineSegments(aContext, points, count)
636 {
637  var i = 0;
638 
639  if (count === NULL)
640  var count = points.length;
641 
642  CGContextBeginPath(aContext);
643 
644  for (; i < count; i += 2)
645  {
646  CGContextMoveToPoint(aContext, points[i].x, points[i].y);
647  CGContextAddLineToPoint(aContext, points[i + 1].x, points[i + 1].y);
648  }
649 
650  CGContextStrokePath(aContext);
651 }
652 
653 
654 //FIXME: THIS IS WRONG!!!
655 
663 function CGContextSetFillColor(aContext, aColor)
664 {
665  if (aColor)
666  aContext.gState.fillStyle = [aColor cssString];
667 }
668 
675 function CGContextSetStrokeColor(aContext, aColor)
676 {
677  if (aColor)
678  aContext.gState.strokeStyle = [aColor cssString];
679 }
680 
692 function CGContextFillRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw)
693 {
694  CGContextBeginPath(aContext);
695  CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
696  CGContextClosePath(aContext);
697  CGContextFillPath(aContext);
698 }
699 
711 function CGContextStrokeRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw)
712 {
713  CGContextBeginPath(aContext);
714  CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
715  CGContextClosePath(aContext);
716  CGContextStrokePath(aContext);
717 }
718 
727 {
728 #include "CGContextCanvas.j"
729 }
731 {
732 #include "CGContextVML.j"
733 }
734 else
735 {
736  // I have declared these functions here to make it compile without warnings with the new compiler under rhino.
737  CGContextClearRect = CGContextDrawLinearGradient = CGContextClip = CGContextClipToRect = CGContextDrawImage = function() {throw new Error("function is not declared in this environment")}
738 }