/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This class provides a summary of the glyph measurements for a Font
* and a set of hints that guide their display. It provides more metrics
* information for the Font than the java.awt.FontMetrics class. There
* is also some redundancy with that class.
* <p>
* The design metrics for a Font are obtained from Font.getDesignMetrics().
* The FontDesignMetrics object returned will be independent of the
* point size of the Font.
* Most users are familiar with the idea of using <i>point size</i> to
* specify the size of glyphs in a font. This point size defines a
* measurement between the baseline of one line to the baseline of the
* following line in a single spaced text document. The point size is
* based on <i>typographic points</i>, approximately 1/72 of an inch.
* <p>
* The Java2D API adopts the convention that one point is equivalent
* to one unit in user coordinates. When using a normalized transform
* for converting user space coordinates to device space coordinates (see
* GraphicsConfiguration.getDefaultTransform() and
* GraphicsConfiguration.getNormalizingTransform()), 72 user space units
* equal 1 inch in device space. In this case one point is 1/72 of an inch.
* <p>
* The FontDesignMetrics class expresses font metrics in terms of arbitrary
* <i>typographic units</i> (not points) chosen by the font supplier
* and used in the underlying platform font representations. These units are
* defined by dividing the em-square into a grid. The em-sqaure is the
* theoretical square whose dimensions are the full body height of the
* font. A typographic unit is the smallest measurable unit in the
* em-square. The number of units-per-em is determined by the font
* designer. The greater the units-per-em, the greater the precision
* in metrics. For example, Type 1 fonts divide the em-square into a
* 1000 x 1000 grid, while TrueType fonts typically use a 2048 x 2048
* grid. The scale of these units can be obtained by calling
* getUnitsPerEm().
* <p>
* Typographic units are relative -- their absolute size changes as the
* size of the of the em-square changes. An em-square is 9 points high
* in a 9-point font. Because typographic units are relative to the
* em-square, a given location on a glyph will have the same coordinates
* in typographic units regardless of the point size.
* <p>
* Converting typographic units to pixels requires computing pixels-per-em
* (ppem). This can be computed as:
* <pre>
ppem = device_resolution * (inches-per-point) * pointSize
* </pre>
* In this case, ppem is equal to the point size on a 72 dpi monitor, so
* that an N point font displays N pixels high. In general,
* <pre>
pixel_units = typographic_units * (ppem / units_per_em)
* </pre>
* @see java.awt.Font
* @see java.awt.GraphicsConfiguration#getDefaultTransform
* @see java.awt.GraphicsConfiguration#getNormalizingTransform
*/
// height, ascent, descent, leading are reported to the client
// as an integer this value is added to the true fp value to
// obtain a value which is usually going to result in a round up
// to the next integer except for very marginal cases.
// These fields are all part of the old serialization representation
private float ascent;
private float descent;
private float leading;
private float maxAdvance;
private double[] matrix;
// End legacy serialization fields
private boolean isAntiAliased;
private boolean usesFractionalMetrics;
if (DEFAULT_FRC == null) {
if (GraphicsEnvironment.isHeadless()) {
tx = new AffineTransform();
} else {
}
}
return DEFAULT_FRC;
}
/* Strongly cache up to 5 most recently requested FontMetrics objects,
* and softly cache as many as GC allows. In practice this means we
* should keep references around until memory gets low.
* We key the cache either by a Font or a combination of the Font and
* and FRC. A lot of callers use only the font so although there's code
* duplication, we allow just a font to be a key implying a default FRC.
* Also we put the references on a queue so that if they do get nulled
* out we can clear the keys from the table.
*/
Disposer.addReference(this, this);
}
/* It is possible that since this reference object has been
* enqueued, that a new metrics has been put into the table
* for the same key value. So we'll test to see if the table maps
* to THIS reference. If its a new one, we'll leave it alone.
* It is possible that a new entry comes in after our test, but
* it is unlikely and if this were a problem we would need to
* synchronize all 'put' and 'remove' accesses to the cache which
* I would prefer not to do.
*/
public void dispose() {
}
}
}
private static class MetricsKey {
int hash;
MetricsKey() {
}
}
}
if (!(key instanceof MetricsKey)) {
return false;
}
return
}
public int hashCode() {
return hash;
}
/* Synchronize access to this on the class */
}
/* All accesses to a CHM do not in general need to be synchronized,
* as incomplete operations on another thread would just lead to
* harmless cache misses.
*/
private static final FontDesignMetrics[]
}
/* When using alternate composites, can't cache based just on
* the java.awt.Font. Since this is rarely used and we can still
* cache the physical fonts, its not a problem to just return a
* new instance in this case.
* Note that currently Swing native L&F composites are not handled
* by this code as they use the metrics of the physical anyway.
*/
if (fm.maybeUsingAlternateCompositeFonts() &&
}
FontDesignMetrics m = null;
KeyReference r;
/* There are 2 possible keys used to perform lookups in metricsCache.
* If the FRC is set to all defaults, we just use the font as the key.
* If the FRC is non-default in any way, we construct a hybrid key
* that combines the font and FRC.
*/
if (usefontkey) {
} else /* use hybrid key */ {
// NB synchronization is not needed here because of updates to
// the metrics cache but is needed for the shared key.
synchronized (MetricsKey.class) {
}
}
if (r != null) {
m = (FontDesignMetrics)r.get();
}
if (m == null) {
/* either there was no reference, or it was cleared. Need a new
* metrics instance. The key to use in the map is a new
* MetricsKey instance when we've determined the FRC is
* non-default. Its constructed from local vars so we are
* thread-safe - no need to worry about the shared key changing.
*/
if (usefontkey) {
} else /* use hybrid key */ {
}
}
/* Here's where we keep the recent metrics */
if (recentMetrics[i]==m) {
return m;
}
}
synchronized (recentMetrics) {
recentMetrics[recentIndex++] = m;
if (recentIndex == MAXRECENT) {
recentIndex = 0;
}
}
return m;
}
/*
* Constructs a new FontDesignMetrics object for the given Font.
* Its private to enable caching - call getMetrics() instead.
* @param font a Font object.
*/
this(font, getDefaultFrc());
}
/* private to enable caching - call getMetrics() instead. */
super(font);
matrix = new double[4];
initAdvCache();
}
private void initMatrixAndMetrics() {
devmatrix = new double[4];
}
private void initAdvCache() {
advCache = new float[256];
// 0 is a valid metric so force it to -1
for (int i = 0; i < 256; i++) {
advCache[i] = UNKNOWN_WIDTH;
}
}
if (serVersion != CURRENT_VERSION) {
frc = getDefaultFrc();
}
else {
}
// when deserialized, members are set to their default values for their type--
// not to the values assigned during initialization before the constructor
// body!
height = -1;
initAdvCache();
}
cache = new int[256];
for (int i=0; i < 256; i++) {
cache[i] = -1;
}
}
}
// Uses advCache to get character width
// It is incorrect to call this method for ch > 255
if (w == UNKNOWN_WIDTH) {
w = handleCharWidth(ch);
}
return w;
}
/* Override of FontMetrics.getFontRenderContext() */
return frc;
}
// default metrics for compatibility with legacy code
float w;
if (ch < 0x100) {
w = getLatinCharWidth(ch);
}
else {
w = handleCharWidth(ch);
}
return (int)(0.5 + w);
}
ch = 0xffff;
}
float w = handleCharWidth(ch);
return (int)(0.5 + w);
}
float width = 0;
if (font.hasLayoutAttributes()) {
/* TextLayout throws IAE for null, so throw NPE explicitly */
throw new NullPointerException("str is null");
}
return 0;
}
} else {
for (int i=0; i < length; i++) {
if (ch < 0x100) {
break;
} else {
}
}
}
return (int) (0.5 + width);
}
float width = 0;
if (font.hasLayoutAttributes()) {
if (len == 0) {
return 0;
}
} else {
/* Explicit test needed to satisfy superclass spec */
if (len < 0) {
}
if (ch < 0x100) {
break;
} else {
}
}
}
return (int) (0.5 + width);
}
/**
* Gets the advance widths of the first 256 characters in the
* <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* character's baseline. Note that the advance of a
* <code>String</code> is not necessarily the sum of the advances
* of its characters.
* @return an array storing the advance widths of the
* characters in the <code>Font</code>
* described by this <code>FontMetrics</code> object.
*/
// More efficient than base class implementation - reuses existing cache
public int[] getWidths() {
int[] widths = new int[256];
if (w == UNKNOWN_WIDTH) {
}
}
return widths;
}
public int getMaxAdvance() {
return (int)(0.99f + this.maxAdvance);
}
/*
* Returns the typographic ascent of the font. This is the maximum distance
* glyphs in this font extend above the base line (measured in typographic
* units).
*/
public int getAscent() {
return (int)(roundingUpValue + this.ascent);
}
/*
* Returns the typographic descent of the font. This is the maximum distance
* glyphs in this font extend below the base line.
*/
public int getDescent() {
return (int)(roundingUpValue + this.descent);
}
public int getLeading() {
// nb this ensures the sum of the results of the public methods
// for leading, ascent & descent sum to height.
// if the calculations in any other methods change this needs
// to be changed too.
// the 0.95 value used here and in the other methods allows some
// tiny fraction of leeway before rouding up. A higher value (0.99)
// caused some excessive rounding up.
return
(int)(roundingUpValue + descent);
}
// height is calculated as the sum of two separately rounded up values
// because typically clients use ascent to determine the y location to
// pass to drawString etc and we need to ensure that the height has enough
// space below the baseline to fully contain any descender.
public int getHeight() {
if (height < 0) {
}
return height;
}
}