I'm trying to draw a string (i.e. "$29.95"), where the dollar sign is
superior (aligned with the top of the price). This is similar to
superscript and that would probably be acceptable also. As far as I can
tell, setting TextAttribute.SUPERSCRIPT=TextAttribute.SUPERSCRIPT_SUPER
doesn't work (in jdk1.3).
To accomplish this, I decided to get the shape of the "$" and use the
ShapeGraphicAttribute which allows me to set the alignment for the shape
(relative to the string it is attached to). As you can see in the
attached code, I set GraphicAttribute.TOP_ALIGNMENT with the hopes of
aligning the shape to the top of the rest of the string.
first problem is that this seems to be a bit high. It may be lined up
with the max ascent, rather than the glyph visual bounds for the string.
second problem is that when a scale transform is set in the
FontRenderContext (which I use to match preview to print res output),
the alignment doesn't follow the change in font size! In fact, it seems
like it aligns with the unscaled font.

I have a clunky workaround that gives decent results, but is this
something I should file as a bug report?

Don't try this in 1.4 since that scaling I use doesn't work there. I did
file a bug for this regression problem, but still under review.

Your report has been assigned an internal review ID of: 138490 <--- for the sun 
folks...


Thanks in advance for the input....

    David

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.GraphicAttribute;
import java.awt.font.ShapeGraphicAttribute;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.text.AttributedString;
import java.util.Map;
import java.util.HashMap;

import javax.swing.JPanel;
import javax.swing.JFrame;

public class TestStringAlign extends JPanel {
        Map fontAttrs;
        Map fontAttrs2;

        public TestStringAlign() {
                fontAttrs = new HashMap();
                fontAttrs.put(TextAttribute.FAMILY, "Arial");
                fontAttrs.put(TextAttribute.SIZE, new Float(50));
                fontAttrs2 = new HashMap();
                fontAttrs2.put(TextAttribute.FAMILY, "Arial");
                fontAttrs2.put(TextAttribute.SIZE, new Float(21));
        }

        public void paint(Graphics g) {
                g.setColor(Color.black);

                // this draws the string at normal size
                AttributedString attrStr = new AttributedString("$29.95", fontAttrs);
                FontRenderContext frc = new FontRenderContext(null, true, true);
                //attrStr.addAttributes(fontAttrs2, 0, 1);
                GlyphVector vect = new Font(fontAttrs2).createGlyphVector(frc, "$");
                ShapeGraphicAttribute sga = new ShapeGraphicAttribute(
                                        vect.getOutline(), 
GraphicAttribute.TOP_ALIGNMENT, false);
                attrStr.addAttribute(TextAttribute.CHAR_REPLACEMENT, sga, 0, 1);
                TextLayout tl = new TextLayout(attrStr.getIterator(), frc);
                tl.draw((Graphics2D)g, 25, 100);

                // this draws the string 50% smaller
                AffineTransform trans = AffineTransform.getScaleInstance(0.5, 0.5);
                frc = new FontRenderContext(trans, true, true);
                vect = new Font(fontAttrs2).createGlyphVector(frc, "$");
                sga = new ShapeGraphicAttribute(
                                        vect.getOutline(), 
GraphicAttribute.TOP_ALIGNMENT, false);
                attrStr.addAttribute(TextAttribute.CHAR_REPLACEMENT, sga, 0, 1);
                tl = new TextLayout(attrStr.getIterator(), frc);
                tl.draw((Graphics2D)g, 25, 200);

                // this draws the string 200% larger
                trans = AffineTransform.getScaleInstance(2.0, 2.0);
                frc = new FontRenderContext(trans, true, true);
                vect = new Font(fontAttrs2).createGlyphVector(frc, "$");
                sga = new ShapeGraphicAttribute(
                                        vect.getOutline(), 
GraphicAttribute.TOP_ALIGNMENT, false);
                attrStr.addAttribute(TextAttribute.CHAR_REPLACEMENT, sga, 0, 1);
                tl = new TextLayout(attrStr.getIterator(), frc);
                tl.draw((Graphics2D)g, 25, 350);
        }

        public static void main(String [] args) {
                JFrame f = new JFrame("Font Scale Tester");
                f.setSize(400, 400);
                f.setContentPane(new TestStringAlign());
                f.addWindowListener(new WindowAdapter() {
                                public void windowClosing(WindowEvent e) { 
System.exit(0); }
                        });
                f.setVisible(true);
        }
}

Reply via email to