Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / June 2005

Tip: Looking for answers? Try searching our database.

Rendering a font

Thread view: 
SPG - 06 Jun 2005 11:18 GMT
Hi,

I have an app that is trying to render a set of strings onto a panel, but
the strings must fillthe entire screen (Therefore I must strech the fonts
etc).

I have to support the MS JVM for this, so I have made two classes, one for
Java2D, and one for AWT 1.1.

Anyway, I am trying to get the cleanest looking rendering on the Java2D side
of things, but seem to be missing something as the image looks to be missing
something still..

The jist of things are as follows:

1. Get the bounds of the panel.
2. Determine the scale from old to new size
3. Derive a new font based on the new scaling
4. Create an image which will fit the strings onto exactly using the new
font metrics to derive size
5. Scale the image to fit the dimensions of the panel

Now, This seems a bit convoluted I know, but I have to fill the screen right
up, regardless of the shape and size! (Users huh?). Simply rescaling the
font is not good enough because you can only scale in steps, the previous
step may be too small, and the next step may be too big...

Anyway, here is a bit of sample code, I wonder if there are better rendering
options I could be using?

Steve

<SNIP>
package com.spg.terminal;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;

public class TestCanvas extends Canvas{

   private String[] _dataSet;
   private int _maxRows;
   private String _sampleString;
   private Font _originalFont;
   private double _scaleXFactor;
   private double _scaleYFactor;
   private int _scaledWidth;
   private int _scaledHeight;
   private int _scaledRowHeight;
   private Font _scaledFont;

   private Rectangle _currentBounds;

   public TestCanvas() {
       super();
       super.addComponentListener(new ComponentListener() {
           public void componentHidden(ComponentEvent e) {}

           public void componentMoved(ComponentEvent e) {}

           public void componentResized(ComponentEvent e) {
               rescale(getGraphics(),  getBounds());
           }
           public void componentShown(ComponentEvent e) {
               rescale(getGraphics(),  getBounds());
           }
       });
   }

   public static void main(String[] args) {
       String[] data = new String[25];
       String[] data2 = new String[25];
       String temp = new String();
       for(int i=0; i < 80; i++){
           if( i % 7 == 0){
               temp+="|";
           }else{
               temp += (i % 10);
           }
       }
       for( int i=0; i < data.length; i++){
           data[i] = new String(temp);
           data2[i] = new String(temp);
       }

       JFrame frame = new JFrame("Test Terminal");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       Canvas canvas2d = create2dCanvas();
       frame.getContentPane().add(canvas2d);
       frame.setBounds(100,100, 800,600);
       frame.show();
   }

   private static Canvas create2dCanvas(){
       TestCanvas canvas = new TestCanvas();
       canvas.setBackground(Color.black);
       canvas.setForeground(Color.green);
       canvas.initialize(25, 80);
       return canvas;

   }

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//Public methods

   public void initialize(int maxRows, int maxCols){
       _originalFont = createOriginalFont();
       _scaleXFactor = 1.0d;
       _scaleYFactor = 1.0d;
       _maxRows = maxRows;

       //Initialise the Data Set to empty strings
       _dataSet = new String[maxRows];
       String temp = new String();
       _sampleString = new String();
       for(int i=0; i < maxCols; i++){
           temp+= (i%10);
           _sampleString+="X";
       }
       for(int i=0; i < _dataSet.length; i++){
           _dataSet[i] = new String(temp);
       }
   }

   public void paint(Graphics g){
       Rectangle bounds = this.getBounds();
       //Check that the current bounds have not changed/
       //If so, do a rescale before painting
       if( _currentBounds == null || !_currentBounds.equals(bounds) ){
           rescale(g, bounds);
           _currentBounds = bounds;
       }

       g.setColor(getBackground());
       g.fillRect(0, 0, bounds.width, bounds.height);

       Image img = getDrawingImage(_scaledWidth, _scaledHeight);
       Graphics g2 = img.getGraphics();
       g2.setFont(_scaledFont);
       FontMetrics fm = g2.getFontMetrics();

       g2.setColor(Color.black);
       g2.fillRect(0, 0, _scaledWidth, _scaledHeight);

       g2.setColor(getForeground());
       int y = 0;
       int maxDecent = fm.getDescent();

       setRenderingProperties(g2);
       //Draw each data line
       for (int i = 0; i < _dataSet.length; i++) {
           y += _scaledRowHeight;
           g2.drawString(_dataSet[i], 0, y-maxDecent);
       }

       Image scaledImg = getScaledImage(img, bounds.width, bounds.height);
       g.drawImage(scaledImg, 0, 0, null);
   }

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//Protected methods

   protected synchronized void rescale(Graphics g, Rectangle bounds){
       if( g==null){
           return;
       }
       g.setFont(_originalFont);
       FontMetrics fm = g.getFontMetrics();
       int maxStringWidth = getMaxStringLength(fm);
       int maxStringHeight = fm.getHeight()- fm.getDescent();
       int gridHeight = maxStringHeight  * _maxRows;

       //Now try and work out the scaling!!!
       _scaleXFactor = (double)bounds.width / (double)maxStringWidth;
       _scaleYFactor = (double)bounds.height / (double)gridHeight;

       //New Scaled Font
       Font f = g.getFont();
       if( f== null){
           f = _originalFont;
       }

       //Scale up the font till it is >= the bounds
       while(true){
           AffineTransform fontTransform = new AffineTransform();
           fontTransform.scale( _scaleXFactor, _scaleYFactor );

           //New Scaled Font
           _scaledFont = f.deriveFont(fontTransform);
           fm = g.getFontMetrics(_scaledFont);
           maxStringWidth = getMaxStringLength(fm);
           maxStringHeight = fm.getHeight()-fm.getDescent()    ;
           gridHeight = maxStringHeight * _maxRows;

           boolean bChanged = false;
           if( maxStringWidth < (bounds.width)){
               _scaleXFactor += 0.1;
               bChanged =true;
           }
           if( gridHeight < (bounds.height)){
               _scaleYFactor += 0.1;
               bChanged = true;
           }
           System.out.println("Width=" + maxStringWidth + "("+ bounds.width
+"), Height=" + gridHeight + "("+ bounds.height  +")");

           if( !bChanged){
               break;
           }
       }

       fm = g.getFontMetrics(_scaledFont);
       _scaledRowHeight = fm.getHeight() - fm.getDescent();
       _scaledHeight = _scaledRowHeight * _maxRows;
       _scaledWidth = getMaxStringLength(fm);

   }

   protected int getMaxStringLength(FontMetrics fm){
       int len = 0;
       for( int i=0; i < _dataSet.length; i++){
           int val = fm.stringWidth(_dataSet[i]);
           if( val > len){
               len = val;
           }
       }
       return len;
   }

   protected Font createOriginalFont(){
       return new Font("Courier", Font.PLAIN, 12);
   }

   protected Image getDrawingImage(int width, int height){
       Image img = this.createImage(width, height);
       Graphics2D g = (Graphics2D)img.getGraphics();
       setRenderingProperties(g);
       return img;
   }

   protected Image getScaledImage(Image imgToScale, int width, int height){
       return imgToScale.getScaledInstance(width, height,
Image.SCALE_DEFAULT);
   }

   protected void setRenderingProperties(Graphics g){
       Graphics2D g2d = (Graphics2D)g;
       g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                              RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
   }

}

</SNIP
SPG - 07 Jun 2005 11:57 GMT
> Hi,
>
[quoted text clipped - 256 lines]
>
> </SNIP

Burgers
Under
My
Pillow

Any takers?


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.