PageRenderTime 34ms CodeModel.GetById 22ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/Frameworks/Debug/AppKit/rhino.platform/CGContext.j

http://github.com/jfahrenkrug/MapKit-HelloWorld
Unknown | 776 lines | 775 code | 1 blank | 0 comment | 0 complexity | f6b5605b9bc0fe9c21b296c038f7fd6d MD5 | raw file
  1i;12;CGGeometry.ji;19;CGAffineTransform.ji;8;CGPath.jc;31196;
  2kCGLineCapButt = 0;
  3kCGLineCapRound = 1;
  4kCGLineCapSquare = 2;
  5kCGLineJoinMiter = 0;
  6kCGLineJoinRound = 1;
  7kCGLineJoinBevel = 2;
  8kCGPathFill = 0;
  9kCGPathEOFill = 1;
 10kCGPathStroke = 2;
 11kCGPathFillStroke = 3;
 12kCGPathEOFillStroke = 4;
 13kCGBlendModeNormal = 0;
 14kCGBlendModeMultiply = 1;
 15kCGBlendModeScreen = 2;
 16kCGBlendModeOverlay = 3;
 17kCGBlendModeDarken = 4;
 18kCGBlendModeLighten = 5;
 19kCGBlendModeColorDodge = 6;
 20kCGBlendModeColorBurn = 7;
 21kCGBlendModeSoftLight = 8;
 22kCGBlendModeHardLight = 9;
 23kCGBlendModeDifference = 10;
 24kCGBlendModeExclusion = 11;
 25kCGBlendModeHue = 12;
 26kCGBlendModeSaturation = 13;
 27kCGBlendModeColor = 14;
 28kCGBlendModeLuminosity = 15;
 29kCGBlendModeClear = 16;
 30kCGBlendModeCopy = 17;
 31kCGBlendModeSourceIn = 18;
 32kCGBlendModeSourceOut = 19;
 33kCGBlendModeSourceAtop = 20;
 34kCGBlendModeDestinationOver = 21;
 35kCGBlendModeDestinationIn = 22;
 36kCGBlendModeDestinationOut = 23;
 37kCGBlendModeDestinationAtop = 24;
 38kCGBlendModeXOR = 25;
 39kCGBlendModePlusDarker = 26;
 40kCGBlendModePlusLighter = 27;
 41CGContextRelease= function()
 42{
 43}
 44CGContextRetain= function(aContext)
 45{
 46    return aContext;
 47}
 48if (!CPFeatureIsCompatible(CPHTMLCanvasFeature))
 49{
 50CGGStateCreate= function()
 51{
 52    return { alpha:1.0, strokeStyle:"#000", fillStyle:"#ccc", lineWidth:1.0, lineJoin:kCGLineJoinMiter, lineCap:kCGLineCapButt, miterLimit:10.0, globalAlpha:1.0,
 53        blendMode:kCGBlendModeNormal,
 54        shadowOffset:{ width:0.0, height:0.0 }, shadowBlur:0.0, shadowColor:NULL, CTM:{ a:1.0, b:0.0, c:0.0, d:1.0, tx:0.0, ty:0.0 } };
 55}
 56CGGStateCreateCopy= function(aGState)
 57{
 58    return { alpha:aGState.alpha, strokeStyle:aGState.strokeStyle, fillStyle:aGState.fillStyle, lineWidth:aGState.lineWidth,
 59        lineJoin:aGState.lineJoin, lineCap:aGState.lineCap, miterLimit:aGState.miterLimit, globalAlpha:aGState.globalAlpha,
 60        blendMode:aGState.blendMode,
 61        shadowOffset:aGState.shadowOffset, shadowBlur:aGState.shadowBlur, shadowColor:aGState.shadowColor, CTM:{ a:aGState.CTM.a, b:aGState.CTM.b, c:aGState.CTM.c, d:aGState.CTM.d, tx:aGState.CTM.tx, ty:aGState.CTM.ty } };
 62}
 63CGBitmapGraphicsContextCreate= function()
 64{
 65    return { DOMElement:document.createElement("div"), path:NULL, gState:CGGStateCreate(), gStateStack:[] };
 66}
 67CGContextSaveGState= function(aContext)
 68{
 69    aContext.gStateStack.push(CGGStateCreateCopy(aContext.gState));
 70}
 71CGContextRestoreGState= function(aContext)
 72{
 73    aContext.gState = aContext.gStateStack.pop();
 74}
 75CGContextSetLineCap= function(aContext, aLineCap)
 76{
 77    aContext.gState.lineCap = aLineCap;
 78}
 79CGContextSetLineJoin= function(aContext, aLineJoin)
 80{
 81    aContext.gState.lineJoin = aLineJoin;
 82}
 83CGContextSetLineWidth= function(aContext, aLineWidth)
 84{
 85    aContext.gState.lineWidth = aLineWidth;
 86}
 87CGContextSetMiterLimit= function(aContext, aMiterLimit)
 88{
 89    aContext.gState.miterLimit = aMiterLimit;
 90}
 91CGContextSetBlendMode= function(aContext, aBlendMode)
 92{
 93    aContext.gState.blendMode = aBlendMode;
 94}
 95CGContextAddArc= function(aContext, x, y, radius, startAngle, endAngle, clockwise)
 96{
 97    CGPathAddArc(aContext.path, aContext.gState.CTM, x, y, radius, startAngle, endAngle, clockwise);
 98}
 99CGContextAddArcToPoint= function(aContext, x1, y1, x2, y2, radius)
100{
101    CGPathAddArcToPoint(aContext.path, aContext.gState.CTM, x1, y1, x2, y2, radius);
102}
103CGContextAddCurveToPoint= function(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
104{
105    CGPathAddCurveToPoint(aContext.path, aContext.gState.CTM, cp1x, cp1y, cp2x, cp2y, x, y);
106}
107CGContextAddLines= function(aContext, points, count)
108{
109    CGPathAddLines(aContext.path, aContext.gState.CTM, points, count);
110}
111CGContextAddLineToPoint= function(aContext, x, y)
112{
113    CGPathAddLineToPoint(aContext.path, aContext.gState.CTM, x, y);
114}
115CGContextAddPath= function(aContext, aPath)
116{
117    if (!aContext || CGPathIsEmpty(aPath))
118        return;
119    if (!aContext.path)
120        aContext.path = CGPathCreateMutable();
121    CGPathAddPath(aContext.path, aContext.gState.CTM, aPath);
122}
123CGContextAddQuadCurveToPoint= function(aContext, cpx, cpy, x, y)
124{
125    CGPathAddQuadCurveToPoint(aContext.path, aContext.gState.CTM, cpx, cpy, x, y);
126}
127CGContextAddRect= function(aContext, aRect)
128{
129    CGPathAddRect(aContext.path, aContext.gState.CTM, aRect);
130}
131CGContextAddRects= function(aContext, rects, count)
132{
133    CGPathAddRects(aContext.path, aContext.gState.CTM, rects, count);
134}
135CGContextBeginPath= function(aContext)
136{
137    aContext.path = CGPathCreateMutable();
138}
139CGContextClosePath= function(aContext)
140{
141    CGPathCloseSubpath(aContext.path);
142}
143CGContextMoveToPoint= function(aContext, x, y)
144{
145    if (!aContext.path)
146        aContext.path = CGPathCreateMutable();
147    CGPathMoveToPoint(aContext.path, aContext.gState.CTM, x, y);
148}
149CGContextFillRect= function(aContext, aRect)
150{
151    CGContextFillRects(aContext, [aRect], 1);
152}
153CGContextFillRects= function(aContext, rects, count)
154{
155    if (arguments[2] === undefined)
156        var count = rects.length;
157    CGContextBeginPath(aContext);
158    CGContextAddRects(aContext, rects, count);
159    CGContextClosePath(aContext);
160    CGContextDrawPath(aContext, kCGPathFill);
161}
162CGContextStrokeRect= function(aContext, aRect)
163{
164    CGContextBeginPath(aContext);
165    CGContextAddRect(aContext, aRect);
166    CGContextClosePath(aContext);
167    CGContextDrawPath(aContext, kCGPathStroke);
168}
169CGContextStrokeRectWithWidth= function(aContext, aRect, aWidth)
170{
171    CGContextSaveGState(aContext);
172    CGContextSetLineWidth(aContext, aWidth);
173    CGContextStrokeRect(aContext, aRect);
174    CGContextRestoreGState(aContext);
175}
176CGContextConcatCTM= function(aContext, aTransform)
177{
178    var CTM = aContext.gState.CTM;
179    var tx = CTM.tx * aTransform.a + CTM.ty * aTransform.c + aTransform.tx;CTM.ty = CTM.tx * aTransform.b + CTM.ty * aTransform.d + aTransform.ty;CTM.tx = tx;var a = CTM.a * aTransform.a + CTM.b * aTransform.c, b = CTM.a * aTransform.b + CTM.b * aTransform.d, c = CTM.c * aTransform.a + CTM.d * aTransform.c;CTM.d = CTM.c * aTransform.b + CTM.d * aTransform.d;CTM.a = a;CTM.b = b;CTM.c = c;;
180}
181CGContextGetCTM= function(aContext)
182{
183    return aContext.gState.CTM;
184}
185CGContextRotateCTM= function(aContext, anAngle)
186{
187    var gState = aContext.gState;
188    gState.CTM = CGAffineTransformRotate(gState.CTM, anAngle);
189}
190CGContextScaleCTM= function(aContext, sx, sy)
191{
192    var gState = aContext.gState;
193    gState.CTM = { a:gState.CTM.a * sx, b:gState.CTM.b * sx, c:gState.CTM.c * sy, d:gState.CTM.d * sy, tx:gState.CTM.tx, ty:gState.CTM.ty };
194}
195CGContextTranslateCTM= function(aContext, tx, ty)
196{
197    var gState = aContext.gState;
198    gState.CTM = { a:gState.CTM.a, b:gState.CTM.b, c:gState.CTM.c, d:gState.CTM.d, tx:gState.CTM.tx + gState.CTM.a * tx + gState.CTM.c * ty, ty:gState.CTM.ty + gState.CTM.b * tx + gState.CTM.d * ty };
199}
200CGContextSetShadow= function(aContext, aSize, aBlur)
201{
202    var gState = aContext.gState;
203    gState.shadowOffset = { width:aSize.width, height:aSize.height };
204    gState.shadowBlur = aBlur;
205    gState.shadowColor = objj_msgSend(CPColor, "shadowColor");
206}
207CGContextSetShadowWithColor= function(aContext, aSize, aBlur, aColor)
208{
209    var gState = aContext.gState;
210    gState.shadowOffset = { width:aSize.width, height:aSize.height };
211    gState.shadowBlur = aBlur;
212    gState.shadowColor = aColor;
213}
214CGContextSetAlpha= function(aContext, anAlpha)
215{
216    aContext.gState.alpha = MAX(MIN(anAlpha, 1.0), 0.0);
217}
218}
219CGContextEOFillPath= function(aContext)
220{
221    CGContextDrawPath(aContext, kCGPathEOFill);
222}
223CGContextFillPath= function(aContext)
224{
225    CGContextDrawPath(aContext, kCGPathFill);
226}
227var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
228CGContextAddEllipseInRect= function(aContext, aRect)
229{
230    CGContextAddPath(aContext, CGPathWithEllipseInRect(aRect));
231}
232CGContextFillEllipseInRect= function(aContext, aRect)
233{
234    CGContextBeginPath(aContext);
235    CGContextAddEllipseInRect(aContext, aRect);
236    CGContextClosePath(aContext);
237    CGContextFillPath(aContext);
238}
239CGContextStrokeEllipseInRect= function(aContext, aRect)
240{
241    CGContextBeginPath(aContext);
242    CGContextAddEllipseInRect(aContext, aRect);
243    CGContextClosePath(aContext);
244    CGContextStrokePath(aContext);
245}
246CGContextStrokePath= function(aContext)
247{
248    CGContextDrawPath(aContext, kCGPathStroke);
249}
250CGContextStrokeLineSegments= function(aContext, points, count)
251{
252    var i = 0;
253    if (arguments["count"] == NULL)
254        var count = points.length;
255    CGContextBeginPath(aContext);
256    for (; i < count; i += 2)
257    {
258        CGContextMoveToPoint(aContext, points[i].x, points[i].y);
259        CGContextAddLineToPoint(aContext, points[i + 1].x, points[i + 1].y);
260    }
261    CGContextStrokePath(aContext);
262}
263CGContextSetFillColor= function(aContext, aColor)
264{
265    if (aColor)
266        aContext.gState.fillStyle = objj_msgSend(aColor, "cssString");
267}
268CGContextSetStrokeColor= function(aContext, aColor)
269{
270    if (aColor)
271        aContext.gState.strokeStyle = objj_msgSend(aColor, "cssString");
272}
273CGContextFillRoundedRectangleInRect= function(aContext, aRect, aRadius, ne, se, sw, nw)
274{
275    CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
276    CGContextFillPath(aContext);
277}
278CGContextStrokeRoundedRectangleInRect= function(aContext, aRect, aRadius, ne, se, sw, nw)
279{
280    CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
281    CGContextStrokePath(aContext);
282}
283if (CPFeatureIsCompatible(CPHTMLCanvasFeature))
284{
285var CANVAS_LINECAP_TABLE = [ "butt", "round", "square" ],
286    CANVAS_LINEJOIN_TABLE = [ "miter", "round", "bevel" ],
287    CANVAS_COMPOSITE_TABLE = [ "source-over", "source-over", "source-over", "source-over", "darker",
288                                "lighter", "source-over", "source-over", "source-over", "source-over",
289                                "source-over", "source-over", "source-over", "source-over", "source-over",
290                                "source-over", "source-over",
291                                "copy", "source-in", "source-out", "source-atop",
292                                "destination-over", "destination-in", "destination-out", "destination-atop",
293                                "xor", "source-over", "source-over" ];
294CGContextSaveGState= function(aContext)
295{
296    aContext.save();
297}
298CGContextRestoreGState= function(aContext)
299{
300    aContext.restore();
301}
302CGContextSetLineCap= function(aContext, aLineCap)
303{
304    aContext.lineCap = CANVAS_LINECAP_TABLE[aLineCap];
305}
306CGContextSetLineJoin= function(aContext, aLineJoin)
307{
308    aContext.lineJoin = CANVAS_LINEJOIN_TABLE[aLineJoin];
309}
310CGContextSetLineWidth= function(aContext, aLineWidth)
311{
312    aContext.lineWidth = aLineWidth;
313}
314CGContextSetMiterLimit= function(aContext, aMiterLimit)
315{
316    aContext.miterLimit = aMiterLimit;
317}
318CGContextSetBlendMode= function(aContext, aBlendMode)
319{
320    aContext.globalCompositeOperation = CANVAS_COMPOSITE_TABLE[aBlendMode];
321}
322CGContextAddArc= function(aContext, x, y, radius, startAngle, endAngle, clockwise)
323{
324    aContext.arc(x, y, radius, startAngle, endAngle, !clockwise);
325}
326CGContextAddArcToPoint= function(aContext, x1, y1, x2, y2, radius)
327{
328    aContext.arcTo(x1, y1, x2, y2, radius);
329}
330CGContextAddCurveToPoint= function(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
331{
332    aContext.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
333}
334CGContextAddLineToPoint= function(aContext, x, y)
335{
336    aContext.lineTo(x, y);
337}
338CGContextAddPath= function(aContext, aPath)
339{
340    if (!aContext || CGPathIsEmpty(aPath))
341        return;
342    var elements = aPath.elements,
343        i = 0,
344        count = aPath.count;
345    for (; i < count; ++i)
346    {
347        var element = elements[i],
348            type = element.type;
349        switch (type)
350        {
351            case kCGPathElementMoveToPoint: aContext.moveTo(element.x, element.y);
352                                                    break;
353            case kCGPathElementAddLineToPoint: aContext.lineTo(element.x, element.y);
354                                                    break;
355            case kCGPathElementAddQuadCurveToPoint: aContext.quadraticCurveTo(element.cpx, element.cpy, element.x, element.y);
356                                                    break;
357            case kCGPathElementAddCurveToPoint: aContext.bezierCurveTo(element.cp1x, element.cp1y, element.cp2x, element.cp2y, element.x, element.y);
358                                                    break;
359            case kCGPathElementCloseSubpath: aContext.closePath();
360                                                    break;
361            case kCGPathElementAddArc: aContext.arc(element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
362                                                    break;
363            case kCGPathElementAddArcTo:
364                                                    break;
365        }
366    }
367}
368CGContextAddRect= function(aContext, aRect)
369{
370    aContext.rect((aRect.origin.x), (aRect.origin.y), (aRect.size.width), (aRect.size.height));
371}
372CGContextAddRects= function(aContext, rects, count)
373{
374    var i = 0;
375    if (arguments["count"] == NULL)
376        var count = rects.length;
377    for (; i < count; ++i)
378    {
379        var rect = rects[i];
380        aContext.rect((rect.origin.x), (rect.origin.y), (rect.size.width), (rect.size.height));
381    }
382}
383CGContextBeginPath= function(aContext)
384{
385    aContext.beginPath();
386}
387CGContextClosePath= function(aContext)
388{
389    aContext.closePath();
390}
391CGContextMoveToPoint= function(aContext, x, y)
392{
393    aContext.moveTo(x, y);
394}
395CGContextClearRect= function(aContext, aRect)
396{
397    aContext.clearRect((aRect.origin.x), (aRect.origin.y), (aRect.size.width), (aRect.size.height));
398}
399CGContextDrawPath= function(aContext, aMode)
400{
401    if (aMode == kCGPathFill || aMode == kCGPathFillStroke)
402        aContext.fill();
403    else if (aMode == kCGPathEOFill || aMode == kCGPathEOFillStroke)
404        alert("not implemented!!!");
405    if (aMode == kCGPathStroke || aMode == kCGPathFillStroke || aMode == kCGPathEOFillStroke)
406        aContext.stroke();
407}
408CGContextFillRect= function(aContext, aRect)
409{
410    aContext.fillRect((aRect.origin.x), (aRect.origin.y), (aRect.size.width), (aRect.size.height));
411}
412CGContextFillRects= function(aContext, rects, count)
413{
414    var i = 0;
415    if (arguments["count"] == NULL)
416        var count = rects.length;
417    for (; i < count; ++i)
418    {
419        var rect = rects[i];
420        aContext.fillRect((rect.origin.x), (rect.origin.y), (rect.size.width), (rect.size.height));
421    }
422}
423CGContextStrokeRect= function(aContext, aRect)
424{
425    aContext.strokeRect((aRect.origin.x), (aRect.origin.y), (aRect.size.width), (aRect.size.height));
426}
427CGContextClip= function(aContext)
428{
429    aContext.clip();
430}
431CGContextClipToRect= function(aContext, aRect)
432{
433    aContext.beginPath();
434    aContext.rect((aRect.origin.x), (aRect.origin.y), (aRect.size.width), (aRect.size.height));
435    aContext.closePath();
436    aContext.clip();
437}
438CGContextClipToRects= function(aContext, rects, count)
439{
440    if (arguments["count"] == NULL)
441        var count = rects.length;
442    aContext.beginPath();
443    CGContextAddRects(aContext, rects, count);
444    aContext.clip();
445}
446CGContextSetAlpha= function(aContext, anAlpha)
447{
448    aContext.globalAlpha = anAlpha;
449}
450CGContextSetFillColor= function(aContext, aColor)
451{
452    aContext.fillStyle = objj_msgSend(aColor, "cssString");
453}
454CGContextSetStrokeColor= function(aContext, aColor)
455{
456    aContext.strokeStyle = objj_msgSend(aColor, "cssString");
457}
458CGContextSetShadow= function(aContext, aSize, aBlur)
459{
460    aContext.shadowOffsetX = aSize.width;
461    aContext.shadowOffsetY = aSize.height;
462    aContext.shadowBlur = aBlur;
463}
464CGContextSetShadowWithColor= function(aContext, aSize, aBlur, aColor)
465{
466    aContext.shadowOffsetX = aSize.width;
467    aContext.shadowOffsetY = aSize.height;
468    aContext.shadowBlur = aBlur;
469    aContext.shadowColor = objj_msgSend(aColor, "cssString");
470}
471CGContextRotateCTM= function(aContext, anAngle)
472{
473    aContext.rotate(anAngle);
474}
475CGContextScaleCTM= function(aContext, sx, sy)
476{
477    aContext.scale(sx, sy);
478}
479CGContextTranslateCTM= function(aContext, tx, ty)
480{
481    aContext.translate(tx, ty);
482}
483eigen= function(anAffineTransform)
484{
485    alert("IMPLEMENT ME!");
486}
487if (CPFeatureIsCompatible(CPJavaScriptCanvasTransformFeature))
488{
489CGContextConcatCTM = function(aContext, anAffineTransform)
490{
491    aContext.transform(anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty);
492}
493}
494else
495{
496CGContextConcatCTM = function(aContext, anAffineTransform)
497{
498    var a = anAffineTransform.a,
499        b = anAffineTransform.b,
500        c = anAffineTransform.c,
501        d = anAffineTransform.d,
502        tx = anAffineTransform.tx,
503        ty = anAffineTransform.ty,
504        sx = 1.0,
505        sy = 1.0,
506        a1 = 0.0,
507        a2 = 0.0;
508    if (b == 0.0 && c == 0.0)
509    {
510        sx = a;
511        sy = d;
512    }
513    else if (a * b == -c * d)
514    {
515        var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0, a2 = (ATAN2(b, d) + ATAN2(-sign * c, sign * a)) / 2.0, cos = COS(a2), sin = SIN(a2); if (cos == 0) { sx = -c / sin; sy = b / sin; } else if (sin == 0) { sx = a / cos; sy = d / cos; } else { abs_cos = ABS(cos); abs_sin = ABS(sin); sx = (abs_cos * a / cos + abs_sin * -c / sin) / (abs_cos + abs_sin); sy = (abs_cos * d / cos + abs_sin * b / sin) / (abs_cos + abs_sin); }
516    }
517    else if (a * c == -b * d)
518    {
519        var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0; a1 = (Math.atan2(sign * b, sign * a) + Math.atan2(-c, d)) / 2.0, cos = COS(a1), sin = SIN(a1); if (cos == 0) { sx = b / sin; sy = -c / sin; } else if (sin == 0) { sx = a / cos; sy = d / cos; } else { abs_cos = ABS(cos); abs_sin = ABS(sin); sx = (abs_cos * a / cos + abs_sin * b / sin) / (abs_cos + abs_sin); sy = (abs_cos * d / cos + abs_sin * -c / sin) / (abs_cos + abs_sin); }
520    }
521    else
522    {
523        var transpose = CGAffineTransformMake(a, c, b, d, 0.0, 0.0),
524            u = eigen(CGAffineTransformConcat(anAffineTransform, transpose)),
525            v = eigen(CGAffineTransformConcat(transpose, anAffineTransform)),
526            U = CGAffineTransformMake(u.vector_1.x, u.vector_2.x, u.vector_1.y, u.vector_2.y, 0.0, 0.0),
527            VT = CGAffineTransformMake(v.vector_1.x, v.vector_1.y, v.vector_2.x, v.vector_2.y, 0.0, 0.0),
528            S = CGAffineTransformConcat(CGAffineTransformConcat(CGAffineTransformInvert(U), anAffineTransform), CGAffineTransformInvert(VT));
529        a = VT.a;
530        b = VT.b;
531        c = VT.c;
532        d = VT.d;
533        var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0, a2 = (ATAN2(b, d) + ATAN2(-sign * c, sign * a)) / 2.0, cos = COS(a2), sin = SIN(a2); if (cos == 0) { sx = -c / sin; sy = b / sin; } else if (sin == 0) { sx = a / cos; sy = d / cos; } else { abs_cos = ABS(cos); abs_sin = ABS(sin); sx = (abs_cos * a / cos + abs_sin * -c / sin) / (abs_cos + abs_sin); sy = (abs_cos * d / cos + abs_sin * b / sin) / (abs_cos + abs_sin); }
534        S.a *= sx;
535        S.d *= sy;
536        a = U.a;
537        b = U.b;
538        c = U.c;
539        d = U.d;
540        var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0; a1 = (Math.atan2(sign * b, sign * a) + Math.atan2(-c, d)) / 2.0, cos = COS(a1), sin = SIN(a1); if (cos == 0) { sx = b / sin; sy = -c / sin; } else if (sin == 0) { sx = a / cos; sy = d / cos; } else { abs_cos = ABS(cos); abs_sin = ABS(sin); sx = (abs_cos * a / cos + abs_sin * b / sin) / (abs_cos + abs_sin); sy = (abs_cos * d / cos + abs_sin * -c / sin) / (abs_cos + abs_sin); }
541        sx = S.a * sx;
542        sy = S.d * sy;
543    }
544    if (tx != 0 || ty != 0)
545        CGContextTranslateCTM(aContext, tx, ty);
546    if (a1 != 0.0)
547        CGContextRotateCTM(aContext, a1);
548    if (sx != 1.0 || sy != 1.0)
549        CGContextScaleCTM(aContext, sx, sy);
550    if (a2 != 0.0)
551        CGContextRotateCTM(aContext, a2);
552}
553}
554CGContextDrawImage= function(aContext, aRect, anImage)
555{
556    aContext.drawImage(anImage._image, (aRect.origin.x), (aRect.origin.y), (aRect.size.width), (aRect.size.height));
557}
558to_string= function(aColor)
559{
560    return "rgba(" + ROUND(aColor.components[0] * 255) + ", " + ROUND(aColor.components[1] * 255) + ", " + ROUND(255 * aColor.components[2]) + ", " + aColor.components[3] + ")";
561}
562CGContextDrawLinearGradient= function(aContext, aGradient, aStartPoint, anEndPoint, options)
563{
564    var colors = aGradient.colors,
565        count = colors.length,
566        linearGradient = aContext.createLinearGradient(aStartPoint.x, aStartPoint.y, anEndPoint.x, anEndPoint.y);
567    while (count--)
568        linearGradient.addColorStop(aGradient.locations[count], to_string(colors[count]));
569    aContext.fillStyle = linearGradient;
570    aContext.fill();
571}
572CGBitmapGraphicsContextCreate= function()
573{
574    var DOMElement = document.createElement("canvas"),
575        context = DOMElement.getContext("2d");
576    context.DOMElement = DOMElement;
577    return context;
578}
579}
580else if (CPFeatureIsCompatible(CPVMLFeature))
581{
582var VML_TRUTH_TABLE = [ "f", "t"],
583    VML_LINECAP_TABLE = [ "flat", "round", "square" ],
584    VML_LINEJOIN_TABLE = [ "miter", "round", "bevel" ],
585    VML_ELEMENT_TABLE = [ " m ", " l ", "qb", " c ", " x ", [" at ", " wa "]];
586var _CGBitmapGraphicsContextCreate = CGBitmapGraphicsContextCreate;
587CGBitmapGraphicsContextCreate= function()
588{
589    document.namespaces.add("cg_vml_", "urn:schemas-microsoft-com:vml");
590    document.createStyleSheet().cssText = "cg_vml_\\:*{behavior:url(#default#VML)}";
591    CGBitmapGraphicsContextCreate = _CGBitmapGraphicsContextCreate;
592    return _CGBitmapGraphicsContextCreate();
593}
594CGContextClearRect= function(aContext, aRect)
595{
596    if (aContext.buffer != nil)
597        aContext.buffer = "";
598    else
599        aContext.DOMElement.innerHTML = "";
600    aContext.path = NULL;
601}
602var W = 10.0,
603    H = 10.0,
604    Z = 10.0,
605    Z_2 = Z / 2.0;
606CGContextDrawImage= function(aContext, aRect, anImage)
607{
608    var string = "";
609    if (anImage.buffer != nil)
610        string = anImage.buffer;
611    else
612    {
613        var ctm = aContext.gState.CTM,
614            origin = CGPointApplyAffineTransform(aRect.origin, ctm),
615            similarity = ctm.a == ctm.d && ctm.b == -ctm.c,
616            vml = ["<cg_vml_:group coordsize=\"1,1\" coordorigin=\"0,0\" style=\"width:1;height:1;position:absolute"];
617        {
618            var transformedRect = CGRectApplyAffineTransform(aRect, ctm);
619            vml.push( ";padding:0 ", ROUND((transformedRect.origin.x + transformedRect.size.width)), "px ", ROUND((transformedRect.origin.y + transformedRect.size.height)),
620                        "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
621                        "M11='", ctm.a, "',M12='", ctm.c, "',M21='", ctm.b, "',M22='", ctm.d, "',",
622                        "Dx='", ROUND(origin.x), "', Dy='", ROUND(origin.y), "', sizingmethod='clip');");
623        }
624        vml.push( "\"><cg_vml_:image src=\"", anImage._image.src,
625                    "\" style=\"width:", (aRect.size.width), "px;height:", (aRect.size.height),
626                    "px;\"/></g_vml_:group>");
627        string = vml.join("");
628    }
629    if (aContext.buffer != nil)
630        aContext.buffer += string;
631    else
632        aContext.DOMElement.insertAdjacentHTML("BeforeEnd", string);
633}
634CGContextDrawPath= function(aContext, aMode)
635{
636    if (!aContext || CGPathIsEmpty(aContext.path))
637        return;
638    var elements = aContext.path.elements,
639        i = 0,
640        count = aContext.path.count,
641        gState = aContext.gState,
642        fill = (aMode == kCGPathFill || aMode == kCGPathFillStroke) ? 1 : 0,
643        stroke = (aMode == kCGPathStroke || aMode == kCGPathFillStroke) ? 1 : 0,
644        opacity = gState.alpha,
645        vml = [ "<cg_vml_:shape",
646                " fillcolor=\"", gState.fillStyle,
647                "\" filled=\"", VML_TRUTH_TABLE[fill],
648                "\" style=\"position:absolute;width:", W, ";height:", H,
649                ";\" coordorigin=\"0 0\" coordsize=\"", Z * W, " ", Z * H,
650                "\" stroked=\"", VML_TRUTH_TABLE[stroke],
651                "\" strokeweight=\"", gState.lineWidth,
652                "\" strokecolor=\"", gState.strokeStyle,
653                "\" path=\""];
654    for (; i < count; ++i)
655    {
656        var element = elements[i],
657            type = element.type;
658        switch(type)
659        {
660            case kCGPathElementMoveToPoint:
661            case kCGPathElementAddLineToPoint: vml.push(VML_ELEMENT_TABLE[type], (ROUND(Z * (element.x) - Z_2)), ',', (ROUND(Z * (element.y) - Z_2)));
662                                                    break;
663            case kCGPathElementAddQuadCurveToPoint: vml.push(VML_ELEMENT_TABLE[type],
664                                                        (ROUND(Z * (element.cpx) - Z_2)), ',', (ROUND(Z * (element.cpy) - Z_2)), ',',
665                                                        (ROUND(Z * (element.x) - Z_2)), ',', (ROUND(Z * (element.y) - Z_2)));
666                                                    break;
667            case kCGPathElementAddCurveToPoint: vml.push(VML_ELEMENT_TABLE[type],
668                                                        (ROUND(Z * (element.cp1x) - Z_2)), ',', (ROUND(Z * (element.cp1y) - Z_2)), ',',
669                                                        (ROUND(Z * (element.cp2x) - Z_2)), ',', (ROUND(Z * (element.cp2y) - Z_2)), ',',
670                                                        (ROUND(Z * (element.x) - Z_2)), ',', (ROUND(Z * (element.y) - Z_2)));
671                                                    break;
672            case kCGPathElementCloseSubpath: vml.push(VML_ELEMENT_TABLE[type]);
673                                                    break;
674            case kCGPathElementAddArc: var x = element.x,
675                                                        y = element.y,
676                                                        radius = element.radius,
677                                                        clockwise = element.clockwise ? 1 : 0,
678                                                        endAngle = element.endAngle,
679                                                        startAngle = element.startAngle,
680                                                        start = { x:x + radius * COS(startAngle), y:y + radius * SIN(startAngle) };
681                                                    if (startAngle == endAngle && !clockwise)
682                                                    {
683                                                        vml.push(VML_ELEMENT_TABLE[kCGPathElementMoveToPoint], (ROUND(Z * (start.x) - Z_2)), ',', (ROUND(Z * (start.y) - Z_2)));
684                                                        continue;
685                                                    }
686                                                    var end = { x:x + radius * COS(endAngle), y:y + radius * SIN(endAngle) };
687                                                    if (clockwise && startAngle != endAngle && (start.x == end.x && start.y == end.y))
688                                                        if (start.x >= x)
689                                                        {
690                                                            if (start.y < y)
691                                                                start.x += 0.125;
692                                                            else
693                                                                start.y += 0.125;
694                                                        }
695                                                        else
696                                                        {
697                                                            if (end.y <= y)
698                                                                end.x += 0.125;
699                                                            else
700                                                                end.y += 0.125;
701                                                        }
702                                                    vml.push(VML_ELEMENT_TABLE[type][clockwise],
703                                                        (ROUND(Z * (x - radius) - Z_2)), ',', (ROUND(Z * (y - radius) - Z_2)), " ",
704                                                        (ROUND(Z * (x + radius) - Z_2)), ',', (ROUND(Z * (y + radius) - Z_2)), " ",
705                                                        (ROUND(Z * (start.x) - Z_2)), ',', (ROUND(Z * (start.y) - Z_2)), " ",
706                                                        (ROUND(Z * (end.x) - Z_2)), ',', (ROUND(Z * (end.y) - Z_2)));
707                                                    break;
708            case kCGPathElementAddArcTo: break;
709        }
710    }
711    vml.push("\">");
712    if (gState.gradient)
713        vml.push(gState.gradient)
714    else if (fill)
715        vml.push("<cg_vml_:fill color=\"", gState.fillStyle, "\" opacity=\"", opacity, "\" />");
716    if (stroke)
717        vml.push( "<cg_vml_:stroke opacity=\"", opacity,
718                    "\" joinstyle=\"", VML_LINEJOIN_TABLE[gState.lineJoin],
719                    "\" miterlimit=\"", gState.miterLimit,
720                    "\" endcap=\"", VML_LINECAP_TABLE[gState.lineCap],
721                    "\" weight=\"", gState.lineWidth, "",
722                    "px\" color=\"", gState.strokeStyle,"\" />");
723    var shadowColor = gState.shadowColor;
724    if (shadowColor)
725    {
726        var shadowOffset = gState.shadowOffset;
727        vml.push("<cg_vml_:shadow on=\"t\" offset=\"",
728            shadowOffset.width, "pt ", shadowOffset.height, "pt\" opacity=\"", objj_msgSend(shadowColor, "alphaComponent"), "\" color=black />");
729    }
730    vml.push("</cg_vml_:shape>");
731    aContext.path = NULL;
732    if (aContext.buffer != nil)
733        aContext.buffer += vml.join("");
734    else
735        aContext.DOMElement.insertAdjacentHTML("BeforeEnd", vml.join(""));
736}
737to_string= function(aColor)
738{
739    return "rgb(" + ROUND(aColor.components[0] * 255) + ", " + ROUND(aColor.components[1] * 255) + ", " + ROUND(255 * aColor.components[2]) + ")";
740}
741CGContextDrawLinearGradient= function(aContext, aGradient, aStartPoint, anEndPoint, options)
742{
743    if (!aContext || !aGradient)
744        return;
745    var vml = nil;
746    if (aGradient.vml_gradient)
747    {
748        var stops = objj_msgSend(objj_msgSend(aGradient.vml_gradient, "stops"), "sortedArrayUsingSelector:", sel_getUid("comparePosition:")),
749            count = objj_msgSend(stops, "count");
750        vml = ["<cg_vml_:fill type=\"gradient\" method=\"linear sigma\" "];
751        vml.push("angle=\"" + (objj_msgSend(aGradient.vml_gradient, "angle") + 90) +"\" ");
752        vml.push("colors=\"");
753        for (var i = 0; i < count; i++)
754        {
755            vml.push((objj_msgSend(stops[i], "position")*100).toFixed(0)+"% ");
756            vml.push(objj_msgSend(objj_msgSend(objj_msgSend(stops[i], "color"), "colorForSlideBase:", nil), "cssString"));
757            if (i < count-1)
758                vml.push(",");
759        }
760        vml.push("\" />");
761    }
762    else
763    {
764        var colors = aGradient.colors,
765            count = colors.length;
766        vml = ["<cg_vml_:fill type=\"gradient\" "];
767        vml.push("colors=\"");
768        for (var i = 0; i < count; i++)
769            vml.push((aGradient.locations[i]*100).toFixed(0)+"% "+to_string(colors[i])+(i<count-1 ? "," : ""));
770        vml.push("\" />");
771    }
772    aContext.gState.gradient = vml.join("");
773    console.log(vml.join(""));
774}
775}
776