Re: Rendering a font
- From: "SPG" <steve.nospoo.goodsell@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 07 Jun 2005 10:57:42 GMT
"SPG" <steve.nospoo.goodsell@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:7rVoe.46088$G8.15249@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> 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
>
>
>
Burgers
Under
My
Pillow
Any takers?
.
- References:
- Rendering a font
- From: SPG
- Rendering a font
- Prev by Date: Re: To listen to clicking on hyperlink in HTML in JLabel
- Next by Date: copy-paste in an applet, SwingSet
- Previous by thread: Rendering a font
- Next by thread: JTabbedPane with Icon
- Index(es):
Relevant Pages
|
Loading