Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Font scaling using AffineTransform



Thanks for the comments, Greg. The most confusing thing about this to me is hearing that Apple has apparently known about this for almost two years; I don't understand why it hasn't been fixed.

I found a few more complexities...if you find offsets that work for one JComponent, they don't work for another one; here's a sample with JLabel and JButton; the button text looks ok, but the label text is shifted too far to the left:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class MacFontTest
{
    public static void main(String[] p_argv)
    {
        JFrame frame = new JFrame("test");
        frame.getContentPane().setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);

        Font f = new Font("SansSerif", Font.BOLD, 12);
        AffineTransform a;

        JLabel l1 = new JLabel("Hello, world");
        a = AffineTransform.getScaleInstance(1.0, 1.0);
        Font f1 = f.deriveFont(a);
        l1.setFont(f1);

        JLabel l2 = new JLabel("Hello, world");
        a = AffineTransform.getScaleInstance(2.0, 2.0);
        a.translate(-6.5,-13); // Why??????????
        Font f2 = f.deriveFont(a);
        l2.setFont(f2);

        JLabel l3 = new JLabel("Hello, world");
        Font f3 = new Font("SansSerif",Font.BOLD,24);
        l3.setFont(f3);

        JButton b1 = new JButton("Hello, world");
        b1.setFont(f1);

        JButton b2 = new JButton("Hello, world");
        b2.setFont(f2);

        JButton b3 = new JButton("Hello, world");
        b3.setFont(f3);

        frame.getContentPane().add(l1);
        frame.getContentPane().add(l2);
        frame.getContentPane().add(l3);
        frame.getContentPane().add(b1);
        frame.getContentPane().add(b2);
        frame.getContentPane().add(b3);
        frame.pack();
        frame.setSize(300,300);
        frame.show();
    }
}

On 19-Mar-05, at 12:09 PM, Greg Guerin wrote:

Jim Douglas
I can't work out any coherent rules for what translation to apply in any
situation, so this doesn't seem to be the basis for a workaround.

Great sample code. I love a puzzle on a dismal Saturday afternoon.

Playing with the code a little while, I discovered:
  a) the translation to apply is independent of the scaling.
  b) the translation is related to the nominal original point-size.

In your example, you had:
        Font f = new Font("SansSerif", Font.BOLD, 12);
        ....
        a.translate(-6.5,-13);

12 is the nominal original point size, and 13 is 12+1. The -6.5 is simply
-13/2, though in practice it works better to use 2.5, as in:
private void tweak( AffineTransform a, int nominal )
{
double ty = nominal + 1.0D;
double tx = ty / 2.5D;
a.translate( -tx, -ty );
}


This is only APPROXIMATE, but it works pretty well.  The tx calculation
still needs further divination.

I expanded your test case to also present a 3X nominal original size, using
both a scaled AffineTransform and literally multiplying the original size
by 3. At 3X scaled and an original size of 18, the tx is pretty far off
with /2.0, and better with /2.5 yet still imperfect.


I suppose one could do a curve fit with enough data points and derive even
better parameters.


Things I didn't try:
  1) Other fonts.
  2) Scale transforms less than unity.
  3) Rotation transforms.


The real puzzle is what kind of haywire calculation is going on in the
first place that it needs to translate by those amounts in order to correct
it. It seems like an elementary blunder that then cascades through the
rest of the calculations.


The one thing I can think of is that there's some original mistake in Y
that's based on the font's ascent or nominal point-size.  Since font
baseline (i.e. it's ascent height) is at coordinate 0,0, there's a
discernible "footprint" on the trail for that mistake.

The really weird one is why TX is TY/2.5, or whatever it turns out to be.
That one just seems wacko, because the X of a rendered glyph isn't offset
by ascent height.


Maybe there's less here than meets the eye, and I'm just reading imagined
patterns into clues.


Still, it looks like the beginnings of a workaround.

-- GG

_______________________________________________ Do not post admin requests to the list. They will be ignored. Java-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden
References: 
 >Re: Font scaling using AffineTransform (From: Greg Guerin <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.