source: ether_statistics/service/implementation/gov/noaa/pmel/sgt/LabelDrawer2.java @ 569

Last change on this file since 569 was 569, checked in by vmipsl, 12 years ago

Nouveau projet

File size: 19.3 KB
Line 
1/*
2 * $Id: LabelDrawer2.java,v 1.6 2003/08/22 23:02:32 dwd Exp $
3 *
4 * This software is provided by NOAA for full, free and open release.  It is
5 * understood by the recipient/user that NOAA assumes no liability for any
6 * errors contained in the code.  Although this software is released without
7 * conditions or restrictions in its use, it is expected that appropriate
8 * credit be given to its author and to the National Oceanic and Atmospheric
9 * Administration should the software be included by the recipient as an
10 * element in other product development.
11 */
12
13package gov.noaa.pmel.sgt;
14
15import gov.noaa.pmel.swing.MRJUtil;
16import gov.noaa.pmel.util.Point2D;
17import gov.noaa.pmel.util.Rectangle2D;
18
19import java.awt.*;
20import java.awt.font.FontRenderContext;
21import java.awt.font.TextAttribute;
22import java.awt.font.TextLayout;
23import java.awt.geom.AffineTransform;
24import java.text.AttributedString;
25
26/**
27 * Implements label drawing using Java2D functionality.
28 *
29 * @author Donald Denbo
30 * @version $Revision: 1.6 $, $Date: 2003/08/22 23:02:32 $
31 * @since 2.0
32 */
33public class LabelDrawer2
34        implements LabelDrawer, Cloneable
35{
36    private String label_;
37    private Color clr_;
38    private Font font_;
39    private transient Layer layer_;
40    private int orient_;
41    private int halign_;
42    private int valign_;
43    private Point dorigin_;
44    private Rectangle dbounds_;
45    private Point2D.Double porigin_;
46    private Rectangle2D.Double pbounds_;
47    private Polygon dpolygon_;
48    private double angle_;
49    private double sinthta_;
50    private double costhta_;
51    private double height_;
52    private boolean visible_;
53    private static boolean fixMetrics_ = MRJUtil.fixFontMetrics();
54
55    private int xoff_ = 0;
56    private int yoff_ = 0;
57
58    private boolean alwaysAntiAlias_ = true;
59
60    private Rectangle savedBounds_ = null;
61    private Point savedLoc_ = null;
62
63    public LabelDrawer2( String lbl, double hgt, Point2D.Double loc,
64                         int valign, int halign )
65    {
66        label_ = lbl;
67        height_ = hgt;
68        porigin_ = loc;
69        valign_ = valign;
70        halign_ = halign;
71        //
72        dbounds_ = new Rectangle();
73        dorigin_ = new Point( 0, 0 );
74        pbounds_ = new Rectangle2D.Double();
75    }
76
77    public LabelDrawer copy()
78    {
79        LabelDrawer1 newLabel = null;
80//      try {
81//        newLabel = (LabelDrawer1)clone();
82//      } catch (CloneNotSupportedException e) {
83//        newLabel = new LabelDrawer1(ident_, label_, height_,
84//                           porigin_, valign_, halign_);
85//        newLabel.setColor(clr_);
86//        newLabel.setFont(font_);
87//        if(orient_ == ANGLE) {
88//      newLabel.setAngle(angle_);
89//        } else {
90//      newLabel.setOrientation(orient_);
91//        }
92//      }
93        return newLabel;
94    }
95
96    public void draw( Graphics g )
97            throws LayerNotFoundException
98    {
99        int xs, ys;
100        if( ( label_.length() <= 0 ) || !visible_ || g == null ) return;
101        if( layer_ == (Layer) null ) throw new LayerNotFoundException();
102        //
103        // set label heigth in physical units
104        //
105        computeBoundsD( g );
106        if( clr_ == null )
107        {
108            g.setColor( layer_.getPane().getComponent().getForeground() );
109        }
110        else
111        {
112            g.setColor( clr_ );
113        }
114//        g.setFont( new Font( "Helvetica", Font.PLAIN, 6 ) );
115
116        if( orient_ == SGLabel.HORIZONTAL )
117        {
118            xs = dbounds_.x + xoff_;
119            ys = dbounds_.y + yoff_;
120            drawString( g, xs, ys );
121        }
122        else if( orient_ == SGLabel.VERTICAL )
123        {
124            //
125            // draw text in offscreen image (horizontal)
126            //
127            xs = dbounds_.x + xoff_;
128            ys = dbounds_.y + yoff_;
129            drawString( g, xs, ys );
130        }
131        else
132        {
133            //
134            // Angled text, draw in offscreen image and rotate
135            //
136            xs = layer_.getXPtoD( porigin_.x );
137            ys = layer_.getYPtoD( porigin_.y );
138            drawString( g, xs, ys );
139        }
140    }
141
142    public void setText( String lbl )
143    {
144        label_ = lbl;
145    }
146
147    public String getText()
148    {
149        return label_;
150    }
151
152    public void setColor( Color clr )
153    {
154        clr_ = clr;
155    }
156
157    public Color getColor()
158    {
159        return clr_;
160    }
161
162    public void setFont( Font font )
163    {
164        font_ = font;
165    }
166
167    public Font getFont()
168    {
169        return font_;
170    }
171
172    public void setLayer( Layer layer )
173    {
174        layer_ = layer;
175        if( savedBounds_ != null )
176        {
177            setBounds( savedBounds_.x, savedBounds_.y,
178                    savedBounds_.width, savedBounds_.height );
179            savedBounds_ = null;
180        }
181        if( savedLoc_ != null )
182        {
183            setLocation( savedLoc_ );
184            savedLoc_ = null;
185        }
186    }
187
188    public Layer getLayer()
189    {
190        return layer_;
191    }
192
193    public void setOrientation( int orient )
194    {
195        if( orient_ != orient )
196        {
197            if( orient == SGLabel.HORIZONTAL )
198            {
199                costhta_ = 1.0;
200                sinthta_ = 0.0;
201            }
202            else if( orient == SGLabel.VERTICAL )
203            {
204                costhta_ = 0.0;
205                sinthta_ = 1.0;
206            }
207            orient_ = orient;
208        }
209    }
210
211    public int getOrientation()
212    {
213        return orient_;
214    }
215
216    public void setHAlign( int halign )
217    {
218        halign_ = halign;
219    }
220
221    public int getHAlign()
222    {
223        return halign_;
224    }
225
226    public void setVAlign( int valign )
227    {
228        valign_ = valign;
229    }
230
231    public int getVAlign()
232    {
233        return valign_;
234    }
235
236    public void setLocation( Point loc )
237    {
238        if( layer_ == null )
239        {
240            savedLoc_ = new Point( loc );
241            return;
242        }
243        computeBoundsD( layer_.getPane().getComponent().getGraphics() );
244        if( dbounds_.x != loc.x || dbounds_.y != loc.y )
245        {
246            setBounds( loc.x, loc.y, dbounds_.width, dbounds_.height );
247        }
248    }
249
250    public Point getLocation()
251    {
252        if( savedLoc_ != null ) return savedLoc_;
253        return dorigin_;
254    }
255
256    public void setBounds( int x, int y, int width, int height )
257    {
258        int swidth, sascent, xd, yd;
259        if( layer_ == null )
260        {
261            savedBounds_ = new Rectangle( x, y, width, height );
262            return;
263        }
264        Graphics g = layer_.getPane().getComponent().getGraphics();
265        if( g == null ) return;
266        font_ = computeFontSize( g );
267        FontRenderContext frc = getFontRenderContext( (Graphics2D) g );
268        TextLayout tlayout;
269        if( label_.length() == 0 )
270        {
271            tlayout = new TextLayout( " ", font_, frc );
272        }
273        else
274        {
275            tlayout = new TextLayout( label_, font_, frc );
276        }
277        java.awt.geom.Rectangle2D tbounds = tlayout.getBounds();
278        int theight = (int) tbounds.getHeight();
279        int twidth = (int) tbounds.getWidth();
280        int tx = (int) tbounds.getX();
281        int ty = (int) tbounds.getY();
282        if( fixMetrics_ )
283            ty -= (int) ( 0.7 * tlayout.getAscent() );  // hack for MacOS X java.runtime.version = 1.4.1_01-39
284        sascent = (int) tlayout.getAscent();
285
286        if( orient_ == SGLabel.HORIZONTAL )
287        {
288            swidth = width;
289            xd = x;
290            yd = y - ty;
291            switch( valign_ )
292            {
293                case SGLabel.TOP:
294                    yd = yd - sascent;
295                    break;
296                case SGLabel.MIDDLE:
297                    yd = yd + ( ty + theight / 2 );
298                    break;
299                case SGLabel.BOTTOM:
300            }
301            switch( halign_ )
302            {
303                case SGLabel.RIGHT:
304                    xd = xd + swidth;
305                    break;
306                case SGLabel.CENTER:
307                    xd = xd + swidth / 2;
308                    break;
309                case SGLabel.LEFT:
310            }
311        }
312        else
313        {
314            swidth = height;
315            yd = y + height;
316            xd = x - ty;
317            switch( valign_ )
318            {
319                case SGLabel.TOP:
320                    xd = xd - sascent;
321                    break;
322                case SGLabel.MIDDLE:
323                    xd = xd - sascent / 2;
324                    break;
325                case SGLabel.BOTTOM:
326            }
327            switch( halign_ )
328            {
329                case SGLabel.RIGHT:
330                    yd = yd - swidth;
331                    break;
332                case SGLabel.CENTER:
333                    yd = yd - swidth / 2;
334                    break;
335                case SGLabel.LEFT:
336            }
337        }
338        if( dorigin_.x != xd || dorigin_.y != yd )
339        {
340            dorigin_.x = xd;
341            dorigin_.y = yd;
342            porigin_.x = layer_.getXDtoP( xd );
343            porigin_.y = layer_.getYDtoP( yd );
344        }
345    }
346
347    public Rectangle getBounds()
348    {
349        if( savedBounds_ != null ) return savedBounds_;
350        if( layer_ != null ) computeBoundsD( layer_.getPane().getComponent().getGraphics() );
351        return dbounds_;
352    }
353
354    public void setLocationP( Point2D.Double loc )
355    {
356        porigin_ = loc;
357    }
358
359    public Point2D.Double getLocationP()
360    {
361        return porigin_;
362    }
363
364    public Rectangle2D.Double getBoundsP()
365    {
366        computeBoundsD( layer_.getPane().getComponent().getGraphics() );
367        return pbounds_;
368    }
369
370    public void setAngle( double angle )
371    {
372        angle_ = angle;
373        double thta = angle_ * Math.PI / 180.0;
374        if( Math.abs( thta ) < 0.001 )
375        {
376            orient_ = SGLabel.HORIZONTAL;
377            costhta_ = 1.0;
378            sinthta_ = 0.0;
379        }
380        else if( Math.abs( thta - 90.0 ) < 0.001 )
381        {
382            orient_ = SGLabel.VERTICAL;
383            costhta_ = 0.0;
384            sinthta_ = 1.0;
385        }
386        else
387        {
388            orient_ = SGLabel.ANGLE;
389            costhta_ = Math.cos( thta );
390            sinthta_ = Math.sin( thta );
391        }
392    }
393
394    public double getAngle()
395    {
396        return angle_;
397    }
398
399    public void setHeightP( double hgt )
400    {
401        height_ = hgt;
402    }
403
404    public double getHeightP()
405    {
406        return height_;
407    }
408
409    public void setVisible( boolean vis )
410    {
411        visible_ = vis;
412    }
413
414    public boolean isVisible()
415    {
416        return visible_;
417    }
418
419    private void computeBoundsD( Graphics g )
420    {
421        int sascent, xd, yd;
422        int xorig, yorig;
423        int[] xt = new int[4];
424        int[] yt = new int[4];
425        int[] xn = new int[4];
426        int[] yn = new int[4];
427        //
428        // compute size of font and adjust to be height tall!
429        //
430        if( g == null ) return;
431        // VMIPSL
432//        font_ = computeFontSize( g );
433        FontRenderContext frc = getFontRenderContext( (Graphics2D) g );
434        TextLayout tlayout;
435        if( label_.length() == 0 )
436        {
437            tlayout = new TextLayout( " ", font_, frc );
438        }
439        else
440        {
441            tlayout = new TextLayout( label_, font_, frc );
442        }
443        java.awt.geom.Rectangle2D tbounds = tlayout.getBounds();
444
445//    System.out.println("LabelDrawer2('" + label_ + "'): fixMetrics = " + fixMetrics_);
446//    System.out.println("LabelDrawer2('" + label_ + "'): TextLayout.bounds = " + tbounds);
447//    System.out.println("LabelDrawer2('" + label_ + "'): ascent, descent = " + tlayout.getAscent() + ", " + tlayout.getDescent());
448//    System.out.println("LabelDrawer2('" + label_ + "'): leading, baseline = " + tlayout.getLeading() + ", " + tlayout.getBaseline());
449//    System.out.println("LabelDrawer2('" + label_ + "'): TextLayout = " + tlayout);
450
451        int theight = (int) tbounds.getHeight();
452        int twidth = (int) tbounds.getWidth();
453        int tx = (int) tbounds.getX();
454        int ty = (int) tbounds.getY();
455        if( fixMetrics_ )
456            ty -= (int) ( 0.7 * tlayout.getAscent() );  // hack for MacOS X java.runtime.version = 1.4.1_01-39
457        sascent = (int) tlayout.getAscent();
458        //
459        xd = layer_.getXPtoD( porigin_.x );
460        yd = layer_.getYPtoD( porigin_.y );
461        //
462        // set device origin
463        //
464        dorigin_.x = xd;
465        dorigin_.y = yd;
466        xorig = xd;
467        yorig = yd;
468        //
469        switch( valign_ )
470        {
471            case SGLabel.TOP:
472                yd = yd + sascent;
473                break;
474            case SGLabel.MIDDLE:
475                yd = yd - ( ty + theight / 2 );
476                break;
477            case SGLabel.BOTTOM:
478        }
479        switch( halign_ )
480        {
481            case SGLabel.RIGHT:
482                xd = xd - twidth;
483                break;
484            case SGLabel.CENTER:
485                xd = xd - twidth / 2;
486                break;
487            case SGLabel.LEFT:
488        }
489        if( orient_ == SGLabel.HORIZONTAL )
490        {
491            xoff_ = 0;
492            yoff_ = -ty;
493        }
494        else if( orient_ == SGLabel.VERTICAL )
495        {
496            xoff_ = -ty;
497            yoff_ = twidth;
498        }
499        xt[0] = xd + tx;
500        xt[1] = xt[0];
501        xt[2] = xt[0] + twidth;
502        xt[3] = xt[2];
503
504        yt[0] = yd + ty;
505        yt[1] = yt[0] + theight;
506        yt[2] = yt[1];
507        yt[3] = yt[0];
508        //
509        // rotate
510        //
511        for( int i = 0; i < 4; i++ )
512        {
513            xn[i] = (int) ( ( xt[i] - xorig ) * costhta_ + ( yt[i] - yorig ) * sinthta_ ) + xorig;
514            yn[i] = (int) ( ( yt[i] - yorig ) * costhta_ - ( xt[i] - xorig ) * sinthta_ ) + yorig;
515        }
516
517        dpolygon_ = new Polygon( xn, yn, 4 );
518        dbounds_ = dpolygon_.getBounds();
519        //
520        // compute pbounds
521        //
522        pbounds_.x = layer_.getXDtoP( dbounds_.x );
523        pbounds_.y = layer_.getYDtoP( dbounds_.y );
524        pbounds_.width = layer_.getXDtoP( dbounds_.x +
525                dbounds_.width ) - pbounds_.x;
526        pbounds_.height = pbounds_.y -
527                layer_.getYDtoP( dbounds_.y + dbounds_.height );
528    }
529
530    //
531    // a bad method to compute the font size!
532    //
533    Font computeFontSize( Graphics g )
534    {
535        Font tfont;
536        int pt_0, pt_1, hgt;
537        int count = 1;
538        double hgt_0, hgt_1, del_0, del_1;
539        double a, b;
540        FontRenderContext frc = getFontRenderContext( (Graphics2D) g );
541        TextLayout tlayout;
542        //
543        // first guess
544        //
545        if( g == null ) return font_;  // return original font!
546        hgt = layer_.getXPtoD( height_ ) - layer_.getXPtoD( 0.0f );
547        pt_0 = hgt - 3;
548        tfont = new Font( font_.getName(), font_.getStyle(), pt_0 );
549        if( label_.length() == 0 )
550        {
551            tlayout = new TextLayout( " ", tfont, frc );
552        }
553        else
554        {
555            tlayout = new TextLayout( label_, tfont, frc );
556        }
557        hgt = (int) ( tlayout.getAscent() + tlayout.getDescent() );
558        hgt_0 = layer_.getXDtoP( hgt ) - layer_.getXDtoP( 0 );
559        pt_0 = tfont.getSize();
560        pt_1 = (int) ( (double) pt_0 * ( height_ / hgt_0 ) );
561        while( ( pt_0 != pt_1 ) && ( count < 5 ) )
562        {
563            tfont = new Font( font_.getName(), font_.getStyle(), pt_1 );
564            if( label_.length() == 0 )
565            {
566                tlayout = new TextLayout( " ", tfont, frc );
567            }
568            else
569            {
570                tlayout = new TextLayout( label_, tfont, frc );
571            }
572            hgt = (int) ( tlayout.getAscent() + tlayout.getDescent() );
573            hgt_1 = layer_.getXDtoP( hgt ) - layer_.getXDtoP( 0 );
574            del_0 = Math.abs( height_ - hgt_0 );
575            del_1 = Math.abs( height_ - hgt_1 );
576            if( ( Math.abs( pt_0 - pt_1 ) <= 1 ) && ( del_0 > del_1 ) ) return tfont;
577            pt_0 = pt_1;
578            hgt_0 = hgt_1;
579            pt_1 = (int) ( (double) pt_0 * ( height_ / hgt_0 ) );
580            count++;
581        }
582        return tfont;
583    }
584
585    private void drawString( Graphics g, int x, int y )
586    {
587        float angle;
588        if( g == null ) return;
589        if( orient_ == SGLabel.HORIZONTAL )
590        {
591            angle = 0.0f;
592        }
593        else if( orient_ == SGLabel.VERTICAL )
594        {
595            angle = -90.0f;
596        }
597        else
598        {
599            angle = -(float) angle_;
600        }
601        RenderingHints oldRenderingHints = null;
602        Graphics2D g2 = (Graphics2D) g;
603        if( angle != 0.0f || alwaysAntiAlias_ )
604        {
605            oldRenderingHints = g2.getRenderingHints();
606            g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
607                    RenderingHints.VALUE_ANTIALIAS_ON );
608            g2.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS,
609                    RenderingHints.VALUE_FRACTIONALMETRICS_ON );
610        }
611        AffineTransform oldTransform = g2.getTransform();
612        //    System.out.println("\n angle = " + angle + ", text = " + label_);
613        //    System.out.println("oldTransform = " + oldTransform);
614        AttributedString as = new AttributedString( label_ );
615        as.addAttribute( TextAttribute.FONT, font_ );
616        g2.translate( x, y );
617        //   System.out.println("translated = " + g2.getTransform());
618        g2.rotate( Math.PI * angle / 180.0 );
619        //   System.out.println("newTransform = " + g2.getTransform());
620        g2.drawString( as.getIterator(), 0, 0 );
621        g2.setTransform( oldTransform );
622        if( angle != 0.0f || alwaysAntiAlias_ )
623        {
624            g2.setRenderingHints( oldRenderingHints );
625        }
626        //
627//      g2.setStroke(normal);
628//      Color oldColor = g.getColor();
629//      g.setColor(Color.red);
630//      int x1= x - 5;
631//      int x2= x + 5;
632//      int y1= y - 5;
633//      int y2= y + 5;
634//      g.drawLine(x1, y, x2, y);
635//      g.drawLine(x, y1, x, y2);
636//      g.setColor(oldColor);
637
638    }
639
640    public float getStringWidth( Graphics g )
641    {
642        if( g == null ) return 0.0f;
643        font_ = computeFontSize( g );
644        FontRenderContext frc = getFontRenderContext( (Graphics2D) g );
645        TextLayout tlayout;
646        if( label_.length() == 0 )
647        {
648            tlayout = new TextLayout( " ", font_, frc );
649        }
650        else
651        {
652            tlayout = new TextLayout( label_, font_, frc );
653        }
654        java.awt.geom.Rectangle2D tbounds = tlayout.getBounds();
655        return (float) tbounds.getWidth();
656    }
657
658    public float getStringHeight( Graphics g )
659    {
660        if( g == null ) return 0.0f;
661        font_ = computeFontSize( g );
662        FontRenderContext frc = getFontRenderContext( (Graphics2D) g );
663        TextLayout tlayout;
664        if( label_.length() == 0 )
665        {
666            tlayout = new TextLayout( " ", font_, frc );
667        }
668        else
669        {
670            tlayout = new TextLayout( label_, font_, frc );
671        }
672        java.awt.geom.Rectangle2D tbounds = tlayout.getBounds();
673        return (float) tbounds.getHeight();
674    }
675
676    FontRenderContext getFontRenderContext( Graphics2D g2 )
677    {
678        if( g2 == null ) return null;
679        RenderingHints oldRenderingHints = null;
680        if( angle_ != 0.0 || alwaysAntiAlias_ )
681        {
682            oldRenderingHints = g2.getRenderingHints();
683            g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
684                    RenderingHints.VALUE_ANTIALIAS_ON );
685        }
686        FontRenderContext frc = g2.getFontRenderContext();
687        if( angle_ != 0.0 || alwaysAntiAlias_ )
688        {
689            g2.setRenderingHints( oldRenderingHints );
690        }
691        return frc;
692    }
693}
Note: See TracBrowser for help on using the repository browser.