123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.render.intermediate;
-
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.Point;
- import java.awt.Rectangle;
- import java.awt.geom.AffineTransform;
- import java.util.HashMap;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Set;
-
- import javax.xml.transform.Source;
- import javax.xml.transform.Transformer;
- import javax.xml.transform.TransformerException;
- import javax.xml.transform.sax.SAXResult;
- import javax.xml.transform.sax.SAXTransformerFactory;
-
- import org.w3c.dom.DOMImplementation;
- import org.w3c.dom.Document;
- import org.xml.sax.Attributes;
- import org.xml.sax.ContentHandler;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.AttributesImpl;
- import org.xml.sax.helpers.DefaultHandler;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
-
- import org.apache.xmlgraphics.util.QName;
-
- import org.apache.fop.accessibility.AccessibilityEventProducer;
- import org.apache.fop.accessibility.StructureTreeElement;
- import org.apache.fop.accessibility.StructureTreeEventHandler;
- import org.apache.fop.apps.FOUserAgent;
- import org.apache.fop.fo.ElementMapping;
- import org.apache.fop.fo.ElementMappingRegistry;
- import org.apache.fop.fo.expr.PropertyException;
- import org.apache.fop.fo.extensions.InternalElementMapping;
- import org.apache.fop.render.intermediate.extensions.DocumentNavigationExtensionConstants;
- import org.apache.fop.render.intermediate.extensions.DocumentNavigationHandler;
- import org.apache.fop.traits.BorderProps;
- import org.apache.fop.traits.RuleStyle;
- import org.apache.fop.util.ColorUtil;
- import org.apache.fop.util.ContentHandlerFactory;
- import org.apache.fop.util.ContentHandlerFactoryRegistry;
- import org.apache.fop.util.DOMBuilderContentHandlerFactory;
- import org.apache.fop.util.DefaultErrorListener;
- import org.apache.fop.util.LanguageTags;
- import org.apache.fop.util.XMLUtil;
-
- /**
- * This is a parser for the intermediate format XML which converts the intermediate file into
- * {@link IFPainter} events.
- */
- public class IFParser implements IFConstants {
-
- /** Logger instance */
- protected static final Log log = LogFactory.getLog(IFParser.class);
-
- private static SAXTransformerFactory tFactory
- = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
-
- private static Set<String> handledNamespaces = new java.util.HashSet<String>();
-
- static {
- handledNamespaces.add(XMLNS_NAMESPACE_URI);
- handledNamespaces.add(XML_NAMESPACE);
- handledNamespaces.add(NAMESPACE);
- handledNamespaces.add(XLINK_NAMESPACE);
- }
-
- /**
- * Parses an intermediate file and paints it.
- * @param src the Source instance pointing to the intermediate file
- * @param documentHandler the intermediate format document handler used to process the IF events
- * @param userAgent the user agent
- * @throws TransformerException if an error occurs while parsing the area tree XML
- * @throws IFException if an IF-related error occurs inside the target document handler
- */
- public void parse(Source src, IFDocumentHandler documentHandler, FOUserAgent userAgent)
- throws TransformerException, IFException {
- try {
- Transformer transformer = tFactory.newTransformer();
- transformer.setErrorListener(new DefaultErrorListener(log));
-
- SAXResult res = new SAXResult(getContentHandler(documentHandler, userAgent));
-
- transformer.transform(src, res);
- } catch (TransformerException te) {
- Throwable cause = te.getCause();
- //Unpack original IFException if applicable
- if (cause instanceof SAXException) {
- SAXException se = (SAXException) cause;
- cause = se.getCause();
- if (cause instanceof IFException) {
- throw (IFException) cause;
- }
- } else if (cause instanceof IFException) {
- throw (IFException) cause;
- }
- throw te;
- }
- }
-
- /**
- * Creates a new ContentHandler instance that you can send the area tree XML to. The parsed
- * pages are added to the AreaTreeModel instance you pass in as a parameter.
- * @param documentHandler the intermediate format document handler used to process the IF events
- * @param userAgent the user agent
- * @return the ContentHandler instance to receive the SAX stream from the area tree XML
- */
- public ContentHandler getContentHandler(IFDocumentHandler documentHandler,
- FOUserAgent userAgent) {
- ElementMappingRegistry elementMappingRegistry
- = userAgent.getElementMappingRegistry();
- return new Handler(documentHandler, userAgent, elementMappingRegistry);
- }
-
- private static class Handler extends DefaultHandler {
-
- private Map<String, ElementHandler> elementHandlers = new HashMap<String, ElementHandler>();
-
- private IFDocumentHandler documentHandler;
- private IFPainter painter;
- private FOUserAgent userAgent;
- private ElementMappingRegistry elementMappingRegistry;
-
- private Attributes lastAttributes;
-
- private StringBuffer content = new StringBuffer();
- private boolean ignoreCharacters = true;
-
- //private Stack delegateStack = new Stack();
- private int delegateDepth;
- private ContentHandler delegate;
- private boolean inForeignObject;
- private Document foreignObject;
-
- private ContentHandler navParser;
-
- private StructureTreeHandler structureTreeHandler;
-
- private Attributes pageSequenceAttributes;
-
- private Map<String, StructureTreeElement> structureTreeElements
- = new HashMap<String, StructureTreeElement>();
-
- private class StructureTreeHandler extends DefaultHandler {
-
- protected final StructureTreeEventHandler structureTreeEventHandler;
-
- StructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler) {
- this.structureTreeEventHandler = structureTreeEventHandler;
- }
-
- void startStructureTree(String type) {
- }
-
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if (!"structure-tree".equals(localName)) {
- if (localName.equals("marked-content")) {
- localName = "#PCDATA";
- }
- StructureTreeElement parent = getStructureTreeElement(attributes);
- String structID = attributes.getValue(InternalElementMapping.URI,
- InternalElementMapping.STRUCT_ID);
- if (structID == null) {
- structureTreeEventHandler.startNode(localName, attributes, parent);
- } else if (localName.equals("external-graphic")
- || localName.equals("instream-foreign-object")) {
- StructureTreeElement structureTreeElement
- = structureTreeEventHandler.startImageNode(localName, attributes, parent);
- structureTreeElements.put(structID, structureTreeElement);
- } else {
- StructureTreeElement structureTreeElement = structureTreeEventHandler
- .startReferencedNode(localName, attributes, parent);
- structureTreeElements.put(structID, structureTreeElement);
- }
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String arqNameg2)
- throws SAXException {
- if (!"structure-tree".equals(localName)) {
- structureTreeEventHandler.endNode(localName);
- }
- }
- }
-
- private class MainStructureTreeHandler extends StructureTreeHandler {
-
- private final Locale pageSequenceLanguage;
-
- MainStructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler,
- Locale pageSequenceLanguage) throws SAXException {
- super(structureTreeEventHandler);
- this.pageSequenceLanguage = pageSequenceLanguage;
- }
-
- @Override
- void startStructureTree(String type) {
- structureTreeEventHandler.startPageSequence(pageSequenceLanguage, type);
- }
-
- public void endDocument() throws SAXException {
- startIFElement(EL_PAGE_SEQUENCE, pageSequenceAttributes);
- pageSequenceAttributes = null;
- }
-
- }
-
- public Handler(IFDocumentHandler documentHandler, FOUserAgent userAgent,
- ElementMappingRegistry elementMappingRegistry) {
- this.documentHandler = documentHandler;
- this.userAgent = userAgent;
- this.elementMappingRegistry = elementMappingRegistry;
- elementHandlers.put(EL_DOCUMENT, new DocumentHandler());
- elementHandlers.put(EL_HEADER, new DocumentHeaderHandler());
- elementHandlers.put(EL_LOCALE, new LocaleHandler());
- elementHandlers.put(EL_TRAILER, new DocumentTrailerHandler());
- elementHandlers.put(EL_PAGE_SEQUENCE, new PageSequenceHandler());
- elementHandlers.put(EL_PAGE, new PageHandler());
- elementHandlers.put(EL_PAGE_HEADER, new PageHeaderHandler());
- elementHandlers.put(EL_PAGE_CONTENT, new PageContentHandler());
- elementHandlers.put(EL_PAGE_TRAILER, new PageTrailerHandler());
- //Page content
- elementHandlers.put(EL_VIEWPORT, new ViewportHandler());
- elementHandlers.put(EL_GROUP, new GroupHandler());
- elementHandlers.put(EL_ID, new IDHandler());
- elementHandlers.put(EL_FONT, new FontHandler());
- elementHandlers.put(EL_TEXT, new TextHandler());
- elementHandlers.put(EL_CLIP_RECT, new ClipRectHandler());
- elementHandlers.put(EL_RECT, new RectHandler());
- elementHandlers.put(EL_LINE, new LineHandler());
- elementHandlers.put(EL_BORDER_RECT, new BorderRectHandler());
- elementHandlers.put(EL_IMAGE, new ImageHandler());
- }
-
- private void establishForeignAttributes(Map<QName, String> foreignAttributes) {
- documentHandler.getContext().setForeignAttributes(foreignAttributes);
- }
-
- private void resetForeignAttributes() {
- documentHandler.getContext().resetForeignAttributes();
- }
-
- /** {@inheritDoc} */
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException {
- if (delegate != null) {
- delegateDepth++;
- delegate.startElement(uri, localName, qName, attributes);
- } else {
- boolean handled = true;
- if (NAMESPACE.equals(uri)) {
- if (localName.equals(EL_PAGE_SEQUENCE) && userAgent.isAccessibilityEnabled()) {
- pageSequenceAttributes = new AttributesImpl(attributes);
- Locale language = getLanguage(attributes);
- structureTreeHandler = new MainStructureTreeHandler(
- userAgent.getStructureTreeEventHandler(), language);
-
- } else if (localName.equals(EL_STRUCTURE_TREE)) {
- if (userAgent.isAccessibilityEnabled()) {
- String type = attributes.getValue("type");
- structureTreeHandler.startStructureTree(type);
- delegate = structureTreeHandler;
- } else {
- /* Delegate to a handler that does nothing */
- delegate = new DefaultHandler();
- }
- delegateDepth++;
- delegate.startDocument();
- delegate.startElement(uri, localName, qName, attributes);
- } else {
- if (pageSequenceAttributes != null) {
- /*
- * This means that no structure-element tag was
- * found in the XML, otherwise a
- * StructureTreeBuilderWrapper object would have
- * been created, which would have reset the
- * pageSequenceAttributes field.
- */
- AccessibilityEventProducer.Provider
- .get(userAgent.getEventBroadcaster())
- .noStructureTreeInXML(this);
- }
- handled = startIFElement(localName, attributes);
- }
- } else if (DocumentNavigationExtensionConstants.NAMESPACE.equals(uri)) {
- if (this.navParser == null) {
- this.navParser = new DocumentNavigationHandler(
- this.documentHandler.getDocumentNavigationHandler(),
- structureTreeElements);
- }
- delegate = this.navParser;
- delegateDepth++;
- delegate.startDocument();
- delegate.startElement(uri, localName, qName, attributes);
- } else {
- ContentHandlerFactoryRegistry registry
- = userAgent.getContentHandlerFactoryRegistry();
- ContentHandlerFactory factory = registry.getFactory(uri);
- if (factory == null) {
- DOMImplementation domImplementation
- = elementMappingRegistry.getDOMImplementationForNamespace(uri);
- if (domImplementation == null) {
- domImplementation = ElementMapping.getDefaultDOMImplementation();
- /*
- throw new SAXException("No DOMImplementation could be"
- + " identified to handle namespace: " + uri);
- */
- }
- factory = new DOMBuilderContentHandlerFactory(uri, domImplementation);
- }
- delegate = factory.createContentHandler();
- delegateDepth++;
- delegate.startDocument();
- delegate.startElement(uri, localName, qName, attributes);
- }
- if (!handled) {
- if (uri == null || uri.length() == 0) {
- throw new SAXException("Unhandled element " + localName
- + " in namespace: " + uri);
- } else {
- log.warn("Unhandled element " + localName
- + " in namespace: " + uri);
- }
- }
- }
- }
-
- private static Locale getLanguage(Attributes attributes) {
- String xmllang = attributes.getValue(XML_NAMESPACE, "lang");
- return (xmllang == null) ? null : LanguageTags.toLocale(xmllang);
- }
-
- private boolean startIFElement(String localName, Attributes attributes)
- throws SAXException {
- lastAttributes = new AttributesImpl(attributes);
- ElementHandler elementHandler = elementHandlers.get(localName);
- content.setLength(0);
- ignoreCharacters = true;
- if (elementHandler != null) {
- ignoreCharacters = elementHandler.ignoreCharacters();
- try {
- elementHandler.startElement(attributes);
- } catch (IFException ife) {
- handleIFException(ife);
- }
- return true;
- } else {
- return false;
- }
- }
-
- private void handleIFException(IFException ife) throws SAXException {
- Throwable cause = ife.getCause();
- if (cause instanceof SAXException) {
- //unwrap
- throw (SAXException) cause;
- } else {
- //wrap
- throw new SAXException(ife);
- }
- }
-
-
- /** {@inheritDoc} */
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (delegate != null) {
- delegate.endElement(uri, localName, qName);
- delegateDepth--;
- if (delegateDepth == 0) {
- delegate.endDocument();
- if (delegate instanceof ContentHandlerFactory.ObjectSource) {
- Object obj = ((ContentHandlerFactory.ObjectSource)delegate).getObject();
- if (inForeignObject) {
- this.foreignObject = (Document)obj;
- } else {
- handleExternallyGeneratedObject(obj);
- }
- }
- delegate = null; //Sub-document is processed, return to normal processing
- }
- } else {
- if (NAMESPACE.equals(uri)) {
- ElementHandler elementHandler = elementHandlers.get(localName);
- if (elementHandler != null) {
- try {
- elementHandler.endElement();
- } catch (IFException ife) {
- handleIFException(ife);
- }
- content.setLength(0);
- }
- ignoreCharacters = true;
- } else {
- if (log.isTraceEnabled()) {
- log.trace("Ignoring " + localName + " in namespace: " + uri);
- }
- }
- }
- }
-
- // ============== Element handlers for the intermediate format =============
-
- private interface ElementHandler {
- void startElement(Attributes attributes) throws IFException, SAXException;
- void endElement() throws IFException;
- boolean ignoreCharacters();
- }
-
- private abstract class AbstractElementHandler implements ElementHandler {
-
- public void startElement(Attributes attributes) throws IFException, SAXException {
- //nop
- }
-
- public void endElement() throws IFException {
- //nop
- }
-
- public boolean ignoreCharacters() {
- return true;
- }
- }
-
- private class DocumentHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- documentHandler.startDocument();
- }
-
- public void endElement() throws IFException {
- documentHandler.endDocument();
- }
-
- }
-
- private class DocumentHeaderHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- documentHandler.startDocumentHeader();
- }
-
- public void endElement() throws IFException {
- documentHandler.endDocumentHeader();
- }
-
- }
-
- private class LocaleHandler extends AbstractElementHandler {
- public void startElement(Attributes attributes) throws IFException {
- documentHandler.setDocumentLocale(getLanguage(attributes));
- }
- }
-
- private class DocumentTrailerHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- documentHandler.startDocumentTrailer();
- }
-
- public void endElement() throws IFException {
- documentHandler.endDocumentTrailer();
- }
-
- }
-
- private class PageSequenceHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- String id = attributes.getValue("id");
- Locale language = getLanguage(attributes);
- if (language != null) {
- documentHandler.getContext().setLanguage(language);
- }
- Map<QName, String> foreignAttributes = getForeignAttributes(lastAttributes);
- establishForeignAttributes(foreignAttributes);
- documentHandler.startPageSequence(id);
- resetForeignAttributes();
- }
-
- public void endElement() throws IFException {
- documentHandler.endPageSequence();
- documentHandler.getContext().setLanguage(null);
- }
-
- }
-
- private class PageHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- int index = Integer.parseInt(attributes.getValue("index"));
- String name = attributes.getValue("name");
- String pageMasterName = attributes.getValue("page-master-name");
- int width = Integer.parseInt(attributes.getValue("width"));
- int height = Integer.parseInt(attributes.getValue("height"));
- Map<QName, String> foreignAttributes = getForeignAttributes(lastAttributes);
- establishForeignAttributes(foreignAttributes);
- documentHandler.startPage(index, name, pageMasterName,
- new Dimension(width, height));
- documentHandler.getContext().setPageNumber(index + 1);
- resetForeignAttributes();
- }
-
- public void endElement() throws IFException {
- documentHandler.endPage();
- }
-
- }
-
- private class PageHeaderHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- documentHandler.startPageHeader();
- structureTreeHandler = new StructureTreeHandler(userAgent.getStructureTreeEventHandler());
- }
-
- public void endElement() throws IFException {
- documentHandler.endPageHeader();
- }
-
- }
-
- private class PageContentHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- painter = documentHandler.startPageContent();
- }
-
- public void endElement() throws IFException {
- painter = null;
- documentHandler.getContext().setID("");
- documentHandler.endPageContent();
- }
-
- }
-
- private class PageTrailerHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- documentHandler.startPageTrailer();
- }
-
- public void endElement() throws IFException {
- documentHandler.endPageTrailer();
- }
-
- }
-
- private class ViewportHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- String transform = attributes.getValue("transform");
- AffineTransform[] transforms
- = AffineTransformArrayParser.createAffineTransform(transform);
- int width = Integer.parseInt(attributes.getValue("width"));
- int height = Integer.parseInt(attributes.getValue("height"));
- Rectangle clipRect = XMLUtil.getAttributeAsRectangle(attributes, "clip-rect");
- painter.startViewport(transforms, new Dimension(width, height), clipRect);
- }
-
- public void endElement() throws IFException {
- painter.endViewport();
- }
-
- }
-
- private class GroupHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- String transform = attributes.getValue("transform");
- AffineTransform[] transforms
- = AffineTransformArrayParser.createAffineTransform(transform);
- String layer = attributes.getValue("layer");
- painter.startGroup(transforms, layer);
- }
-
- public void endElement() throws IFException {
- painter.endGroup();
- }
-
- }
-
- private class IDHandler extends AbstractElementHandler {
-
- @Override
- public void startElement(Attributes attributes) throws IFException, SAXException {
- String id = attributes.getValue("name");
- documentHandler.getContext().setID(id);
- }
-
- }
-
- private class FontHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- String family = attributes.getValue("family");
- String style = attributes.getValue("style");
- Integer weight = XMLUtil.getAttributeAsInteger(attributes, "weight");
- String variant = attributes.getValue("variant");
- Integer size = XMLUtil.getAttributeAsInteger(attributes, "size");
- Color color;
- try {
- color = getAttributeAsColor(attributes, "color");
- } catch (PropertyException pe) {
- throw new IFException("Error parsing the color attribute", pe);
- }
- painter.setFont(family, style, weight, variant, size, color);
- }
-
- }
-
- private class TextHandler extends AbstractElementHandler {
-
- public void endElement() throws IFException {
- int x = Integer.parseInt(lastAttributes.getValue("x"));
- int y = Integer.parseInt(lastAttributes.getValue("y"));
- String s = lastAttributes.getValue("letter-spacing");
- int letterSpacing = (s != null ? Integer.parseInt(s) : 0);
- s = lastAttributes.getValue("word-spacing");
- int wordSpacing = (s != null ? Integer.parseInt(s) : 0);
- int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx");
- int[][] dp = XMLUtil.getAttributeAsPositionAdjustments(lastAttributes, "dp");
- // if only DX present, then convert DX to DP; otherwise use only DP,
- // effectively ignoring DX
- if ((dp == null) && (dx != null)) {
- dp = IFUtil.convertDXToDP(dx);
- }
- establishStructureTreeElement(lastAttributes);
- boolean isHyphenated = Boolean.valueOf(lastAttributes.getValue("hyphenated"));
- if (isHyphenated) {
- documentHandler.getContext().setHyphenated(isHyphenated);
- }
- boolean nextIsSpace = Boolean.valueOf(lastAttributes.getValue("next-is-space"));
- painter.drawText(x, y, letterSpacing, wordSpacing, dp, content.toString(), nextIsSpace);
- documentHandler.getContext().setHyphenated(false);
- resetStructureTreeElement();
- }
-
- public boolean ignoreCharacters() {
- return false;
- }
-
- }
-
- private class ClipRectHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- int x = Integer.parseInt(attributes.getValue("x"));
- int y = Integer.parseInt(attributes.getValue("y"));
- int width = Integer.parseInt(attributes.getValue("width"));
- int height = Integer.parseInt(attributes.getValue("height"));
- BorderProps[] borders = new BorderProps[4];
- for (int i = 0; i < 4; i++) {
- String b = attributes.getValue(SIDES[i]);
- if (b != null) {
- borders[i] = BorderProps.valueOf(userAgent, b);
- }
- }
-
- if (!(borders[0] == null && borders[1] == null
- && borders[2] == null && borders[3] == null)) {
- painter.clipBackground(new Rectangle(x, y, width, height),
- borders[0], borders[1], borders[2], borders[3]);
- }
- painter.clipRect(new Rectangle(x, y, width, height));
- }
-
- }
-
- private class RectHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- int x = Integer.parseInt(attributes.getValue("x"));
- int y = Integer.parseInt(attributes.getValue("y"));
- int width = Integer.parseInt(attributes.getValue("width"));
- int height = Integer.parseInt(attributes.getValue("height"));
- Color fillColor;
- try {
- fillColor = getAttributeAsColor(attributes, "fill");
- } catch (PropertyException pe) {
- throw new IFException("Error parsing the fill attribute", pe);
- }
-
- Rectangle rectangularArea = new Rectangle(x, y, width, height);
-
- //TODO should rect be overloaded to include rounded corners
- // or should we introduce a new IF element?
- BorderProps[] borders = new BorderProps[4];
- for (int i = 0; i < 4; i++) {
- String b = attributes.getValue(SIDES[i]);
- if (b != null) {
- borders[i] = BorderProps.valueOf(userAgent, b);
- }
- }
-
- if (!(borders[0] == null && borders[1] == null
- && borders[2] == null && borders[3] == null)) {
- painter.clipBackground(rectangularArea,
- borders[0], borders[1], borders[2], borders[3]);
- }
-
- painter.fillRect(rectangularArea , fillColor);
- }
-
- }
-
- private class LineHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- int x1 = Integer.parseInt(attributes.getValue("x1"));
- int y1 = Integer.parseInt(attributes.getValue("y1"));
- int x2 = Integer.parseInt(attributes.getValue("x2"));
- int y2 = Integer.parseInt(attributes.getValue("y2"));
- int width = Integer.parseInt(attributes.getValue("stroke-width"));
- Color color;
- try {
- color = getAttributeAsColor(attributes, "color");
- } catch (PropertyException pe) {
- throw new IFException("Error parsing the fill attribute", pe);
- }
- RuleStyle style = RuleStyle.valueOf(attributes.getValue("style"));
- painter.drawLine(new Point(x1, y1), new Point(x2, y2), width, color, style);
- }
-
- }
-
- private static final String[] SIDES = new String[] {"top", "bottom", "left", "right"};
-
- private class BorderRectHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- int x = Integer.parseInt(attributes.getValue("x"));
- int y = Integer.parseInt(attributes.getValue("y"));
- int width = Integer.parseInt(attributes.getValue("width"));
- int height = Integer.parseInt(attributes.getValue("height"));
- BorderProps[] borders = new BorderProps[4];
- for (int i = 0; i < 4; i++) {
- String b = attributes.getValue(SIDES[i]);
- if (b != null) {
- borders[i] = BorderProps.valueOf(userAgent, b);
- }
- }
- Color backgroundColor;
-
- try {
- backgroundColor = getAttributeAsColor(attributes, "inner-background-color");
- } catch (PropertyException pe) {
- throw new IFException("Error parsing the color attribute", pe);
- }
-
- painter.drawBorderRect(new Rectangle(x, y, width, height),
- borders[0], borders[1], borders[2], borders[3], backgroundColor);
- }
-
- }
-
- private class ImageHandler extends AbstractElementHandler {
-
- public void startElement(Attributes attributes) throws IFException {
- inForeignObject = true;
- }
-
- public void endElement() throws IFException {
- int x = Integer.parseInt(lastAttributes.getValue("x"));
- int y = Integer.parseInt(lastAttributes.getValue("y"));
- int width = Integer.parseInt(lastAttributes.getValue("width"));
- int height = Integer.parseInt(lastAttributes.getValue("height"));
- Map<QName, String> foreignAttributes = getForeignAttributes(lastAttributes);
- establishForeignAttributes(foreignAttributes);
- establishStructureTreeElement(lastAttributes);
- if (foreignObject != null) {
- painter.drawImage(foreignObject,
- new Rectangle(x, y, width, height));
- foreignObject = null;
- } else {
- String uri = lastAttributes.getValue(
- XLINK_HREF.getNamespaceURI(), XLINK_HREF.getLocalName());
- if (uri == null) {
- throw new IFException("xlink:href is missing on image", null);
- }
- painter.drawImage(uri, new Rectangle(x, y, width, height));
- }
- resetStructureTreeElement();
- resetForeignAttributes();
- inForeignObject = false;
- }
-
- public boolean ignoreCharacters() {
- return false;
- }
- }
-
-
- // ====================================================================
-
- /**
- * Handles objects created by "sub-parsers" that implement the ObjectSource interface.
- * An example of object handled here are ExtensionAttachments.
- * @param obj the Object to be handled.
- * @throws SAXException if an error occurs while handling the extension object
- */
- protected void handleExternallyGeneratedObject(Object obj) throws SAXException {
- try {
- documentHandler.handleExtensionObject(obj);
- } catch (IFException ife) {
- handleIFException(ife);
- }
- }
-
- private Color getAttributeAsColor(Attributes attributes, String name)
- throws PropertyException {
- String s = attributes.getValue(name);
- if (s == null) {
- return null;
- } else {
- return ColorUtil.parseColorString(userAgent, s);
- }
- }
-
- private static Map<QName, String> getForeignAttributes(Attributes atts) {
- Map<QName, String> foreignAttributes = null;
- for (int i = 0, c = atts.getLength(); i < c; i++) {
- String ns = atts.getURI(i);
- if (ns.length() > 0) {
- if (handledNamespaces.contains(ns)) {
- continue;
- }
- if (foreignAttributes == null) {
- foreignAttributes = new java.util.HashMap<QName, String>();
- }
- QName qname = new QName(ns, atts.getQName(i));
- foreignAttributes.put(qname, atts.getValue(i));
- }
- }
- return foreignAttributes;
- }
-
- private void establishStructureTreeElement(Attributes attributes) {
- StructureTreeElement element = getStructureTreeElement(attributes);
- if (element != null) {
- documentHandler.getContext().setStructureTreeElement(element);
- }
- }
-
- private StructureTreeElement getStructureTreeElement(Attributes attributes) {
- String structRef = attributes.getValue(InternalElementMapping.URI, InternalElementMapping.STRUCT_REF);
- if (structRef != null && structRef.length() > 0) {
- assert structureTreeElements.containsKey(structRef);
- return structureTreeElements.get(structRef);
- } else {
- return null;
- }
- }
-
- private void resetStructureTreeElement() {
- documentHandler.getContext().resetStructureTreeElement();
- }
-
- /** {@inheritDoc} */
- public void characters(char[] ch, int start, int length) throws SAXException {
- if (delegate != null) {
- delegate.characters(ch, start, length);
- } else if (!ignoreCharacters) {
- this.content.append(ch, start, length);
- }
- }
- }
- }
|