alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (StrikeMetrics.java)

This example Java source code file (StrikeMetrics.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awt, geometry, strikemetrics, string

The StrikeMetrics.java Java example source code

/*
 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * 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.
 */

package sun.font;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

/* These are font metrics: they are in user space, not device space.
 * Hence they are not truly "strike" metrics. However it is convenient to
 * treat them as such since we need to have a scaler context to obtain them
 * and also to cache them. The old implementation obtained a C++ strike object
 * that matched the Font TX + pt size only. It was wasteful of strike objects.
 * This new implementation still has separate StrikeMetrics for 2 fonts that
 * are really the same but are used in different device transforms, but at
 * least it doesn't create a whole new strike just to get the metrics for
 * a strike in a transformed graphics.
 * So these metrics do not take into account the device transform. They
 * are considered inherent properties of the font. Hence it may be that we
 * should use the device transform to obtain the most accurate metrics, but
 * typically 1.1 APIs do not provide for this. So some APIs may want to
 * ignore the dev. tx and others may want to use it, and then apply an
 * inverse transform. For now we ignore the dev. tx.
 * "Font" metrics are representative of a typical glyph in the font.
 * Generally speaking these values are the choice of the font designer and
 * are stored in the font, from which we retrieve the values. They do
 * not necessarily equate to the maximum bounds of all glyphs in the font.
 * Note that the ascent fields are typically a -ve value as we use a top-left
 * origin user space, and text is positioned relative to its baseline.
 */
public final class StrikeMetrics {

    public float ascentX;
    public float ascentY;
    public float descentX;
    public float descentY;
    public float baselineX;
    public float baselineY;
    public float leadingX;
    public float leadingY;
    public float maxAdvanceX;
    public float maxAdvanceY;


    /* The no-args constructor is used by CompositeStrike, which then
     * merges in the metrics of physical fonts.
     * The approach here is the same as earlier releases but it is flawed
     * take for example the following which ignores leading for simplicity.
     * Say we have a composite with an element asc=-9, dsc=2, and another with
     * asc=-7, dsc=3.  The merged font is (-9,3) for height of -(-9)+3=12.
     * Suppose this same font has been derived with a 180% rotation
     * Now its signs for ascent/descent are reversed. Its (9,-2) and (7,-3)
     * Its merged values are (using the code in this class) (7,-2) for
     * a height of -(7)+-2 = =-9!
     * We need to have a more intelligent merging algorithm,
     * which so far as I can see needs to apply an inverse of the font
     * tx, do its merging, and then reapply the font tx.
     * This wouldn't often be a problem as there rarely is a font TX, and
     * the tricky part is getting the information. Probably the no-args
     * constructor needs to pass a TX in to be applied to all merges.
     * CompositeStrike would be left with the problem of figuring out what
     * tx to use.
     * But at least for now we are probably no worse than 1.4 ...
     * REMIND: FIX THIS.
     */
    StrikeMetrics() {
        ascentX = ascentY = Integer.MAX_VALUE;
        descentX = descentY = leadingX = leadingY = Integer.MIN_VALUE;
        baselineX = baselineX = maxAdvanceX = maxAdvanceY = Integer.MIN_VALUE;
    }

    StrikeMetrics(float ax, float ay, float dx, float dy, float bx, float by,
                  float lx, float ly, float mx, float my) {
       ascentX = ax;
       ascentY = ay;
       descentX = dx;
       descentY = dy;
       baselineX = bx;
       baselineY = by;
       leadingX = lx;
       leadingY = ly;
       maxAdvanceX = mx;
       maxAdvanceY = my;
    }

    public float getAscent() {
        return -ascentY;
    }

    public float getDescent() {
        return descentY;
    }

    public float getLeading() {
        return leadingY;
    }

    public float getMaxAdvance() {
        return maxAdvanceX;
    }

    /*
     * Currently only used to merge together slot metrics to create
     * the metrics for a composite font.
     */
     void merge(StrikeMetrics other) {
         if (other == null) {
             return;
         }
         if (other.ascentX < ascentX) {
             ascentX = other.ascentX;
         }
         if (other.ascentY < ascentY) {
             ascentY = other.ascentY;
         }
         if (other.descentX > descentX) {
             descentX = other.descentX;
         }
         if (other.descentY > descentY) {
             descentY = other.descentY;
         }
         if (other.baselineX > baselineX) {
             baselineX = other.baselineX;
         }
         if (other.baselineY > baselineY) {
             baselineY = other.baselineY;
         }
         if (other.leadingX > leadingX) {
             leadingX = other.leadingX;
         }
         if (other.leadingY > leadingY) {
             leadingY = other.leadingY;
         }
         if (other.maxAdvanceX > maxAdvanceX) {
             maxAdvanceX = other.maxAdvanceX;
         }
         if (other.maxAdvanceY > maxAdvanceY) {
             maxAdvanceY = other.maxAdvanceY;
         }
    }

    /* Used to transform the values back into user space.
     * This is done ONCE by the strike so clients should not need
     * to worry about this
     */
    void convertToUserSpace(AffineTransform invTx) {
        Point2D.Float pt2D = new Point2D.Float();

        pt2D.x = ascentX; pt2D.y = ascentY;
        invTx.deltaTransform(pt2D, pt2D);
        ascentX = pt2D.x; ascentY = pt2D.y;

        pt2D.x = descentX; pt2D.y = descentY;
        invTx.deltaTransform(pt2D, pt2D);
        descentX = pt2D.x; descentY = pt2D.y;

        pt2D.x = baselineX; pt2D.y = baselineY;
        invTx.deltaTransform(pt2D, pt2D);
        baselineX = pt2D.x; baselineY = pt2D.y;

        pt2D.x = leadingX; pt2D.y = leadingY;
        invTx.deltaTransform(pt2D, pt2D);
        leadingX = pt2D.x; leadingY = pt2D.y;

        pt2D.x = maxAdvanceX; pt2D.y = maxAdvanceY;
        invTx.deltaTransform(pt2D, pt2D);
        maxAdvanceX = pt2D.x; maxAdvanceY = pt2D.y;
    }

    public String toString() {
        return "ascent:x="      + ascentX +     " y=" + ascentY +
               " descent:x="    + descentX +    " y=" + descentY +
               " baseline:x="   + baselineX +   " y=" + baselineY +
               " leading:x="    + leadingX +    " y=" + leadingY +
               " maxAdvance:x=" + maxAdvanceX + " y=" + maxAdvanceY;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java StrikeMetrics.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.