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