📄 fontpanel.java
字号:
/// Draws one line of text at given position private void tlDrawLine( Graphics2D g2, TextLayout tl, float baseX, float baseY ) { /// ABP - keep track of old tform, restore it later AffineTransform oldTx = null; oldTx = g2.getTransform(); g2.translate( baseX, baseY ); g2.transform( getAffineTransform( g2Transform ) ); tl.draw( g2, (float) 0, (float) 0 ); /// ABP - restore old tform g2.setTransform ( oldTx ); } /// If textToUse is set to range drawing, then convert /// int to hex string and prepends 0s to make it length 4 /// Otherwise line number was fed; simply return number + 1 converted to String /// (This is because first line is 1, not 0) private String modeSpecificNumStr( int i ) { if ( textToUse == USER_TEXT || textToUse == FILE_TEXT ) return String.valueOf( i + 1 ); StringBuffer s = new StringBuffer( Integer.toHexString( i )); while ( s.length() < 4 ) s.insert( 0, "0" ); return s.toString().toUpperCase(); } /// Resets the scrollbar to display correct range of text currently on screen /// (This scrollbar is not part of a "ScrollPane". It merely simulates its effect by /// indicating the necessary area to be drawn within the panel. /// By doing this, it prevents creating gigantic panel when large text range, /// i.e. CJK Ideographs, is requested) private void resetScrollbar( int oldValue ) { int totalNumRows = 1, numCharToDisplay; if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) { if ( textToUse == RANGE_TEXT ) numCharToDisplay = drawRange[1] - drawRange[0]; else /// textToUse == ALL_GLYPHS numCharToDisplay = testFont.getNumGlyphs(); totalNumRows = numCharToDisplay / numCharAcross; if ( numCharToDisplay % numCharAcross != 0 ) totalNumRows++; if ( oldValue / numCharAcross > totalNumRows ) oldValue = 0; verticalBar.setValues( oldValue / numCharAcross, numCharDown, 0, totalNumRows ); } else { if ( textToUse == USER_TEXT ) totalNumRows = userText.length; else /// textToUse == FILE_TEXT; totalNumRows = lineBreakTLs.size(); verticalBar.setValues( oldValue, numCharDown, 0, totalNumRows ); } if ( totalNumRows <= numCharDown && drawStart == 0) { verticalBar.setEnabled( false ); } else { verticalBar.setEnabled( true ); } } /// Calculates the font's metrics that will be used for draw private void calcFontMetrics( Graphics2D g2d, int w, int h ) { FontMetrics fm; Graphics2D g2 = (Graphics2D)g2d.create(); /// ABP if ( g2Transform != NONE && textToUse != FILE_TEXT ) { g2.setFont( g2.getFont().deriveFont( getAffineTransform( g2Transform )) ); fm = g2.getFontMetrics(); } else { fm = g2.getFontMetrics(); } maxAscent = fm.getMaxAscent(); maxDescent = fm.getMaxDescent(); if (maxAscent == 0) maxAscent = 10; if (maxDescent == 0) maxDescent = 5; if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) { /// Give slight extra room for each character maxAscent += 3; maxDescent += 3; gridWidth = fm.getMaxAdvance() + 6; gridHeight = maxAscent + maxDescent; if ( force16Cols ) numCharAcross = 16; else numCharAcross = ( w - 10 ) / gridWidth; numCharDown = ( h - 10 ) / gridHeight; canvasInset_X = ( w - numCharAcross * gridWidth ) / 2; canvasInset_Y = ( h - numCharDown * gridHeight ) / 2; if ( numCharDown == 0 || numCharAcross == 0 ) throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW ); if ( !isPrinting ) resetScrollbar( verticalBar.getValue() * numCharAcross ); } else { maxDescent += fm.getLeading(); canvasInset_X = 5; canvasInset_Y = 5; /// gridWidth and numCharAcross will not be used in this mode... gridHeight = maxAscent + maxDescent; numCharDown = ( h - canvasInset_Y * 2 ) / gridHeight; if ( numCharDown == 0 ) throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW ); /// If this is text loaded from file, prepares the LineBreak'ed /// text layout at this point if ( textToUse == FILE_TEXT ) { if ( !isPrinting ) f2dt.fireChangeStatus( "LineBreaking Text... Please Wait", false ); lineBreakTLs = new Vector(); for ( int i = 0; i < fileText.length; i++ ) { AttributedString as = new AttributedString( fileText[i], g2.getFont().getAttributes() ); LineBreakMeasurer lbm = new LineBreakMeasurer( as.getIterator(), g2.getFontRenderContext() ); while ( lbm.getPosition() < fileText[i].length() ) lineBreakTLs.add( lbm.nextLayout( (float) w )); } } if ( !isPrinting ) resetScrollbar( verticalBar.getValue() ); } } /// Calculates the amount of text that will be displayed on screen private void calcTextRange() { String displaying = null; if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) { if ( isPrinting ) if ( printMode == ONE_PAGE ) drawStart = currentlyShownChar; else /// printMode == CUR_RANGE drawStart = numCharAcross * numCharDown * printPageNumber; else drawStart = verticalBar.getValue() * numCharAcross; if ( textToUse == RANGE_TEXT ) { drawStart += drawRange[0]; drawLimit = drawRange[1]; } else drawLimit = testFont.getNumGlyphs(); drawEnd = drawStart + numCharAcross * numCharDown - 1; if ( drawEnd >= drawLimit ) drawEnd = drawLimit; } else { if ( isPrinting ) if ( printMode == ONE_PAGE ) drawStart = currentlyShownChar; else /// printMode == ALL_TEXT drawStart = numCharDown * printPageNumber; else { drawStart = verticalBar.getValue(); } drawEnd = drawStart + numCharDown - 1; if ( textToUse == USER_TEXT ) drawLimit = userText.length - 1; else drawLimit = lineBreakTLs.size() - 1; if ( drawEnd >= drawLimit ) drawEnd = drawLimit; } // ABP if ( drawStart > drawEnd ) { drawStart = 0; verticalBar.setValue(drawStart); } /// Change the status bar if not printing... if ( !isPrinting ) { backupStatusString = ( "Displaying" + MS_OPENING[textToUse] + modeSpecificNumStr( drawStart ) + " to " + modeSpecificNumStr( drawEnd ) + MS_CLOSING[textToUse] ); f2dt.fireChangeStatus( backupStatusString, false ); } } /// Draws text according to the parameters set by Font2DTest GUI private void drawText( Graphics g, int w, int h ) { Graphics2D g2; /// Create back buffer when not printing, and its Graphics2D /// Then set drawing parameters for that Graphics2D object if ( isPrinting ) g2 = (Graphics2D) g; else { backBuffer = (BufferedImage) this.createImage( w, h ); g2 = backBuffer.createGraphics(); g2.setColor(Color.white); g2.fillRect(0, 0, w, h); g2.setColor(Color.black); } /// sets font, RenderingHints. setParams( g2 ); /// If flag is set, recalculate fontMetrics and reset the scrollbar if ( updateFontMetrics || isPrinting ) { /// NOTE: re-calculates in case G2 transform /// is something other than NONE calcFontMetrics( g2, w, h ); updateFontMetrics = false; } /// Calculate the amount of text that can be drawn... calcTextRange(); /// Draw according to the set "Text to Use" mode if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) { int charToDraw = drawStart; if ( showGrid ) drawGrid( g2 ); if ( !isPrinting ) g.drawImage( backBuffer, 0, 0, this ); for ( int i = 0; i < numCharDown && charToDraw <= drawEnd; i++ ) { for ( int j = 0; j < numCharAcross && charToDraw <= drawEnd; j++, charToDraw++ ) { int gridLocX = j * gridWidth + canvasInset_X; int gridLocY = i * gridHeight + canvasInset_Y; modeSpecificDrawChar( g2, charToDraw, gridLocX + gridWidth / 2, gridLocY + maxAscent ); //if ( !isPrinting ) { // g.setClip( gridLocX, gridLocY, gridWidth + 1, gridHeight + 1 ); // g.drawImage( backBuffer, 0, 0, this ); //} } } } else if ( textToUse == USER_TEXT ) { g2.drawRect( 0, 0, w - 1, h - 1 ); if ( !isPrinting ) g.drawImage( backBuffer, 0, 0, this ); for ( int i = drawStart; i <= drawEnd; i++ ) { int lineStartX = canvasInset_Y; int lineStartY = ( i - drawStart ) * gridHeight + maxAscent; modeSpecificDrawLine( g2, userText[i], lineStartX, lineStartY ); } } else { float xPos, yPos = (float) canvasInset_Y; g2.drawRect( 0, 0, w - 1, h - 1 ); if ( !isPrinting ) g.drawImage( backBuffer, 0, 0, this ); for ( int i = drawStart; i <= drawEnd; i++ ) { TextLayout oneLine = (TextLayout) lineBreakTLs.elementAt( i ); xPos = oneLine.isLeftToRight() ? canvasInset_X : ( (float) w - oneLine.getAdvance() - canvasInset_X ); float fmData[] = {0, oneLine.getAscent(), 0, oneLine.getDescent(), 0, oneLine.getLeading()}; if (g2Transform != NONE) { AffineTransform at = getAffineTransform(g2Transform); at.transform( fmData, 0, fmData, 0, 3); } //yPos += oneLine.getAscent(); yPos += fmData[1]; // ascent //oneLine.draw( g2, xPos, yPos ); tlDrawLine( g2, oneLine, xPos, yPos ); //yPos += oneLine.getDescent() + oneLine.getLeading(); yPos += fmData[3] + fmData[5]; // descent + leading } } if ( !isPrinting ) g.drawImage( backBuffer, 0, 0, this ); g2.dispose(); } /// Component paintComponent function... /// Draws/Refreshes canvas according to flag(s) set by other functions public void paintComponent( Graphics g ) { if ( updateBackBuffer ) { Dimension d = this.getSize(); isPrinting = false; try { drawText( g, d.width, d.height ); } catch ( CannotDrawException e ) { f2dt.fireChangeStatus( ERRORS[ e.id ], true ); super.paintComponent(g); return; } } else { /// Screen refresh g.drawImage( backBuffer, 0, 0, this ); } showingError = false; updateBackBuffer = false; } /// Printable interface function /// Component print function... public int print( Graphics g, PageFormat pf, int pageIndex ) { if ( pageIndex == 0 ) { /// Reset the last page index to max... lastPage = Integer.MAX_VALUE; currentlyShownChar = verticalBar.getValue() * numCharAcross; } if ( printMode == ONE_PAGE ) { if ( pageIndex > 0 ) return NO_SUCH_PAGE; } else { if ( pageIndex > lastPage ) return NO_SUCH_PAGE; } int pageWidth = (int) pf.getImageableWidth(); int pageHeight = (int) pf.getImageableHeight(); /// Back up metrics and other drawing info before printing modifies it int backupDrawStart = drawStart, backupDrawEnd = drawEnd; int backupNumCharAcross = numCharAcross, backupNumCharDown = numCharDown; Vector backupLineBreakTLs = null; if ( textToUse == FILE_TEXT ) backupLineBreakTLs = (Vector) lineBreakTLs.clone(); printPageNumber = pageIndex; isPrinting = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -