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-2008 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 label that can be set to
076     * eight positions relative to the legend graphic. A <tt>LegendElement</tt> can be activated or
077     * deactivated. It depends on the using application what effect this behavior will have.
078     * <p>
079     * <tt>LegendElement</tt>s can be collected in a <tt>LegendElementCollection</tt> which also is
080     * a <tt>LegendElement</tt> to group elements or to create more complex elements.
081     * <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<Rule> 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<Rule>();
115        }
116    
117        /**
118         * 
119         * 
120         */
121        LegendElement( BufferedImage legendImage ) {
122            this();
123            bi = legendImage;
124        }
125    
126        /**
127         * constructor
128         * 
129         * @param rules
130         *            the different rules from the SLD
131         * @param label
132         *            the label beneath the legend symbol
133         * @param orientation
134         *            the rotation of the text in the legend
135         * @param labelPosition
136         *            the position of the text according to the symbol
137         * @param active
138         *            whether the legendsymbol is active or not
139         * @param width
140         *            the requested width of the legend symbol
141         * @param height
142         *            the requested height of the legend symbol
143         */
144        LegendElement( Rule[] rules, String label, double orientation, int labelPosition, boolean active, int width,
145                       int height ) {
146            this();
147            setRules( rules );
148            setLabel( label );
149            setLabelOrientation( orientation );
150            setLabelPlacement( labelPosition );
151            setActive( active );
152            setWidth( width );
153            setHeight( height );
154        }
155    
156        /**
157         * gets the Rules as an array
158         * 
159         * @return array of sld rules
160         */
161        public Rule[] getRules() {
162            if ( ruleslist != null && ruleslist.size() > 0 ) {
163                return ruleslist.toArray( new Rule[ruleslist.size()] );
164            }
165            return null;
166        }
167    
168        /**
169         * adds a rule to the ArrayList ruleslist
170         * 
171         * @param rule
172         *            a sld rule
173         */
174        public void addRule( Rule rule ) {
175            this.ruleslist.add( rule );
176        }
177    
178        /**
179         * sets the rules
180         * 
181         * @param rules
182         *            an array of sld rules
183         */
184        public void setRules( Rule[] rules ) {
185            this.ruleslist.clear();
186    
187            if ( rules != null ) {
188                for ( int i = 0; i < rules.length; i++ ) {
189                    this.ruleslist.add( rules[i] );
190                }
191            }
192        }
193    
194        /**
195         * sets the label of the <tt>LegendElement</tt>
196         * 
197         * @param label
198         *            label of the <tt>LegendElement</tt>
199         * 
200         */
201        public void setLabel( String label ) {
202            this.label = label;
203        }
204    
205        /**
206         * returns the label set to <tt>LegendElement</tt>. If no label is set, the method returns
207         * <tt>null</tt>
208         * 
209         * @return label of the <tt>LegendElement</tt> or <tt>null</tt>
210         * 
211         */
212        public String getLabel() {
213            return this.label;
214        }
215    
216        /**
217         * sets the orientation of the label of the <tt>LegendElement</tt>. A label can have an
218         * orientation from -90� to 90� expressed in radians, where 0� is horizontal
219         * 
220         * @param orientation
221         */
222        public void setLabelOrientation( double orientation ) {
223            this.orientation = orientation;
224        }
225    
226        /**
227         * returns the current orientation of the label of the <tt>LegendElement</tt> in radians. If
228         * the element hasn't a label <tt>Double.NEGATIVE_INFINITY</tt> will be returned.
229         * 
230         * @return orientation of the label of the <tt>LegendElement</tt> in radians
231         */
232        public double getLabelOrientation() {
233            return this.orientation;
234        }
235    
236        /**
237         * sets the placement of the label relative to the legend symbol. Possible values are:
238         * <ul>
239         * <li>LP_TOPCENTER
240         * <li>LP_TOPLEFT
241         * <li>LP_TOPRIGHT
242         * <li>LP_RIGHT
243         * <li>LP_LEFT
244         * <li>LP_BOTTOMCENTER
245         * <li>LP_BOTTOMRIGHT
246         * <li>LP_BOTTOMLEFT
247         * </ul>
248         * 
249         * <pre>
250         *   +---+---+---+
251         *   | 1 | 0 | 2 |
252         *   +---+---+---+
253         *   | 4 |LEG| 3 |
254         *   +---+---+---+
255         *   | 7 | 5 | 6 |
256         *   +---+---+---+
257         * </pre>
258         * 
259         * An implementation of the interface may not supoort all positions.
260         * 
261         * @param labelPosition
262         */
263        public void setLabelPlacement( int labelPosition ) {
264            this.labelPosition = labelPosition;
265        }
266    
267        /**
268         * returns the placement of the label relative to the legend symbol. If the element hasn't a
269         * label <tt>LegendElement.LP_NOLABEL</tt> will be returned. Otherwise possible values are:
270         * <ul>
271         * <li>LP_TOPCENTER
272         * <li>LP_TOPLEFT
273         * <li>LP_TOPRIGHT
274         * <li>LP_RIGHT
275         * <li>LP_LEFT
276         * <li>LP_BOTTOMCENTER
277         * <li>LP_BOTTOMRIGHT
278         * <li>LP_BOTTOMLEFT
279         * </ul>
280         * 
281         * @return coded placement of the label relative to the legend symbol
282         */
283        public int getLabelPlacement() {
284            return this.labelPosition;
285        }
286    
287        /**
288         * activates or deactivates the label
289         * 
290         * @param active
291         */
292        public void setActive( boolean active ) {
293            this.active = active;
294        }
295    
296        /**
297         * @return the activtion-status of the label
298         */
299        public boolean isActive() {
300            return this.active;
301        }
302    
303        /**
304         * sets the width of the LegendSymbol (in pixels)
305         * 
306         * @param width
307         */
308        public void setWidth( int width ) {
309            this.width = width;
310        }
311    
312        /**
313         * @return the width of the LegendSymbol (in pixels)
314         */
315        public int getWidth() {
316            return this.width;
317        }
318    
319        /**
320         * sets the height of the LegendSymbol (in pixels)
321         * 
322         * @param height
323         */
324        public void setHeight( int height ) {
325            this.height = height;
326        }
327    
328        /**
329         * @return the height of the LegendSymbol (in pixels)
330         */
331        public int getHeight() {
332            return this.height;
333        }
334    
335        /**
336         * returns the buffer place between the legend symbol and the legend label in pixels
337         * 
338         * @return the buffer as integer in pixels
339         */
340        public int getBufferBetweenLegendAndLabel() {
341            return this.bufferBetweenLegendAndLabel;
342        }
343    
344        /**
345         * @see org.deegree.graphics.legend.LegendElement#getBufferBetweenLegendAndLabel()
346         * @param i
347         *            the buffer as integer in pixels
348         */
349        public void setBufferBetweenLegendAndLabel( int i ) {
350            this.bufferBetweenLegendAndLabel = i;
351        }
352    
353        /**
354         * draws a legendsymbol, if the SLD defines a point
355         * 
356         * @param g
357         *            the graphics context
358         * @param c
359         *            the PointSymbolizer representing the drawable point
360         * @param width
361         *            the requested width of the symbol
362         * @param height
363         *            the requested height of the symbol
364         * @throws LegendException
365         *             is thrown, if the parsing of the sld failes.
366         */
367        protected void drawPointLegend( Graphics g, PointSymbolizer c, int width, int height )
368                                throws LegendException {
369            org.deegree.graphics.sld.Graphic deegreegraphic = c.getGraphic();
370            try {
371                BufferedImage buffi = deegreegraphic.getAsImage( null );
372                int w = buffi.getWidth();
373                int h = buffi.getHeight();
374                g.drawImage( buffi, width / 2 - w / 2, height / 2 - h / 2, null );
375            } catch ( FilterEvaluationException feex ) {
376                throw new LegendException( "FilterEvaluationException occured during " + "the creation of the legend:\n"
377                                           + "The legend for the PointSymbol can't be processed.\n" + feex.getMessage() );
378            }
379    
380        }
381    
382        /**
383         * draws a legendsymbol, if the SLD defines a line
384         * 
385         * @param g
386         *            the graphics context
387         * @param ls
388         *            the LineSymbolizer representing the drawable line
389         * @param width
390         *            the requested width of the symbol
391         * @param height
392         *            the requested height of the symbol
393         * @throws LegendException
394         *             is thrown, if the parsing of the sld failes.
395         */
396        protected void drawLineStringLegend( Graphics2D g, LineSymbolizer ls, int width, int height )
397                                throws LegendException {
398    
399            org.deegree.graphics.sld.Stroke sldstroke = ls.getStroke();
400            try {
401                // color, opacity
402                setColor( g, sldstroke.getStroke( null ), sldstroke.getOpacity( null ) );
403                g.setStroke( getBasicStroke( sldstroke ) );
404            } catch ( FilterEvaluationException feex ) {
405                throw new LegendException( "FilterEvaluationException occured during the creation "
406                                           + "of the legend:\n The legend for the LineSymbol can't be " + "processed.\n"
407                                           + feex.getMessage() );
408            }
409    
410            // p1 = [0 | height]
411            // p2 = [width / 3 | height / 3]
412            // p3 = [width - width / 3 | height - height / 3]
413            // p4 = [width | 0]
414            int[] xPoints = { 0, width / 3, width - width / 3, width };
415            int[] yPoints = { height, height / 3, height - height / 3, 0 };
416            int nPoints = 4;
417    
418            g.drawPolyline( xPoints, yPoints, nPoints );
419    
420        }
421    
422        /**
423         * draws a legendsymbol, if the SLD defines a polygon
424         * 
425         * @param g
426         *            the graphics context
427         * @param ps
428         *            the PolygonSymbolizer representing the drawable polygon
429         * @param width
430         *            the requested width of the symbol
431         * @param height
432         *            the requested height of the symbol
433         * @throws LegendException
434         *             if the parsing of the sld failes.
435         */
436        protected void drawPolygonLegend( Graphics2D g, PolygonSymbolizer ps, int width, int height )
437                                throws LegendException {
438    
439            Position p1 = GeometryFactory.createPosition( 0, 0 );
440            Position p2 = GeometryFactory.createPosition( 0, height - 1 );
441            Position p3 = GeometryFactory.createPosition( width - 1, height - 1 );
442            Position p4 = GeometryFactory.createPosition( width - 1, 0 );
443    
444            Position[] pos = { p1, p2, p3, p4, p1 };
445            Surface surface = null;
446            try {
447                surface = GeometryFactory.createSurface( pos, null, null, null );
448            } catch ( Exception ex ) {
449                throw new LegendException( "Exception occured during the creation of the legend:\n"
450                                           + "The legendsymbol for the Polygon can't be processed.\n"
451                                           + "Error in creating the Surface from the Positions.\n" + ex.getMessage() );
452            }
453    
454            PolygonDisplayElement pde = null;
455            try {
456                // Feature, Geometry, PolygonSymbolizer
457                pde = DisplayElementFactory.buildPolygonDisplayElement( null, surface, ps );
458            } catch ( IncompatibleGeometryTypeException igtex ) {
459                throw new LegendException( "IncompatibleGeometryTypeException occured during "
460                                           + "the creation of the legend:\n The legendsymbol for "
461                                           + "the Polygon can't be processed.\nError in creating "
462                                           + "the PolygonDisplayElement.\n" + igtex.getMessage() );
463            } catch ( Exception e ) {
464                throw new LegendException( "Could not create symbolizer:\n" + e.getMessage() );
465            }
466    
467            Envelope envelope = GeometryFactory.createEnvelope( p1, p3, null );
468    
469            WorldToScreenTransform wtst = new WorldToScreenTransform( envelope, envelope );
470            pde.paint( g, wtst, -1 );
471    
472        }
473    
474        /**
475         * sets the color including an opacity
476         * 
477         * @param g2
478         *            the graphics contect as Graphics2D
479         * @param color
480         *            the requested color of the legend symbol
481         * @param opacity
482         *            the requested opacity of the legend symbol
483         * @return the Graphics2D object containing color and opacity
484         */
485        private Graphics2D setColor( Graphics2D g2, Color color, double opacity ) {
486            if ( opacity < 0.999 ) {
487                final int alpha = (int) Math.round( opacity * 255 );
488                final int red = color.getRed();
489                final int green = color.getGreen();
490                final int blue = color.getBlue();
491                color = new Color( red, green, blue, alpha );
492            }
493            g2.setColor( color );
494            return g2;
495        }
496    
497        /**
498         * constructs a java.awt.BasicStroke for painting a LineString legend symbol.
499         * 
500         * @param sldstroke
501         *            the deegree sld stroke
502         * @return a java.awt.BasicStroke
503         * @throws LegendException
504         *             if the sld cannot be processed
505         */
506        private BasicStroke getBasicStroke( org.deegree.graphics.sld.Stroke sldstroke )
507                                throws LegendException {
508            BasicStroke bs = null;
509            try {
510                float width = (float) sldstroke.getWidth( null );
511                int cap = sldstroke.getLineCap( null );
512                int join = sldstroke.getLineJoin( null );
513                float miterlimit = 1f;
514                float[] dash = sldstroke.getDashArray( null );
515                float dash_phase = sldstroke.getDashOffset( null );
516    
517                bs = new BasicStroke( width, cap, join, miterlimit, dash, dash_phase );
518                // return new BasicStroke((float)sldstroke.getWidth(null), sldstroke.getLineCap(null),
519                // sldstroke.getLineJoin(null), 1f, sldstroke.getDashArray(null),
520                // sldstroke.getDashOffset(null));
521    
522            } catch ( FilterEvaluationException ex ) {
523                throw new LegendException( "FilterEvaluationException occured during the creation of the legend:\n"
524                                           + "The Stroke of the element can't be processed.\n" + ex.getMessage() );
525            }
526            return bs;
527        }
528    
529        /**
530         * calculates the FontMetrics of the LegendLabel in pixels. It returns an 3-dimensional array
531         * containing [0] the width, [1] the ascent and [2] the descent.
532         * 
533         * @param label
534         *            the label of the LegendElement
535         * @return the 3-dimensional INT-Array contains [0] the width of the string, [1] the ascent and
536         *         [2] the descent.
537         */
538        protected int[] calculateFontMetrics( String label ) {
539            int[] fontmetrics = new int[3];
540    
541            BufferedImage bi = new BufferedImage( 1, 1, BufferedImage.TYPE_INT_ARGB );
542            Graphics g = bi.getGraphics();
543    
544            FontMetrics fm = g.getFontMetrics();
545    
546            if ( label != null && label.length() > 0 ) {
547                fontmetrics[0] = fm.stringWidth( label );
548                fontmetrics[1] = fm.getAscent();
549                fontmetrics[2] = fm.getDescent();
550            } else {
551                fontmetrics[0] = 0;
552                fontmetrics[1] = 0;
553                fontmetrics[2] = 0;
554                // value = 1, because of a bug, which doesn't paint the right border of the
555                // polygon-symbol.
556                setBufferBetweenLegendAndLabel( 1 );
557            }
558            g.dispose();
559    
560            return fontmetrics;
561        }
562    
563        /**
564         * calculates the width and height of the resulting LegendSymbol depending on the LabelPlacement
565         */
566        private BufferedImage calculateImage( int labelposition, int labelwidth, int ascent, int descent, int legendwidth,
567                                              int legendheight, int buffer, String mime ) {
568            // eliminate buffer if label width is zero, so pixel counting works for the reference
569            // implementation
570            if ( labelwidth == 0 ) {
571                buffer = 0;
572            }
573    
574            BufferedImage bi = (BufferedImage) GraphicContextFactory.createGraphicTarget(
575                                                                                          mime,
576                                                                                          ( legendwidth + buffer + labelwidth ),
577                                                                                          legendheight );
578    
579            Graphics g = bi.getGraphics();
580            if ( !( mime.equalsIgnoreCase( "image/png" ) || mime.equalsIgnoreCase( "image/gif" ) ) ) {
581                g.setColor( Color.WHITE );
582                g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() );
583            }
584            g.setColor( Color.BLACK );
585            // TODO labelposition
586    
587            switch ( labelposition ) {
588            // LP_TOPCENTER
589            case 0: {
590                LOG.logInfo( "The text-position LP_TOPCENTER in the legend is not "
591                             + "implemented yet.\n We put the text on the right side (EAST) of " + "the legendsymbol." );
592                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
593                break;
594            }
595                // LP_TOPLEFT
596            case 1: {
597                LOG.logInfo( "The text-position LP_TOPLEFT in the legend is not implemented "
598                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
599                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
600                break;
601            }
602                // LP_TOPRIGHT
603            case 2: {
604                LOG.logInfo( "The text-position LP_TOPRIGHT in the legend is not implemented "
605                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
606                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
607                break;
608            }
609                // LP_RIGHT
610            case 3: {
611                LOG.logInfo( "The text-position LP_RIGHT in the legend is not implemented "
612                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
613                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
614                break;
615    
616            }
617                // LP_LEFT
618            case 4: {
619                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
620                break;
621            }
622                // LP_BOTTOMCENTER
623            case 5: {
624                LOG.logInfo( "The text-position LP_BOTTOMCENTER in the legend is not "
625                             + "implemented yet.\n We put the text on the right side (EAST) of " + "the legendsymbol." );
626                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
627                break;
628            }
629                // LP_BOTTOMRIGHT
630            case 6: {
631                LOG.logInfo( "The text-position LP_BOTTOMRIGHT in the legend is not "
632                             + "implemented yet.\n We put the text on the right side (EAST) of " + "the legendsymbol." );
633                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
634                break;
635            }
636                // LP_BOTTOMLEFT
637            case 7: {
638                LOG.logInfo( "The text-position LP_BOTTOMLEFT in the legend is not implemented "
639                             + "yet.\n We put the text on the right side (EAST) of the legendsymbol." );
640                g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) );
641                break;
642            }
643            }
644            g.dispose();
645            return bi;
646        }
647    
648        /**
649         * exports the <tt>LegendElement</tt> as </tt>BufferedImage</tt>
650         * 
651         * @param mime
652         * 
653         * @return the image
654         * @throws LegendException
655         */
656        public BufferedImage exportAsImage( String mime )
657                                throws LegendException {
658    
659            if ( bi == null ) {
660                // calculates the fontmetrics and creates the bufferedimage
661                // if getLabel() is null is checked in calculateFontMetrics!
662                int[] fontmetrics = calculateFontMetrics( getLabel() );
663                bi = calculateImage( getLabelPlacement(), fontmetrics[0], fontmetrics[1], fontmetrics[2], getWidth(),
664                                     getHeight(), getBufferBetweenLegendAndLabel(), mime );
665                Graphics g = bi.getGraphics();
666                ( (Graphics2D) g ).setClip( 0, 0, getWidth(), getHeight() );
667                g.setColor( Color.WHITE );
668                Rule[] myrules = getRules();
669                Symbolizer[] symbolizer = null;
670                // determines the legendsymbol and paints it
671                for ( int a = 0; a < myrules.length; a++ ) {
672                    symbolizer = myrules[a].getSymbolizers();
673    
674                    for ( int b = 0; b < symbolizer.length; b++ ) {
675                        if ( symbolizer[b] instanceof PointSymbolizer ) {
676                            drawPointLegend( g, (PointSymbolizer) symbolizer[b], getWidth(), getHeight() );
677                        }
678                        if ( symbolizer[b] instanceof LineSymbolizer ) {
679                            drawLineStringLegend( (Graphics2D) g, (LineSymbolizer) symbolizer[b], width, height );
680                        }
681                        if ( symbolizer[b] instanceof PolygonSymbolizer ) {
682                            drawPolygonLegend( (Graphics2D) g, (PolygonSymbolizer) symbolizer[b], width, height );
683                        }
684                        if ( symbolizer[b] instanceof RasterSymbolizer ) {
685                            // throw new LegendException("RasterSymbolizer is not implemented yet!");
686                        }
687                        if ( symbolizer[b] instanceof TextSymbolizer ) {
688                            // throw new LegendException("TextSymbolizer is not implemented yet!");
689                        }
690                    }
691    
692                    // g.setColor(Color.black);
693                    // g.drawString(getLabel(), width + 10, height / 2 + ((fontmetrics[1] -
694                    // fontmetrics[2]) / 2));
695    
696                }
697            } else {
698                if ( mime.equalsIgnoreCase( "image/gif" ) || mime.equalsIgnoreCase( "image/png" ) ) {
699                    BufferedImage bii = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB );
700                    Graphics g = bii.getGraphics();
701                    g.drawImage( bi, 0, 0, null );
702                    g.dispose();
703                    bi = bii;
704                } else if ( mime.equalsIgnoreCase( "image/jpg" ) || mime.equalsIgnoreCase( "image/jpeg" )
705                            || mime.equalsIgnoreCase( "image/tif" ) || mime.equalsIgnoreCase( "image/tiff" )
706                            || mime.equalsIgnoreCase( "image/bmp" ) ) {
707                    BufferedImage bii = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_RGB );
708                    Graphics g = bii.getGraphics();
709                    g.drawImage( bi, 0, 0, null );
710                    g.dispose();
711                    bi = bii;
712                } else if ( mime.equalsIgnoreCase( "image/svg+xml" ) ) {
713                    // not implemented yet
714                }
715            }
716            return bi;
717        }
718    }