All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openhtmltopdf.swing.ImageMapParser Maven / Gradle / Ivy

Go to download

Open HTML to PDF is a CSS 2.1 renderer written in Java. This artifact contains the core rendering and layout code.

The newest version!
package com.openhtmltopdf.swing;
/*
 * {{{ header & license
 * Copyright (c) 2008 elbart0 at free.fr (submitted via email)
 *
 * This program 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 program 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 program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * }}}
 */

import com.openhtmltopdf.layout.SharedContext;
import com.openhtmltopdf.util.LogMessageId;
import com.openhtmltopdf.util.XRLog;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

/**
 * Parser for image maps on elements.
 */
public class ImageMapParser {
	private static final String IMG_USEMAP_ATTR = "usemap";
	private static final String MAP_ELT = "map";
	private static final String MAP_NAME_ATTR = "name";
	private static final String AREA_ELT = "area";
	private static final String AREA_SHAPE_ATTR = "shape";
	private static final String AREA_COORDS_ATTR = "coords";
	private static final String AREA_HREF_ATTR = "href";
	private static final String RECT_SHAPE = "rect";
	private static final String RECTANGLE_SHAPE = "rectangle";
	private static final String CIRC_SHAPE = "circ";
	private static final String CIRCLE_SHAPE = "circle";
	private static final String POLY_SHAPE = "poly";
	private static final String POLYGON_SHAPE = "polygon";

	public static Map findAndParseMap(Element elem, SharedContext c) {
		String usemapAttr = elem.getAttribute(IMG_USEMAP_ATTR);
		if (usemapAttr == null || usemapAttr.isEmpty())
			return null;

		// lookup in cache, or instantiate
		final String mapName = usemapAttr.substring(1);
		Node map = elem.getOwnerDocument().getElementById(mapName);
		if (null == map) {
			final NodeList maps = elem.getOwnerDocument().getElementsByTagName(MAP_ELT);
			for (int i = 0; i < maps.getLength(); i++) {
				String mapAttr = getAttribute(maps.item(i).getAttributes(), MAP_NAME_ATTR);
				if (areEqual(mapName, mapAttr)) {
					map = maps.item(i);
					break;
				}
			}
			if (null == map) {
				XRLog.log(Level.INFO, LogMessageId.LogMessageId1Param.LAYOUT_NO_MAP_NAMED, mapName);
				return null;
			}
		}
		return parseMap(map, c);
	}

	private static boolean areEqual(String str1, String str2) {
		return (str1 == null && str2 == null) || (str1 != null && str1.equals(str2));
	}

	private static boolean areEqualIgnoreCase(String str1, String str2) {
		return (str1 == null && str2 == null) || (str1 != null && str1.equalsIgnoreCase(str2));
	}

	private static Map parseMap(Node map, SharedContext c) {
		if (null == map) {
			return Collections.emptyMap();
		} else if (map.hasChildNodes()) {
			AffineTransform scaleInstance = AffineTransform.getScaleInstance(c.getDotsPerPixel(), c.getDotsPerPixel());
			final NodeList children = map.getChildNodes();
			final Map areas = new HashMap<>(children.getLength());
			for (int i = 0; i < children.getLength(); i++) {
				final Node area = children.item(i);
				if (areEqualIgnoreCase(AREA_ELT, area.getNodeName())) {
					if (area.hasAttributes()) {
						final NamedNodeMap attrs = area.getAttributes();
						final String shapeAttr = getAttribute(attrs, AREA_SHAPE_ATTR);
						String coordsAttr = getAttribute(attrs, AREA_COORDS_ATTR);
						if (coordsAttr == null)
							continue;
						final String[] coords = coordsAttr.split(",");
						final String href = getAttribute(attrs, AREA_HREF_ATTR);
						if (areEqualIgnoreCase(RECT_SHAPE, shapeAttr)
								|| areEqualIgnoreCase(RECTANGLE_SHAPE, shapeAttr)) {
							final Shape shape = getCoords(coords, 4);
							if (null != shape) {
								areas.put(scaleInstance.createTransformedShape(shape), href);
							}
						} else if (areEqualIgnoreCase(CIRC_SHAPE, shapeAttr)
								|| areEqualIgnoreCase(CIRCLE_SHAPE, shapeAttr)) {
							final Shape shape = getCoords(coords, 3);
							if (null != shape) {
								areas.put(scaleInstance.createTransformedShape(shape), href);
							}
						} else if (areEqualIgnoreCase(POLY_SHAPE, shapeAttr)
								|| areEqualIgnoreCase(POLYGON_SHAPE, shapeAttr)) {
							final Shape shape = getCoords(coords, -1);
							if (null != shape) {
								areas.put(scaleInstance.createTransformedShape(shape), href);
							}
						} else {
							if (XRLog.isLoggingEnabled()) {
								XRLog.log(Level.INFO, LogMessageId.LogMessageId1Param.LAYOUT_UNSUPPORTED_SHAPE, shapeAttr);
							}
						}
					}
				}
			}
			return areas;
		} else {
			return Collections.emptyMap();
		}
	}

	private static String getAttribute(NamedNodeMap attrs, String attrName) {
		final Node node = attrs.getNamedItem(attrName);
		return null == node ? null : node.getNodeValue();
	}

	private static Shape getCoords(String[] coordValues, int length) {
		if ((-1 == length && 0 == coordValues.length % 2) || length == coordValues.length) {
			float[] coords = new float[coordValues.length];
			int i = 0;
			for (String coord : coordValues) {
				try {
					coords[i++] = Float.parseFloat(coord.trim());
				} catch (NumberFormatException e) {
					XRLog.log(Level.WARNING, LogMessageId.LogMessageId0Param.LAYOUT_ERROR_PARSING_SHAPE_COORDS, e);
					return null;
				}
			}
			if (4 == length) {
				return new Rectangle2D.Float(coords[0], coords[1], coords[2] - coords[0], coords[3] - coords[1]);
			} else if (3 == length) {
				final float radius = coords[2];
				return new Ellipse2D.Float(coords[0] - radius, coords[1] - radius, radius * 2, radius * 2);
			} else if (-1 == length) {
				final int npoints = coords.length / 2;
				final int[] xpoints = new int[npoints];
				final int[] ypoints = new int[npoints];
				for (int c = 0, p = 0; p < npoints; p++) {
					xpoints[p] = (int)coords[c++];
					ypoints[p] = (int)coords[c++];
				}
				return new Polygon(xpoints, ypoints, npoints);
			} else {
				XRLog.log(Level.INFO, LogMessageId.LogMessageId1Param.LAYOUT_UNSUPPORTED_SHAPE, length);
				return null;
			}
		} else {
			return null;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy