Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / awt / font / opentype / truetype / TrueTypeScaler.java
blobe4d7309cb55013487a88d4471878c9b1dd619a14
1 /* TrueTypeScaler.java -- Font scaler for TrueType outlines.
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.java.awt.font.opentype.truetype;
40 import gnu.java.awt.font.opentype.Scaler;
42 import java.awt.FontFormatException;
43 import java.awt.geom.AffineTransform;
44 import java.awt.geom.GeneralPath;
45 import java.awt.geom.Point2D;
46 import java.nio.ByteBuffer;
49 /**
50 * A scaler for fonts whose outlines are described in the TrueType
51 * format.
53 * <p><b>Lack of Thread Safety:</b> Font scalers are intentionally
54 * <i>not</i> safe to access from multiple concurrent threads.
55 * Synchronization needs to be performed externally. Usually, the font
56 * that uses this scaler already has obtained a lock before calling
57 * the scaler.
59 * @author Sascha Brawer (brawer@dandelis.ch)
61 public final class TrueTypeScaler
62 extends Scaler
64 /**
65 * The TrueType or OpenType table that contains the glyph outlines.
67 private ByteBuffer glyfTable;
70 /**
71 * A helper object for loading glyph outlines.
73 private GlyphLoader glyphLoader;
76 /**
77 * A helper object for measuring the advance width and height of a
78 * glyph.
80 private final GlyphMeasurer glyphMeasurer;
82 private final Zone glyphZone;
85 /**
86 * The number of units per em. A typical value is 2048, but some
87 * font use other numbers as well.
89 private int unitsPerEm;
92 /**
93 * Constructs a new TrueTypeScaler.
95 * @param unitsPerEm the number of font units per em. This value can
96 * be retrieved from the font&#x2019;s <code>head</code> table.
98 * @param maxp the <code>maxp</code> table of the font, which
99 * contains various constants needed for setting up the virtual
100 * machine that interprets TrueType bytecodes.
102 * @param controlValueTable the <code>cvt</code> table of the font,
103 * which contains the initial values of the control value table.
105 * @param fpgm the <code>fpgm</code> table of the font, which
106 * contains a font program that is executed exactly once. The
107 * purpose of the font program is to define functions and to patch
108 * the interpreter.
110 * @param locaFormat the format of the <code>loca</code> table. The
111 * value must be 0 for two-byte offsets, or 1 for four-byte
112 * offsets. TrueType and OpenType fonts indicate the format in the
113 * <code>indexToLoc</code> field of the <a href=
114 * "http://partners.adobe.com/asn/tech/type/opentype/head.html"
115 * >font header</a>.
117 * @param loca the <code>loca</code> table of the font, which
118 * contains for each glyph the offset of its outline data
119 * in <code>glyf</code>.
121 * @param glyf the <code>glyf</code> table of the font, which
122 * contains the outline data for all glyphs in the font.
124 * @param preProgram the <code>prep</code> table of the font, which
125 * contains a program that is executed whenever the point size or
126 * the device transform have changed. This program is called
127 * pre-program because it gets executed before the instructions of
128 * the individual glyphs. If the font does not contain a
129 * pre-program, pass <code>null</code>.
131 * @throws FontFormatException if <code>format</code> is neither 0
132 * nor 1.
134 public TrueTypeScaler(int unitsPerEm,
135 ByteBuffer hhea,
136 ByteBuffer htmx,
137 ByteBuffer vhea,
138 ByteBuffer vtmx,
139 ByteBuffer maxp,
140 ByteBuffer controlValueTable,
141 ByteBuffer fpgm,
142 int locaFormat, ByteBuffer loca,
143 ByteBuffer glyf,
144 ByteBuffer preProgram)
145 throws FontFormatException
147 int maxContours, maxPoints;
148 VirtualMachine vm;
150 maxContours = Math.max(/* maxContours */ (int) maxp.getChar(8),
151 /* maxCompositeContours */ (int) maxp.getChar(12))
152 + /* fix for some broken fonts */ 8;
153 maxPoints = Math.max(/* maxPoints */ (int) maxp.getChar(6),
154 /* maxCompositePoints */ (int) maxp.getChar(10))
155 + /* fix for some broken fonts */ 12;
158 glyphZone = new Zone(maxPoints + /* four phantom points */ 4);
159 this.glyfTable = glyf;
160 vm = new VirtualMachine(unitsPerEm, maxp,
161 controlValueTable, fpgm,
162 preProgram);
164 GlyphLocator locator = GlyphLocator.forTable(locaFormat, loca, glyf);
165 glyphMeasurer = new GlyphMeasurer(hhea, htmx, vhea, vtmx);
166 glyphLoader = new GlyphLoader(locator, vm, unitsPerEm,
167 maxContours, maxPoints,
168 glyphMeasurer);
170 this.unitsPerEm = unitsPerEm;
175 * Retrieves the scaled outline of a glyph, adjusting control points
176 * to the raster grid if necessary.
178 * @param glyphIndex the glyph number whose outline is retrieved.
180 * @param pointSize the point size for the glyph.
182 * @param deviceTransform an affine transformation for the device.
184 * @param antialias whether or not the rasterizer will perform
185 * anti-aliasing on the returned path.
187 * @param fractionalMetrics <code>false</code> for adjusting glyph
188 * positions to the raster grid of device space.
190 public GeneralPath getOutline(int glyphIndex,
191 float pointSize,
192 AffineTransform deviceTransform,
193 boolean antialias,
194 boolean fractionalMetrics)
196 glyphLoader.loadGlyph(glyphIndex, pointSize, deviceTransform,
197 antialias, glyphZone);
198 return glyphZone.getPath();
203 * Determines the advance width and height for a glyph.
205 * @param glyphIndex the glyph whose advance width and height is to
206 * be determined.
208 * @param pointSize the point size of the font.
210 * @param transform a transform that is applied in addition to
211 * scaling to the specified point size. This is often used for
212 * scaling according to the device resolution. Those who lack any
213 * aesthetic sense may also use the transform to slant or stretch
214 * glyphs.
216 * @param antialias <code>true</code> for anti-aliased rendering,
217 * <code>false</code> for normal rendering. For hinted fonts,
218 * this parameter may indeed affect the result.
220 * @param fractionalMetrics <code>true</code> for fractional metrics,
221 * <code>false</code> for rounding the result to a pixel boundary.
223 * @param horizontal <code>true</code> for horizontal line layout,
224 * <code>false</code> for vertical line layout.
226 * @param advance a point whose <code>x</code> and <code>y</code>
227 * fields will hold the advance in each direction. It is possible
228 * that both values are non-zero, for example if
229 * <code>transform</code> is a rotation, or in the case of Urdu
230 * fonts.
232 public void getAdvance(int glyphIndex,
233 float pointSize,
234 AffineTransform transform,
235 boolean antialias,
236 boolean fractionalMetrics,
237 boolean horizontal,
238 Point2D advance)
240 double x, y;
241 double scaleFactor = (double) pointSize / unitsPerEm;
243 /* FIXME: Should grid-fit if needed. Also, use cache if present
244 * in the font.
246 advance.setLocation(
247 scaleFactor * glyphMeasurer.getAdvanceWidth(glyphIndex, horizontal),
248 scaleFactor * glyphMeasurer.getAdvanceHeight(glyphIndex, horizontal));
250 transform.transform(advance, advance);
255 * Scales a value from font units to pixels, given the point size
256 * and the transform.
258 * @param pointSize the point size of the font.
260 * @param transform a transform that is applied in addition to
261 * scaling to the specified point size. This is often used for
262 * scaling according to the device resolution.
264 * @param fractionalMetrics <code>true</code> for fractional
265 * metrics, <code>false</code> for rounding the result to a pixel
266 * boundary.
268 * @param horizontal <code>true</code> if the <code>funits</code>
269 * value is along the x axis, <code>false</code> if it is along the
270 * y axis.
272 private float scaleFromFUnits(int funits,
273 float pointSize,
274 AffineTransform transform,
275 boolean fractionalMetrics,
276 boolean horizontal)
278 double s;
280 s = (double) pointSize / unitsPerEm;
281 if (transform != null)
282 s *= horizontal ? transform.getScaleY() : transform.getScaleX();
283 s *= funits;
284 if (!fractionalMetrics)
285 s = Math.round(s);
286 return (float) s;
291 * Determines the distance between the base line and the highest
292 * ascender.
294 * @param pointSize the point size of the font.
296 * @param transform a transform that is applied in addition to
297 * scaling to the specified point size. This is often used for
298 * scaling according to the device resolution. Those who lack any
299 * aesthetic sense may also use the transform to slant or stretch
300 * glyphs.
302 * @param antialias <code>true</code> for anti-aliased rendering,
303 * <code>false</code> for normal rendering. For hinted fonts,
304 * this parameter may indeed affect the result.
306 * @param fractionalMetrics <code>true</code> for fractional metrics,
307 * <code>false</code> for rounding the result to a pixel boundary.
309 * @param horizontal <code>true</code> for horizontal line layout,
310 * <code>false</code> for vertical line layout.
312 * @return the ascent, which usually is a positive number.
314 public float getAscent(float pointSize,
315 AffineTransform transform,
316 boolean antialias,
317 boolean fractionalMetrics,
318 boolean horizontal)
320 /* Note that the ascent is orthogonal to the direction of line
321 * layout: If the line direction is horizontal, the measurement of
322 * ascent is along the vertical axis, and vice versa.
324 return scaleFromFUnits(glyphMeasurer.getAscent(horizontal),
325 pointSize,
326 transform,
327 fractionalMetrics,
328 /* reverse */ !horizontal);
333 * Determines the distance between the base line and the lowest
334 * descender.
336 * @param pointSize the point size of the font.
338 * @param transform a transform that is applied in addition to
339 * scaling to the specified point size. This is often used for
340 * scaling according to the device resolution. Those who lack any
341 * aesthetic sense may also use the transform to slant or stretch
342 * glyphs.
344 * @param antialiased <code>true</code> for anti-aliased rendering,
345 * <code>false</code> for normal rendering. For hinted fonts,
346 * this parameter may indeed affect the result.
348 * @param fractionalMetrics <code>true</code> for fractional metrics,
349 * <code>false</code> for rounding the result to a pixel boundary.
351 * @param horizontal <code>true</code> for horizontal line layout,
352 * <code>false</code> for vertical line layout.
354 * @return the descent, which usually is a nagative number.
356 public float getDescent(float pointSize,
357 AffineTransform transform,
358 boolean antialiased,
359 boolean fractionalMetrics,
360 boolean horizontal)
362 /* Note that the descent is orthogonal to the direction of line
363 * layout: If the line direction is horizontal, the measurement of
364 * descent is along the vertical axis, and vice versa.
366 return scaleFromFUnits(glyphMeasurer.getDescent(horizontal),
367 pointSize,
368 transform,
369 fractionalMetrics,
370 /* reverse */ !horizontal);