United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6684056 SUPERSCRIPT TextAttribute on font needs to trigger layout.
JDK-6684056 : SUPERSCRIPT TextAttribute on font needs to trigger layout.

Details
Type:
Bug
Submit Date:
2008-04-03
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
client-libs
OS:
generic
Sub-Component:
2d
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Backport:

Sub Tasks

Description
The program below draws a simple string under a rotation transform from
0->360 degrees, and offers options to select strike through, underline,
and superscript options.

When just the superscript option is shown it can be seen that under
rotations, the position of the text from drawString and TextLayout is not
in agreement. If its used in conjunction with either or both of the other
attributes there is no problem.

import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.AffineTransform;
import java.util.HashMap;

public class TBT extends Canvas implements Runnable {
    Checkbox strikethrough;
    Checkbox underline;
    Checkbox superscript;

    int angle;

    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Font fnt = new Font("Arial", Font.PLAIN, 20);
        fnt = fnt.deriveFont(60.0f);
        HashMap attrMap = new HashMap();
        if (strikethrough.getState()) {
            attrMap.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
        }
        if (underline.getState()) {
            attrMap.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        }
        if (superscript.getState()) {
            attrMap.put(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER);
        }
        fnt = fnt.deriveFont(attrMap);
        AffineTransform aff = AffineTransform.getRotateInstance(angle * Math.PI/180.0);
        fnt = fnt.deriveFont(aff);

        g2d.setFont(fnt);
        g2d.translate(200, 200);

        TextLayout tl = new TextLayout("Text", fnt, g2d.getFontRenderContext());        g2d.setColor(Color.yellow);
        g2d.fill(tl.getBounds());

        g2d.setColor(Color.blue);
        tl.draw(g2d,0f,0f);

        g2d.setColor(Color.black);
        g2d.drawString("Text", 0, 0);
    }

    public void start() {
        Thread t = new Thread(this);
        t.run();
    }
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                return;
            }
            angle += 1;
            repaint();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    public Panel getPanel() {
        Panel p = new Panel();
        p.add(strikethrough = makeCheckbox("strikethrough"));
        p.add(underline = makeCheckbox("underline"));
        p.add(superscript = makeCheckbox("superscript"));
        return p;
    }

    public Checkbox makeCheckbox(String label) {
        Checkbox cb = new Checkbox(label);
        cb.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                repaint();
            }
        });
        return cb;
    }

    public static void main(String argv[]) {
        Frame f = new Frame("Text bounds test");
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        TBT tbt = new TBT();
        f.add(tbt, BorderLayout.CENTER);
        f.add(tbt.getPanel(), BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        tbt.start();
    }
}

                                    

Comments
EVALUATION

All of these attributes should trigger layout (ie TextLayout.draw to
be internally used to implement drawString), but presently the superscript does not
on its own. Superscripting is presently implemented as a font transformation,
but drawString can't handle this properly under rotation.
And in any case if we were to provide proper font table driven superscripting
that would require layout.
                                     
2008-04-03



Hardware and Software, Engineered to Work Together