View | Details | Raw Unified | Return to bug 45783
Collapse All | Expand All

(-)sources/org/apache/batik/apps/rasterizer/DestinationType.java (-1 / +11 lines)
Lines 22-27 Link Here
22
import org.apache.batik.transcoder.image.JPEGTranscoder;
22
import org.apache.batik.transcoder.image.JPEGTranscoder;
23
import org.apache.batik.transcoder.image.PNGTranscoder;
23
import org.apache.batik.transcoder.image.PNGTranscoder;
24
import org.apache.batik.transcoder.image.TIFFTranscoder;
24
import org.apache.batik.transcoder.image.TIFFTranscoder;
25
import org.apache.batik.transcoder.imagemap.ImageMapTranscoder;
25
26
26
/**
27
/**
27
 * Describes the type of destination for an <tt>SVGConverter</tt>
28
 * Describes the type of destination for an <tt>SVGConverter</tt>
Lines 36-51 Link Here
36
    public static final String JPEG_STR = "image/jpeg";
37
    public static final String JPEG_STR = "image/jpeg";
37
    public static final String TIFF_STR = "image/tiff";
38
    public static final String TIFF_STR = "image/tiff";
38
    public static final String PDF_STR  = "application/pdf";
39
    public static final String PDF_STR  = "application/pdf";
40
    public static final String IMGMAP_STR = "text/xml";
39
41
40
    public static final int PNG_CODE  = 0;
42
    public static final int PNG_CODE  = 0;
41
    public static final int JPEG_CODE = 1;
43
    public static final int JPEG_CODE = 1;
42
    public static final int TIFF_CODE = 2;
44
    public static final int TIFF_CODE = 2;
43
    public static final int PDF_CODE  = 3;
45
    public static final int PDF_CODE  = 3;
46
    public static final int IMGMAP_CODE = 4;
44
47
45
    public static final String PNG_EXTENSION  = ".png";
48
    public static final String PNG_EXTENSION  = ".png";
46
    public static final String JPEG_EXTENSION = ".jpg";
49
    public static final String JPEG_EXTENSION = ".jpg";
47
    public static final String TIFF_EXTENSION = ".tif";
50
    public static final String TIFF_EXTENSION = ".tif";
48
    public static final String PDF_EXTENSION  = ".pdf";
51
    public static final String PDF_EXTENSION  = ".pdf";
52
    public static final String IMGMAP_EXTENSION = ".xml";
49
53
50
    public static final DestinationType PNG
54
    public static final DestinationType PNG
51
        = new DestinationType(PNG_STR, PNG_CODE, PNG_EXTENSION);
55
        = new DestinationType(PNG_STR, PNG_CODE, PNG_EXTENSION);
Lines 55-60 Link Here
55
        = new DestinationType(TIFF_STR, TIFF_CODE, TIFF_EXTENSION);
59
        = new DestinationType(TIFF_STR, TIFF_CODE, TIFF_EXTENSION);
56
    public static final DestinationType PDF
60
    public static final DestinationType PDF
57
        = new DestinationType(PDF_STR, PDF_CODE, PDF_EXTENSION);
61
        = new DestinationType(PDF_STR, PDF_CODE, PDF_EXTENSION);
62
    public static final DestinationType IMGMAP  
63
	= new DestinationType(IMGMAP_STR, IMGMAP_CODE, IMGMAP_EXTENSION);
58
64
59
    private String type;
65
    private String type;
60
    private int    code;
66
    private int    code;
Lines 98-103 Link Here
98
                } catch(Exception e) {
104
                } catch(Exception e) {
99
                    return null;
105
                    return null;
100
                }
106
                }
107
            case IMGMAP_CODE:
108
                return new ImageMapTranscoder();
101
            default:
109
            default:
102
                return null;
110
                return null;
103
        }
111
        }
Lines 110-116 Link Here
110
     * @return Array of valid values as strings.
118
     * @return Array of valid values as strings.
111
     */
119
     */
112
    public DestinationType[] getValues() {
120
    public DestinationType[] getValues() {
113
        return new DestinationType[]{PNG, JPEG, TIFF, PDF};
121
        return new DestinationType[]{PNG, JPEG, TIFF, PDF, IMGMAP};
114
    }
122
    }
115
123
116
    public Object readResolve(){
124
    public Object readResolve(){
Lines 123-128 Link Here
123
            return TIFF;
131
            return TIFF;
124
        case PDF_CODE:
132
        case PDF_CODE:
125
            return PDF;
133
            return PDF;
134
        case IMGMAP_CODE:
135
            return IMGMAP;
126
        default:
136
        default:
127
            throw new Error("unknown code:" + code );
137
            throw new Error("unknown code:" + code );
128
        }
138
        }
(-)sources/org/apache/batik/apps/rasterizer/Main.java (+1 lines)
Lines 534-539 Link Here
534
        mimeTypeMap.put("image/png", DestinationType.PNG);
534
        mimeTypeMap.put("image/png", DestinationType.PNG);
535
        mimeTypeMap.put("application/pdf", DestinationType.PDF);
535
        mimeTypeMap.put("application/pdf", DestinationType.PDF);
536
        mimeTypeMap.put("image/tiff", DestinationType.TIFF);
536
        mimeTypeMap.put("image/tiff", DestinationType.TIFF);
537
        mimeTypeMap.put("text/xml", DestinationType.IMGMAP);
537
538
538
        optionMap.put(CL_OPTION_OUTPUT,
539
        optionMap.put(CL_OPTION_OUTPUT,
539
                      new SingleValueOptionHandler(){
540
                      new SingleValueOptionHandler(){
(-)sources/org/apache/batik/transcoder/imagemap/ImageMapTranscoder.java (+289 lines)
Line 0 Link Here
1
/*****************************************************************************
2
 * Copyright (C) The Apache Software Foundation. All rights reserved.        *
3
 * ------------------------------------------------------------------------- *
4
 * This software is published under the terms of the Apache Software License *
5
 * version 1.1, a copy of which has been included with this distribution in  *
6
 * the LICENSE file.                                                         *
7
 *****************************************************************************/
8
9
package org.apache.batik.transcoder.imagemap;
10
11
import org.apache.batik.transcoder.SVGAbstractTranscoder;
12
import org.apache.batik.transcoder.TranscoderOutput;
13
import org.apache.batik.transcoder.TranscoderException;
14
import org.apache.batik.bridge.SVGUtilities;
15
import org.apache.batik.bridge.BridgeContext;
16
import org.apache.batik.gvt.GraphicsNode;
17
import org.apache.batik.dom.svg.SVGOMDocument;
18
19
import javax.xml.transform.sax.TransformerHandler;
20
import javax.xml.transform.sax.SAXTransformerFactory;
21
import javax.xml.transform.sax.SAXSource;
22
import javax.xml.transform.stream.StreamResult;
23
import javax.xml.transform.OutputKeys;
24
import javax.xml.transform.Transformer;
25
import javax.xml.transform.TransformerConfigurationException;
26
27
import java.awt.geom.PathIterator;
28
import java.awt.geom.AffineTransform;
29
30
import org.w3c.dom.Document;
31
import org.w3c.dom.Node;
32
import org.w3c.dom.traversal.DocumentTraversal;
33
import org.w3c.dom.traversal.NodeFilter;
34
import org.w3c.dom.traversal.NodeIterator;
35
import org.w3c.dom.svg.SVGAElement;
36
import org.w3c.dom.svg.SVGDocument;
37
import org.w3c.dom.svg.SVGElement;
38
39
import org.xml.sax.helpers.AttributesImpl;
40
import org.xml.sax.SAXException;
41
42
/**
43
 * This class transcodes an input to a html imagemap.
44
 *
45
 * @author <a href="mailto:[EMAIL PROTECTED]";>Torsten Knodt</a>
46
 */
47
public class ImageMapTranscoder extends SVGAbstractTranscoder {
48
49
    private final String XHTML_URI = "http://www.w3.org/1999/xhtml";;
50
    private final String CDATA = "CDATA";
51
    private final String AREA_TAG = "area";
52
    private final String MAP_TAG = "map";
53
    private final String TITLE_ATTR = "title";
54
    private final String ALT_ATTR = "alt";
55
    private final String AREA_TAG_SHAPE_ATTR = "shape";
56
    private final String AREA_TAG_SHAPE_ATTR_POLY = "poly";
57
    private final String AREA_TAG_COORDS_ATTR = "coords";
58
    private final String AREA_TAG_HREF_ATTR = "href";
59
    private final String XHTML_SYSID = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";;
60
    private final String XHTML_PUBID = "-//W3C//DTD XHTML 1.0 Strict//EN";
61
62
    /**
63
     * Constructs a new <tt>ImageMapTranscoder</tt>.
64
     */
65
    public ImageMapTranscoder() {
66
    }
67
68
    /**
69
     * Get SAX Transformer factory
70
     *
71
     * @result SAX Transformer factory to use
72
     */
73
    private SAXTransformerFactory getTransformerHandlerFactory()
74
    {
75
        return (SAXTransformerFactory) SAXTransformerFactory.newInstance();
76
    }
77
78
    /**
79
     * Get SAX Transformer from Factory
80
     *
81
     * @param output the output where to transcode
82
     * @result the transformer handler
83
     */
84
    private TransformerHandler getTransformerHandler(TranscoderOutput output)
85
    throws TransformerConfigurationException
86
    {
87
        SAXTransformerFactory tfactory = getTransformerHandlerFactory();
88
        if (tfactory.getFeature(SAXSource.FEATURE) && tfactory.getFeature(StreamResult.FEATURE))
89
        {
90
            TransformerHandler ch = tfactory.newTransformerHandler();
91
            ch.setResult (new StreamResult (output.getOutputStream()));
92
            return ch;
93
        }
94
        return null;
95
    }
96
97
    /**
98
     * Configure the SAX transformer handler
99
     *
100
     * @param th the SAX transformer handler
101
     */
102
    private void configureTransformerHandler(TransformerHandler th)
103
    {
104
        //        th.setSystemId (XHTML_SYSID);
105
        // FIXME: ID/ name attribute must be added to map element to make output valid
106
    }
107
108
    /**
109
     * Configure the SAX transformer
110
     *
111
     * @param th the SAX transformer
112
     */
113
    private void configureTransformer(Transformer t)
114
    {
115
        //        t.setOutputProperty (OutputKeys.DOCTYPE_PUBLIC, XHTML_PUBID);
116
        //        t.setOutputProperty (OutputKeys.DOCTYPE_SYSTEM, XHTML_SYSID);
117
        // FIXME: ID/ name attribute must be added to map element to make output valid
118
        t.setOutputProperty (OutputKeys.INDENT, "yes");
119
        t.setOutputProperty (OutputKeys.MEDIA_TYPE, "text/xml");
120
        t.setOutputProperty (OutputKeys.STANDALONE, "no");
121
        t.setOutputProperty (OutputKeys.OMIT_XML_DECLARATION, "no");
122
        t.setOutputProperty (OutputKeys.METHOD, "xml");
123
    }
124
125
    /**
126
     * Sets the title attribute for an element
127
     *
128
     * @param element the element to fetch the title for
129
     * @param att the Attribute Implementation to use
130
     */
131
    private void setTitle(SVGElement element, AttributesImpl att)
132
    {
133
        // We could also use xlink:title, but I think svg:desc is better.
134
        String s = SVGUtilities.getDescription (element);
135
        if (s != null)
136
            if (! s.equals (""))
137
                att.addAttribute("", TITLE_ATTR, TITLE_ATTR, CDATA, s);
138
    }
139
140
    /**
141
     * Sets the alt attribute for an element
142
     *
143
     * @param element the element to fetch the title for
144
     * @param att the Attribute Implementation to use
145
     */
146
    private void setAlt(SVGElement element, AttributesImpl att)
147
    {
148
        // Here svg:title should be used instead of svg:desc, I think. Perhaps xlink:title would also be an idea.
149
        String s = SVGUtilities.getDescription (element);
150
        if (s == null)
151
            s = "";
152
        att.addAttribute("", ALT_ATTR, ALT_ATTR, CDATA, s);
153
    }
154
155
    /**
156
     * Reimplemented here to set the dynamic flag so the BridgeContext
157
     * tracks the DOM node <-> gvt node association.
158
     * @param doc the SVG document to create the BridgeContext for
159
     * @return the newly instantiated BridgeContext
160
     */
161
    protected BridgeContext createBridgeContext(SVGOMDocument doc) {
162
        BridgeContext c = super.createBridgeContext(doc);
163
	c.setDynamicState(BridgeContext.DYNAMIC);
164
	return c;
165
    }
166
167
    /**
168
     * Transcodes the specified Document as an image in the specified output.
169
     *
170
     * @param document the document to transcode
171
     * @param uri the uri of the document or null if any
172
     * @param output the ouput where to transcode
173
     * @exception TranscoderException if an error occured while transcoding
174
     */
175
    protected void transcode(Document document,
176
                             String uri,
177
                             TranscoderOutput output)
178
	throws TranscoderException
179
    {
180
        super.transcode(document, uri, output);
181
182
        TransformerHandler filter;
183
        try {
184
            filter = getTransformerHandler(output);
185
        } 
186
	catch (TransformerConfigurationException ex) {
187
            throw new TranscoderException (ex);
188
        }
189
        configureTransformerHandler (filter);
190
        configureTransformer (filter.getTransformer());
191
192
        AttributesImpl myatt = new AttributesImpl();
193
        setTitle ((SVGElement) (document.getDocumentElement()), myatt);
194
        try {
195
            filter.startDocument();
196
            //            filter.startDTD(MAP_TAG, XHTML_PUBID, XHTML_SYSID);
197
            //            filter.endDTD();
198
            // FIXME: ID/ name attribute must be added to map element to make output valid
199
            filter.startElement (XHTML_URI, MAP_TAG, MAP_TAG, myatt);
200
        } 
201
	catch (SAXException ex) { 
202
	    throw new TranscoderException (ex); 
203
	}
204
205
        NodeIterator i = ((DocumentTraversal) document).createNodeIterator(document, NodeFilter.SHOW_ELEMENT, null, true);
206
        Node node;
207
        while ((node = i.nextNode()) != null)
208
        {
209
            SVGAElement e;
210
            try {
211
                e = (SVGAElement) node;
212
            } 
213
	    catch (ClassCastException ex) { 
214
		continue;
215
	    }
216
217
	    GraphicsNode gn = ctx.getGraphicsNode(e);
218
	    System.out.println("Node: " + e + ", GraphicsNode: " + gn);
219
	    AffineTransform tx = gn.getGlobalTransform();
220
	    tx.preConcatenate(curTxf);
221
222
	    int state = PathIterator.SEG_CLOSE;
223
	    String coords = "";
224
	    int[] lastpoints = null;
225
226
	    for ( PathIterator path = gn.getOutline().getPathIterator(tx, 1.0); 
227
		  ! path.isDone(); 
228
		  path.next() )
229
	    {
230
		float[] points = new float[6];
231
		int seg = path.currentSegment (points);
232
		int[] newpoints = { Math.round(points[0]), Math.round(points[1]) };
233
234
		switch (seg)
235
		{
236
		case PathIterator.SEG_CLOSE:
237
		    // End of path segment, so push out Tag
238
		    if (! coords.equals(""))
239
		    {
240
			AttributesImpl att = new AttributesImpl();
241
			att.addAttribute("", AREA_TAG_SHAPE_ATTR, AREA_TAG_SHAPE_ATTR, CDATA, AREA_TAG_SHAPE_ATTR_POLY);
242
			att.addAttribute("", AREA_TAG_COORDS_ATTR, AREA_TAG_COORDS_ATTR, CDATA, coords);
243
			att.addAttribute("", AREA_TAG_HREF_ATTR, AREA_TAG_HREF_ATTR, CDATA, e.getHref().getBaseVal());
244
			setTitle (e, att);
245
			setAlt (e, att);
246
			try {
247
			    filter.startElement(XHTML_URI, AREA_TAG, AREA_TAG, att);
248
			    filter.endElement(XHTML_URI, AREA_TAG, AREA_TAG);
249
			} catch (SAXException ex) { throw new TranscoderException (ex); }
250
			coords = "";
251
			lastpoints = null;
252
		    }
253
		    break;
254
		case PathIterator.SEG_CUBICTO:
255
		    // Cubic segment not allowed in flattened path
256
		    throw new TranscoderException ("Cubic segment not allowed in flattened path");
257
		case PathIterator.SEG_QUADTO:
258
		    // Quad segment not allowed in flattened path
259
		    throw new TranscoderException ("Quad segment not allowed in flattened path");
260
		case PathIterator.SEG_LINETO:
261
		    if (coords.equals(""))
262
			throw new TranscoderException ("Line segment not allowed at begin of path");
263
		    // Add line segment to polygon coords
264
		    if (! lastpoints.equals (newpoints))
265
			coords = coords + "," + newpoints[0] + "," + newpoints[1];
266
		    break;
267
		case PathIterator.SEG_MOVETO:
268
		    if (! coords.equals(""))
269
			throw new TranscoderException ("Move segment only allowed at begin of path");
270
		    // Use move segment as polygon start coords
271
		    coords = newpoints[0] + "," + newpoints[1];
272
		    break;
273
		default:
274
		    throw new TranscoderException ("Unknown segment with type number " + seg);
275
		}
276
277
		lastpoints = newpoints;
278
	    }
279
        }
280
        try {
281
            filter.endElement (XHTML_URI, MAP_TAG, MAP_TAG);
282
            filter.endDocument();
283
        } 
284
	catch (SAXException ex) { 
285
	    throw new TranscoderException (ex); 
286
	}
287
    }
288
289
}

Return to bug 45783