< prev index next >

src/demo/share/jfc/Font2DTest/FontPanel.java

Print this page




  57 import java.awt.event.AdjustmentListener;
  58 import java.awt.event.ComponentAdapter;
  59 import java.awt.event.ComponentEvent;
  60 import java.awt.event.MouseEvent;
  61 import java.awt.event.MouseListener;
  62 import java.awt.event.MouseMotionListener;
  63 import java.awt.font.FontRenderContext;
  64 import java.awt.font.GlyphVector;
  65 import java.awt.font.LineBreakMeasurer;
  66 import java.awt.font.TextLayout;
  67 import java.awt.geom.AffineTransform;
  68 import java.awt.geom.NoninvertibleTransformException;
  69 import java.awt.geom.Rectangle2D;
  70 import java.awt.image.BufferedImage;
  71 import java.awt.print.PageFormat;
  72 import java.awt.print.Printable;
  73 import java.awt.print.PrinterJob;
  74 import java.io.BufferedOutputStream;
  75 import java.io.FileOutputStream;
  76 import java.text.AttributedString;
  77 import java.util.EnumSet;
  78 import java.util.Vector;
  79 
  80 import javax.imageio.*;
  81 import javax.swing.*;
  82 
  83 import static java.awt.RenderingHints.*;
  84 
  85 /**
  86  * FontPanel.java
  87  *
  88  * @author Shinsuke Fukuda
  89  * @author Ankit Patel [Conversion to Swing - 01/07/30]
  90  */
  91 
  92 /// This panel is combination of the text drawing area of Font2DTest
  93 /// and the custom controlled scroll bar
  94 
  95 public final class FontPanel extends JPanel implements AdjustmentListener {
  96 
  97     /// Drawing Option Constants


 375     /// Reload all options and refreshes the canvas
 376     public void loadOptions( boolean grid, boolean force16, int start, int end,
 377                              String name, float size, int style,
 378                              int transform, int g2transform,
 379                              int text, int method, int aa, int fm,
 380                              int contrast, String[] user ) {
 381         int[] range = { start, end };
 382 
 383         /// Since repaint call has a low priority, these functions will finish
 384         /// before the actual repainting is done
 385         setGridDisplay( grid );
 386         setForce16Columns( force16 );
 387         // previous call to readTextFile has already set the text to draw
 388         if (textToUse != FILE_TEXT) {
 389           setTextToDraw( text, range, user, null );
 390         }
 391         setFontParams( name, size, style, transform );
 392         setTransformG2( g2transform ); // ABP
 393         setDrawMethod( method );
 394         setRenderingHints(AAValues.getValue(aa), FMValues.getValue(fm),
 395                           new Integer(contrast));
 396     }
 397 
 398     /// Writes the current screen to PNG file
 399     public void doSavePNG( String fileName ) {
 400         fc.writePNG( fileName );
 401     }
 402 
 403     /// When scrolled using the scroll bar, update the backbuffer
 404     public void adjustmentValueChanged( AdjustmentEvent e ) {
 405         fc.repaint();
 406     }
 407 
 408     public void paintComponent( Graphics g ) {
 409         // Windows does not repaint correctly, after
 410         // a zoom. Thus, we need to force the canvas
 411         // to repaint, but only once. After the first repaint,
 412         // everything stabilizes. [ABP]
 413         fc.repaint();
 414     }
 415 


 417 
 418     /// Inner panel that holds the actual drawing area and its routines
 419     private class FontCanvas extends JPanel implements MouseListener, MouseMotionListener, Printable {
 420 
 421         /// Number of characters that will fit across and down this canvas
 422         private int numCharAcross, numCharDown;
 423 
 424         /// First and last character/line that will be drawn
 425         /// Limit is the end of range/text where no more draw will be done
 426         private int drawStart, drawEnd, drawLimit;
 427 
 428         /// FontMetrics variables
 429         /// Here, gridWidth is equivalent to maxAdvance (slightly bigger though)
 430         /// and gridHeight is equivalent to lineHeight
 431         private int maxAscent, maxDescent, gridWidth = 0, gridHeight = 0;
 432 
 433         /// Offset from the top left edge of the canvas where the draw will start
 434         private int canvasInset_X = 5, canvasInset_Y = 5;
 435 
 436         /// LineBreak'ed TextLayout vector
 437         private Vector lineBreakTLs = null;
 438 
 439         /// Whether the current draw command requested is for printing
 440         private boolean isPrinting = false;
 441 
 442         /// Other printing infos
 443         private int lastPage, printPageNumber, currentlyShownChar = 0;
 444         private final int PR_OFFSET = 10;
 445         private final int PR_TITLE_LINEHEIGHT = 30;
 446 
 447         /// Information about zooming (used with range text draw)
 448         private final JWindow zoomWindow;
 449         private BufferedImage zoomImage = null;
 450         private int mouseOverCharX = -1, mouseOverCharY = -1;
 451         private int currMouseOverChar = -1, prevZoomChar = -1;
 452         private float ZOOM = 2.0f;
 453         private boolean nowZooming = false;
 454         private boolean firstTime = true;
 455 // ABP
 456 
 457         /// Status bar message backup


 783                   throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW );
 784 
 785                 if ( !isPrinting )
 786                   resetScrollbar( verticalBar.getValue() * numCharAcross );
 787             }
 788             else {
 789                 maxDescent += fm.getLeading();
 790                 canvasInset_X = 5;
 791                 canvasInset_Y = 5;
 792                 /// gridWidth and numCharAcross will not be used in this mode...
 793                 gridHeight = maxAscent + maxDescent;
 794                 numCharDown = ( h - canvasInset_Y * 2 ) / gridHeight;
 795 
 796                 if ( numCharDown == 0 )
 797                   throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW );
 798                 /// If this is text loaded from file, prepares the LineBreak'ed
 799                 /// text layout at this point
 800                 if ( textToUse == FILE_TEXT ) {
 801                     if ( !isPrinting )
 802                       f2dt.fireChangeStatus( "LineBreaking Text... Please Wait", false );
 803                     lineBreakTLs = new Vector();
 804                     for ( int i = 0; i < fileText.length; i++ ) {
 805                         AttributedString as =
 806                           new AttributedString( fileText[i], g2.getFont().getAttributes() );
 807 
 808                         LineBreakMeasurer lbm =
 809                           new LineBreakMeasurer( as.getIterator(), g2.getFontRenderContext() );
 810 
 811                         while ( lbm.getPosition() < fileText[i].length() )
 812                           lineBreakTLs.add( lbm.nextLayout( (float) w ));
 813 
 814                     }
 815                 }
 816                 if ( !isPrinting )
 817                   resetScrollbar( verticalBar.getValue() );
 818             }
 819         }
 820 
 821         /// Calculates the amount of text that will be displayed on screen
 822         private void calcTextRange() {
 823             String displaying = null;


 912 
 913                       modeSpecificDrawChar( g2, charToDraw,
 914                                             gridLocX + gridWidth / 2,
 915                                             gridLocY + maxAscent );
 916 
 917                   }
 918                 }
 919             }
 920             else if ( textToUse == USER_TEXT ) {
 921                 g2.drawRect( 0, 0, w - 1, h - 1 );
 922                 for ( int i = drawStart; i <= drawEnd; i++ ) {
 923                     int lineStartX = canvasInset_Y;
 924                     int lineStartY = ( i - drawStart ) * gridHeight + maxAscent;
 925                     modeSpecificDrawLine( g2, userText[i], lineStartX, lineStartY );
 926                 }
 927             }
 928             else {
 929                 float xPos, yPos = (float) canvasInset_Y;
 930                 g2.drawRect( 0, 0, w - 1, h - 1 );
 931                 for ( int i = drawStart; i <= drawEnd; i++ ) {
 932                     TextLayout oneLine = (TextLayout) lineBreakTLs.elementAt( i );
 933                     xPos =
 934                       oneLine.isLeftToRight() ?
 935                       canvasInset_X : ( (float) w - oneLine.getAdvance() - canvasInset_X );
 936 
 937                     float[] fmData = {0, oneLine.getAscent(), 0, oneLine.getDescent(), 0, oneLine.getLeading()};
 938                     if (g2Transform != NONE) {
 939                         AffineTransform at = getAffineTransform(g2Transform);
 940                         at.transform( fmData, 0, fmData, 0, 3);
 941                     }
 942                     //yPos += oneLine.getAscent();
 943                     yPos += fmData[1]; // ascent
 944                     //oneLine.draw( g2, xPos, yPos );
 945                     tlDrawLine( g2, oneLine, xPos, yPos );
 946                     //yPos += oneLine.getDescent() + oneLine.getLeading();
 947                     yPos += fmData[3] + fmData[5]; // descent + leading
 948                 }
 949             }
 950             g2.dispose();
 951         }
 952 


 975             if ( pageIndex == 0 ) {
 976                 /// Reset the last page index to max...
 977                 lastPage = Integer.MAX_VALUE;
 978                 currentlyShownChar = verticalBar.getValue() * numCharAcross;
 979             }
 980 
 981             if ( printMode == ONE_PAGE ) {
 982                 if ( pageIndex > 0 )
 983                   return NO_SUCH_PAGE;
 984             }
 985             else {
 986                 if ( pageIndex > lastPage )
 987                   return NO_SUCH_PAGE;
 988             }
 989 
 990             int pageWidth = (int) pf.getImageableWidth();
 991             int pageHeight = (int) pf.getImageableHeight();
 992             /// Back up metrics and other drawing info before printing modifies it
 993             int backupDrawStart = drawStart, backupDrawEnd = drawEnd;
 994             int backupNumCharAcross = numCharAcross, backupNumCharDown = numCharDown;
 995             Vector backupLineBreakTLs = null;
 996             if ( textToUse == FILE_TEXT )
 997               backupLineBreakTLs = (Vector) lineBreakTLs.clone();
 998 
 999             printPageNumber = pageIndex;
1000             isPrinting = true;
1001             /// Push the actual draw area 60 down to allow info to be printed
1002             g.translate( (int) pf.getImageableX(), (int) pf.getImageableY() + 60 );
1003             try {
1004                 drawText( g, pageWidth, pageHeight - 60 );
1005             }
1006             catch ( CannotDrawException e ) {
1007                 f2dt.fireChangeStatus( ERRORS[ e.id ], true );
1008                 return NO_SUCH_PAGE;
1009             }
1010 
1011             /// Draw information about what is being printed
1012             String hints = ( " with antialias " + antiAliasType + "and" +
1013                              " fractional metrics " + fractionalMetricsType +
1014                              " and lcd contrast = " + lcdContrast);
1015             String infoLine1 = ( "Printing" + MS_OPENING[textToUse] +
1016                                  modeSpecificNumStr( drawStart ) + " to " +
1017                                  modeSpecificNumStr( drawEnd ) + MS_CLOSING[textToUse] );


1120                   zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 20 );
1121                 else
1122                   zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 1 );
1123             }
1124 
1125             /// Prepare zoomed image
1126             zoomImage =
1127               (BufferedImage) zoomWindow.createImage( zoomAreaWidth + 1,
1128                                                       zoomAreaHeight + 1 );
1129             Graphics2D g2 = (Graphics2D) zoomImage.getGraphics();
1130             testFont = testFont.deriveFont( fontSize * ZOOM );
1131             setParams( g2 );
1132             g2.setColor( Color.white );
1133             g2.fillRect( 0, 0, zoomAreaWidth, zoomAreaHeight );
1134             g2.setColor( Color.black );
1135             g2.drawRect( 0, 0, zoomAreaWidth, zoomAreaHeight );
1136             modeSpecificDrawChar( g2, currMouseOverChar,
1137                                   zoomAreaWidth / 2, (int) ( maxAscent * ZOOM ));
1138             g2.dispose();
1139             if ( !nowZooming )
1140               zoomWindow.show();
1141             /// This is sort of redundant... since there is a paint function
1142             /// inside zoomWindow definition that does the drawImage.
1143             /// (I should be able to call just repaint() here)
1144             /// However, for some reason, that paint function fails to respond
1145             /// from second time and on; So I have to force the paint here...
1146             zoomWindow.getGraphics().drawImage( zoomImage, 0, 0, this );
1147 
1148             nowZooming = true;
1149             prevZoomChar = currMouseOverChar;
1150             testFont = backup;
1151 
1152             // Windows does not repaint correctly, after
1153             // a zoom. Thus, we need to force the canvas
1154             // to repaint, but only once. After the first repaint,
1155             // everything stabilizes. [ABP]
1156             if ( firstTime() ) {
1157                 refresh();
1158             }
1159         }
1160 
1161         /// Listener Functions
1162 
1163         /// MouseListener interface function
1164         /// Zooms a character when mouse is pressed above it
1165         public void mousePressed( MouseEvent e ) {
1166             if ( !showingError) {
1167                 if ( checkMouseLoc( e )) {
1168                     showZoomed();
1169                     this.setCursor( blankCursor );
1170                 }
1171             }
1172         }
1173 
1174         /// MouseListener interface function
1175         /// Redraws the area that was drawn over by zoomed character
1176         public void mouseReleased( MouseEvent e ) {
1177             if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
1178                 if ( nowZooming )
1179                   zoomWindow.hide();
1180                 nowZooming = false;
1181             }
1182             this.setCursor( Cursor.getDefaultCursor() );
1183         }
1184 
1185         /// MouseListener interface function
1186         /// Resets the status bar to display range instead of a specific character
1187         public void mouseExited( MouseEvent e ) {
1188             if ( !showingError && !nowZooming )
1189               f2dt.fireChangeStatus( backupStatusString, false );
1190         }
1191 
1192         /// MouseMotionListener interface function
1193         /// Adjusts the status bar message when mouse moves over a character
1194         public void mouseMoved( MouseEvent e ) {
1195             if ( !showingError ) {
1196                 if ( !checkMouseLoc( e ))
1197                   f2dt.fireChangeStatus( backupStatusString, false );
1198             }
1199         }


1229 
1230         private String name;
1231         private Object hint;
1232 
1233         private static FMValues[] valArray;
1234 
1235         FMValues(String s, Object o) {
1236             name = s;
1237             hint = o;
1238         }
1239 
1240         public String toString() {
1241             return name;
1242         }
1243 
1244        public Object getHint() {
1245            return hint;
1246        }
1247        public static Object getValue(int ordinal) {
1248            if (valArray == null) {
1249                valArray = (FMValues[])EnumSet.allOf(FMValues.class).toArray(new FMValues[0]);
1250            }
1251            for (int i=0;i<valArray.length;i++) {
1252                if (valArray[i].ordinal() == ordinal) {
1253                    return valArray[i];
1254                }
1255            }
1256            return valArray[0];
1257        }
1258        private static FMValues[] getArray() {
1259            if (valArray == null) {
1260                valArray = (FMValues[])EnumSet.allOf(FMValues.class).toArray(new FMValues[0]);
1261            }
1262            return valArray;
1263        }
1264 
1265        public static int getHintVal(Object hint) {
1266            getArray();
1267            for (int i=0;i<valArray.length;i++) {
1268                if (valArray[i].getHint() == hint) {
1269                    return i;
1270                }
1271            }
1272            return 0;
1273        }
1274     }
1275 
1276    enum AAValues {
1277        AADEFAULT ("DEFAULT",  VALUE_TEXT_ANTIALIAS_DEFAULT),
1278        AAOFF     ("OFF",      VALUE_TEXT_ANTIALIAS_OFF),
1279        AAON      ("ON",       VALUE_TEXT_ANTIALIAS_ON),
1280        AAGASP    ("GASP",     VALUE_TEXT_ANTIALIAS_GASP),


1291         AAValues(String s, Object o) {
1292             name = s;
1293             hint = o;
1294         }
1295 
1296         public String toString() {
1297             return name;
1298         }
1299 
1300        public Object getHint() {
1301            return hint;
1302        }
1303 
1304        public static boolean isLCDMode(Object o) {
1305            return (o instanceof AAValues &&
1306                    ((AAValues)o).ordinal() >= AALCDHRGB.ordinal());
1307        }
1308 
1309        public static Object getValue(int ordinal) {
1310            if (valArray == null) {
1311                valArray = (AAValues[])EnumSet.allOf(AAValues.class).toArray(new AAValues[0]);
1312            }
1313            for (int i=0;i<valArray.length;i++) {
1314                if (valArray[i].ordinal() == ordinal) {
1315                    return valArray[i];
1316                }
1317            }
1318            return valArray[0];
1319        }
1320 
1321        private static AAValues[] getArray() {
1322            if (valArray == null) {
1323                Object [] oa = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]);
1324                valArray = (AAValues[])(EnumSet.allOf(AAValues.class).toArray(new AAValues[0]));
1325            }
1326            return valArray;
1327        }
1328 
1329        public static int getHintVal(Object hint) {
1330            getArray();
1331            for (int i=0;i<valArray.length;i++) {
1332                if (valArray[i].getHint() == hint) {
1333                    return i;
1334                }
1335            }
1336            return 0;
1337        }
1338 
1339     }
1340 
1341     private static Integer defaultContrast;
1342     static Integer getDefaultLCDContrast() {
1343         if (defaultContrast == null) {
1344             GraphicsConfiguration gc =


  57 import java.awt.event.AdjustmentListener;
  58 import java.awt.event.ComponentAdapter;
  59 import java.awt.event.ComponentEvent;
  60 import java.awt.event.MouseEvent;
  61 import java.awt.event.MouseListener;
  62 import java.awt.event.MouseMotionListener;
  63 import java.awt.font.FontRenderContext;
  64 import java.awt.font.GlyphVector;
  65 import java.awt.font.LineBreakMeasurer;
  66 import java.awt.font.TextLayout;
  67 import java.awt.geom.AffineTransform;
  68 import java.awt.geom.NoninvertibleTransformException;
  69 import java.awt.geom.Rectangle2D;
  70 import java.awt.image.BufferedImage;
  71 import java.awt.print.PageFormat;
  72 import java.awt.print.Printable;
  73 import java.awt.print.PrinterJob;
  74 import java.io.BufferedOutputStream;
  75 import java.io.FileOutputStream;
  76 import java.text.AttributedString;

  77 import java.util.Vector;
  78 
  79 import javax.imageio.*;
  80 import javax.swing.*;
  81 
  82 import static java.awt.RenderingHints.*;
  83 
  84 /**
  85  * FontPanel.java
  86  *
  87  * @author Shinsuke Fukuda
  88  * @author Ankit Patel [Conversion to Swing - 01/07/30]
  89  */
  90 
  91 /// This panel is combination of the text drawing area of Font2DTest
  92 /// and the custom controlled scroll bar
  93 
  94 public final class FontPanel extends JPanel implements AdjustmentListener {
  95 
  96     /// Drawing Option Constants


 374     /// Reload all options and refreshes the canvas
 375     public void loadOptions( boolean grid, boolean force16, int start, int end,
 376                              String name, float size, int style,
 377                              int transform, int g2transform,
 378                              int text, int method, int aa, int fm,
 379                              int contrast, String[] user ) {
 380         int[] range = { start, end };
 381 
 382         /// Since repaint call has a low priority, these functions will finish
 383         /// before the actual repainting is done
 384         setGridDisplay( grid );
 385         setForce16Columns( force16 );
 386         // previous call to readTextFile has already set the text to draw
 387         if (textToUse != FILE_TEXT) {
 388           setTextToDraw( text, range, user, null );
 389         }
 390         setFontParams( name, size, style, transform );
 391         setTransformG2( g2transform ); // ABP
 392         setDrawMethod( method );
 393         setRenderingHints(AAValues.getValue(aa), FMValues.getValue(fm),
 394                           Integer.valueOf(contrast));
 395     }
 396 
 397     /// Writes the current screen to PNG file
 398     public void doSavePNG( String fileName ) {
 399         fc.writePNG( fileName );
 400     }
 401 
 402     /// When scrolled using the scroll bar, update the backbuffer
 403     public void adjustmentValueChanged( AdjustmentEvent e ) {
 404         fc.repaint();
 405     }
 406 
 407     public void paintComponent( Graphics g ) {
 408         // Windows does not repaint correctly, after
 409         // a zoom. Thus, we need to force the canvas
 410         // to repaint, but only once. After the first repaint,
 411         // everything stabilizes. [ABP]
 412         fc.repaint();
 413     }
 414 


 416 
 417     /// Inner panel that holds the actual drawing area and its routines
 418     private class FontCanvas extends JPanel implements MouseListener, MouseMotionListener, Printable {
 419 
 420         /// Number of characters that will fit across and down this canvas
 421         private int numCharAcross, numCharDown;
 422 
 423         /// First and last character/line that will be drawn
 424         /// Limit is the end of range/text where no more draw will be done
 425         private int drawStart, drawEnd, drawLimit;
 426 
 427         /// FontMetrics variables
 428         /// Here, gridWidth is equivalent to maxAdvance (slightly bigger though)
 429         /// and gridHeight is equivalent to lineHeight
 430         private int maxAscent, maxDescent, gridWidth = 0, gridHeight = 0;
 431 
 432         /// Offset from the top left edge of the canvas where the draw will start
 433         private int canvasInset_X = 5, canvasInset_Y = 5;
 434 
 435         /// LineBreak'ed TextLayout vector
 436         private Vector<TextLayout> lineBreakTLs = null;
 437 
 438         /// Whether the current draw command requested is for printing
 439         private boolean isPrinting = false;
 440 
 441         /// Other printing infos
 442         private int lastPage, printPageNumber, currentlyShownChar = 0;
 443         private final int PR_OFFSET = 10;
 444         private final int PR_TITLE_LINEHEIGHT = 30;
 445 
 446         /// Information about zooming (used with range text draw)
 447         private final JWindow zoomWindow;
 448         private BufferedImage zoomImage = null;
 449         private int mouseOverCharX = -1, mouseOverCharY = -1;
 450         private int currMouseOverChar = -1, prevZoomChar = -1;
 451         private float ZOOM = 2.0f;
 452         private boolean nowZooming = false;
 453         private boolean firstTime = true;
 454 // ABP
 455 
 456         /// Status bar message backup


 782                   throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW );
 783 
 784                 if ( !isPrinting )
 785                   resetScrollbar( verticalBar.getValue() * numCharAcross );
 786             }
 787             else {
 788                 maxDescent += fm.getLeading();
 789                 canvasInset_X = 5;
 790                 canvasInset_Y = 5;
 791                 /// gridWidth and numCharAcross will not be used in this mode...
 792                 gridHeight = maxAscent + maxDescent;
 793                 numCharDown = ( h - canvasInset_Y * 2 ) / gridHeight;
 794 
 795                 if ( numCharDown == 0 )
 796                   throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW );
 797                 /// If this is text loaded from file, prepares the LineBreak'ed
 798                 /// text layout at this point
 799                 if ( textToUse == FILE_TEXT ) {
 800                     if ( !isPrinting )
 801                       f2dt.fireChangeStatus( "LineBreaking Text... Please Wait", false );
 802                     lineBreakTLs = new Vector<>();
 803                     for ( int i = 0; i < fileText.length; i++ ) {
 804                         AttributedString as =
 805                           new AttributedString( fileText[i], g2.getFont().getAttributes() );
 806 
 807                         LineBreakMeasurer lbm =
 808                           new LineBreakMeasurer( as.getIterator(), g2.getFontRenderContext() );
 809 
 810                         while ( lbm.getPosition() < fileText[i].length() )
 811                           lineBreakTLs.add( lbm.nextLayout( (float) w ));
 812 
 813                     }
 814                 }
 815                 if ( !isPrinting )
 816                   resetScrollbar( verticalBar.getValue() );
 817             }
 818         }
 819 
 820         /// Calculates the amount of text that will be displayed on screen
 821         private void calcTextRange() {
 822             String displaying = null;


 911 
 912                       modeSpecificDrawChar( g2, charToDraw,
 913                                             gridLocX + gridWidth / 2,
 914                                             gridLocY + maxAscent );
 915 
 916                   }
 917                 }
 918             }
 919             else if ( textToUse == USER_TEXT ) {
 920                 g2.drawRect( 0, 0, w - 1, h - 1 );
 921                 for ( int i = drawStart; i <= drawEnd; i++ ) {
 922                     int lineStartX = canvasInset_Y;
 923                     int lineStartY = ( i - drawStart ) * gridHeight + maxAscent;
 924                     modeSpecificDrawLine( g2, userText[i], lineStartX, lineStartY );
 925                 }
 926             }
 927             else {
 928                 float xPos, yPos = (float) canvasInset_Y;
 929                 g2.drawRect( 0, 0, w - 1, h - 1 );
 930                 for ( int i = drawStart; i <= drawEnd; i++ ) {
 931                     TextLayout oneLine = lineBreakTLs.elementAt( i );
 932                     xPos =
 933                       oneLine.isLeftToRight() ?
 934                       canvasInset_X : ( (float) w - oneLine.getAdvance() - canvasInset_X );
 935 
 936                     float[] fmData = {0, oneLine.getAscent(), 0, oneLine.getDescent(), 0, oneLine.getLeading()};
 937                     if (g2Transform != NONE) {
 938                         AffineTransform at = getAffineTransform(g2Transform);
 939                         at.transform( fmData, 0, fmData, 0, 3);
 940                     }
 941                     //yPos += oneLine.getAscent();
 942                     yPos += fmData[1]; // ascent
 943                     //oneLine.draw( g2, xPos, yPos );
 944                     tlDrawLine( g2, oneLine, xPos, yPos );
 945                     //yPos += oneLine.getDescent() + oneLine.getLeading();
 946                     yPos += fmData[3] + fmData[5]; // descent + leading
 947                 }
 948             }
 949             g2.dispose();
 950         }
 951 


 974             if ( pageIndex == 0 ) {
 975                 /// Reset the last page index to max...
 976                 lastPage = Integer.MAX_VALUE;
 977                 currentlyShownChar = verticalBar.getValue() * numCharAcross;
 978             }
 979 
 980             if ( printMode == ONE_PAGE ) {
 981                 if ( pageIndex > 0 )
 982                   return NO_SUCH_PAGE;
 983             }
 984             else {
 985                 if ( pageIndex > lastPage )
 986                   return NO_SUCH_PAGE;
 987             }
 988 
 989             int pageWidth = (int) pf.getImageableWidth();
 990             int pageHeight = (int) pf.getImageableHeight();
 991             /// Back up metrics and other drawing info before printing modifies it
 992             int backupDrawStart = drawStart, backupDrawEnd = drawEnd;
 993             int backupNumCharAcross = numCharAcross, backupNumCharDown = numCharDown;
 994             Vector<TextLayout> backupLineBreakTLs = null;
 995             if ( textToUse == FILE_TEXT )
 996               backupLineBreakTLs = new Vector<>(lineBreakTLs);
 997 
 998             printPageNumber = pageIndex;
 999             isPrinting = true;
1000             /// Push the actual draw area 60 down to allow info to be printed
1001             g.translate( (int) pf.getImageableX(), (int) pf.getImageableY() + 60 );
1002             try {
1003                 drawText( g, pageWidth, pageHeight - 60 );
1004             }
1005             catch ( CannotDrawException e ) {
1006                 f2dt.fireChangeStatus( ERRORS[ e.id ], true );
1007                 return NO_SUCH_PAGE;
1008             }
1009 
1010             /// Draw information about what is being printed
1011             String hints = ( " with antialias " + antiAliasType + "and" +
1012                              " fractional metrics " + fractionalMetricsType +
1013                              " and lcd contrast = " + lcdContrast);
1014             String infoLine1 = ( "Printing" + MS_OPENING[textToUse] +
1015                                  modeSpecificNumStr( drawStart ) + " to " +
1016                                  modeSpecificNumStr( drawEnd ) + MS_CLOSING[textToUse] );


1119                   zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 20 );
1120                 else
1121                   zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 1 );
1122             }
1123 
1124             /// Prepare zoomed image
1125             zoomImage =
1126               (BufferedImage) zoomWindow.createImage( zoomAreaWidth + 1,
1127                                                       zoomAreaHeight + 1 );
1128             Graphics2D g2 = (Graphics2D) zoomImage.getGraphics();
1129             testFont = testFont.deriveFont( fontSize * ZOOM );
1130             setParams( g2 );
1131             g2.setColor( Color.white );
1132             g2.fillRect( 0, 0, zoomAreaWidth, zoomAreaHeight );
1133             g2.setColor( Color.black );
1134             g2.drawRect( 0, 0, zoomAreaWidth, zoomAreaHeight );
1135             modeSpecificDrawChar( g2, currMouseOverChar,
1136                                   zoomAreaWidth / 2, (int) ( maxAscent * ZOOM ));
1137             g2.dispose();
1138             if ( !nowZooming )
1139               zoomWindow.setVisible(true);
1140             /// This is sort of redundant... since there is a paint function
1141             /// inside zoomWindow definition that does the drawImage.
1142             /// (I should be able to call just repaint() here)
1143             /// However, for some reason, that paint function fails to respond
1144             /// from second time and on; So I have to force the paint here...
1145             zoomWindow.getGraphics().drawImage( zoomImage, 0, 0, this );
1146 
1147             nowZooming = true;
1148             prevZoomChar = currMouseOverChar;
1149             testFont = backup;
1150 
1151             // Windows does not repaint correctly, after
1152             // a zoom. Thus, we need to force the canvas
1153             // to repaint, but only once. After the first repaint,
1154             // everything stabilizes. [ABP]
1155             if ( firstTime() ) {
1156                 refresh();
1157             }
1158         }
1159 
1160         /// Listener Functions
1161 
1162         /// MouseListener interface function
1163         /// Zooms a character when mouse is pressed above it
1164         public void mousePressed( MouseEvent e ) {
1165             if ( !showingError) {
1166                 if ( checkMouseLoc( e )) {
1167                     showZoomed();
1168                     this.setCursor( blankCursor );
1169                 }
1170             }
1171         }
1172 
1173         /// MouseListener interface function
1174         /// Redraws the area that was drawn over by zoomed character
1175         public void mouseReleased( MouseEvent e ) {
1176             if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
1177                 if ( nowZooming )
1178                   zoomWindow.setVisible(false);
1179                 nowZooming = false;
1180             }
1181             this.setCursor( Cursor.getDefaultCursor() );
1182         }
1183 
1184         /// MouseListener interface function
1185         /// Resets the status bar to display range instead of a specific character
1186         public void mouseExited( MouseEvent e ) {
1187             if ( !showingError && !nowZooming )
1188               f2dt.fireChangeStatus( backupStatusString, false );
1189         }
1190 
1191         /// MouseMotionListener interface function
1192         /// Adjusts the status bar message when mouse moves over a character
1193         public void mouseMoved( MouseEvent e ) {
1194             if ( !showingError ) {
1195                 if ( !checkMouseLoc( e ))
1196                   f2dt.fireChangeStatus( backupStatusString, false );
1197             }
1198         }


1228 
1229         private String name;
1230         private Object hint;
1231 
1232         private static FMValues[] valArray;
1233 
1234         FMValues(String s, Object o) {
1235             name = s;
1236             hint = o;
1237         }
1238 
1239         public String toString() {
1240             return name;
1241         }
1242 
1243        public Object getHint() {
1244            return hint;
1245        }
1246        public static Object getValue(int ordinal) {
1247            if (valArray == null) {
1248                valArray = FMValues.values();
1249            }
1250            for (int i=0;i<valArray.length;i++) {
1251                if (valArray[i].ordinal() == ordinal) {
1252                    return valArray[i];
1253                }
1254            }
1255            return valArray[0];
1256        }
1257        private static FMValues[] getArray() {
1258            if (valArray == null) {
1259                valArray = FMValues.values();
1260            }
1261            return valArray;
1262        }
1263 
1264        public static int getHintVal(Object hint) {
1265            getArray();
1266            for (int i=0;i<valArray.length;i++) {
1267                if (valArray[i].getHint() == hint) {
1268                    return i;
1269                }
1270            }
1271            return 0;
1272        }
1273     }
1274 
1275    enum AAValues {
1276        AADEFAULT ("DEFAULT",  VALUE_TEXT_ANTIALIAS_DEFAULT),
1277        AAOFF     ("OFF",      VALUE_TEXT_ANTIALIAS_OFF),
1278        AAON      ("ON",       VALUE_TEXT_ANTIALIAS_ON),
1279        AAGASP    ("GASP",     VALUE_TEXT_ANTIALIAS_GASP),


1290         AAValues(String s, Object o) {
1291             name = s;
1292             hint = o;
1293         }
1294 
1295         public String toString() {
1296             return name;
1297         }
1298 
1299        public Object getHint() {
1300            return hint;
1301        }
1302 
1303        public static boolean isLCDMode(Object o) {
1304            return (o instanceof AAValues &&
1305                    ((AAValues)o).ordinal() >= AALCDHRGB.ordinal());
1306        }
1307 
1308        public static Object getValue(int ordinal) {
1309            if (valArray == null) {
1310                valArray = AAValues.values();
1311            }
1312            for (int i=0;i<valArray.length;i++) {
1313                if (valArray[i].ordinal() == ordinal) {
1314                    return valArray[i];
1315                }
1316            }
1317            return valArray[0];
1318        }
1319 
1320        private static AAValues[] getArray() {
1321            if (valArray == null) {
1322                valArray = AAValues.values();

1323            }
1324            return valArray;
1325        }
1326 
1327        public static int getHintVal(Object hint) {
1328            getArray();
1329            for (int i=0;i<valArray.length;i++) {
1330                if (valArray[i].getHint() == hint) {
1331                    return i;
1332                }
1333            }
1334            return 0;
1335        }
1336 
1337     }
1338 
1339     private static Integer defaultContrast;
1340     static Integer getDefaultLCDContrast() {
1341         if (defaultContrast == null) {
1342             GraphicsConfiguration gc =
< prev index next >