/* * CGContextVML.j * AppKit * * Created by Francisco Tolmasky. * Copyright 2008, 280 North, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ var VML_TRUTH_TABLE = [ "f", "t"], VML_LINECAP_TABLE = [ "flat", "round", "square" ], VML_LINEJOIN_TABLE = [ "miter", "round", "bevel" ], VML_ELEMENT_TABLE = [ " m ", " l ", "qb", " c ", " x ", [" at ", " wa "]]; var _CGBitmapGraphicsContextCreate = CGBitmapGraphicsContextCreate; function CGBitmapGraphicsContextCreate() { // The first time around, we have to set up our environment to support vml. document.namespaces.add("cg_vml_", "urn:schemas-microsoft-com:vml"); document.createStyleSheet().cssText = "cg_vml_\\:*{behavior:url(#default#VML)}"; CGBitmapGraphicsContextCreate = _CGBitmapGraphicsContextCreate; return _CGBitmapGraphicsContextCreate(); } // FIXME: aRect is ignored. function CGContextClearRect(aContext, aRect) { if (aContext.buffer != nil) aContext.buffer = ""; else aContext.DOMElement.innerHTML = ""; aContext.path = NULL; } var W = 10.0, H = 10.0, Z = 10.0, Z_2 = Z / 2.0; #define COORD(aCoordinate) (ROUND(Z * (aCoordinate) - Z_2)) function CGContextDrawImage(aContext, aRect, anImage) { var string = ""; if (anImage.buffer != nil) string = anImage.buffer; else { var ctm = aContext.gState.CTM, origin = CGPointApplyAffineTransform(aRect.origin, ctm), similarity = ctm.a == ctm.d && ctm.b == -ctm.c, vml = [""); string = vml.join(""); } if (aContext.buffer != nil) aContext.buffer += string; else aContext.DOMElement.insertAdjacentHTML("BeforeEnd", string); } function CGContextDrawPath(aContext, aMode) { if (!aContext || CGPathIsEmpty(aContext.path)) return; var elements = aContext.path.elements, i = 0, count = aContext.path.count, gState = aContext.gState, fill = (aMode == kCGPathFill || aMode == kCGPathFillStroke) ? 1 : 0, stroke = (aMode == kCGPathStroke || aMode == kCGPathFillStroke) ? 1 : 0, opacity = gState.alpha, vml = [ "= x) { if (start.y < y) start.x += 0.125; else start.y += 0.125; } else { if (end.y <= y) end.x += 0.125; else end.y += 0.125; } vml.push(VML_ELEMENT_TABLE[type][clockwise], COORD(x - radius), ',', COORD(y - radius), " ", COORD(x + radius), ',', COORD(y + radius), " ", COORD(start.x), ',', COORD(start.y), " ", COORD(end.x), ',', COORD(end.y)); break; case kCGPathElementAddArcTo: break; } // TODO: Following is broken for curves due to // move to proper paths. // Figure out dimensions so we can do gradient fills // properly /*if(c) { if (min.x == null || c.x < min.x) { min.x = c.x; } if (max.x == null || c.x > max.x) { max.x = c.x; } if (min.y == null || c.y < min.y) { min.y = c.y; } if (max.y == null || c.y > max.y) { max.y = c.y; } }*/ } vml.push("\">"); if (gState.gradient) vml.push(gState.gradient) else if (fill) vml.push(""); if (stroke) vml.push( ""); var shadowColor = gState.shadowColor; //\"", [shadowColor cssString], "\" if (shadowColor) { var shadowOffset = gState.shadowOffset; vml.push(""); } vml.push(""); aContext.path = NULL; if (aContext.buffer != nil) aContext.buffer += vml.join(""); else aContext.DOMElement.insertAdjacentHTML("BeforeEnd", vml.join("")); } function to_string(aColor) { return "rgb(" + ROUND(aColor.components[0] * 255) + ", " + ROUND(aColor.components[1] * 255) + ", " + ROUND(255 * aColor.components[2]) + ")"; } function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoint, options) { if (!aContext || !aGradient) return; var vml = nil; if (aGradient.vml_gradient) { var stops = [[aGradient.vml_gradient stops] sortedArrayUsingSelector:@selector(comparePosition:)], count = [stops count]; vml = [""); } else { var colors = aGradient.colors, count = colors.length; vml = [""); } aContext.gState.gradient = vml.join(""); // if (aContext.buffer != nil) // aContext.buffer += vml.join(""); // else // aContext.DOMElement.innerHTML = vml.join(""); }