| /****************************************************************************** |
| * Copyright (c) 2005, 2010 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| ****************************************************************************/ |
| |
| package org.eclipse.gmf.runtime.draw2d.ui.render.awt.internal.svg; |
| |
| import java.awt.Color; |
| |
| import org.apache.batik.dom.svg.SVGOMDocument; |
| import org.apache.batik.svggen.SVGColor; |
| import org.apache.batik.svggen.SVGGeneratorContext; |
| import org.apache.batik.svggen.SVGPaintDescriptor; |
| import org.apache.batik.util.SVGConstants; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.svg.SVGSVGElement; |
| import org.w3c.dom.traversal.NodeFilter; |
| import org.w3c.dom.traversal.NodeIterator; |
| |
| /** |
| * @author sshaw |
| * |
| * Utility class that will replace Black and white with corresponding outline and |
| * fill colors respectively. |
| */ |
| public class SVGColorConverter { |
| |
| static private SVGColorConverter INSTANCE = new SVGColorConverter(); |
| |
| /** |
| * getInstance |
| * Implementation of the singleton pattern |
| * |
| * @return the Singleton Instance of SVGColorConverter |
| */ |
| static public SVGColorConverter getInstance() { |
| return INSTANCE; |
| } |
| /** |
| * |
| */ |
| private SVGColorConverter() { |
| super(); |
| } |
| |
| /** |
| * replaceDocumentColors |
| * Given an SVGOMDocument, this method will replace all fill, stroke and gradient |
| * colors with values that are based in. Black color will be replaced by the given |
| * outlineColor and White color will be replaced by the given fillColor. |
| * |
| * @param svgDoc SVGOMDocument to perform the replace on. |
| * @param fillColor This is the fill color that will replace all occurrences of white |
| * @param outlineColor This is the outline color that will replace all occurrences of black. |
| */ |
| public void replaceDocumentColors(SVGOMDocument svgDoc, Color fillColor, Color outlineColor) { |
| SVGSVGElement svgRoot = svgDoc.getRootElement(); |
| NodeIterator ni = svgDoc.createNodeIterator(svgRoot, NodeFilter.SHOW_ALL, null, true); |
| Node node = ni.nextNode(); |
| while (node != null) { |
| if (node.getNodeType() == Node.ELEMENT_NODE) { |
| Element element = (Element)node; |
| |
| if (fillColor != null) { |
| setColorAttribute(svgDoc, element, SVGConstants.SVG_FILL_ATTRIBUTE, false, fillColor); |
| setColorAttribute(svgDoc, element, SVGConstants.SVG_STOP_COLOR_ATTRIBUTE, false, fillColor); |
| } |
| |
| if (outlineColor != null) { |
| setColorAttribute(svgDoc, element, SVGConstants.SVG_STROKE_ATTRIBUTE, true, outlineColor); |
| setColorAttribute(svgDoc, element, SVGConstants.SVG_STOP_COLOR_ATTRIBUTE, true, outlineColor); |
| } |
| } |
| |
| node = ni.nextNode(); |
| } |
| } |
| |
| public static final String SEMICOLON = ";"; //$NON-NLS-1$ |
| public static final String COLON = ":"; //$NON-NLS-1$ |
| |
| private boolean isBlack(String color) { |
| String cleanColorStr = cleanFromSpaces(color); |
| return cleanColorStr.equals("#000000") || cleanColorStr.equalsIgnoreCase("BLACK") || cleanColorStr.equalsIgnoreCase("rgb(0,0,0)");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
| } |
| |
| private boolean isWhite(String color) { |
| String cleanColorStr = cleanFromSpaces(color); |
| return cleanColorStr.equalsIgnoreCase("#FFFFFF") || cleanColorStr.equalsIgnoreCase("WHITE") || cleanColorStr.equalsIgnoreCase("rgb(255,255,255)");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
| } |
| |
| private String cleanFromSpaces(String s) { |
| char [] chars = new char[s.length()]; |
| int index = 0; |
| for (int i = 0; i < s.length(); i++) { |
| if (s.charAt(i) != ' ') { |
| chars[index++] = s.charAt(i); |
| } |
| } |
| return new String(chars, 0, index); |
| } |
| |
| /** |
| * setColorAttribute |
| * Utility function that will set the color attribute to the specified color |
| * |
| * @param element Element to set the attribute color of |
| * @param attributeName String attribute name, usually one of SVGConstants.SVG_FILL_ATTRIBUTE or |
| * SVGConstants.SVG_STROKE_ATTRIBUTE |
| * @param boolean black is true if replace with color, false to replace white. |
| * @param color Color to change the attribute to. |
| */ |
| protected void setColorAttribute(SVGOMDocument svgDoc, Element element, String attributeName, boolean black, Color color) { |
| SVGPaintDescriptor svgPD = SVGColor.toSVG(color, SVGGeneratorContext.createDefault(svgDoc)); |
| |
| if (element.hasAttribute(attributeName)) { |
| String value = element.getAttribute(attributeName); |
| |
| // Only change the Stroke color if the current color is black |
| if( attributeName.equals(SVGConstants.SVG_STROKE_ATTRIBUTE) || |
| attributeName.equals(SVGConstants.SVG_FILL_ATTRIBUTE)) { |
| |
| if( (black && isBlack(value)) || (!black && isWhite(value)) ) { |
| element.setAttribute(attributeName, svgPD.getPaintValue()); |
| } |
| } |
| } |
| else if (element.hasAttribute(SVGConstants.SVG_STYLE_TAG)) { |
| //TODO There must be a better way to set fill / outline color with the Batik libraries. |
| String style = element.getAttribute(SVGConstants.SVG_STYLE_TAG); |
| |
| String preColor = ""; //$NON-NLS-1$ |
| int nStart = style.indexOf(attributeName + COLON); |
| if (nStart != -1) { |
| if (nStart > 0) |
| preColor = style.substring(0, nStart); |
| |
| String postColor = ""; //$NON-NLS-1$ |
| int nEnd = style.indexOf(SEMICOLON, nStart); |
| if (nEnd == -1) |
| nEnd = style.length(); |
| if (nEnd < style.length() - 1) |
| postColor = style.substring(nEnd + 1, style.length()); |
| |
| String currentColor = style.substring(nStart+attributeName.length() + 1, nEnd); |
| if( (black && isBlack(currentColor)) || (!black && isWhite(currentColor))) { |
| if (!currentColor.equals(SVGConstants.SVG_NONE_VALUE)) { |
| StringBuffer styleBuffer = new StringBuffer(style.length() + 5); |
| styleBuffer.append(preColor); |
| styleBuffer.append(" "); //$NON-NLS-1$ |
| styleBuffer.append(attributeName); |
| styleBuffer.append(COLON); |
| styleBuffer.append(svgPD.getPaintValue()); |
| if (!postColor.equals("")) { //$NON-NLS-1$ |
| styleBuffer.append(SEMICOLON); |
| styleBuffer.append(postColor); |
| } |
| String styleNew = styleBuffer.toString(); |
| |
| element.setAttribute(SVGConstants.SVG_STYLE_TAG, styleNew); |
| } |
| } |
| } |
| } |
| } |
| } |