diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/format/SVG.hx b/format/SVG.hx old mode 100644 new mode 100755 diff --git a/format/gfx/BitmapFill.hx b/format/gfx/BitmapFill.hx new file mode 100755 index 0000000..f1ee88a --- /dev/null +++ b/format/gfx/BitmapFill.hx @@ -0,0 +1,31 @@ +package format.gfx; + +import flash.geom.ColorTransform; +import flash.geom.Rectangle; +import flash.geom.Matrix; +import flash.display.BitmapData; + +class BitmapFill { + public function new() { + matrix = new Matrix(); + } + + public var bitmapData:BitmapData; + public var matrix: Matrix; + public var repeat: Bool = true; + public var smooth: Bool = false; + @:isVar + public var alpha(default, set): Float = 1; + + private function set_alpha(value:Float):Float { + alpha = value; + if(bitmapData != null && value < 1) { + bitmapData.lock(); + var rect: Rectangle = new Rectangle(0,0,bitmapData.width,bitmapData.height); + bitmapData.colorTransform(rect, new ColorTransform(1,1,1,alpha)); + bitmapData.unlock(rect); + } + return alpha; + } +} + diff --git a/format/gfx/Gfx.hx b/format/gfx/Gfx.hx old mode 100644 new mode 100755 index b865ae4..13aaa1c --- a/format/gfx/Gfx.hx +++ b/format/gfx/Gfx.hx @@ -16,6 +16,7 @@ class Gfx public function geometryOnly() { return false; } public function size(inWidth:Float,inHeight:Float) { } public function beginGradientFill(grad:Gradient) { } + public function beginBitmapFill(bitmap: BitmapFill) {} public function beginFill(color:Int, alpha:Float) { } public function endFill() { } diff --git a/format/gfx/Gfx2Haxe.hx b/format/gfx/Gfx2Haxe.hx old mode 100644 new mode 100755 diff --git a/format/gfx/GfxBytes.hx b/format/gfx/GfxBytes.hx old mode 100644 new mode 100755 index df3ccdb..c61c01e --- a/format/gfx/GfxBytes.hx +++ b/format/gfx/GfxBytes.hx @@ -118,7 +118,7 @@ class GfxBytes extends Gfx case GRADIENT_FILL: var grad = new Gradient(); - grad.type = Type.createEnumIndex(GradientType,buffer.readByte()); + grad.type = cast buffer.readByte(); var len = buffer.readByte(); for(i in 0...len) { @@ -208,7 +208,7 @@ class GfxBytes extends Gfx override public function beginGradientFill(grad:Gradient) { buffer.writeByte(GRADIENT_FILL); - buffer.writeByte(Type.enumIndex(grad.type)); + buffer.writeByte(cast grad.type); buffer.writeByte(grad.colors.length); for(i in 0...grad.colors.length) { @@ -222,8 +222,8 @@ class GfxBytes extends Gfx buffer.writeFloat(grad.matrix.d); buffer.writeFloat(grad.matrix.tx); buffer.writeFloat(grad.matrix.ty); - buffer.writeByte(Type.enumIndex(grad.spread)); - buffer.writeByte(Type.enumIndex(grad.interp)); + buffer.writeByte(cast grad.spread); + buffer.writeByte(cast grad.interp); buffer.writeFloat(grad.focus); } @@ -245,9 +245,9 @@ class GfxBytes extends Gfx writeRGB(style.color); buffer.writeFloat(style.alpha); buffer.writeByte(style.pixelHinting?1:0); - buffer.writeByte(Type.enumIndex(style.scaleMode)); - buffer.writeByte(Type.enumIndex(style.capsStyle)); - buffer.writeByte(Type.enumIndex(style.jointStyle)); + buffer.writeByte(cast style.scaleMode); + buffer.writeByte(cast style.capsStyle); + buffer.writeByte(cast style.jointStyle); buffer.writeFloat(style.miterLimit); } diff --git a/format/gfx/GfxExtent.hx b/format/gfx/GfxExtent.hx old mode 100644 new mode 100755 diff --git a/format/gfx/GfxGraphics.hx b/format/gfx/GfxGraphics.hx old mode 100644 new mode 100755 index 233e7d9..83ed428 --- a/format/gfx/GfxGraphics.hx +++ b/format/gfx/GfxGraphics.hx @@ -25,6 +25,11 @@ class GfxGraphics extends Gfx graphics.beginGradientFill(grad.type,grad.colors,grad.alphas,grad.ratios,grad.matrix,grad.spread,grad.interp,grad.focus); } + override public function beginBitmapFill(fill:BitmapFill) + { + graphics.beginBitmapFill(fill.bitmapData, fill.matrix, fill.repeat, fill.smooth); + } + override public function beginFill(color:Int, alpha:Float) { graphics.beginFill(color,alpha); } override public function endFill() { graphics.endFill(); } diff --git a/format/gfx/GfxTextFinder.hx b/format/gfx/GfxTextFinder.hx old mode 100644 new mode 100755 diff --git a/format/gfx/Gradient.hx b/format/gfx/Gradient.hx old mode 100644 new mode 100755 index ba9e7e0..f1faf62 --- a/format/gfx/Gradient.hx +++ b/format/gfx/Gradient.hx @@ -23,7 +23,7 @@ class Gradient } public var type:GradientType; - public var colors:Array; + public var colors:Array; public var alphas:Array; public var ratios:Array; public var matrix: Matrix; diff --git a/format/gfx/LineStyle.hx b/format/gfx/LineStyle.hx old mode 100644 new mode 100755 diff --git a/format/svg/BitmapDataManager.hx b/format/svg/BitmapDataManager.hx old mode 100644 new mode 100755 index f04199e..6a396a5 --- a/format/svg/BitmapDataManager.hx +++ b/format/svg/BitmapDataManager.hx @@ -1,8 +1,9 @@ package format.svg; //import gm2d.reso.Resources; -import format.svg.SvgRenderer; +//import format.svg.SVGRenderer; +import flash.display.DisplayObjectContainer; import flash.geom.Matrix; import flash.display.Shape; import flash.display.Bitmap; @@ -11,36 +12,30 @@ import flash.display.BitmapData; class BitmapDataManager { - static var bitmaps = new Hash(); + static var bitmaps = new Map(); static var mScale = 0.0; public static function create(inSVG:String, inGroup:String, inScale:Float, inCache=false) { var key = inSVG + " : " + inGroup + " : " +inScale; - if (bitmaps.exists(key)) - return bitmaps.get(key); + if (bitmaps.exists(key)) { + return bitmaps.get(key); + } - //var svg:SvgRenderer = new SvgRenderer( Resources.loadSvg(inSVG) ); var svg = null; - return; - + var shape = new Shape(); - if (inGroup=="") - svg.RenderObject(shape,shape.graphics); - else - svg.RenderObject(shape,shape.graphics,null, function(_,groups) { return groups[0]==inGroup; }); + + svg = new SVG(inSVG); + svg.render(shape.graphics, 0, 0); var matrix = new Matrix(); matrix.scale(inScale,inScale); - var w = Std.int(svg.width*inScale + 0.99); - var h = Std.int(svg.height*inScale + 0.99); + var w = Std.int(svg.data.width); + var h = Std.int(svg.data.height); var bmp = new BitmapData(w,h,true,0x00); - var q = gm2d.Lib.current.stage.quality; - flash.Lib.current.stage.quality = flash.display.StageQuality.BEST; bmp.draw(shape,matrix); - flash.Lib.current.stage.quality = q; - if (inCache) bitmaps.set(key,bmp); return bmp; @@ -50,7 +45,7 @@ class BitmapDataManager { if (inScale!=mScale) { - bitmaps = new Hash(); + bitmaps = new Map(); mScale = inScale; } } diff --git a/format/svg/BitmapFill.hx b/format/svg/BitmapFill.hx new file mode 100755 index 0000000..00e4c61 --- /dev/null +++ b/format/svg/BitmapFill.hx @@ -0,0 +1,38 @@ +package format.svg; + +import flash.geom.Matrix; +import flash.display.BitmapData; + +class BitmapFill extends format.gfx.BitmapFill { + public var fillMatrix: Matrix; + public var x1:Float; + public var y1:Float; + public var x2:Float; + public var y2:Float; + + public function new() { + super(); + fillMatrix = new Matrix(); + x1 = 0.0; + y1 = 0.0; + x2 = 0.0; + y2 = 0.0; + } + + public function updateMatrix(inMatrix:Matrix) + { + var dx = x2 - x1; + var dy = y2 - y1; + var theta = Math.atan2(dy,dx); + var len = Math.sqrt(dx*dx+dy*dy); + + var mtx = new Matrix(); + + mtx.rotate(theta); + mtx.translate(x1,y1); + mtx.concat(fillMatrix); + mtx.concat(inMatrix); + matrix = mtx; + } +} + diff --git a/format/svg/FillType.hx b/format/svg/FillType.hx old mode 100644 new mode 100755 index 787d6b5..aacea99 --- a/format/svg/FillType.hx +++ b/format/svg/FillType.hx @@ -4,6 +4,7 @@ enum FillType { FillGrad(grad:Grad); FillSolid(colour:Int); + BitmapFill(fill: BitmapFill); FillNone; } diff --git a/format/svg/Grad.hx b/format/svg/Grad.hx old mode 100644 new mode 100755 diff --git a/format/svg/Gradient.hx b/format/svg/Gradient.hx old mode 100644 new mode 100755 diff --git a/format/svg/Group.hx b/format/svg/Group.hx old mode 100644 new mode 100755 diff --git a/format/svg/Path.hx b/format/svg/Path.hx old mode 100644 new mode 100755 diff --git a/format/svg/PathParser.hx b/format/svg/PathParser.hx old mode 100644 new mode 100755 index f11a279..188bb94 --- a/format/svg/PathParser.hx +++ b/format/svg/PathParser.hx @@ -15,33 +15,33 @@ class PathParser { static var sCommandArgs:Array; - static inline var MOVE = 77; //"M".charCodeAt(0); - static inline var MOVER = 109; //"m".charCodeAt(0); - static inline var LINE = 76; // "L".charCodeAt(0); - static inline var LINER = 108; // "l".charCodeAt(0); - static inline var HLINE = 72; // "H".charCodeAt(0); - static inline var HLINER = 104; // "h".charCodeAt(0); - static inline var VLINE = 86; // "V".charCodeAt(0); - static inline var VLINER = 118; // "v".charCodeAt(0); - static inline var CUBIC = 67; // "C".charCodeAt(0); - static inline var CUBICR = 99; // "c".charCodeAt(0); - static inline var SCUBIC = 83; // "S".charCodeAt(0); - static inline var SCUBICR = 115; // "s".charCodeAt(0); - static inline var QUAD = 81; // "Q".charCodeAt(0); - static inline var QUADR = 113; // "q".charCodeAt(0); - static inline var SQUAD = 84; // "T".charCodeAt(0); - static inline var SQUADR = 116; // "t".charCodeAt(0); - static inline var ARC = 65; // "A".charCodeAt(0); - static inline var ARCR = 97; // "a".charCodeAt(0); - static inline var CLOSE = 90; // "Z".charCodeAt(0); - static inline var CLOSER = 122; // "z".charCodeAt(0); + static inline var MOVE = "M".code; + static inline var MOVER = "m".code; + static inline var LINE = "L".code; + static inline var LINER = "l".code; + static inline var HLINE = "H".code; + static inline var HLINER = "h".code; + static inline var VLINE = "V".code; + static inline var VLINER = "v".code; + static inline var CUBIC = "C".code; + static inline var CUBICR = "c".code; + static inline var SCUBIC = "S".code; + static inline var SCUBICR = "s".code; + static inline var QUAD = "Q".code; + static inline var QUADR = "q".code; + static inline var SQUAD = "T".code; + static inline var SQUADR = "t".code; + static inline var ARC = "A".code; + static inline var ARCR = "a".code; + static inline var CLOSE = "Z".code; + static inline var CLOSER = "z".code; - static var UNKNOWN = -1; - static var SEPARATOR = -2; - static var FLOAT = -3; - static var FLOAT_SIGN = -4; - static var FLOAT_DOT = -5; - static var FLOAT_EXP = -6; + static inline var UNKNOWN = -1; + static inline var SEPARATOR = -2; + static inline var FLOAT = -3; + static inline var FLOAT_SIGN = -4; + static inline var FLOAT_DOT = -5; + static inline var FLOAT_EXP = -6; diff --git a/format/svg/PathSegment.hx b/format/svg/PathSegment.hx old mode 100644 new mode 100755 diff --git a/format/svg/RenderContext.hx b/format/svg/RenderContext.hx old mode 100644 new mode 100755 diff --git a/format/svg/SVG2Gfx.hx b/format/svg/SVG2Gfx.hx old mode 100644 new mode 100755 index 11d3901..28871f6 --- a/format/svg/SVG2Gfx.hx +++ b/format/svg/SVG2Gfx.hx @@ -6,7 +6,7 @@ import Xml; class SVG2Gfx { - var renderer : SvgRenderer; + var renderer : SVGRenderer; public function new (inXml:Xml) { diff --git a/format/svg/SVGData.hx b/format/svg/SVGData.hx old mode 100644 new mode 100755 index 85dbe8c..8dfc130 --- a/format/svg/SVGData.hx +++ b/format/svg/SVGData.hx @@ -25,633 +25,812 @@ typedef StringMap = Hash; class SVGData extends Group { - - - private static var SIN45:Float = 0.70710678118654752440084436210485; - private static var TAN22:Float = 0.4142135623730950488016887242097; - private static var mStyleSplit = ~/;/g; - private static var mStyleValue = ~/\s*(.*)\s*:\s*(.*)\s*/; - private static var mTranslateMatch = ~/translate\((.*)[, ](.*)\)/; - private static var mScaleMatch = ~/scale\((.*)\)/; - private static var mMatrixMatch = ~/matrix\((.*)[, ](.*)[, ](.*)[, ](.*)[, ](.*)[, ](.*)\)/; - private static var mURLMatch = ~/url\(#(.*)\)/; - private static var defaultFill = FillSolid(0x000000); - - public var height (default, null):Float; - public var width (default, null):Float; - - private var mConvertCubics:Bool; - private var mGrads:GradHash; - private var mPathParser:PathParser; - - - public function new (inXML:Xml, inConvertCubics:Bool = false) { - - super(); - - var svg = inXML.firstElement(); - - if (svg == null || (svg.nodeName != "svg" && svg.nodeName != "svg:svg")) - throw "Not an SVG file (" + (svg==null ? "null" : svg.nodeName) + ")"; - - mGrads = new GradHash (); - mPathParser = new PathParser (); - mConvertCubics = inConvertCubics; - - width = getFloatStyle ("width", svg, null, 0.0); - height = getFloatStyle ("height", svg, null, 0.0); - - if (width == 0 && height == 0) - width = height = 400; - else if (width == 0) - width = height; - else if (height == 0) - height = width; - - loadGroup(this, svg, new Matrix (), null); - - } - - - private function applyTransform (ioMatrix:Matrix, inTrans:String):Float { - - var scale = 1.0; - - if (mTranslateMatch.match(inTrans)) - { - // TODO: Pre-translate - - ioMatrix.translate (Std.parseFloat (mTranslateMatch.matched (1)), Std.parseFloat (mTranslateMatch.matched (2))); - - } else if (mScaleMatch.match (inTrans)) { - - // TODO: Pre-scale - var s = Std.parseFloat (mScaleMatch.matched (1)); - ioMatrix.scale (s, s); - scale = s; - - } else if (mMatrixMatch.match (inTrans)) { - - var m = new Matrix ( - Std.parseFloat (mMatrixMatch.matched (1)), - Std.parseFloat (mMatrixMatch.matched (2)), - Std.parseFloat (mMatrixMatch.matched (3)), - Std.parseFloat (mMatrixMatch.matched (4)), - Std.parseFloat (mMatrixMatch.matched (5)), - Std.parseFloat (mMatrixMatch.matched (6)) - ); - - m.concat (ioMatrix); - - ioMatrix.a = m.a; - ioMatrix.b = m.b; - ioMatrix.c = m.c; - ioMatrix.d = m.d; - ioMatrix.tx = m.tx; - ioMatrix.ty = m.ty; - - scale = Math.sqrt (ioMatrix.a * ioMatrix.a + ioMatrix.c * ioMatrix.c); - - } else { - - trace("Warning, unknown transform:" + inTrans); - - } - - return scale; - - } - - - private function dumpGroup (g:Group, indent:String) { - - trace (indent + "Group:" + g.name); - indent += " "; - - for (e in g.children) { - - switch (e) { - - case DisplayPath (path): trace (indent + "Path" + " " + path.matrix); - case DisplayGroup (group): dumpGroup (group, indent+" "); - case DisplayText (text): trace (indent + "Text " + text.text); - - } - - } - - } - - - private function getColorStyle (inKey:String, inNode:Xml, inStyles:StringMap , inDefault:Int) { - - var s = getStyle (inKey, inNode, inStyles, ""); - - if (s == "") { - - return inDefault; - - } - - if (s.charAt (0) == '#') { - - return Std.parseInt ("0x" + s.substr (1)); - - } - - return Std.parseInt (s); - - } - - - private function getFillStyle (inKey:String, inNode:Xml, inStyles:StringMap) { - - var s = getStyle (inKey, inNode, inStyles, ""); - - if (s == "") { - - return defaultFill; - - } - - if (s.charAt (0) == '#') { - - return FillSolid (Std.parseInt ("0x" + s.substr (1))); - - } - - if (s == "none") { - - return FillNone; - - } - - if (mURLMatch.match (s)) { - - var url = mURLMatch.matched (1); - - if (mGrads.exists (url)) { - - return FillGrad(mGrads.get(url)); - - } - - throw ("Unknown url:" + url); - - } - - throw ("Unknown fill string:" + s); - - return FillNone; - - } - - - private function getFloat (inXML:Xml, inName:String, inDef:Float = 0.0):Float { - - if (inXML.exists (inName)) - return Std.parseFloat (inXML.get (inName)); - - return inDef; - - } - - - private function getFloatStyle (inKey:String, inNode:Xml, inStyles:StringMap, inDefault:Float) { - - var s = getStyle (inKey, inNode, inStyles, ""); - - if (s == "") { - - return inDefault; - - } - - return Std.parseFloat (s); - - } - - - private function getStrokeStyle (inKey:String, inNode:Xml, inStyles:StringMap , inDefault:Null) { - - var s = getStyle (inKey, inNode, inStyles, ""); - - if (s == "") { - - return inDefault; - - } - - if (s == "none") { - - return null; - - } - - if (s.charAt (0) == '#') { - - return Std.parseInt ("0x" + s.substr (1)); - - } - - return Std.parseInt (s); - - } - - - private function getStyle (inKey:String, inNode:Xml, inStyles:StringMap , inDefault:String) { - - if (inNode != null && inNode.exists (inKey)) { - - return inNode.get (inKey); - - } - - if (inStyles != null && inStyles.exists (inKey)) { - - return inStyles.get (inKey); - - } - - return inDefault; - - } - - - private function getStyles (inNode:Xml, inPrevStyles:StringMap):StringMap { - - if (!inNode.exists ("style")) - return inPrevStyles; - - var styles = new StringMap (); - - if (inPrevStyles != null) { - - for (s in inPrevStyles.keys ()) { - - styles.set (s, inPrevStyles.get (s)); - - } - - } - - var style = inNode.get ("style"); - var strings = mStyleSplit.split (style); - - for (s in strings) { - - if (mStyleValue.match (s)) { - - styles.set (mStyleValue.matched (1), mStyleValue.matched (2)); - - } - - } - - return styles; - - } - - - private function loadDefs (inXML:Xml) { - - // Two passes - to allow forward xlinks - - for (pass in 0...2) { - - for (def in inXML.elements ()) { - - var name = def.nodeName; - - if (name.substr (0, 4) == "svg:") { - - name = name.substr (4); - - } - - if (name == "linearGradient") { - - loadGradient (def, GradientType.LINEAR, pass == 1); - - } else if (name == "radialGradient") { - - loadGradient (def, GradientType.RADIAL, pass == 1); - - } - - } - - } - - } - - - private function loadGradient (inGrad:Xml, inType:GradientType, inCrossLink:Bool) { - - var name = inGrad.get ("id"); - var grad = new Grad (inType); - - if (inCrossLink && inGrad.exists("xlink:href")) { - - var xlink = inGrad.get ("xlink:href"); - - if (xlink.charAt(0) != "#") - throw ("xlink - unkown syntax : " + xlink); - - var base = mGrads.get (xlink.substr (1)); - - if (base != null) { - - grad.colors = base.colors; - grad.alphas = base.alphas; - grad.ratios = base.ratios; - grad.gradMatrix = base.gradMatrix.clone (); - grad.spread = base.spread; - grad.interp = base.interp; - grad.radius = base.radius; - - } else { - - throw ("Unknown xlink : " + xlink); - - } - - } - - if (inGrad.exists ("x1")) { - - grad.x1 = getFloat (inGrad, "x1"); - grad.y1 = getFloat (inGrad, "y1"); - grad.x2 = getFloat (inGrad, "x2"); - grad.y2 = getFloat (inGrad, "y2"); - - } else { - - grad.x1 = getFloat (inGrad, "cx"); - grad.y1 = getFloat (inGrad, "cy"); - grad.x2 = getFloat (inGrad, "fx", grad.x1); - grad.y2 = getFloat (inGrad, "fy", grad.y1); - - } - - grad.radius = getFloat (inGrad, "r"); - - if (inGrad.exists ("gradientTransform")) { - - applyTransform (grad.gradMatrix, inGrad.get ("gradientTransform")); - - } - - // todo - grad.spread = base.spread; - - for (stop in inGrad.elements ()) { - - var styles = getStyles (stop, null); - - grad.colors.push (getColorStyle ("stop-color", stop, styles, 0x000000)); - grad.alphas.push (getFloatStyle ("stop-opacity", stop, styles, 1.0)); - grad.ratios.push (Std.int (Std.parseFloat (stop.get ("offset")) * 255.0)); - - } - - mGrads.set (name, grad); - - } - - - public function loadGroup (g:Group, inG:Xml, matrix:Matrix, inStyles:StringMap ):Group { - - if (inG.exists ("transform")) { - - matrix = matrix.clone (); - applyTransform (matrix, inG.get ("transform")); - - } - - if (inG.exists ("inkscape:label")) { - - g.name = inG.get ("inkscape:label"); - - } else if (inG.exists ("id")) { - - g.name = inG.get ("id"); - - } - - var styles = getStyles (inG, inStyles); - - for (el in inG.elements ()) { - - var name = el.nodeName; - - if (name.substr (0, 4) == "svg:") { - - name = name.substr(4); - - } - - if (name == "defs") { - - loadDefs (el); - - } else if (name == "g") { - - if (!(el.exists("display") && el.get("display") == "none")) { - - g.children.push (DisplayGroup (loadGroup (new Group (), el, matrix, styles))); - - } - - } else if (name == "path" || name == "line" || name == "polyline") { - - g.children.push (DisplayPath (loadPath (el, matrix, styles, false, false))); - - } else if (name == "rect") { - - g.children.push (DisplayPath (loadPath (el, matrix, styles, true, false))); - - } else if (name == "polygon") { - - g.children.push (DisplayPath (loadPath (el, matrix, styles, false, false))); - - } else if (name == "ellipse") { - - g.children.push (DisplayPath (loadPath (el, matrix, styles, false, true))); - - } else if (name == "circle") { - - g.children.push (DisplayPath (loadPath (el, matrix, styles, false, true, true))); - - } else if (name == "text") { - - g.children.push (DisplayText (loadText (el, matrix, styles))); - - } else if (name == "linearGradient") { - - loadGradient (el, GradientType.LINEAR, true); - - } else if (name == "radialGradient") { - - loadGradient (el, GradientType.RADIAL, true); - - } else { - - // throw("Unknown child : " + el.nodeName ); - - } - - } - - return g; - - } - - - public function loadPath (inPath:Xml, matrix:Matrix, inStyles:StringMap, inIsRect:Bool, inIsEllipse:Bool, inIsCircle:Bool=false):Path { - - if (inPath.exists ("transform")) { - - matrix = matrix.clone (); - applyTransform (matrix, inPath.get ("transform")); - - } - - var styles = getStyles (inPath, inStyles); - var name = inPath.exists ("id") ? inPath.get ("id") : ""; - var path = new Path (); - - path.fill = getFillStyle ("fill", inPath, styles); - path.alpha = getFloatStyle ("opacity", inPath, styles, 1.0); - path.fill_alpha = getFloatStyle ("fill-opacity", inPath, styles, 1.0); - path.stroke_alpha = getFloatStyle ("stroke-opacity", inPath, styles, 1.0); - path.stroke_colour = getStrokeStyle ("stroke", inPath, styles, null); - path.stroke_width = getFloatStyle ("stroke-width", inPath, styles, 1.0); - path.stroke_caps = CapsStyle.ROUND; - path.joint_style = JointStyle.ROUND; - path.miter_limit = getFloatStyle ("stroke-miterlimit", inPath, styles, 3.0); - path.segments = []; - path.matrix = matrix; - path.name = name; - - if (inIsRect) { - - var x = inPath.exists ("x") ? Std.parseFloat (inPath.get ("x")) : 0; - var y = inPath.exists ("y") ? Std.parseFloat (inPath.get ("y")) : 0; - var w = Std.parseFloat (inPath.get ("width")); - var h = Std.parseFloat (inPath.get ("height")); - var rx = inPath.exists ("rx") ? Std.parseFloat (inPath.get ("rx")) : 0.0; - var ry = inPath.exists ("ry") ? Std.parseFloat (inPath.get ("ry")) : 0.0; - - if (rx == 0 || ry == 0) { - - path.segments.push (new MoveSegment (x , y)); - path.segments.push (new DrawSegment (x + w, y)); - path.segments.push (new DrawSegment (x + w, y + h)); - path.segments.push (new DrawSegment (x, y + h)); - path.segments.push (new DrawSegment (x, y)); - - } else { - - path.segments.push (new MoveSegment (x, y + ry)); - - // top-left - path.segments.push (new QuadraticSegment (x, y, x + rx, y)); - path.segments.push (new DrawSegment (x + w - rx, y)); - - // top-right - path.segments.push (new QuadraticSegment (x + w, y, x + w, y + rx)); - path.segments.push (new DrawSegment (x + w, y + h - ry)); - - // bottom-right - path.segments.push (new QuadraticSegment (x + w, y + h, x + w - rx, y + h)); - path.segments.push (new DrawSegment (x + rx, y + h)); - - // bottom-left - path.segments.push (new QuadraticSegment (x, y + h, x, y + h - ry)); - path.segments.push (new DrawSegment (x, y + ry)); - - } - - } else if (inIsEllipse) { - - var x = inPath.exists ("cx") ? Std.parseFloat (inPath.get ("cx")) : 0; - var y = inPath.exists ("cy") ? Std.parseFloat (inPath.get ("cy")) : 0; - var r = inIsCircle && inPath.exists ("r") ? Std.parseFloat (inPath.get ("r")) : 0.0; - var w = inIsCircle ? r : inPath.exists ("rx") ? Std.parseFloat (inPath.get ("rx")) : 0.0; - var w_ = w * SIN45; - var cw_ = w * TAN22; - var h = inIsCircle ? r : inPath.exists ("ry") ? Std.parseFloat (inPath.get ("ry")) : 0.0; - var h_ = h * SIN45; - var ch_ = h * TAN22; - - path.segments.push (new MoveSegment (x + w, y)); - path.segments.push (new QuadraticSegment (x + w, y + ch_, x + w_, y + h_)); - path.segments.push (new QuadraticSegment (x + cw_, y + h, x, y + h)); - path.segments.push (new QuadraticSegment (x - cw_, y + h, x - w_, y + h_)); - path.segments.push (new QuadraticSegment (x - w, y + ch_, x - w, y)); - path.segments.push (new QuadraticSegment (x - w, y - ch_, x - w_, y - h_)); - path.segments.push (new QuadraticSegment (x - cw_, y - h, x, y - h)); - path.segments.push (new QuadraticSegment (x + cw_, y - h, x + w_, y - h_)); - path.segments.push (new QuadraticSegment (x + w, y - ch_, x + w, y)); - - } else { - - var d = inPath.exists ("points") ? ("M" + inPath.get ("points") + "z") : - inPath.exists ("x1") ? ("M" + inPath.get ("x1") + "," + inPath.get ("y1") + " " + inPath.get ("x2") + "," + inPath.get ("y2") + "z") : - inPath.get ("d"); - - for (segment in mPathParser.parse (d, mConvertCubics)) { - - path.segments.push (segment); - - } - - } - - return path; - - } - - - public function loadText (inText:Xml, matrix:Matrix, inStyles:StringMap ):Text { - - if (inText.exists ("transform")) { - - matrix = matrix.clone (); - applyTransform (matrix, inText.get ("transform")); - - } - - var styles = getStyles (inText, inStyles); - var text = new Text (); - - text.matrix = matrix; - text.name = inText.exists ("id") ? inText.get ("id") : ""; - text.x = getFloat (inText, "x", 0.0); - text.y = getFloat (inText, "y", 0.0); - text.fill = getFillStyle ("fill", inText, styles); - text.fill_alpha = getFloatStyle ("fill-opacity", inText, styles, 1.0); - text.stroke_alpha = getFloatStyle ("stroke-opacity", inText, styles, 1.0); - text.stroke_colour = getStrokeStyle ("stroke", inText, styles, null); - text.stroke_width = getFloatStyle ("stroke-width", inText, styles, 1.0); - text.font_family = getStyle ("font-family", inText, styles, ""); - text.font_size = getFloatStyle ("font-size", inText, styles, 12); - text.letter_spacing = getFloatStyle ("letter-spacing", inText, styles, 0); - text.kerning = getFloatStyle ("kerning", inText, styles, 0); - - var string = ""; - - for (el in inText.elements ()) { - - string += el.toString(); - - } - - //trace(string); - text.text = string; - return text; - - } - - -} \ No newline at end of file + + + private static inline var SIN45:Float = 0.70710678118654752440084436210485; + private static inline var TAN22:Float = 0.4142135623730950488016887242097; + private static var mStyleSplit = ~/;/g; + private static var mStyleValue = ~/\s*(.*)\s*:\s*(.*)\s*/; + private static var mTranslateMatch = ~/translate\((.*)[, ](.*)\)/; + private static var mScaleMatch = ~/scale\((.*)\)/; + private static var mMatrixMatch = ~/matrix\((.*)[, ](.*)[, ](.*)[, ](.*)[, ](.*)[, ](.*)\)/; + private static var mURLMatch = ~/url\(#(.*)\)/; + private static var defaultFill = FillSolid(0x000000); + + public var height (default, null):Float; + public var width (default, null):Float; + + private var mConvertCubics:Bool; + private var mGrads:GradHash; + private var mPatterns: Map; + private var mPatternsSVG: Map; + private var mPathParser:PathParser; + private var symbols: Map; + private var mLinkPaths: Map; + private var mClipPathLinks: Map; + private var clipIncId: Int = 1; + + public function new (inXML:Xml, inConvertCubics:Bool = false) { + + super(); + + var svg = inXML.firstElement(); + + if (svg == null || (svg.nodeName != "svg" && svg.nodeName != "svg:svg")) + throw "Not an SVG file (" + (svg==null ? "null" : svg.nodeName) + ")"; + + mGrads = new GradHash (); + mPathParser = new PathParser (); + symbols = new Map(); + mPatterns = new Map(); + mPatternsSVG = new Map(); + mConvertCubics = inConvertCubics; + + width = getFloatStyle ("width", svg, null, 0.0); + height = getFloatStyle ("height", svg, null, 0.0); + + if (width == 0 && height == 0) + width = height = 400; + else if (width == 0) + width = height; + else if (height == 0) + height = width; + + var viewBox = new Rectangle(0, 0, width, height); + + if (svg.exists("viewBox")) { + + var vbox = svg.get("viewBox"); + var params = vbox.indexOf(",") != -1 ? vbox.split(",") : vbox.split(" "); + viewBox = new Rectangle( trimToFloat(params[0]), trimToFloat(params[1]), trimToFloat(params[2]), trimToFloat(params[3]) ); + } + + loadGroup(this, svg, new Matrix (1, 0, 0, 1, -viewBox.x, -viewBox.y), null); + + } + + + inline function trimToFloat (value:String) { + + return Std.parseFloat( StringTools.trim(value) ); + + } + + + private function applyTransform (ioMatrix:Matrix, inTrans:String):Float { + + var scale = 1.0; + + if (mTranslateMatch.match(inTrans)) + { +// TODO: Pre-translate + + ioMatrix.translate (Std.parseFloat (mTranslateMatch.matched (1)), Std.parseFloat (mTranslateMatch.matched (2))); + + } else if (mScaleMatch.match (inTrans)) { + +// TODO: Pre-scale + var s = Std.parseFloat (mScaleMatch.matched (1)); + ioMatrix.scale (s, s); + scale = s; + + } else if (mMatrixMatch.match (inTrans)) { + + var m = new Matrix ( + Std.parseFloat (mMatrixMatch.matched (1)), + Std.parseFloat (mMatrixMatch.matched (2)), + Std.parseFloat (mMatrixMatch.matched (3)), + Std.parseFloat (mMatrixMatch.matched (4)), + Std.parseFloat (mMatrixMatch.matched (5)), + Std.parseFloat (mMatrixMatch.matched (6)) + ); + + m.concat (ioMatrix); + + ioMatrix.a = m.a; + ioMatrix.b = m.b; + ioMatrix.c = m.c; + ioMatrix.d = m.d; + ioMatrix.tx = m.tx; + ioMatrix.ty = m.ty; + + scale = Math.sqrt (ioMatrix.a * ioMatrix.a + ioMatrix.c * ioMatrix.c); + + } else { + + trace("Warning, unknown transform:" + inTrans); + + } + + return scale; + + } + + + private function dumpGroup (g:Group, indent:String) { + + trace (indent + "Group:" + g.name); + indent += " "; + + for (e in g.children) { + + switch (e) { + + case DisplayPath (path): trace (indent + "Path" + " " + path.matrix); + case DisplayGroup (group): dumpGroup (group, indent+" "); + case DisplayText (text): trace (indent + "Text " + text.text); + + } + + } + + } + + + private function getColorStyle (inKey:String, inNode:Xml, inStyles:StringMap , inDefault:Int) { + + var s = getStyle (inKey, inNode, inStyles, ""); + + if (s == "") { + + return inDefault; + + } + + if (s.charAt (0) == '#') { + + return Std.parseInt ("0x" + s.substr (1)); + + } + + return Std.parseInt (s); + + } + + + private function getFillStyle (inKey:String, inNode:Xml, inStyles:StringMap) { + var s = getStyle (inKey, inNode, inStyles, ""); + + if (s == "") { + + return defaultFill; + + } + + if (s.charAt (0) == '#') { + + return FillSolid (Std.parseInt ("0x" + s.substr (1))); + + } + + if (s == "none") { + + return FillNone; + + } + + if (mURLMatch.match (s)) { + + var url = mURLMatch.matched (1); + + if (mGrads.exists (url)) { + + return FillGrad(mGrads.get(url)); + + } else if(mPatterns.exists(url)) { + return BitmapFill(mPatterns.get(url)); + } + + throw ("Unknown url:" + url); + + } + + if(StringTools.startsWith(s, "rgb")) { + var r: EReg = ~/rgb/g; + var rgbFull: Array = r.split(s); + var rgb: String = StringTools.replace(rgbFull[1], "(", ""); + rgb = StringTools.replace(rgb, ")", ""); + var frags: Array = rgb.split(","); + return FillSolid(rgbToHex(Std.parseInt(frags[0]), Std.parseInt(frags[1]), Std.parseInt(frags[2]))); + } + throw ("Unknown fill string:" + s); + + return FillNone; + + } + + + private function getFloat (inXML:Xml, inName:String, inDef:Float = 0.0):Float { + + if (inXML.exists (inName)) + return Std.parseFloat (inXML.get (inName)); + + return inDef; + + } + + + private function getFloatStyle (inKey:String, inNode:Xml, inStyles:StringMap, inDefault:Float) { + + var s = getStyle (inKey, inNode, inStyles, ""); + + if (s == "") { + + return inDefault; + + } + + return Std.parseFloat (s); + + } + + + private function getStrokeStyle (inKey:String, inNode:Xml, inStyles:StringMap , inDefault:Null) { + + var s = getStyle (inKey, inNode, inStyles, ""); + + if (s == "") { + + return inDefault; + + } + + if (s == "none") { + + return null; + + } + + if (s.charAt (0) == '#') { + + return Std.parseInt ("0x" + s.substr (1)); + + } + + return Std.parseInt (s); + + } + + + private function getStyle (inKey:String, inNode:Xml, inStyles:StringMap , inDefault:String) { + + if (inNode != null && inNode.exists (inKey)) { + + return inNode.get (inKey); + + } + + if (inStyles != null && inStyles.exists (inKey)) { + + return inStyles.get (inKey); + + } + + return inDefault; + + } + + + private function getStyles (inNode:Xml, inPrevStyles:StringMap):StringMap { + + if (!inNode.exists ("style")) + return inPrevStyles; + + var styles = new StringMap (); + + if (inPrevStyles != null) { + + for (s in inPrevStyles.keys ()) { + + styles.set (s, inPrevStyles.get (s)); + + } + + } + + var style = inNode.get ("style"); + var strings = mStyleSplit.split (style); + for (s in strings) { + + if (mStyleValue.match (s)) { + + styles.set (mStyleValue.matched (1), mStyleValue.matched (2)); + + } + + } + + return styles; + + } + + + private function loadDefs (inXML:Xml) { + +// Two passes - to allow forward xlinks + + for (pass in 0...2) { + + for (def in inXML.elements ()) { + + var name = def.nodeName; + + if (name.substr (0, 4) == "svg:") { + + name = name.substr (4); + + } + + if (name == "linearGradient") { + + loadGradient (def, GradientType.LINEAR, pass == 1); + + } else if (name == "radialGradient") { + + loadGradient (def, GradientType.RADIAL, pass == 1); + + } else if(name == "path") { + if(mLinkPaths == null) { + mLinkPaths = new Map(); + } + mLinkPaths.set(def.get("id"), def); + } + + } + + } + + } + + private function loadPattern(inPattern: Xml, inCrossLink: Bool) { + var name = inPattern.get("id"); + + if (inCrossLink && inPattern.exists("xlink:href")) { + + var xlink = inPattern.get ("xlink:href"); + + if (xlink.charAt(0) != "#") + throw ("xlink - unkown syntax : " + xlink); + + var base = mPatterns.get (xlink.substr (1)); + + if (base != null) { + mPatterns.set(inPattern.get("id"), base); + } else { + + throw ("Unknown xlink : " + xlink); + + } + + } else { + var pattern = new BitmapFill(); + inPattern.nodeName = "svg"; + var bitmapData = BitmapDataManager.create(inPattern.toString(), name, 1, true); + pattern.bitmapData = bitmapData; + + mPatternsSVG.set(name, inPattern); + mPatterns.set(name, pattern); + } + } + + private function loadGradient (inGrad:Xml, inType:GradientType, inCrossLink:Bool) { + + var name = inGrad.get ("id"); + var grad = new Grad (inType); + + if (inCrossLink && inGrad.exists("xlink:href")) { + + var xlink = inGrad.get ("xlink:href"); + + if (xlink.charAt(0) != "#") + throw ("xlink - unkown syntax : " + xlink); + + var base = mGrads.get (xlink.substr (1)); + + if (base != null) { + + grad.colors = base.colors; + grad.alphas = base.alphas; + grad.ratios = base.ratios; + grad.gradMatrix = base.gradMatrix.clone (); + grad.spread = base.spread; + grad.interp = base.interp; + grad.radius = base.radius; + + } else { + + throw ("Unknown xlink : " + xlink); + + } + + } + + if (inGrad.exists ("x1")) { + + grad.x1 = getFloat (inGrad, "x1"); + grad.y1 = getFloat (inGrad, "y1"); + grad.x2 = getFloat (inGrad, "x2"); + grad.y2 = getFloat (inGrad, "y2"); + + } else { + + grad.x1 = getFloat (inGrad, "cx"); + grad.y1 = getFloat (inGrad, "cy"); + grad.x2 = getFloat (inGrad, "fx", grad.x1); + grad.y2 = getFloat (inGrad, "fy", grad.y1); + + } + + grad.radius = getFloat (inGrad, "r"); + + if (inGrad.exists ("gradientTransform")) { + + applyTransform (grad.gradMatrix, inGrad.get ("gradientTransform")); + + } + +// todo - grad.spread = base.spread; + + for (stop in inGrad.elements ()) { + + var styles = getStyles (stop, null); + + grad.colors.push (getColorStyle ("stop-color", stop, styles, 0x000000)); + grad.alphas.push (getFloatStyle ("stop-opacity", stop, styles, 1.0)); + grad.ratios.push (Std.int (Std.parseFloat (stop.get ("offset")) * 255.0)); + + } + + mGrads.set (name, grad); + + } + + + public function loadGroup (g:Group, inG:Xml, matrix:Matrix, inStyles:StringMap ):Group { + + if (inG.exists ("transform")) { + + matrix = matrix.clone (); + applyTransform (matrix, inG.get ("transform")); + + } + + if (inG.exists ("inkscape:label")) { + + g.name = inG.get ("inkscape:label"); + + } else if (inG.exists ("id")) { + + g.name = inG.get ("id"); + + } + + var styles = getStyles (inG, inStyles); + +/* +supports eg: + + + + + + +*/ + if (inG.exists("opacity")) { + + var opacity = inG.get("opacity"); + + if (styles == null) + styles = new StringMap(); + + if (styles.exists("opacity")) + opacity = Std.string( Std.parseFloat(opacity) * Std.parseFloat(styles.get("opacity")) ); + + styles.set("opacity", opacity); + + } + + if(styles != null && styles.exists("clip-path")) { +//we're clipping +// we need to get the bitmap fill and apply it to the path + var clipFill = new BitmapFill(); + inG.nodeName = "svg"; + inG.remove("style"); + var inGString: String = inG.toString(); + var bitmapData = BitmapDataManager.create(inGString, inGString, 1, false); + clipFill.bitmapData = bitmapData; + + var clipId: String = styles.get("clip-path"); + clipId = clipId.substring(5, clipId.length - 1); + var pathId: String = mClipPathLinks.get(clipId); + var clipXml: Xml = mLinkPaths.get(pathId); + pathId += "_" + clipIncId++; + mPatterns.set(pathId, clipFill); + clipXml.set("style:fill", "url(#" + pathId + ")"); + styles.set("fill", "url(#" + pathId + ")"); + g.children.push (DisplayPath (loadPath (clipXml, matrix, styles, false, false))); + return g; + } + + for (el in inG.elements ()) { + + var name = el.nodeName; + + if (name.substr (0, 4) == "svg:") { + + name = name.substr(4); + + } + + if (name == "defs") { + + loadDefs (el); + + } else if(name == "symbol") { + saveSymbol(el); + } else if(name == "use") { + g.children.push (DisplayGroup (applyRef(new Group(), el, matrix, styles))); + } else if (name == "g") { + + if (!(el.exists("display") && el.get("display") == "none")) { + + g.children.push (DisplayGroup (loadGroup (new Group (), el, matrix, styles))); + + } + + } else if (name == "path" || name == "line" || name == "polyline") { + + g.children.push (DisplayPath (loadPath (el, matrix, styles, false, false))); + + } else if (name == "rect") { + + g.children.push (DisplayPath (loadPath (el, matrix, styles, true, false))); + + } else if (name == "polygon") { + + g.children.push (DisplayPath (loadPath (el, matrix, styles, false, false))); + + } else if (name == "ellipse") { + + g.children.push (DisplayPath (loadPath (el, matrix, styles, false, true))); + + } else if (name == "circle") { + + g.children.push (DisplayPath (loadPath (el, matrix, styles, false, true, true))); + + } else if (name == "text") { + + g.children.push (DisplayText (loadText (el, matrix, styles))); + + } else if (name == "linearGradient") { + + loadGradient (el, GradientType.LINEAR, true); + + } else if (name == "radialGradient") { + + loadGradient (el, GradientType.RADIAL, true); + + } else if (name == "pattern") { + loadPattern(el, true); + } else if (name == "clipPath") { + storeClipPath(el); + } else { + +// throw("Unknown child : " + el.nodeName ); + + } + + } + + return g; + + } + + public inline function saveSymbol(inText: Xml): Void { + symbols.set(inText.get("id"), inText); + } + + private inline function storeClipPath(inText: Xml): Void { + if(mClipPathLinks == null) { + mClipPathLinks = new Map(); + } + var linkUrl: String = ""; + for(el in inText.elements()) { + var name = el.nodeName; + if(name == "use") { + linkUrl = el.get("xlink:href"); + break; + } + } + mClipPathLinks.set(inText.get("id"), linkUrl.substring(1)); + } + + public function applyRef(g:Group, inText:Xml, matrix:Matrix, inStyles:StringMap ): Group { + var id: String = inText.get("xlink:href"); + var svg: Xml = symbols.get(id.substring(1)); //Remove the # + + if(svg != null) { + + if(svg.firstElement().get("operated") == null) { + var newParent: Xml = Xml.createElement("g"); + newParent.set("operated", "true"); + var newChildren: List = new List(); + while(svg.firstElement() != null) { + newChildren.add(svg.firstElement()); + svg.removeChild(svg.firstElement()); + } + svg.addChild(newParent); + for(child in newChildren) { + newParent.addChild(child); + } + } + + for(attr in inText.attributes()) { + var value = inText.get(attr); + if(value != null && attr != "xlink:href") { + svg.firstElement().set(attr, value); + } + } + return loadGroup(g, svg.firstElement(), matrix, null); + } + return g; + } + + + public function loadPath (inPath:Xml, matrix:Matrix, inStyles:StringMap, inIsRect:Bool, inIsEllipse:Bool, inIsCircle:Bool=false):Path { + if (inPath.exists ("transform")) { + + matrix = matrix.clone (); + applyTransform (matrix, inPath.get ("transform")); + + } + + var styles = getStyles (inPath, inStyles); + var name = inPath.exists ("id") ? inPath.get ("id") : ""; + var path = new Path (); + path.fill = getFillStyle ("fill", inPath, styles); + path.alpha = getFloatStyle ("opacity", inPath, styles, 1.0); + switch(path.fill) { + case FillGrad(grad): + var alphas: Array = grad.alphas; + for(i in 0...alphas.length) { + alphas[i] = alphas[i] * path.alpha; + } + default: + } + path.fill_alpha = getFloatStyle ("fill-opacity", inPath, styles, 1.0); + path.stroke_alpha = getFloatStyle ("stroke-opacity", inPath, styles, 1.0); + path.stroke_colour = getStrokeStyle ("stroke", inPath, styles, null); + path.stroke_width = getFloatStyle ("stroke-width", inPath, styles, 1.0); + path.stroke_caps = CapsStyle.ROUND; + path.joint_style = JointStyle.ROUND; + path.miter_limit = getFloatStyle ("stroke-miterlimit", inPath, styles, 3.0); + path.segments = []; + path.matrix = matrix; + path.name = name; + + if (inIsRect) { + + var x = inPath.exists ("x") ? Std.parseFloat (inPath.get ("x")) : 0; + var y = inPath.exists ("y") ? Std.parseFloat (inPath.get ("y")) : 0; + var w = Std.parseFloat (inPath.get ("width")); + var h = Std.parseFloat (inPath.get ("height")); + var rx = inPath.exists ("rx") ? Std.parseFloat (inPath.get ("rx")) : 0.0; + var ry = inPath.exists ("ry") ? Std.parseFloat (inPath.get ("ry")) : 0.0; + + if (rx == 0 || ry == 0) { + + path.segments.push (new MoveSegment (x , y)); + path.segments.push (new DrawSegment (x + w, y)); + path.segments.push (new DrawSegment (x + w, y + h)); + path.segments.push (new DrawSegment (x, y + h)); + path.segments.push (new DrawSegment (x, y)); + + } else { + + path.segments.push (new MoveSegment (x, y + ry)); + +// top-left + path.segments.push (new QuadraticSegment (x, y, x + rx, y)); + path.segments.push (new DrawSegment (x + w - rx, y)); + +// top-right + path.segments.push (new QuadraticSegment (x + w, y, x + w, y + rx)); + path.segments.push (new DrawSegment (x + w, y + h - ry)); + +// bottom-right + path.segments.push (new QuadraticSegment (x + w, y + h, x + w - rx, y + h)); + path.segments.push (new DrawSegment (x + rx, y + h)); + +// bottom-left + path.segments.push (new QuadraticSegment (x, y + h, x, y + h - ry)); + path.segments.push (new DrawSegment (x, y + ry)); + + } + + } else if (inIsEllipse) { + + var x = inPath.exists ("cx") ? Std.parseFloat (inPath.get ("cx")) : 0; + var y = inPath.exists ("cy") ? Std.parseFloat (inPath.get ("cy")) : 0; + var r = inIsCircle && inPath.exists ("r") ? Std.parseFloat (inPath.get ("r")) : 0.0; + var w = inIsCircle ? r : inPath.exists ("rx") ? Std.parseFloat (inPath.get ("rx")) : 0.0; + var w_ = w * SIN45; + var cw_ = w * TAN22; + var h = inIsCircle ? r : inPath.exists ("ry") ? Std.parseFloat (inPath.get ("ry")) : 0.0; + var h_ = h * SIN45; + var ch_ = h * TAN22; + + path.segments.push (new MoveSegment (x + w, y)); + path.segments.push (new QuadraticSegment (x + w, y + ch_, x + w_, y + h_)); + path.segments.push (new QuadraticSegment (x + cw_, y + h, x, y + h)); + path.segments.push (new QuadraticSegment (x - cw_, y + h, x - w_, y + h_)); + path.segments.push (new QuadraticSegment (x - w, y + ch_, x - w, y)); + path.segments.push (new QuadraticSegment (x - w, y - ch_, x - w_, y - h_)); + path.segments.push (new QuadraticSegment (x - cw_, y - h, x, y - h)); + path.segments.push (new QuadraticSegment (x + cw_, y - h, x + w_, y - h_)); + path.segments.push (new QuadraticSegment (x + w, y - ch_, x + w, y)); + + } else { + + var d = inPath.exists ("points") ? ("M" + inPath.get ("points") + "z") : + inPath.exists ("x1") ? ("M" + inPath.get ("x1") + "," + inPath.get ("y1") + " " + inPath.get ("x2") + "," + inPath.get ("y2") + "z") : + inPath.get ("d"); + + for (segment in mPathParser.parse (d, mConvertCubics)) { + + path.segments.push (segment); + + } + + } + + return path; + + } + + + public function loadText (inText:Xml, matrix:Matrix, inStyles:StringMap ):Text { + + if (inText.exists ("transform")) { + + matrix = matrix.clone (); + applyTransform (matrix, inText.get ("transform")); + + } + + var styles = getStyles (inText, inStyles); + var text = new Text (); + + text.matrix = matrix; + text.name = inText.exists ("id") ? inText.get ("id") : ""; + text.x = getFloat (inText, "x", 0.0); + text.y = getFloat (inText, "y", 0.0); + text.fill = getFillStyle ("fill", inText, styles); + text.fill_alpha = getFloatStyle ("fill-opacity", inText, styles, 1.0); + text.stroke_alpha = getFloatStyle ("stroke-opacity", inText, styles, 1.0); + text.stroke_colour = getStrokeStyle ("stroke", inText, styles, null); + text.stroke_width = getFloatStyle ("stroke-width", inText, styles, 1.0); + text.font_family = getStyle ("font-family", inText, styles, ""); + text.font_size = getFloatStyle ("font-size", inText, styles, 12); + text.letter_spacing = getFloatStyle ("letter-spacing", inText, styles, 0); + text.kerning = getFloatStyle ("kerning", inText, styles, 0); + + var string = ""; + + for (el in inText.elements ()) { + + string += el.toString(); + + } + +//trace(string); + text.text = string; + return text; + + } + + + private inline function rgbToHex(r: Int, g: Int, b: Int): Int { + return r << 16 ^ g << 8 ^ b; + } +} diff --git a/format/svg/SVGRenderer.hx b/format/svg/SVGRenderer.hx old mode 100644 new mode 100755 index 720084c..7c9fb81 --- a/format/svg/SVGRenderer.hx +++ b/format/svg/SVGRenderer.hx @@ -115,13 +115,17 @@ class SVGRenderer // 4. continue with "real" drawing inPath.segments[0].toGfx(mGfx, context); - switch(inPath.fill) + switch(inPath.fill) { case FillGrad(grad): grad.updateMatrix(m); mGfx.beginGradientFill(grad); case FillSolid(colour): mGfx.beginFill(colour,inPath.fill_alpha*inPath.alpha); + case BitmapFill(fill): + fill.updateMatrix(m); + fill.alpha = inPath.alpha; + mGfx.beginBitmapFill(fill); case FillNone: //mGfx.endFill(); } diff --git a/format/svg/Text.hx b/format/svg/Text.hx old mode 100644 new mode 100755 diff --git a/haxelib.xml b/haxelib.xml old mode 100644 new mode 100755