001    //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/graphics/legend/LegendElement.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003     
004     This file is part of deegree.
005     Copyright (C) 2001-2006 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010     
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015     
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020     
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024     
025     Contact:
026     
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53115 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033     
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041     
042     
043     ---------------------------------------------------------------------------*/
044    package org.deegree.graphics.legend;
045    
046    import java.awt.BasicStroke;
047    import java.awt.Color;
048    import java.awt.FontMetrics;
049    import java.awt.Graphics;
050    import java.awt.Graphics2D;
051    import java.awt.image.BufferedImage;
052    import java.util.ArrayList;
053    
054    import org.deegree.framework.log.ILogger;
055    import org.deegree.framework.log.LoggerFactory;
056    import org.deegree.graphics.displayelements.DisplayElementFactory;
057    import org.deegree.graphics.displayelements.IncompatibleGeometryTypeException;
058    import org.deegree.graphics.displayelements.PolygonDisplayElement;
059    import org.deegree.graphics.sld.LineSymbolizer;
060    import org.deegree.graphics.sld.PointSymbolizer;
061    import org.deegree.graphics.sld.PolygonSymbolizer;
062    import org.deegree.graphics.sld.RasterSymbolizer;
063    import org.deegree.graphics.sld.Rule;
064    import org.deegree.graphics.sld.Symbolizer;
065    import org.deegree.graphics.sld.TextSymbolizer;
066    import org.deegree.graphics.transformation.WorldToScreenTransform;
067    import org.deegree.model.filterencoding.FilterEvaluationException;
068    import org.deegree.model.spatialschema.Envelope;
069    import org.deegree.model.spatialschema.GeometryFactory;
070    import org.deegree.model.spatialschema.Position;
071    import org.deegree.model.spatialschema.Surface;
072    import org.deegree.ogcwebservices.wms.GraphicContextFactory;
073    
074    /**
075     * The implements the basic legend element. a legend element may has a
076     * label that can be set to eight positions relative to the legend graphic. A
077     * <tt>LegendElement</tt> can be activated or deactivated. It depends on the
078     * using application what effect this behavior will have. <p>
079     * <tt>LegendElement</tt>s can be collected in a <tt>LegendElementCollection</tt>
080     * which also is a <tt>LegendElement</tt> to group elements or to create more
081     * complex elements.<p>
082     * Each <tt>LegendElement</tt> is able to paint itself as <tt>BufferedImage</tt>
083     *
084     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
085     * @version $Revision: 7363 $ $Date: 2007-05-29 20:47:55 +0200 (Di, 29 Mai 2007) $
086     */
087    public class LegendElement {
088    
089        private static final ILogger LOG = LoggerFactory.getLogger( LegendElement.class );
090    
091        protected ArrayList ruleslist = null;
092     
093        protected String label = "";
094    
095        protected double orientation = 0;
096    
097        protected int labelPosition = -1;
098    
099        protected boolean active = false;
100    
101        protected int width = 0;
102    
103        protected int height = 0;
104    
105        protected int bufferBetweenLegendAndLabel = 10;
106    
107        protected BufferedImage bi;
108    
109        /**
110         * empty constructor
111         *
112         */
113        protected LegendElement() {
114            this.ruleslist = new ArrayList();
115        }
116    
117        /**
118         * 
119         *
120         */
121        LegendElement( BufferedImage legendImage ) {
122            this();
123            bi = legendImage;
124        }
125    
126        /**
127         * constructor
128         * @param rules the different rules from the SLD
129         * @param label the label beneath the legend symbol
130         * @param orientation the rotation of the text in the legend
131         * @param labelPosition the position of the text according to the symbol
132         * @param active whether the legendsymbol is active or not
133         * @param width the requested width of the legend symbol
134         * @param height the requested height of the legend symbol
135         */
136        LegendElement( Rule[] rules, String label, double orientation, int labelPosition,
137                      boolean active, int width, int height ) {
138            this();
139            setRules( rules );
140            setLabel( label );
141            setLabelOrientation( orientation );
142            setLabelPlacement( labelPosition );
143            setActive( active );
144            setWidth( width );
145            setHeight( height );
146        }
147    
148        /**
149         * gets the Rules as an array
150         * @return array of sld rules
151         */
152        public Rule[] getRules() {
153            if ( ruleslist != null && ruleslist.size() > 0 ) {
154                return (Rule[]) ruleslist.toArray( new Rule[ruleslist.size()] );
155            }
156            return null;
157        }
158    
159        /**
160         * adds a rule to the ArrayList ruleslist
161         * @param rule a sld rule
162         */
163        public void addRule( Rule rule ) {
164            this.ruleslist.add( rule );
165        }
166    
167        /**
168         * sets the rules
169         * @param rules an array of sld rules
170         */
171        public void setRules( Rule[] rules ) {
172            this.ruleslist.clear();
173    
174            if ( rules != null ) {
175                for ( int i = 0; i < rules.length; i++ ) {
176                    this.ruleslist.add( rules[i] );
177                }
178            }
179        }
180    
181        /**
182         * sets the label of the <tt>LegendElement</tt>
183         * 
184         * @param label label of the <tt>LegendElement</tt>
185         * 
186         */
187        public void setLabel( String label ) {
188            this.label = label;
189        }
190    
191        /**
192         * returns the label set to <tt>LegendElement</tt>. If no label is set, the
193         * method returns <tt>null</tt>
194         * 
195         * @return label of the <tt>LegendElement</tt> or <tt>null</tt>
196         * 
197         */
198        public String getLabel() {
199            return this.label;
200        }
201    
202        /**
203         * sets the orientation of the label of the <tt>LegendElement</tt>. A label
204         * can have an orientation from -90� to 90� expressed in radians, where 0�
205         * is horizontal
206         *
207         * @param orientation
208         */
209        public void setLabelOrientation( double orientation ) {
210            this.orientation = orientation;
211        }
212    
213        /**
214         * returns the current orientation of the label of the <tt>LegendElement</tt>
215         * in radians. If the element hasn't a label <tt>Double.NEGATIVE_INFINITY</tt>
216         * will be returned.
217         *
218         * @return orientation of the label of the <tt>LegendElement</tt> in radians
219         */
220        public double getLabelOrientation() {
221            return this.orientation;
222        }
223    
224        /**
225         * sets the placement of the label relative to the legend symbol. Possible
226         * values are:
227         * <ul>
228         *  <li>LP_TOPCENTER
229         *  <li>LP_TOPLEFT
230         *  <li>LP_TOPRIGHT
231         *  <li>LP_RIGHT
232         *  <li>LP_LEFT
233         *  <li>LP_BOTTOMCENTER
234         *  <li>LP_BOTTOMRIGHT
235         *  <li>LP_BOTTOMLEFT
236         * </ul>
237         * <pre>
238         * +---+---+---+
239         * | 1 | 0 | 2 |
240         * +---+---+---+
241         * | 4 |LEG| 3 |
242         * +---+---+---+
243         * | 7 | 5 | 6 |
244         * +---+---+---+
245         * </pre>
246         * An implementation of the interface may not supoort all positions.
247         *
248         * @param labelPosition
249         */
250        public void setLabelPlacement( int labelPosition ) {
251            this.labelPosition = labelPosition;
252        }
253    
254        /**
255         * returns the placement of the label relative to the legend symbol. If the
256         * element hasn't a label <tt>LegendElement.LP_NOLABEL</tt> will be returned.
257         * Otherwise possible values are:
258         * <ul>
259         *  <li>LP_TOPCENTER
260         *  <li>LP_TOPLEFT
261         *  <li>LP_TOPRIGHT
262         *  <li>LP_RIGHT
263         *  <li>LP_LEFT
264         *  <li>LP_BOTTOMCENTER
265         *  <li>LP_BOTTOMRIGHT
266         *  <li>LP_BOTTOMLEFT
267         * </ul>
268         *
269         * @return coded placement of the label relative to the legend symbol
270         */
271        public int getLabelPlacement() {
272            return this.labelPosition;
273        }
274    
275        /**
276         * activates or deactivates the label
277         * 
278         * @param active
279         */
280        public void setActive( boolean active ) {
281            this.active = active;
282        }
283    
284        /**
285         * @return the activtion-status of the label
286         */
287        public boolean isActive() {
288            return this.active;
289        }
290    
291        /**
292         * sets the width of the LegendSymbol (in pixels)
293         * @param width 
294         */
295        public void setWidth( int width ) {
296            this.width = width;
297        }
298    
299        /**
300         * @return the width of the LegendSymbol (in pixels)
301         */
302        public int getWidth() {
303            return this.width;
304        }
305    
306        /**
307         * sets the height of the LegendSymbol (in pixels)
308         * @param height 
309         */
310        public void setHeight( int height ) {
311            this.height = height;
312        }
313    
314        /**
315         * @return the height of the LegendSymbol (in pixels)
316         */
317        public int getHeight() {
318            return this.height;
319        }
320    
321        /**
322         * returns the buffer place between the legend symbol and the legend label in pixels
323         * @return the buffer as integer in pixels
324         */
325        public int getBufferBetweenLegendAndLabel() {
326            return this.bufferBetweenLegendAndLabel;
327        }
328    
329        /**
330         * @see org.deegree.graphics.legend.LegendElement#getBufferBetweenLegendAndLabel()
331         * @param i the buffer as integer in pixels
332         */
333        public void setBufferBetweenLegendAndLabel( int i ) {
334            this.bufferBetweenLegendAndLabel = i;
335        }
336    
337        /**
338         * draws a legendsymbol, if the SLD defines a point
339         * @param g the graphics context
340         * @param c the PointSymbolizer representing the drawable point
341         * @param width the requested width of the symbol
342         * @param height the requested height of the symbol
343         * @throws LegendException is thrown, if the parsing of the sld failes.
344         */
345        protected void drawPointLegend( Graphics g, PointSymbolizer c, int width, int height )
346                                throws LegendException {
347            org.deegree.graphics.sld.Graphic deegreegraphic = c.getGraphic();
348            try {
349                BufferedImage buffi = deegreegraphic.getAsImage( null );
350                int w = buffi.getWidth();
351                int h = buffi.getHeight();
352                g.drawImage( buffi, width / 2 - w / 2, height / 2 - h / 2, null );
353            } catch ( FilterEvaluationException feex ) {
354                throw new LegendException( "FilterEvaluationException occured during "
355                                           + "the creation of the legend:\n"
356                                           + "The legend for the PointSymbol can't be processed.\n"
357                                           + feex.getMessage() );
358            }
359    
360        }
361    
362        /**
363         * draws a legendsymbol, if the SLD defines a line
364         * @param g the graphics context
365         * @param ls the LineSymbolizer representing the drawable line
366         * @param width the requested width of the symbol
367         * @param height the requested height of the symbol
368         * @throws LegendException is thrown, if the parsing of the sld failes.
369         */
370        protected void drawLineStringLegend( Graphics2D g, LineSymbolizer ls, int width, int height )
371                                throws LegendException {
372    
373            org.deegree.graphics.sld.Stroke sldstroke = ls.getStroke();
374            try {
375                // color, opacity
376                setColor( g, sldstroke.getStroke( null ), sldstroke.getOpacity( null ) );
377                g.setStroke( getBasicStroke( sldstroke ) );
378            } catch ( FilterEvaluationException feex ) {
379                throw new LegendException( "FilterEvaluationException occured during the creation "
380                                           + "of the legend:\n The legend for the LineSymbol can't be "
381                                           + "processed.\n" + feex.getMessage() );
382            }
383    
384            // p1 = [0 | height]
385            // p2 = [width / 3 | height / 3]
386            // p3 = [width - width / 3 | height - height / 3]
387            // p4 = [width | 0]
388            int[] xPoints = { 0, width / 3, width - width / 3, width };
389            int[] yPoints = { height, height / 3, height - height / 3, 0 };
390            int nPoints = 4;
391    
392            g.drawPolyline( xPoints, yPoints, nPoints );
393    
394        }
395    
396        /**
397         * draws a legendsymbol, if the SLD defines a polygon
398         * @param g the graphics context
399         * @param ps the PolygonSymbolizer representing the drawable polygon
400         * @param width the requested width of the symbol
401         * @param height the requested height of the symbol
402         * @throws LegendException if the parsing of the sld failes.
403         */
404        protected void drawPolygonLegend( Graphics2D g, PolygonSymbolizer ps, int width, int height )
405                                throws LegendException {
406    
407            Position p1 = GeometryFactory.createPosition( 0, 0 );
408            Position p2 = GeometryFactory.createPosition( 0, height - 1 );
409            Position p3 = GeometryFactory.createPosition( width, height - 1 );
410            Position p4 = GeometryFactory.createPosition( width, 0 );
411    
412            Position[] pos = { p1, p2, p3, p4, p1 };
413            Surface surface = null;
414            try {
415                surface = GeometryFactory.createSurface( pos, null, null, null );
416            } catch ( Exception ex ) {
417                throw new LegendException( "Exception occured during the creation of the legend:\n"
418                                           + "The legendsymbol for the Polygon can't be processed.\n"
419                                           + "Error in creating the Surface from the Positions.\n"
420                                           + ex.getMessage() );
421            }
422    
423            PolygonDisplayElement pde = null;
424            try {
425                // Feature, Geometry, PolygonSymbolizer
426                pde = DisplayElementFactory.buildPolygonDisplayElement( null, surface, ps );
427            } catch ( IncompatibleGeometryTypeException igtex ) {
428                throw new LegendException( "IncompatibleGeometryTypeException occured during "
429                                           + "the creation of the legend:\n The legendsymbol for "
430                                           + "the Polygon can't be processed.\nError in creating "
431                                           + "the PolygonDisplayElement.\n" + igtex.getMessage() );
432            } catch ( Exception e ) {
433                throw new LegendException( "Could not create symbolizer:\n" + e.getMessage() );
434            }
435    
436            Envelope envelope = GeometryFactory.createEnvelope( p1, p3, null );
437    
438            WorldToScreenTransform wtst = new WorldToScreenTransform( envelope, envelope );
439            pde.paint( g, wtst, -1 );
440    
441        }
442    
443        /**
444         * sets the color including an opacity
445         * @param g2 the graphics contect as Graphics2D
446         * @param color the requested color of the legend symbol
447         * @param opacity the requested opacity of the legend symbol
448         * @return the Graphics2D object containing color and opacity
449         */
450        private Graphics2D setColor( Graphics2D g2, Color color, double opacity ) {
451            if ( opacity < 0.999 ) {
452                final int alpha = (int) Math.round( opacity * 255 );
453                final int red = color.getRed();
454                final int green = color.getGreen();
455                final int blue = color.getBlue();
456                color = new Color( red, green, blue, alpha );
457            }
458            g2.setColor( color );
459            return g2;
460        }
461    
462        /**
463         * constructs a java.awt.BasicStroke for painting a LineString legend symbol. 
464         * @param sldstroke the deegree sld stroke
465         * @return a java.awt.BasicStroke
466         * @throws LegendException if the sld cannot be processed
467         */
468        private BasicStroke getBasicStroke( org.deegree.graphics.sld.Stroke sldstroke )
469                                throws LegendException {
470            BasicStroke bs = null;
471            try {
472                float width = (float) sldstroke.getWidth( null );
473                int cap = sldstroke.getLineCap( null );
474                int join = sldstroke.getLineJoin( null );
475                float miterlimit = 1f;
476                float[] dash = sldstroke.getDashArray( null );
477                float dash_phase = sldstroke.getDashOffset( null );
478    
479                bs = new BasicStroke( width, cap, join, miterlimit, dash, dash_phase );
480                // return new BasicStroke((float)sldstroke.getWidth(null), sldstroke.getLineCap(null), sldstroke.getLineJoin(null), 1f, sldstroke.getDashArray(null), sldstroke.getDashOffset(null));
481    
482            } catch ( FilterEvaluationException ex ) {
483                throw new LegendException(
484                                           "FilterEvaluationException occured during the creation of the legend:\n"
485                                                                   + "The Stroke of the element can't be processed.\n"
486                                                                   + ex.getMessage() );
487            }
488            return bs;
489        }
490    
491        /**
492         * calculates the FontMetrics of the LegendLabel in pixels. It returns an 3-dimensional array
493         * containing [0] the width, [1] the ascent and [2] the descent.
494         * @param label the label of the LegendElement
495         * @return the 3-dimensional INT-Array contains [0] the width of the string, [1] the ascent and [2] the descent.
496         */
497        protected int[] calculateFontMetrics( String label ) {
498            int[] fontmetrics = new int[3];
499    
500            BufferedImage bi = new BufferedImage( 1, 1, BufferedImage.TYPE_INT_ARGB );
501            Graphics g = bi.getGraphics();
502    
503            FontMetrics fm = g.getFontMetrics();
504    
505            if ( label != null && label.length() > 0 ) {
506                fontmetrics[0] = fm.stringWidth( label );
507                fontmetrics[1] = fm.getAscent();
508                fontmetrics[2] = fm.getDescent();
509            } else {
510                fontmetrics[0] = 0;
511                fontmetrics[1] = 0;
512                fontmetrics[2] = 0;
513                // value = 1, because of a bug, which doesn't paint the right border of the polygon-symbol.
514                setBufferBetweenLegendAndLabel( 1 );
515            }
516            g.dispose();
517    
518            return fontmetrics;
519        }
520    
521        /**
522         * calculates the width and height of the resulting LegendSymbol depending
523         * on the LabelPlacement
524         */
525        private BufferedImage calculateImage( int labelposition, int labelwidth, int ascent,
526                                             int descent, int legendwidth, int legendheight,
527                                             int buffer, String mime ) {
528            // eliminate buffer if label width is zero, so pixel counting works for the reference
529            // implementation
530            if ( labelwidth == 0 ) {
531                buffer = 0;
532            }
533    
534            BufferedImage bi = (BufferedImage) GraphicContextFactory.createGraphicTarget(
535                                                                                          mime,
536                                                                                          ( legendwidth
537                                                                                            + buffer + labelwidth ),
538                                                                                          legendheight );
539    
540            Graphics g = bi.getGraphics();
541            if (!(mime.equalsIgnoreCase("image/png") || mime.equalsIgnoreCase("image/gif"))) {
542                g.setColor( Color.WHITE );
543                    g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
544            }
545            g.setColor( Color.BLACK );
546            // TODO labelposition
547    
548            switch ( labelposition ) {
549            // LP_TOPCENTER
550            case 0: {
551                LOG.logInfo( "The text-position LP_TOPCENTER in the legend is not "
552                             + "implemented yet.\n We put the text on the right side (EAST) of "
553                             + "the legendsymbol." );
554                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
555                break;
556            }
557            // LP_TOPLEFT
558            case 1: {
559                LOG.logInfo( "The text-position LP_TOPLEFT in the legend is not implemented "
560                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
561                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
562                break;
563            }
564            // LP_TOPRIGHT
565            case 2: {
566                LOG.logInfo( "The text-position LP_TOPRIGHT in the legend is not implemented "
567                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
568                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
569                break;
570            }
571            // LP_RIGHT
572            case 3: {
573                LOG.logInfo( "The text-position LP_RIGHT in the legend is not implemented "
574                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
575                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
576                break;
577    
578            }
579            // LP_LEFT
580            case 4: {
581                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
582                break;
583            }
584            // LP_BOTTOMCENTER
585            case 5: {
586                LOG.logInfo( "The text-position LP_BOTTOMCENTER in the legend is not "
587                             + "implemented yet.\n We put the text on the right side (EAST) of "
588                             + "the legendsymbol." );
589                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
590                break;
591            }
592            // LP_BOTTOMRIGHT
593            case 6: {
594                LOG.logInfo( "The text-position LP_BOTTOMRIGHT in the legend is not "
595                             + "implemented yet.\n We put the text on the right side (EAST) of "
596                             + "the legendsymbol." );
597                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
598                break;
599            }
600            // LP_BOTTOMLEFT
601            case 7: {
602                LOG.logInfo( "The text-position LP_BOTTOMLEFT in the legend is not implemented "
603                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
604                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
605                break;
606            }
607            }
608            g.dispose();
609            return bi;
610        }
611    
612        /**
613         * exports the <tt>LegendElement</tt> as </tt>BufferedImage</tt>
614         * @param mime 
615         *
616         * @return the image
617         * @throws LegendException 
618         */
619        public BufferedImage exportAsImage( String mime )
620                                throws LegendException {
621    
622            if ( bi == null ) {
623                // calculates the fontmetrics and creates the bufferedimage
624                // if getLabel() is null is checked in calculateFontMetrics!
625                int[] fontmetrics = calculateFontMetrics( getLabel() );
626                bi = calculateImage( getLabelPlacement(), fontmetrics[0], fontmetrics[1],
627                                     fontmetrics[2], getWidth(), getHeight(),
628                                     getBufferBetweenLegendAndLabel(), mime );
629                Graphics g = bi.getGraphics();
630                ((Graphics2D)g).setClip( 0, 0, getWidth(), getHeight() );
631                g.setColor( Color.WHITE );
632                Rule[] myrules = getRules();
633                Symbolizer[] symbolizer = null;
634                // determines the legendsymbol and paints it
635                for ( int a = 0; a < myrules.length; a++ ) {
636                    symbolizer = myrules[a].getSymbolizers();
637    
638                    for ( int b = 0; b < symbolizer.length; b++ ) {
639                        if ( symbolizer[b] instanceof PointSymbolizer ) {
640                            drawPointLegend( g, (PointSymbolizer) symbolizer[b], getWidth(),
641                                             getHeight() );
642                        }
643                        if ( symbolizer[b] instanceof LineSymbolizer ) {
644                            drawLineStringLegend( (Graphics2D) g, (LineSymbolizer) symbolizer[b],
645                                                  width, height );
646                        }
647                        if ( symbolizer[b] instanceof PolygonSymbolizer ) {
648                            drawPolygonLegend( (Graphics2D) g, (PolygonSymbolizer) symbolizer[b],
649                                               width, height );
650                        }
651                        if ( symbolizer[b] instanceof RasterSymbolizer ) {
652                            // throw new LegendException("RasterSymbolizer is not implemented yet!");
653                        }
654                        if ( symbolizer[b] instanceof TextSymbolizer ) {
655                            // throw new LegendException("TextSymbolizer is not implemented yet!");
656                        }
657                    }
658    
659                    // g.setColor(Color.black);
660                    // g.drawString(getLabel(), width + 10, height / 2 + ((fontmetrics[1] - fontmetrics[2]) / 2));
661    
662                }
663            } else {
664                if ( mime.equalsIgnoreCase( "image/gif" ) || mime.equalsIgnoreCase( "image/png" ) ) {
665                    BufferedImage bii = new BufferedImage( bi.getWidth(), bi.getHeight(),
666                                                           BufferedImage.TYPE_INT_ARGB );
667                    Graphics g = bii.getGraphics();
668                    g.drawImage( bi, 0, 0, null );
669                    g.dispose();
670                    bi = bii;
671                } else if ( mime.equalsIgnoreCase( "image/jpg" )
672                            || mime.equalsIgnoreCase( "image/jpeg" )
673                            || mime.equalsIgnoreCase( "image/tif" )
674                            || mime.equalsIgnoreCase( "image/tiff" )
675                            || mime.equalsIgnoreCase( "image/bmp" ) ) {
676                    BufferedImage bii = new BufferedImage( bi.getWidth(), bi.getHeight(),
677                                                           BufferedImage.TYPE_INT_RGB );
678                    Graphics g = bii.getGraphics();
679                    g.drawImage( bi, 0, 0, null );
680                    g.dispose();
681                    bi = bii;
682                } else if ( mime.equalsIgnoreCase( "image/svg+xml" ) ) {
683    
684                }
685            }
686            return bi;
687        }
688    }
689    
690    /* ***************************************************************************
691     Changes to this class. What the people have been up to:
692     $Log$
693     Revision 1.17  2006/11/28 12:49:54  poth
694     bug fix - returning correct height now
695    
696     Revision 1.16  2006/11/27 12:57:35  poth
697     bug fix - setting graphic clip bounds for rendering polygon symbol
698    
699     Revision 1.15  2006/10/27 09:52:24  schmitz
700     Brought the WMS up to date regarding 1.1.1 and 1.3.0 conformance.
701     Fixed a bug while creating the default GetLegendGraphics URLs.
702    
703     Revision 1.14  2006/07/29 08:51:12  poth
704     references to deprecated classes removed
705    
706     Revision 1.13  2006/06/06 13:19:29  poth
707     bug fix setting image size
708    
709     Revision 1.12  2006/04/06 20:25:31  poth
710     *** empty log message ***
711    
712     Revision 1.11  2006/04/04 20:39:44  poth
713     *** empty log message ***
714    
715     Revision 1.10  2006/03/30 21:20:28  poth
716     *** empty log message ***
717    
718     Revision 1.9  2005/12/06 13:45:20  poth
719     System.out.println substituted by logging api
720    
721     Revision 1.8  2005/03/12 10:45:03  poth
722     no message
723    
724     Revision 1.7  2005/03/09 11:55:47  mschneider
725     *** empty log message ***
726    
727     Revision 1.6  2005/02/24 20:04:04  poth
728     no message
729    
730     Revision 1.5  2005/02/21 18:04:19  poth
731     no message
732    
733     Revision 1.4  2005/02/21 08:57:59  poth
734     no message
735    
736     Revision 1.3  2005/02/18 20:54:18  poth
737     no message
738    
739     Revision 1.2  2005/01/18 22:08:54  poth
740     no message
741    
742     Revision 1.6  2004/07/23 07:14:45  ap
743     no message
744    
745     
746     **************************************************************************** */