Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

GlyphVector bounds and kerning, ligatures

843807Jun 4 2009 — edited Jun 11 2009
IS THIS A BUG?? Shouldn't GlyphVector report positions/bounds for glyphs which reflect kerning and ligatures, i.e., shouldn't it yield metrics which correspond to what is actually rendered by Graphics2D.drawString() or TextLayout.draw()? If not, what does provide this service? Below is a little app which will throw up a frame showing a string rendered in black, the GlyphVector's logicalBounds in yellow fill, and the logicalBounds of each glyph in red. You can see the bounding rectangles creep ahead as kerns and ligatures are encountered. I had to pick a font that actually does kerning and ligatures, DejaVu Sans, because on my system (JDK1.6-u13 on Ubuntu 9.04) the default fonts do not.
package examples;

import java.util.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import static java.awt.font.TextAttribute.*;
import javax.swing.*;


public class GlyphVectorBounds {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel p = new XPanel();
        p.setBackground(Color.WHITE);
        p.setOpaque(true);
        f.setContentPane(p);
        f.setSize(750, 150);
        f.setVisible(true);
    }

    static class XPanel extends JPanel {
        String text = "Tiffany's Terrific Toffee Taffy";
        Font baseFont = new Font("DejaVu Sans", Font.PLAIN, 48);
        Map attr= new HashMap();
        {
            attr.put(KERNING, KERNING_ON);
            attr.put(LIGATURES, LIGATURES_ON);
        }
        AffineTransform trans = AffineTransform.getTranslateInstance(20, 70);

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setTransform(trans);
            Font font = baseFont.deriveFont(attr);
            g2.setFont(font);
            FontRenderContext frc = g2.getFontRenderContext();
            GlyphVector gv = font.createGlyphVector(frc, text);
            Rectangle2D vb = gv.getLogicalBounds();
            g2.setColor(Color.YELLOW);
            g2.fill(vb);
            g2.setColor(Color.RED);
            for (int i=0; i<gv.getNumGlyphs(); i++) {
                Shape gb = gv.getGlyphLogicalBounds(i);
                g2.draw(gb);
            }
            g2.setColor(Color.BLACK);
            g2.drawString(text, 0, 0);
        }
    }

}
Edited by: slovelace on Jun 5, 2009 12:06 AM

Edited by: slovelace on Jun 5, 2009 2:43 AM

Edited by: slovelace on Jun 5, 2009 4:11 PM

Comments

Processing
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jul 9 2009
Added on Jun 4 2009
4 comments
655 views