summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java')
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java228
1 files changed, 228 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java
new file mode 100644
index 000000000..452456d13
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java
@@ -0,0 +1,228 @@
+/* GlyphMeasurer.java -- Helper for measuring TrueType glyphs.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.opentype.truetype;
+
+import java.awt.FontFormatException;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
+
+/**
+ * A class for measuring TrueType and OpenType glyphs.
+ *
+ * <p><b>Lack of Thread Safety:</b> Glyph measurers are intentionally
+ * <i>not</i> safe to access from multiple concurrent
+ * threads. Synchronization needs to be performed externally. Usually,
+ * the font has already obtained a lock before calling the scaler,
+ * which in turn calls the GlyphMeasurer. It would thus be wasteful to
+ * acquire additional locks for the GlyphMeasurer.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class GlyphMeasurer
+{
+ /**
+ * A view buffer that allows accessing the contents of the
+ * font&#x2019;s <code>hmtx</code> table as shorts.
+ */
+ private final ShortBuffer horizontalGlyphMetrics;
+
+
+ /**
+ * A view buffer that allows accessing the contents of the
+ * font&#x2019;s <code>vmtx</code> table as shorts.
+ */
+ private final ShortBuffer verticalGlyphMetrics;
+
+
+ private final int numLongHorizontalMetricsEntries;
+ private final int numLongVerticalMetricsEntries;
+
+ private final int horizontalAscent;
+ private final int verticalAscent;
+
+ private final int horizontalDescent;
+ private final int verticalDescent;
+
+ private final int horizontalLineGap;
+
+
+ /**
+ * Constructs a GlyphMeasurer from TrueType/OpenType font tables.
+ *
+ * @param hhea the <code>hhea</code> table, which contains
+ * information about horizontal metrics that is common to all
+ * glyphs.
+ *
+ * @param hmtx the <code>hmtx</code> table, which contains
+ * glyph-specific information about horizontal metrics.
+ *
+ * @param vhea the <code>vhea</code> table, which contains
+ * information about vertical metrics that is common to all
+ * glyphs. If a font does not provide such a table, pass
+ * <code>null</code>.
+ *
+ * @param vmtx the <code>vmtx</code> table, which contains
+ * glyph-specific information about vertical metrics. If a font
+ * does not provide such a table, pass <code>null</code>.
+ */
+ GlyphMeasurer(ByteBuffer hhea, ByteBuffer hmtx,
+ ByteBuffer vhea, ByteBuffer vmtx)
+ throws FontFormatException
+ {
+ if ((hhea.getInt(0) != 0x00010000) || (hhea.getInt(30) != 0))
+ throw new FontFormatException("unsupported hhea format");
+
+ horizontalAscent = hhea.getShort(4);
+ horizontalDescent = hhea.getShort(6);
+ horizontalLineGap = hhea.getShort(8);
+
+ numLongHorizontalMetricsEntries = hhea.getChar(34);
+ horizontalGlyphMetrics = hmtx.asShortBuffer();
+
+ if (vhea != null)
+ {
+ verticalAscent = vhea.getShort(4);
+ verticalDescent = vhea.getShort(6);
+ numLongVerticalMetricsEntries = vhea.getChar(34);
+ verticalGlyphMetrics = vmtx.asShortBuffer();
+ }
+ else
+ {
+ verticalAscent = /* advanceWidthMax */ hhea.getChar(10) / 2;
+ verticalDescent = -verticalAscent;
+ numLongVerticalMetricsEntries = 0;
+ verticalGlyphMetrics = null;
+ }
+ }
+
+
+ /**
+ * Returns the distance from the baseline to the highest ascender.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the maximal ascent, in font units.
+ */
+ public int getAscent(boolean horizontal)
+ {
+ return horizontal ? horizontalAscent : verticalAscent;
+ }
+
+
+ /**
+ * Returns the distance from the baseline to the lowest descender.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the maximal descent, in font units.
+ */
+ public int getDescent(boolean horizontal)
+ {
+ return horizontal ? horizontalDescent : verticalDescent;
+ }
+
+
+ /**
+ * Returns the typographic line gap.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the line gap, in font units.
+ */
+ public int getLineGap(boolean horizontal)
+ {
+ return horizontalLineGap;
+ }
+
+
+ /**
+ * Determines the advance width of a glyph, without considering
+ * hinting.
+ *
+ * @param glyphIndex the index of the glyph whose advance width is
+ * to be determined.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the advance width, in font units.
+ */
+ public int getAdvanceWidth(int glyphIndex, boolean horizontal)
+ {
+ if (!horizontal)
+ return 0;
+
+ glyphIndex = Math.min(glyphIndex,
+ numLongHorizontalMetricsEntries - 1);
+ return horizontalGlyphMetrics.get(glyphIndex << 1);
+ }
+
+
+ /**
+ * Determines the advance width of a glyph, without considering
+ * hinting.
+ *
+ * @param glyphIndex the index of the glyph whose advance width is
+ * to be determined.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the advance width, in font units.
+ */
+ public int getAdvanceHeight(int glyphIndex, boolean horizontal)
+ {
+ if (horizontal)
+ return 0;
+
+ /* If a font does not provide vertical glyph metrics, advance
+ * by the height of one horizontal line.
+ */
+ if (verticalGlyphMetrics == null)
+ return horizontalAscent - horizontalDescent + horizontalLineGap;
+
+ glyphIndex = Math.min(glyphIndex,
+ numLongVerticalMetricsEntries - 1);
+ return verticalGlyphMetrics.get(glyphIndex << 1);
+ }
+}