/** * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ /** * Class: mxXmlCanvas2D * * Base class for all canvases. The following methods make up the public * interface of the canvas 2D for all painting in mxGraph: * * - , * - , , * - , , , , , * , , , , , * , * - , , , , * , * - , , , * - , , , , * - , , , , * - , , * * is an additional method for drawing paths. This is * a synthetic method, meaning that it is turned into a sequence of curves by * default. Subclassers may add native support for arcs. * * Constructor: mxXmlCanvas2D * * Constructs a new abstract canvas. */ function mxXmlCanvas2D(root) { mxAbstractCanvas2D.call(this); /** * Variable: root * * Reference to the container for the SVG content. */ this.root = root; // Writes default settings; this.writeDefaults(); }; /** * Extends mxAbstractCanvas2D */ mxUtils.extend(mxXmlCanvas2D, mxAbstractCanvas2D); /** * Variable: textEnabled * * Specifies if text output should be enabled. Default is true. */ mxXmlCanvas2D.prototype.textEnabled = true; /** * Variable: compressed * * Specifies if the output should be compressed by removing redundant calls. * Default is true. */ mxXmlCanvas2D.prototype.compressed = true; /** * Function: writeDefaults * * Writes the rendering defaults to : */ mxXmlCanvas2D.prototype.writeDefaults = function() { var elem; // Writes font defaults elem = this.createElement('fontfamily'); elem.setAttribute('family', mxConstants.DEFAULT_FONTFAMILY); this.root.appendChild(elem); elem = this.createElement('fontsize'); elem.setAttribute('size', mxConstants.DEFAULT_FONTSIZE); this.root.appendChild(elem); // Writes shadow defaults elem = this.createElement('shadowcolor'); elem.setAttribute('color', mxConstants.SHADOWCOLOR); this.root.appendChild(elem); elem = this.createElement('shadowalpha'); elem.setAttribute('alpha', mxConstants.SHADOW_OPACITY); this.root.appendChild(elem); elem = this.createElement('shadowoffset'); elem.setAttribute('dx', mxConstants.SHADOW_OFFSET_X); elem.setAttribute('dy', mxConstants.SHADOW_OFFSET_Y); this.root.appendChild(elem); }; /** * Function: format * * Returns a formatted number with 2 decimal places. */ mxXmlCanvas2D.prototype.format = function(value) { return parseFloat(parseFloat(value).toFixed(2)); }; /** * Function: createElement * * Creates the given element using the owner document of . */ mxXmlCanvas2D.prototype.createElement = function(name) { return this.root.ownerDocument.createElement(name); }; /** * Function: save * * Saves the drawing state. */ mxXmlCanvas2D.prototype.save = function() { if (this.compressed) { mxAbstractCanvas2D.prototype.save.apply(this, arguments); } this.root.appendChild(this.createElement('save')); }; /** * Function: restore * * Restores the drawing state. */ mxXmlCanvas2D.prototype.restore = function() { if (this.compressed) { mxAbstractCanvas2D.prototype.restore.apply(this, arguments); } this.root.appendChild(this.createElement('restore')); }; /** * Function: scale * * Scales the output. * * Parameters: * * scale - Number that represents the scale where 1 is equal to 100%. */ mxXmlCanvas2D.prototype.scale = function(value) { var elem = this.createElement('scale'); elem.setAttribute('scale', value); this.root.appendChild(elem); }; /** * Function: translate * * Translates the output. * * Parameters: * * dx - Number that specifies the horizontal translation. * dy - Number that specifies the vertical translation. */ mxXmlCanvas2D.prototype.translate = function(dx, dy) { var elem = this.createElement('translate'); elem.setAttribute('dx', this.format(dx)); elem.setAttribute('dy', this.format(dy)); this.root.appendChild(elem); }; /** * Function: rotate * * Rotates and/or flips the output around a given center. (Note: Due to * limitations in VML, the rotation cannot be concatenated.) * * Parameters: * * theta - Number that represents the angle of the rotation (in degrees). * flipH - Boolean indicating if the output should be flipped horizontally. * flipV - Boolean indicating if the output should be flipped vertically. * cx - Number that represents the x-coordinate of the rotation center. * cy - Number that represents the y-coordinate of the rotation center. */ mxXmlCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy) { var elem = this.createElement('rotate'); if (theta != 0 || flipH || flipV) { elem.setAttribute('theta', this.format(theta)); elem.setAttribute('flipH', (flipH) ? '1' : '0'); elem.setAttribute('flipV', (flipV) ? '1' : '0'); elem.setAttribute('cx', this.format(cx)); elem.setAttribute('cy', this.format(cy)); this.root.appendChild(elem); } }; /** * Function: setAlpha * * Sets the current alpha. * * Parameters: * * value - Number that represents the new alpha. Possible values are between * 1 (opaque) and 0 (transparent). */ mxXmlCanvas2D.prototype.setAlpha = function(value) { if (this.compressed) { if (this.state.alpha == value) { return; } mxAbstractCanvas2D.prototype.setAlpha.apply(this, arguments); } var elem = this.createElement('alpha'); elem.setAttribute('alpha', this.format(value)); this.root.appendChild(elem); }; /** * Function: setFillAlpha * * Sets the current fill alpha. * * Parameters: * * value - Number that represents the new fill alpha. Possible values are between * 1 (opaque) and 0 (transparent). */ mxXmlCanvas2D.prototype.setFillAlpha = function(value) { if (this.compressed) { if (this.state.fillAlpha == value) { return; } mxAbstractCanvas2D.prototype.setFillAlpha.apply(this, arguments); } var elem = this.createElement('fillalpha'); elem.setAttribute('alpha', this.format(value)); this.root.appendChild(elem); }; /** * Function: setStrokeAlpha * * Sets the current stroke alpha. * * Parameters: * * value - Number that represents the new stroke alpha. Possible values are between * 1 (opaque) and 0 (transparent). */ mxXmlCanvas2D.prototype.setStrokeAlpha = function(value) { if (this.compressed) { if (this.state.strokeAlpha == value) { return; } mxAbstractCanvas2D.prototype.setStrokeAlpha.apply(this, arguments); } var elem = this.createElement('strokealpha'); elem.setAttribute('alpha', this.format(value)); this.root.appendChild(elem); }; /** * Function: setFillColor * * Sets the current fill color. * * Parameters: * * value - Hexadecimal representation of the color or 'none'. */ mxXmlCanvas2D.prototype.setFillColor = function(value) { if (value == mxConstants.NONE) { value = null; } if (this.compressed) { if (this.state.fillColor == value) { return; } mxAbstractCanvas2D.prototype.setFillColor.apply(this, arguments); } var elem = this.createElement('fillcolor'); elem.setAttribute('color', (value != null) ? value : mxConstants.NONE); this.root.appendChild(elem); }; /** * Function: setGradient * * Sets the gradient. Note that the coordinates may be ignored by some implementations. * * Parameters: * * color1 - Hexadecimal representation of the start color. * color2 - Hexadecimal representation of the end color. * x - X-coordinate of the gradient region. * y - y-coordinate of the gradient region. * w - Width of the gradient region. * h - Height of the gradient region. * direction - One of , , * or . * alpha1 - Optional alpha of the start color. Default is 1. Possible values * are between 1 (opaque) and 0 (transparent). * alpha2 - Optional alpha of the end color. Default is 1. Possible values * are between 1 (opaque) and 0 (transparent). */ mxXmlCanvas2D.prototype.setGradient = function(color1, color2, x, y, w, h, direction, alpha1, alpha2) { if (color1 != null && color2 != null) { mxAbstractCanvas2D.prototype.setGradient.apply(this, arguments); var elem = this.createElement('gradient'); elem.setAttribute('c1', color1); elem.setAttribute('c2', color2); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); elem.setAttribute('w', this.format(w)); elem.setAttribute('h', this.format(h)); // Default direction is south if (direction != null) { elem.setAttribute('direction', direction); } if (alpha1 != null) { elem.setAttribute('alpha1', alpha1); } if (alpha2 != null) { elem.setAttribute('alpha2', alpha2); } this.root.appendChild(elem); } }; /** * Function: setStrokeColor * * Sets the current stroke color. * * Parameters: * * value - Hexadecimal representation of the color or 'none'. */ mxXmlCanvas2D.prototype.setStrokeColor = function(value) { if (value == mxConstants.NONE) { value = null; } if (this.compressed) { if (this.state.strokeColor == value) { return; } mxAbstractCanvas2D.prototype.setStrokeColor.apply(this, arguments); } var elem = this.createElement('strokecolor'); elem.setAttribute('color', (value != null) ? value : mxConstants.NONE); this.root.appendChild(elem); }; /** * Function: setStrokeWidth * * Sets the current stroke width. * * Parameters: * * value - Numeric representation of the stroke width. */ mxXmlCanvas2D.prototype.setStrokeWidth = function(value) { if (this.compressed) { if (this.state.strokeWidth == value) { return; } mxAbstractCanvas2D.prototype.setStrokeWidth.apply(this, arguments); } var elem = this.createElement('strokewidth'); elem.setAttribute('width', this.format(value)); this.root.appendChild(elem); }; /** * Function: setDashed * * Enables or disables dashed lines. * * Parameters: * * value - Boolean that specifies if dashed lines should be enabled. * value - Boolean that specifies if the stroke width should be ignored * for the dash pattern. Default is false. */ mxXmlCanvas2D.prototype.setDashed = function(value, fixDash) { if (this.compressed) { if (this.state.dashed == value) { return; } mxAbstractCanvas2D.prototype.setDashed.apply(this, arguments); } var elem = this.createElement('dashed'); elem.setAttribute('dashed', (value) ? '1' : '0'); if (fixDash != null) { elem.setAttribute('fixDash', (fixDash) ? '1' : '0'); } this.root.appendChild(elem); }; /** * Function: setDashPattern * * Sets the current dash pattern. Default is '3 3'. * * Parameters: * * value - String that represents the dash pattern, which is a sequence of * numbers defining the length of the dashes and the length of the spaces * between the dashes. The lengths are relative to the line width - a length * of 1 is equals to the line width. */ mxXmlCanvas2D.prototype.setDashPattern = function(value) { if (this.compressed) { if (this.state.dashPattern == value) { return; } mxAbstractCanvas2D.prototype.setDashPattern.apply(this, arguments); } var elem = this.createElement('dashpattern'); elem.setAttribute('pattern', value); this.root.appendChild(elem); }; /** * Function: setLineCap * * Sets the line cap. Default is 'flat' which corresponds to 'butt' in SVG. * * Parameters: * * value - String that represents the line cap. Possible values are flat, round * and square. */ mxXmlCanvas2D.prototype.setLineCap = function(value) { if (this.compressed) { if (this.state.lineCap == value) { return; } mxAbstractCanvas2D.prototype.setLineCap.apply(this, arguments); } var elem = this.createElement('linecap'); elem.setAttribute('cap', value); this.root.appendChild(elem); }; /** * Function: setLineJoin * * Sets the line join. Default is 'miter'. * * Parameters: * * value - String that represents the line join. Possible values are miter, * round and bevel. */ mxXmlCanvas2D.prototype.setLineJoin = function(value) { if (this.compressed) { if (this.state.lineJoin == value) { return; } mxAbstractCanvas2D.prototype.setLineJoin.apply(this, arguments); } var elem = this.createElement('linejoin'); elem.setAttribute('join', value); this.root.appendChild(elem); }; /** * Function: setMiterLimit * * Sets the miter limit. Default is 10. * * Parameters: * * value - Number that represents the miter limit. */ mxXmlCanvas2D.prototype.setMiterLimit = function(value) { if (this.compressed) { if (this.state.miterLimit == value) { return; } mxAbstractCanvas2D.prototype.setMiterLimit.apply(this, arguments); } var elem = this.createElement('miterlimit'); elem.setAttribute('limit', value); this.root.appendChild(elem); }; /** * Function: setFontColor * * Sets the current font color. Default is '#000000'. * * Parameters: * * value - Hexadecimal representation of the color or 'none'. */ mxXmlCanvas2D.prototype.setFontColor = function(value) { if (this.textEnabled) { if (value == mxConstants.NONE) { value = null; } if (this.compressed) { if (this.state.fontColor == value) { return; } mxAbstractCanvas2D.prototype.setFontColor.apply(this, arguments); } var elem = this.createElement('fontcolor'); elem.setAttribute('color', (value != null) ? value : mxConstants.NONE); this.root.appendChild(elem); } }; /** * Function: setFontBackgroundColor * * Sets the current font background color. * * Parameters: * * value - Hexadecimal representation of the color or 'none'. */ mxXmlCanvas2D.prototype.setFontBackgroundColor = function(value) { if (this.textEnabled) { if (value == mxConstants.NONE) { value = null; } if (this.compressed) { if (this.state.fontBackgroundColor == value) { return; } mxAbstractCanvas2D.prototype.setFontBackgroundColor.apply(this, arguments); } var elem = this.createElement('fontbackgroundcolor'); elem.setAttribute('color', (value != null) ? value : mxConstants.NONE); this.root.appendChild(elem); } }; /** * Function: setFontBorderColor * * Sets the current font border color. * * Parameters: * * value - Hexadecimal representation of the color or 'none'. */ mxXmlCanvas2D.prototype.setFontBorderColor = function(value) { if (this.textEnabled) { if (value == mxConstants.NONE) { value = null; } if (this.compressed) { if (this.state.fontBorderColor == value) { return; } mxAbstractCanvas2D.prototype.setFontBorderColor.apply(this, arguments); } var elem = this.createElement('fontbordercolor'); elem.setAttribute('color', (value != null) ? value : mxConstants.NONE); this.root.appendChild(elem); } }; /** * Function: setFontSize * * Sets the current font size. Default is . * * Parameters: * * value - Numeric representation of the font size. */ mxXmlCanvas2D.prototype.setFontSize = function(value) { if (this.textEnabled) { if (this.compressed) { if (this.state.fontSize == value) { return; } mxAbstractCanvas2D.prototype.setFontSize.apply(this, arguments); } var elem = this.createElement('fontsize'); elem.setAttribute('size', value); this.root.appendChild(elem); } }; /** * Function: setFontFamily * * Sets the current font family. Default is . * * Parameters: * * value - String representation of the font family. This handles the same * values as the CSS font-family property. */ mxXmlCanvas2D.prototype.setFontFamily = function(value) { if (this.textEnabled) { if (this.compressed) { if (this.state.fontFamily == value) { return; } mxAbstractCanvas2D.prototype.setFontFamily.apply(this, arguments); } var elem = this.createElement('fontfamily'); elem.setAttribute('family', value); this.root.appendChild(elem); } }; /** * Function: setFontStyle * * Sets the current font style. * * Parameters: * * value - Numeric representation of the font family. This is the sum of the * font styles from . */ mxXmlCanvas2D.prototype.setFontStyle = function(value) { if (this.textEnabled) { if (value == null) { value = 0; } if (this.compressed) { if (this.state.fontStyle == value) { return; } mxAbstractCanvas2D.prototype.setFontStyle.apply(this, arguments); } var elem = this.createElement('fontstyle'); elem.setAttribute('style', value); this.root.appendChild(elem); } }; /** * Function: setShadow * * Enables or disables shadows. * * Parameters: * * value - Boolean that specifies if shadows should be enabled. */ mxXmlCanvas2D.prototype.setShadow = function(value) { if (this.compressed) { if (this.state.shadow == value) { return; } mxAbstractCanvas2D.prototype.setShadow.apply(this, arguments); } var elem = this.createElement('shadow'); elem.setAttribute('enabled', (value) ? '1' : '0'); this.root.appendChild(elem); }; /** * Function: setShadowColor * * Sets the current shadow color. Default is . * * Parameters: * * value - Hexadecimal representation of the color or 'none'. */ mxXmlCanvas2D.prototype.setShadowColor = function(value) { if (this.compressed) { if (value == mxConstants.NONE) { value = null; } if (this.state.shadowColor == value) { return; } mxAbstractCanvas2D.prototype.setShadowColor.apply(this, arguments); } var elem = this.createElement('shadowcolor'); elem.setAttribute('color', (value != null) ? value : mxConstants.NONE); this.root.appendChild(elem); }; /** * Function: setShadowAlpha * * Sets the current shadows alpha. Default is . * * Parameters: * * value - Number that represents the new alpha. Possible values are between * 1 (opaque) and 0 (transparent). */ mxXmlCanvas2D.prototype.setShadowAlpha = function(value) { if (this.compressed) { if (this.state.shadowAlpha == value) { return; } mxAbstractCanvas2D.prototype.setShadowAlpha.apply(this, arguments); } var elem = this.createElement('shadowalpha'); elem.setAttribute('alpha', value); this.root.appendChild(elem); }; /** * Function: setShadowOffset * * Sets the current shadow offset. * * Parameters: * * dx - Number that represents the horizontal offset of the shadow. * dy - Number that represents the vertical offset of the shadow. */ mxXmlCanvas2D.prototype.setShadowOffset = function(dx, dy) { if (this.compressed) { if (this.state.shadowDx == dx && this.state.shadowDy == dy) { return; } mxAbstractCanvas2D.prototype.setShadowOffset.apply(this, arguments); } var elem = this.createElement('shadowoffset'); elem.setAttribute('dx', dx); elem.setAttribute('dy', dy); this.root.appendChild(elem); }; /** * Function: rect * * Puts a rectangle into the drawing buffer. * * Parameters: * * x - Number that represents the x-coordinate of the rectangle. * y - Number that represents the y-coordinate of the rectangle. * w - Number that represents the width of the rectangle. * h - Number that represents the height of the rectangle. */ mxXmlCanvas2D.prototype.rect = function(x, y, w, h) { var elem = this.createElement('rect'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); elem.setAttribute('w', this.format(w)); elem.setAttribute('h', this.format(h)); this.root.appendChild(elem); }; /** * Function: roundrect * * Puts a rounded rectangle into the drawing buffer. * * Parameters: * * x - Number that represents the x-coordinate of the rectangle. * y - Number that represents the y-coordinate of the rectangle. * w - Number that represents the width of the rectangle. * h - Number that represents the height of the rectangle. * dx - Number that represents the horizontal rounding. * dy - Number that represents the vertical rounding. */ mxXmlCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy) { var elem = this.createElement('roundrect'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); elem.setAttribute('w', this.format(w)); elem.setAttribute('h', this.format(h)); elem.setAttribute('dx', this.format(dx)); elem.setAttribute('dy', this.format(dy)); this.root.appendChild(elem); }; /** * Function: ellipse * * Puts an ellipse into the drawing buffer. * * Parameters: * * x - Number that represents the x-coordinate of the ellipse. * y - Number that represents the y-coordinate of the ellipse. * w - Number that represents the width of the ellipse. * h - Number that represents the height of the ellipse. */ mxXmlCanvas2D.prototype.ellipse = function(x, y, w, h) { var elem = this.createElement('ellipse'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); elem.setAttribute('w', this.format(w)); elem.setAttribute('h', this.format(h)); this.root.appendChild(elem); }; /** * Function: image * * Paints an image. * * Parameters: * * x - Number that represents the x-coordinate of the image. * y - Number that represents the y-coordinate of the image. * w - Number that represents the width of the image. * h - Number that represents the height of the image. * src - String that specifies the URL of the image. * aspect - Boolean indicating if the aspect of the image should be preserved. * flipH - Boolean indicating if the image should be flipped horizontally. * flipV - Boolean indicating if the image should be flipped vertically. */ mxXmlCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV) { src = this.converter.convert(src); // LATER: Add option for embedding images as base64. var elem = this.createElement('image'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); elem.setAttribute('w', this.format(w)); elem.setAttribute('h', this.format(h)); elem.setAttribute('src', src); elem.setAttribute('aspect', (aspect) ? '1' : '0'); elem.setAttribute('flipH', (flipH) ? '1' : '0'); elem.setAttribute('flipV', (flipV) ? '1' : '0'); this.root.appendChild(elem); }; /** * Function: begin * * Starts a new path and puts it into the drawing buffer. */ mxXmlCanvas2D.prototype.begin = function() { this.root.appendChild(this.createElement('begin')); this.lastX = 0; this.lastY = 0; }; /** * Function: moveTo * * Moves the current path the given point. * * Parameters: * * x - Number that represents the x-coordinate of the point. * y - Number that represents the y-coordinate of the point. */ mxXmlCanvas2D.prototype.moveTo = function(x, y) { var elem = this.createElement('move'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); this.root.appendChild(elem); this.lastX = x; this.lastY = y; }; /** * Function: lineTo * * Draws a line to the given coordinates. * * Parameters: * * x - Number that represents the x-coordinate of the endpoint. * y - Number that represents the y-coordinate of the endpoint. */ mxXmlCanvas2D.prototype.lineTo = function(x, y) { var elem = this.createElement('line'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); this.root.appendChild(elem); this.lastX = x; this.lastY = y; }; /** * Function: quadTo * * Adds a quadratic curve to the current path. * * Parameters: * * x1 - Number that represents the x-coordinate of the control point. * y1 - Number that represents the y-coordinate of the control point. * x2 - Number that represents the x-coordinate of the endpoint. * y2 - Number that represents the y-coordinate of the endpoint. */ mxXmlCanvas2D.prototype.quadTo = function(x1, y1, x2, y2) { var elem = this.createElement('quad'); elem.setAttribute('x1', this.format(x1)); elem.setAttribute('y1', this.format(y1)); elem.setAttribute('x2', this.format(x2)); elem.setAttribute('y2', this.format(y2)); this.root.appendChild(elem); this.lastX = x2; this.lastY = y2; }; /** * Function: curveTo * * Adds a bezier curve to the current path. * * Parameters: * * x1 - Number that represents the x-coordinate of the first control point. * y1 - Number that represents the y-coordinate of the first control point. * x2 - Number that represents the x-coordinate of the second control point. * y2 - Number that represents the y-coordinate of the second control point. * x3 - Number that represents the x-coordinate of the endpoint. * y3 - Number that represents the y-coordinate of the endpoint. */ mxXmlCanvas2D.prototype.curveTo = function(x1, y1, x2, y2, x3, y3) { var elem = this.createElement('curve'); elem.setAttribute('x1', this.format(x1)); elem.setAttribute('y1', this.format(y1)); elem.setAttribute('x2', this.format(x2)); elem.setAttribute('y2', this.format(y2)); elem.setAttribute('x3', this.format(x3)); elem.setAttribute('y3', this.format(y3)); this.root.appendChild(elem); this.lastX = x3; this.lastY = y3; }; /** * Function: close * * Closes the current path. */ mxXmlCanvas2D.prototype.close = function() { this.root.appendChild(this.createElement('close')); }; /** * Function: text * * Paints the given text. Possible values for format are empty string for * plain text and html for HTML markup. Background and border color as well * as clipping is not available in plain text labels for VML. HTML labels * are not available as part of shapes with no foreignObject support in SVG * (eg. IE9, IE10). * * Parameters: * * x - Number that represents the x-coordinate of the text. * y - Number that represents the y-coordinate of the text. * w - Number that represents the available width for the text or 0 for automatic width. * h - Number that represents the available height for the text or 0 for automatic height. * str - String that specifies the text to be painted. * align - String that represents the horizontal alignment. * valign - String that represents the vertical alignment. * wrap - Boolean that specifies if word-wrapping is enabled. Requires w > 0. * format - Empty string for plain text or 'html' for HTML markup. * overflow - Specifies the overflow behaviour of the label. Requires w > 0 and/or h > 0. * clip - Boolean that specifies if the label should be clipped. Requires w > 0 and/or h > 0. * rotation - Number that specifies the angle of the rotation around the anchor point of the text. * dir - Optional string that specifies the text direction. Possible values are rtl and lrt. */ mxXmlCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir) { if (this.textEnabled && str != null) { if (mxUtils.isNode(str)) { str = mxUtils.getOuterHtml(str); } var elem = this.createElement('text'); elem.setAttribute('x', this.format(x)); elem.setAttribute('y', this.format(y)); elem.setAttribute('w', this.format(w)); elem.setAttribute('h', this.format(h)); elem.setAttribute('str', str); if (align != null) { elem.setAttribute('align', align); } if (valign != null) { elem.setAttribute('valign', valign); } elem.setAttribute('wrap', (wrap) ? '1' : '0'); if (format == null) { format = ''; } elem.setAttribute('format', format); if (overflow != null) { elem.setAttribute('overflow', overflow); } if (clip != null) { elem.setAttribute('clip', (clip) ? '1' : '0'); } if (rotation != null) { elem.setAttribute('rotation', rotation); } if (dir != null) { elem.setAttribute('dir', dir); } this.root.appendChild(elem); } }; /** * Function: stroke * * Paints the outline of the current drawing buffer. */ mxXmlCanvas2D.prototype.stroke = function() { this.root.appendChild(this.createElement('stroke')); }; /** * Function: fill * * Fills the current drawing buffer. */ mxXmlCanvas2D.prototype.fill = function() { this.root.appendChild(this.createElement('fill')); }; /** * Function: fillAndStroke * * Fills the current drawing buffer and its outline. */ mxXmlCanvas2D.prototype.fillAndStroke = function() { this.root.appendChild(this.createElement('fillstroke')); };