Discussions
Categories
- 197K All Categories
- 2.5K Data
- 546 Big Data Appliance
- 1.9K Data Science
- 450.8K Databases
- 221.9K General Database Discussions
- 3.8K Java and JavaScript in the Database
- 31 Multilingual Engine
- 552 MySQL Community Space
- 479 NoSQL Database
- 7.9K Oracle Database Express Edition (XE)
- 3.1K ORDS, SODA & JSON in the Database
- 555 SQLcl
- 4K SQL Developer Data Modeler
- 187.2K SQL & PL/SQL
- 21.4K SQL Developer
- 296.3K Development
- 17 Developer Projects
- 139 Programming Languages
- 293K Development Tools
- 110 DevOps
- 3.1K QA/Testing
- 646.1K Java
- 28 Java Learning Subscription
- 37K Database Connectivity
- 158 Java Community Process
- 105 Java 25
- 22.1K Java APIs
- 138.2K Java Development Tools
- 165.3K Java EE (Java Enterprise Edition)
- 19 Java Essentials
- 162 Java 8 Questions
- 86K Java Programming
- 81 Java Puzzle Ball
- 65.1K New To Java
- 1.7K Training / Learning / Certification
- 13.8K Java HotSpot Virtual Machine
- 94.3K Java SE
- 13.8K Java Security
- 205 Java User Groups
- 24 JavaScript - Nashorn
- Programs
- 468 LiveLabs
- 39 Workshops
- 10.2K Software
- 6.7K Berkeley DB Family
- 3.5K JHeadstart
- 5.7K Other Languages
- 2.3K Chinese
- 175 Deutsche Oracle Community
- 1.1K Español
- 1.9K Japanese
- 233 Portuguese
GlyphVector bounds and kerning, ligatures

843807
Member Posts: 46,582
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.
Edited by: slovelace on Jun 5, 2009 2:43 AM
Edited by: slovelace on Jun 5, 2009 4:11 PM
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
-
Hi,
You may replace:GlyphVector gv = font.createGlyphVector(frc, text);
with:char[] chars = text.toCharArray(); GlyphVector gv = font.layoutGlyphVector(frc, chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT);
Piet -
Thanks for the reply. I see that this works, but I can't say that my question, "IS THIS A BUG??", has been completely answered (did tick the option to give you the stars, though). Maybe this is just a documentation bug - here's the doc string for Font.createGlyphVector():
Creates a GlyphVector by mapping characters to glyphs one-to-one based on the Unicode cmap in this Font. This method does no other processing besides the mapping of glyphs to characters. This means that this method is not useful for some scripts, such as Arabic, Hebrew, Thai, and Indic, that require reordering, shaping, or ligature substitution.
And here's the opening one for layoutGlyphVector():
Returns a new GlyphVector object, performing full layout of the text if possible. Full layout is required for complex text, such as Arabic or Hindi. Support for different scripts depends on the font and implementation.
But I'm not using Arabic, Hebrew, Thai or Hindi. I'm dealing with English, which is to say Latin characters, in the usual way, though I am expecting "usual" to include kerning and ligatures. Okay, so maybe I should have spotted the phrase "ligature substitution" and thrown English into the list with Arabic, Hebrew, Thai, and Hindi. But what about kerning? Try typing the word "To" into any decent word processor (like the message window I'm typing into now) using any decent proportional font (any font smart enough to handle kerning - this excludes whatever Java is defaulting to on my system - is it Nimbus?) and you will see the "o" tucked part way under the arm of the "T". If this isn't done, the spacing looks horrible. I'm saying that kerning is routine, not a cause for setting the complexity flag. Or if for engineering reasons the complexity flag needs to be set, then the docs need to be changed.
So there's my rant. Thanks again for the solution. -
Yes, I think you are right when you spot an omission in the docs. It should state that full layout is needed not only for some languages, but for kerning as well.
BTW, the solution works also when you pass a flag parameter of zero. So, it's not the complexity flag itself that does the trick, it is the method that will do a full layout, in contrast to the createGlyphVector methods.
Thanks for the dukes. But they didn't arrive yet. Did you only tick a "answered" button or did you as well tick a "award" button? I don't exactly know how the mechanism works.
Piet -
Right. Dukes are on their way (this was my first post).
Steve
This discussion has been closed.