jdk/src/share/classes/sun/font/StandardGlyphVector.java
author prr
Mon, 30 Nov 2009 14:39:35 -0800
changeset 4358 0549f5b9abd1
parent 3928 be186a33df9b
child 5506 202f599c92aa
permissions -rw-r--r--
6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space. Reviewed-by: igor, dougfelt
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Graphics2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.Point;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import static java.awt.RenderingHints.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.Shape;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.font.FontRenderContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.font.GlyphMetrics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.font.GlyphJustificationInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.font.GlyphVector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.font.LineMetrics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.awt.font.TextAttribute;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.geom.AffineTransform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.awt.geom.GeneralPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.awt.geom.NoninvertibleTransformException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.geom.PathIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.geom.Point2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.awt.geom.Rectangle2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.lang.ref.SoftReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.text.CharacterIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import sun.awt.SunHints;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import sun.java2d.loops.FontInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * Standard implementation of GlyphVector used by Font, GlyphList, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * SunGraphics2D.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * The main issues involve the semantics of the various transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * (font, glyph, device) and their effect on rendering and metrics.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * Very, very unfortunately, the translation component of the font
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * transform affects where the text gets rendered.  It offsets the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * rendering origin.  None of the other metrics of the glyphvector
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * are affected, making them inconsistent with the rendering behavior.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * I think the translation component of the font would be better
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * interpreted as the translation component of a per-glyph transform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * but I don't know if this is possible to change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * After the font transform is applied, the glyph transform is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * applied.  This makes glyph transforms relative to font transforms,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * if the font transform changes, the glyph transform will have the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * same (relative) effect on the outline of the glyph.  The outline
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * and logical bounds are passed through the glyph transform before
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * being returned.  The glyph metrics ignore the glyph transform, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * provide the outline bounds and the advance vector of the glyph (the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * latter will be rotated if the font is rotated).  The default layout
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * places each glyph at the end of the advance vector of the previous
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * glyph, and since the glyph transform translates the advance vector,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * this means a glyph transform affects the positions of all
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * subsequent glyphs if defaultLayout is called after setting a glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * transform.  In the glyph info array, the bounds are the outline
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * bounds including the glyph transform, and the positions are as
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * computed, and the advances are the deltas between the positions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * (There's a bug in the logical bounds of a rotated glyph for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * composite fonts, it's not to spec (in 1.4.0, 1.4.1, 1.4.2).  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * problem is that the rotated composite doesn't handle the multiple
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * ascents and descents properly in both x and y.  You end up with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * a rotated advance vector but an unrotated ascent and descent.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * Finally, the whole thing is transformed by the device transform to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * position it on the page.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * Another bug: The glyph outline seems to ignore fractional point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * size information, but the images (and advances) don't ignore it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * Small fonts drawn at large magnification have odd advances when
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * fractional metrics is off-- that's because the advances depend on
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 * the frc.  When the frc is scaled appropriately, the advances are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * fine.  FM or a large frc (high numbers) make the advances right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 * The buffer aa flag doesn't affect rendering, the glyph vector
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 * renders as AA if aa is set in its frc, and as non-aa if aa is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 * set in its frc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * font rotation, baseline, vertical etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * Font rotation and baseline Line metrics should be measured along a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * unit vector pi/4 cc from the baseline vector.  For 'horizontal'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * fonts the baseline vector is the x vector passed through the font
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * transform (ignoring translation), for 'vertical' it is the y
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * vector.  This definition makes ascent, descent, etc independent of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 * shear, so shearing can be used to simulate italic. This means no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 * fonts have 'negative ascents' or 'zero ascents' etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 * Having a coordinate system with orthogonal axes where one is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 * parallel to the baseline means we could use rectangles and interpret
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
 * them in terms of this coordinate system.  Unfortunately there
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 * is support for rotated fonts in the jdk already so maintaining
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 * the semantics of existing code (getlogical bounds, etc) might
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * be difficult.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 * A font transform transforms both the baseline and all the glyphs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * in the font, so it does not rotate the glyph w.r.t the baseline.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * If you do want to rotate individual glyphs, you need to apply a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 * glyph transform.  If performDefaultLayout is called after this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
 * the transformed glyph advances will affect the glyph positions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
 * useful additions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
 * - select vertical metrics - glyphs are rotated pi/4 cc and vertical
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
 * metrics are used to align them to the baseline.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
 * - define baseline for font (glyph rotation not linked to baseline)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 * - define extra space (delta between each glyph along baseline)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * - define offset (delta from 'true' baseline, impacts ascent and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * descent as these are still computed from true basline and pinned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 * to zero, used in superscript).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
public class StandardGlyphVector extends GlyphVector {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    private Font font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    private FontRenderContext frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    private int[] glyphs; // always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    private int[] userGlyphs; // used to return glyphs to the client.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    private float[] positions; // only if not default advances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    private int[] charIndices;  // only if interesting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    private int flags; // indicates whether positions, charIndices is interesting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    private static final int UNINITIALIZED_FLAGS = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    // transforms information
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    private GlyphTransformInfo gti; // information about per-glyph transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    // !!! can we get rid of any of this extra stuff?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    private AffineTransform ftx;   // font transform without translation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    private AffineTransform dtx;   // device transform used for strike calculations, no translation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    private AffineTransform invdtx; // inverse of dtx or null if dtx is identity
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    private AffineTransform frctx; // font render context transform, wish we could just share it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    private Font2D font2D;         // basic strike-independent stuff
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    private SoftReference fsref;   // font strike reference for glyphs with no per-glyph transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    /////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    // Constructors and Factory methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    /////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    public StandardGlyphVector(Font font, String str, FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        init(font, str.toCharArray(), 0, str.length(), frc, UNINITIALIZED_FLAGS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    public StandardGlyphVector(Font font, char[] text, FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        init(font, text, 0, text.length, frc, UNINITIALIZED_FLAGS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    public StandardGlyphVector(Font font, char[] text, int start, int count,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                               FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        init(font, text, start, count, frc, UNINITIALIZED_FLAGS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    private float getTracking(Font font) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        if (font.hasLayoutAttributes()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            AttributeValues values = ((AttributeMap)font.getAttributes()).getValues();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            return values.getTracking();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     // used by GlyphLayout to construct a glyphvector
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    public StandardGlyphVector(Font font, FontRenderContext frc, int[] glyphs, float[] positions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                               int[] indices, int flags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        initGlyphVector(font, frc, glyphs, positions, indices, flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        // this code should go into layout
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        float track = getTracking(font);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        if (track != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            track *= font.getSize2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            Point2D.Float trackPt = new Point2D.Float(track, 0); // advance delta
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            if (font.isTransformed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                AffineTransform at = font.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                at.deltaTransform(trackPt, trackPt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            // how do we know its a base glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            // for now, it is if the natural advance of the glyph is non-zero
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2
diff changeset
   200
            Font2D f2d = FontUtilities.getFont2D(font);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            FontStrike strike = f2d.getStrike(font, frc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            float[] deltas = { trackPt.x, trackPt.y };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            for (int j = 0; j < deltas.length; ++j) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                float inc = deltas[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                if (inc != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                    float delta = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                    for (int i = j, n = 0; n < glyphs.length; i += 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                        if (strike.getGlyphAdvance(glyphs[n++]) != 0) { // might be an inadequate test
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                            positions[i] += delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                            delta += inc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                    positions[positions.length-2+j] += delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    public void initGlyphVector(Font font, FontRenderContext frc, int[] glyphs, float[] positions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                                int[] indices, int flags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        this.font = font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        this.frc = frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        this.glyphs = glyphs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        this.userGlyphs = glyphs; // no need to check
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        this.positions = positions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        this.charIndices = indices;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        this.flags = flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        initFontData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    public StandardGlyphVector(Font font, CharacterIterator iter, FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        int offset = iter.getBeginIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        char[] text = new char [iter.getEndIndex() - offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        for(char c = iter.first();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            c != CharacterIterator.DONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            c = iter.next()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            text[iter.getIndex() - offset] = c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        init(font, text, 0, text.length, frc, UNINITIALIZED_FLAGS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    public StandardGlyphVector(Font font, int[] glyphs, FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        // !!! find callers of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        // should be able to fully init from raw data, e.g. charmap, flags too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        this.font = font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        this.frc = frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        this.flags = UNINITIALIZED_FLAGS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        initFontData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        this.userGlyphs = glyphs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        this.glyphs = getValidatedGlyphs(this.userGlyphs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    /* This is called from the rendering loop. FontInfo is supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * because a GV caches a strike and glyph images suitable for its FRC.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * LCD text isn't currently supported on all surfaces, in which case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * standard AA must be used. This is most likely to occur when LCD text
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * is requested and the surface is some non-standard type or hardward
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * surface for which there are no accelerated loops.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * We can detect this as being AA=="ON" in the FontInfo and AA!="ON"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * and AA!="GASP" in the FRC - since this only occurs for LCD text we don't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * need to check any more precisely what value is in the FRC.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    public static StandardGlyphVector getStandardGV(GlyphVector gv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                                                    FontInfo info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        if (info.aaHint == SunHints.INTVAL_TEXT_ANTIALIAS_ON) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            Object aaHint = gv.getFontRenderContext().getAntiAliasingHint();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            if (aaHint != VALUE_TEXT_ANTIALIAS_ON &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                aaHint != VALUE_TEXT_ANTIALIAS_GASP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                /* We need to create a new GV with AA==ON for rendering */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                FontRenderContext frc = gv.getFontRenderContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                frc = new FontRenderContext(frc.getTransform(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                                            VALUE_TEXT_ANTIALIAS_ON,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                                            frc.getFractionalMetricsHint());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                return new StandardGlyphVector(gv, frc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        if (gv instanceof StandardGlyphVector) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            return (StandardGlyphVector)gv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        return new StandardGlyphVector(gv, gv.getFontRenderContext());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    /////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    // GlyphVector API
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    /////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    public Font getFont() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        return this.font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    public FontRenderContext getFontRenderContext() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        return this.frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    public void performDefaultLayout() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        positions = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        if (getTracking(font) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            clearFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    public int getNumGlyphs() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        return glyphs.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    public int getGlyphCode(int glyphIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        return userGlyphs[glyphIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    public int[] getGlyphCodes(int start, int count, int[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        if (count < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            throw new IllegalArgumentException("count = " + count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        if (start < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            throw new IndexOutOfBoundsException("start = " + start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (start > glyphs.length - count) { // watch out for overflow if index + count overlarge
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            throw new IndexOutOfBoundsException("start + count = " + (start + count));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            result = new int[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        // if arraycopy were faster, we wouldn't code this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        for (int i = 0; i < count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            result[i] = userGlyphs[i + start];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    public int getGlyphCharIndex(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (ix < 0 && ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            throw new IndexOutOfBoundsException("" + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        if (charIndices == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            if ((getLayoutFlags() & FLAG_RUN_RTL) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                return glyphs.length - 1 - ix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            return ix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        return charIndices[ix];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    public int[] getGlyphCharIndices(int start, int count, int[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        if (start < 0 || count < 0 || (count > glyphs.length - start)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            throw new IndexOutOfBoundsException("" + start + ", " + count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            result = new int[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        if (charIndices == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            if ((getLayoutFlags() & FLAG_RUN_RTL) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                for (int i = 0, n = glyphs.length - 1 - start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                     i < count; ++i, --n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                         result[i] = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                for (int i = 0, n = start; i < count; ++i, ++n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                    result[i] = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            for (int i = 0; i < count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                result[i] = charIndices[i + start];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    // !!! not cached, assume TextLayout will cache if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    // !!! reexamine for per-glyph-transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    // !!! revisit for text-on-a-path, vertical
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    public Rectangle2D getLogicalBounds() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        setFRCTX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        LineMetrics lm = font.getLineMetrics("", frc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        float minX, minY, maxX, maxY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        // horiz only for now...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        minX = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        minY = -lm.getAscent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        maxX = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        maxY = lm.getDescent() + lm.getLeading();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        if (glyphs.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            maxX = positions[positions.length - 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    // !!! not cached, assume TextLayout will cache if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    public Rectangle2D getVisualBounds() {
4358
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   399
        Rectangle2D result = null;
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   400
        for (int i = 0; i < glyphs.length; ++i) {
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   401
            Rectangle2D glyphVB = getGlyphVisualBounds(i).getBounds2D();
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   402
            if (!glyphVB.isEmpty()) {
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   403
                if (result == null) {
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   404
                    result = glyphVB;
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   405
                } else {
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   406
                    Rectangle2D.union(result, glyphVB, result);
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   407
                }
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   408
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
4358
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   410
        if (result == null) {
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
   411
            result = new Rectangle2D.Float(0, 0, 0, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    // !!! not cached, assume TextLayout will cache if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    // !!! fontStrike needs a method for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    public Rectangle getPixelBounds(FontRenderContext renderFRC, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
      return getGlyphsPixelBounds(renderFRC, x, y, 0, glyphs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    public Shape getOutline() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        return getGlyphsOutline(0, glyphs.length, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    public Shape getOutline(float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        return getGlyphsOutline(0, glyphs.length, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    // relative to gv origin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    public Shape getGlyphOutline(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        return getGlyphsOutline(ix, 1, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    // relative to gv origin offset by x, y
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    public Shape getGlyphOutline(int ix, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        return getGlyphsOutline(ix, 1, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    public Point2D getGlyphPosition(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        ix *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        return new Point2D.Float(positions[ix], positions[ix + 1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    public void setGlyphPosition(int ix, Point2D pos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        int ix2 = ix << 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        positions[ix2] = (float)pos.getX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        positions[ix2 + 1] = (float)pos.getY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        clearCaches(ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    public AffineTransform getGlyphTransform(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        if (ix < 0 || ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            throw new IndexOutOfBoundsException("ix = " + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        if (gti != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            return gti.getGlyphTransform(ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        return null; // spec'd as returning null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    public void setGlyphTransform(int ix, AffineTransform newTX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        if (ix < 0 || ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            throw new IndexOutOfBoundsException("ix = " + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        if (gti == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            if (newTX == null || newTX.isIdentity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            gti = new GlyphTransformInfo(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        gti.setGlyphTransform(ix, newTX); // sets flags
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        if (gti.transformCount() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            gti = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    public int getLayoutFlags() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        if (flags == UNINITIALIZED_FLAGS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            flags = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            if (charIndices != null && glyphs.length > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                boolean ltr = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                boolean rtl = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                int rtlix = charIndices.length; // rtl index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                for (int i = 0; i < charIndices.length && (ltr || rtl); ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                    int cx = charIndices[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                    ltr = ltr && (cx == i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                    rtl = rtl && (cx == --rtlix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                if (rtl) flags |= FLAG_RUN_RTL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                if (!rtl && !ltr) flags |= FLAG_COMPLEX_GLYPHS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        return flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    public float[] getGlyphPositions(int start, int count, float[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        if (count < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            throw new IllegalArgumentException("count = " + count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        if (start < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            throw new IndexOutOfBoundsException("start = " + start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        if (start > glyphs.length + 1 - count) { // watch for overflow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            throw new IndexOutOfBoundsException("start + count = " + (start + count));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        return internalGetGlyphPositions(start, count, 0, result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    public Shape getGlyphLogicalBounds(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        if (ix < 0 || ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            throw new IndexOutOfBoundsException("ix = " + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        Shape[] lbcache;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        if (lbcacheRef == null || (lbcache = (Shape[])lbcacheRef.get()) == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            lbcache = new Shape[glyphs.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            lbcacheRef = new SoftReference(lbcache);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        Shape result = lbcache[ix];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            setFRCTX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            // !!! ought to return a rectangle2d for simple cases, though the following works for all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            // get the position, the tx offset, and the x,y advance and x,y adl.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            // shape is the box formed by adv (width) and adl (height) offset by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            // the position plus the tx offset minus the ascent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            ADL adl = new ADL();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            GlyphStrike gs = getGlyphStrike(ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            gs.getADL(adl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            Point2D.Float adv = gs.strike.getGlyphMetrics(glyphs[ix]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            float wx = adv.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            float wy = adv.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            float hx = adl.descentX + adl.leadingX + adl.ascentX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            float hy = adl.descentY + adl.leadingY + adl.ascentY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            float x = positions[ix*2] + gs.dx - adl.ascentX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            float y = positions[ix*2+1] + gs.dy - adl.ascentY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            GeneralPath gp = new GeneralPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            gp.moveTo(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            gp.lineTo(x + wx, y + wy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            gp.lineTo(x + wx + hx, y + wy + hy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            gp.lineTo(x + hx, y + hy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            gp.closePath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            result = new DelegatingShape(gp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            lbcache[ix] = result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    private SoftReference lbcacheRef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    public Shape getGlyphVisualBounds(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        if (ix < 0 || ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            throw new IndexOutOfBoundsException("ix = " + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        Shape[] vbcache;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        if (vbcacheRef == null || (vbcache = (Shape[])vbcacheRef.get()) == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            vbcache = new Shape[glyphs.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            vbcacheRef = new SoftReference(vbcache);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        Shape result = vbcache[ix];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            result = new DelegatingShape(getGlyphOutlineBounds(ix));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            vbcache[ix] = result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    private SoftReference vbcacheRef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    public Rectangle getGlyphPixelBounds(int index, FontRenderContext renderFRC, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
      return getGlyphsPixelBounds(renderFRC, x, y, index, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    public GlyphMetrics getGlyphMetrics(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        if (ix < 0 || ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            throw new IndexOutOfBoundsException("ix = " + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        Rectangle2D vb = getGlyphVisualBounds(ix).getBounds2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        Point2D pt = getGlyphPosition(ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        vb.setRect(vb.getMinX() - pt.getX(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                   vb.getMinY() - pt.getY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                   vb.getWidth(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                   vb.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        Point2D.Float adv =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            getGlyphStrike(ix).strike.getGlyphMetrics(glyphs[ix]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        GlyphMetrics gm = new GlyphMetrics(true, adv.x, adv.y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                                           vb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                                           GlyphMetrics.STANDARD);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        return gm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    public GlyphJustificationInfo getGlyphJustificationInfo(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        if (ix < 0 || ix >= glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            throw new IndexOutOfBoundsException("ix = " + ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        // currently we don't have enough information to do this right.  should
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        // get info from the font and use real OT/GX justification.  Right now
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        // sun/font/ExtendedTextSourceLabel assigns one of three infos
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        // based on whether the char is kanji, space, or other.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    public boolean equals(GlyphVector rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        if (this == rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        if (rhs == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            StandardGlyphVector other = (StandardGlyphVector)rhs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            if (glyphs.length != other.glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            for (int i = 0; i < glyphs.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                if (glyphs[i] != other.glyphs[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
            if (!font.equals(other.font)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            if (!frc.equals(other.frc)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            if ((other.positions == null) != (positions == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                if (positions == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                    initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    other.initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            if (positions != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                for (int i = 0; i < positions.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                    if (positions[i] != other.positions[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            if (gti == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                return other.gti == null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                return gti.equals(other.gti);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        catch (ClassCastException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            // assume they are different simply by virtue of the class difference
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * As a concrete subclass of Object that implements equality, this must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * implement hashCode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        return font.hashCode() ^ glyphs.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * Since we implement equality comparisons for GlyphVector, we implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     * the inherited Object.equals(Object) as well.  GlyphVector should do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * this, and define two glyphvectors as not equal if the classes differ.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    public boolean equals(Object rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            return equals((GlyphVector)rhs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        catch (ClassCastException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
     * Sometimes I wish java had covariant return types...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    public StandardGlyphVector copy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        return (StandardGlyphVector)clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     * As a concrete subclass of GlyphVector, this must implement clone.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    public Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        // positions, gti are mutable so we have to clone them
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        // font2d can be shared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        // fsref is a cache and can be shared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            StandardGlyphVector result = (StandardGlyphVector)super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            result.clearCaches();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            if (positions != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                result.positions = (float[])positions.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            if (gti != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                result.gti = new GlyphTransformInfo(result, gti);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        catch (CloneNotSupportedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    //////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    // StandardGlyphVector new public methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    /////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
     * Set a multiple glyph positions at one time.  GlyphVector only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
     * provides API to set a single glyph at a time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    public void setGlyphPositions(float[] srcPositions, int srcStart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                                  int start, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        if (count < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            throw new IllegalArgumentException("count = " + count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        for (int i = start * 2, e = i + count * 2, p = srcStart; i < e; ++i, ++p) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
            positions[i] = srcPositions[p];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        clearCaches();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
     * Set all the glyph positions, including the 'after last glyph' position.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
     * The srcPositions array must be of length (numGlyphs + 1) * 2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    public void setGlyphPositions(float[] srcPositions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        int requiredLength = glyphs.length * 2 + 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        if (srcPositions.length != requiredLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            throw new IllegalArgumentException("srcPositions.length != " + requiredLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        positions = (float[])srcPositions.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        clearCaches();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     * This is a convenience overload that gets all the glyph positions, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     * is what you usually want to do if you're getting more than one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
     * !!! should I bother taking result parameter?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    public float[] getGlyphPositions(float[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        return internalGetGlyphPositions(0, glyphs.length + 1, 0, result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     * Get transform information for the requested range of glyphs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
     * If no glyphs have a transform, return null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     * If a glyph has no transform (or is the identity transform) its entry in the result array will be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     * If the passed-in result is null an array will be allocated for the caller.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     * Each transform instance in the result array will unique, and independent of the GlyphVector's transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    public AffineTransform[] getGlyphTransforms(int start, int count, AffineTransform[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        if (start < 0 || count < 0 || start + count > glyphs.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            throw new IllegalArgumentException("start: " + start + " count: " + count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        if (gti == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            result = new AffineTransform[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
        for (int i = 0; i < count; ++i, ++start) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            result[i] = gti.getGlyphTransform(start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
     * Convenience overload for getGlyphTransforms(int, int, AffineTransform[], int);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    public AffineTransform[] getGlyphTransforms() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        return getGlyphTransforms(0, glyphs.length, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     * Set a number of glyph transforms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     * Original transforms are unchanged.  The array may contain nulls, and also may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
     * contain multiple references to the same transform instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
    public void setGlyphTransforms(AffineTransform[] srcTransforms, int srcStart, int start, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        for (int i = start, e = start + count; i < e; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
            setGlyphTransform(i, srcTransforms[srcStart + i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
     * Convenience overload of setGlyphTransforms(AffineTransform[], int, int, int).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    public void setGlyphTransforms(AffineTransform[] srcTransforms) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
        setGlyphTransforms(srcTransforms, 0, 0, glyphs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
     * For each glyph return posx, posy, advx, advy, visx, visy, visw, vish.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    public float[] getGlyphInfo() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        setFRCTX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        float[] result = new float[glyphs.length * 8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        for (int i = 0, n = 0; i < glyphs.length; ++i, n += 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            float x = positions[i*2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            float y = positions[i*2+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
            result[n] = x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            result[n+1] = y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
            int glyphID = glyphs[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
            GlyphStrike s = getGlyphStrike(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
            Point2D.Float adv = s.strike.getGlyphMetrics(glyphID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            result[n+2] = adv.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            result[n+3] = adv.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            Rectangle2D vb = getGlyphVisualBounds(i).getBounds2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            result[n+4] = (float)(vb.getMinX());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            result[n+5] = (float)(vb.getMinY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            result[n+6] = (float)(vb.getWidth());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
            result[n+7] = (float)(vb.getHeight());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     * !!! not used currently, but might be by getPixelbounds?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
    public void pixellate(FontRenderContext renderFRC, Point2D loc, Point pxResult) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        if (renderFRC == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
            renderFRC = frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
        // it is a total pain that you have to copy the transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        AffineTransform at = renderFRC.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
        at.transform(loc, loc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
        pxResult.x = (int)loc.getX(); // but must not behave oddly around zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        pxResult.y = (int)loc.getY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        loc.setLocation(pxResult.x, pxResult.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
            at.inverseTransform(loc, loc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        catch (NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            throw new IllegalArgumentException("must be able to invert frc transform");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    //////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    // StandardGlyphVector package private methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    /////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    // used by glyphlist to determine if it needs to allocate/size positions array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    // gti always uses positions because the gtx might have translation.  We also
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    // need positions if the rendering dtx is different from the frctx.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    boolean needsPositions(double[] devTX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        return gti != null ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
            (getLayoutFlags() & FLAG_HAS_POSITION_ADJUSTMENTS) != 0 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
            !matchTX(devTX, frctx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    // used by glyphList to get strong refs to font strikes for duration of rendering call
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    // if devTX matches current devTX, we're ready to go
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    // if we don't have multiple transforms, we're already ok
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
    // !!! I'm not sure fontInfo works so well for glyphvector, since we have to be able to handle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
    // the multiple-strikes case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     * GlyphList calls this to set up its images data.  First it calls needsPositions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
     * passing the devTX, to see if it should provide us a positions array to fill.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     * It only doesn't need them if we're a simple glyph vector whose frctx matches the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
     * devtx.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
     * Then it calls setupGlyphImages.  If we need positions, we make sure we have our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
     * default positions based on the frctx first. Then we set the devTX, and use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
     * strikes based on it to generate the images.  Finally, we fill in the positions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
     * array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
     * If we have transforms, we delegate to gti.  It depends on our having first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
     * initialized the positions and devTX.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
    Object setupGlyphImages(long[] images, float[] positions, double[] devTX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        initPositions(); // FIRST ensure we have positions based on our frctx
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        setRenderTransform(devTX); // THEN make sure we are using the desired devTX
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
        if (gti != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
            return gti.setupGlyphImages(images, positions, dtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        GlyphStrike gs = getDefaultStrike();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        gs.strike.getGlyphImagePtrs(glyphs, images, glyphs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        if (positions != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            if (dtx.isIdentity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
                System.arraycopy(this.positions, 0, positions, 0, glyphs.length * 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
                dtx.transform(this.positions, 0, positions, 0, glyphs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        return gs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    //////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
    // StandardGlyphVector private methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
    /////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
    // We keep translation in our frctx since getPixelBounds uses it.  But
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
    // GlyphList pulls out the translation and applies it separately, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    // we strip it out when we set the dtx.  Basically nothing uses the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
    // translation except getPixelBounds.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    // called by needsPositions, setRenderTransform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
    private static boolean matchTX(double[] lhs, AffineTransform rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
            lhs[0] == rhs.getScaleX() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
            lhs[1] == rhs.getShearY() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            lhs[2] == rhs.getShearX() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
            lhs[3] == rhs.getScaleY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    // returns new tx if old one has translation, otherwise returns old one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    private static AffineTransform getNonTranslateTX(AffineTransform tx) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        if (tx.getTranslateX() != 0 || tx.getTranslateY() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
            tx = new AffineTransform(tx.getScaleX(), tx.getShearY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
                                     tx.getShearX(), tx.getScaleY(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
                                     0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        return tx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
    private static boolean equalNonTranslateTX(AffineTransform lhs, AffineTransform rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        return lhs.getScaleX() == rhs.getScaleX() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
            lhs.getShearY() == rhs.getShearY() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            lhs.getShearX() == rhs.getShearX() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
            lhs.getScaleY() == rhs.getScaleY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    // called by setupGlyphImages (after needsPositions, so redundant match check?)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    private void setRenderTransform(double[] devTX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
        assert(devTX.length == 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
        if (!matchTX(devTX, dtx)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
            resetDTX(new AffineTransform(devTX)); // no translation since devTX len == 4.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    // called by getGlyphsPixelBounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    private final void setDTX(AffineTransform tx) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        if (!equalNonTranslateTX(dtx, tx)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            resetDTX(getNonTranslateTX(tx));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    // called by most functions
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
    private final void setFRCTX() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        if (!equalNonTranslateTX(frctx, dtx)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
            resetDTX(getNonTranslateTX(frctx));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
     * Change the dtx for the strike refs we use.  Keeps a reference to the at.  At
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
     * must not contain translation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
     * Called by setRenderTransform, setDTX, initFontData.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    private final void resetDTX(AffineTransform at) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        fsref = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
        dtx = at;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        invdtx = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        if (!dtx.isIdentity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
                invdtx = dtx.createInverse();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
            catch (NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                // we needn't care for rendering
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        if (gti != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            gti.strikesRef = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
     * Utility used by getStandardGV.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
     * Constructs a StandardGlyphVector from a generic glyph vector.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
     * Do not call this from new contexts without considering the comment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
     * about "userGlyphs".
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
    private StandardGlyphVector(GlyphVector gv, FontRenderContext frc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
        this.font = gv.getFont();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
        this.frc = frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
        initFontData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
        int nGlyphs = gv.getNumGlyphs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
        this.userGlyphs = gv.getGlyphCodes(0, nGlyphs, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
        if (gv instanceof StandardGlyphVector) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            /* userGlyphs will be OK because this is a private constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
             * and the returned instance is used only for rendering.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
             * It's not constructable by user code, nor returned to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
             * application. So we know "userGlyphs" are valid as having
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
             * been either already validated or are the result of layout.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            this.glyphs = userGlyphs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
            this.glyphs = getValidatedGlyphs(this.userGlyphs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
        this.flags = gv.getLayoutFlags() & FLAG_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
        if ((flags & FLAG_HAS_POSITION_ADJUSTMENTS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
            this.positions = gv.getGlyphPositions(0, nGlyphs + 1, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
        if ((flags & FLAG_COMPLEX_GLYPHS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            this.charIndices = gv.getGlyphCharIndices(0, nGlyphs, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
        if ((flags & FLAG_HAS_TRANSFORMS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
            AffineTransform[] txs = new AffineTransform[nGlyphs]; // worst case
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            for (int i = 0; i < nGlyphs; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                txs[i] = gv.getGlyphTransform(i); // gv doesn't have getGlyphsTransforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            setGlyphTransforms(txs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
    /* Before asking the Font we see if the glyph code is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
     * FFFE or FFFF which are special values that we should be internally
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
     * ready to handle as meaning invisible glyphs. The Font would report
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
     * those as the missing glyph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
    int[] getValidatedGlyphs(int[] oglyphs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
        int len = oglyphs.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
        int[] vglyphs = new int[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
        for (int i=0; i<len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
            if (oglyphs[i] == 0xFFFE || oglyphs[i] == 0xFFFF) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                vglyphs[i] = oglyphs[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                vglyphs[i] = font2D.getValidatedGlyphCode(oglyphs[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
        return vglyphs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
    // utility used by constructors
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
    private void init(Font font, char[] text, int start, int count,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
                      FontRenderContext frc, int flags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
        if (start < 0 || count < 0 || start + count > text.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
            throw new ArrayIndexOutOfBoundsException("start or count out of bounds");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
        this.font = font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        this.frc = frc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
        this.flags = flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
        if (getTracking(font) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
            addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
        // !!! change mapper interface?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
        if (start != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
            char[] temp = new char[count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
            System.arraycopy(text, start, temp, 0, count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            text = temp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        initFontData(); // sets up font2D
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        // !!! no layout for now, should add checks
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
        // !!! need to support creating a StandardGlyphVector from a TextMeasurer's info...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
        glyphs = new int[count]; // hmmm
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        /* Glyphs obtained here are already validated by the font */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
        userGlyphs = glyphs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
        font2D.getMapper().charsToGlyphs(count, text, glyphs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
    private void initFontData() {
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2
diff changeset
  1126
        font2D = FontUtilities.getFont2D(font);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
        float s = font.getSize2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        if (font.isTransformed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
            ftx = font.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
            if (ftx.getTranslateX() != 0 || ftx.getTranslateY() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
            ftx.setTransform(ftx.getScaleX(), ftx.getShearY(), ftx.getShearX(), ftx.getScaleY(), 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
            ftx.scale(s, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            ftx = AffineTransform.getScaleInstance(s, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
        frctx = frc.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        resetDTX(getNonTranslateTX(frctx));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
     * Copy glyph position data into a result array starting at the indicated
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
     * offset in the array.  If the passed-in result array is null, a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
     * array will be allocated and returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
     * This is an internal method and does no extra argument checking.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
     * @param start the index of the first glyph to get
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
     * @param count the number of glyphs to get
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
     * @param offset the offset into result at which to put the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
     * @param result an array to hold the x,y positions
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
     * @return the modified position array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
    private float[] internalGetGlyphPositions(int start, int count, int offset, float[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
            result = new float[offset + count * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
        // System.arraycopy is slow for stuff like this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
        for (int i = offset, e = offset + count * 2, p = start * 2; i < e; ++i, ++p) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
            result[i] = positions[p];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
    private Rectangle2D getGlyphOutlineBounds(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
        setFRCTX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
        return getGlyphStrike(ix).getGlyphOutlineBounds(glyphs[ix], positions[ix*2], positions[ix*2+1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
     * Used by getOutline, getGlyphsOutline
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
    private Shape getGlyphsOutline(int start, int count, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        setFRCTX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
        initPositions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
        GeneralPath result = new GeneralPath(GeneralPath.WIND_NON_ZERO);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
        for (int i = start, e = start + count, n = start * 2; i < e; ++i, n += 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
            float px = x + positions[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
            float py = y + positions[n+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
            getGlyphStrike(i).appendGlyphOutline(glyphs[i], result, px, py);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
    private Rectangle getGlyphsPixelBounds(FontRenderContext frc, float x, float y, int start, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
        initPositions(); // FIRST ensure we have positions based on our frctx
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
        AffineTransform tx = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
        if (frc == null || frc.equals(this.frc)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
            tx = frctx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
            tx = frc.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
        setDTX(tx); // need to get the right strikes, but we use tx itself to translate the points
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
        if (gti != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            return gti.getGlyphsPixelBounds(tx, x, y, start, count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
        FontStrike fs = getDefaultStrike().strike;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
        Rectangle result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
        Rectangle r = new Rectangle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        Point2D.Float pt = new Point.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
        int n = start * 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
        while (--count >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
            pt.x = x + positions[n++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            pt.y = y + positions[n++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
            tx.transform(pt, pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
            fs.getGlyphImageBounds(glyphs[start++], pt, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
            if (!r.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                    result = new Rectangle(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                    result.add(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
        return result != null ? result : r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
    private void clearCaches(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
        if (lbcacheRef != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
            Shape[] lbcache = (Shape[])lbcacheRef.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
            if (lbcache != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                lbcache[ix] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
        if (vbcacheRef != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            Shape[] vbcache = (Shape[])vbcacheRef.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
            if (vbcache != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
                vbcache[ix] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
    private void clearCaches() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
        lbcacheRef = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
        vbcacheRef = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
    // internal use only for possible future extension
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
     * A flag used with getLayoutFlags that indicates whether this <code>GlyphVector</code> uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
     * a vertical baseline.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
    public static final int FLAG_USES_VERTICAL_BASELINE = 128;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
     * A flag used with getLayoutFlags that indicates whether this <code>GlyphVector</code> uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
     * vertical glyph metrics.  A <code>GlyphVector</code> can use vertical metrics on a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
     * horizontal line, or vice versa.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
    public static final int FLAG_USES_VERTICAL_METRICS = 256;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
     * A flag used with getLayoutFlags that indicates whether this <code>GlyphVector</code> uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
     * the 'alternate orientation.'  Glyphs have a default orientation given a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
     * particular baseline and metrics orientation, this is the orientation appropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
     * for left-to-right text.  For example, the letter 'A' can have four orientations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
     * with the point at 12, 3, 6, or 9 'o clock.  The following table shows where the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
     * point displays for different values of vertical baseline (vb), vertical
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
     * metrics (vm) and alternate orientation (fo):<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
     * <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
     * vb vm ao
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
     * -- -- --  --
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
     *  f  f  f  12   ^  horizontal metrics on horizontal lines
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
     *  f  f  t   6   v
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
     *  f  t  f   9   <  vertical metrics on horizontal lines
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
     *  f  t  t   3   >
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
     *  t  f  f   3   >  horizontal metrics on vertical lines
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
     *  t  f  t   9   <
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
     *  t  t  f  12   ^  vertical metrics on vertical lines
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
     *  t  t  t   6   v
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
     * </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
    public static final int FLAG_USES_ALTERNATE_ORIENTATION = 512;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
     * Ensure that the positions array exists and holds position data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
     * If the array is null, this allocates it and sets default positions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
    private void initPositions() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
        if (positions == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
            setFRCTX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
            positions = new float[glyphs.length * 2 + 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
            Point2D.Float trackPt = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
            float track = getTracking(font);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
            if (track != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
                track *= font.getSize2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
                trackPt = new Point2D.Float(track, 0); // advance delta
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
            Point2D.Float pt = new Point2D.Float(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
            if (font.isTransformed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                AffineTransform at = font.getTransform();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                at.transform(pt, pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                positions[0] = pt.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                positions[1] = pt.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                if (trackPt != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                    at.deltaTransform(trackPt, trackPt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
            for (int i = 0, n = 2; i < glyphs.length; ++i, n += 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                getGlyphStrike(i).addDefaultGlyphAdvance(glyphs[i], pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                if (trackPt != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
                    pt.x += trackPt.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
                    pt.y += trackPt.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
                positions[n] = pt.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
                positions[n+1] = pt.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
     * OR newFlags with existing flags.  First computes existing flags if needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
    private void addFlags(int newflags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
        flags = getLayoutFlags() | newflags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
     * AND the complement of clearedFlags with existing flags.  First computes existing flags if needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
    private void clearFlags(int clearedFlags) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
        flags = getLayoutFlags() & ~clearedFlags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
    // general utility methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
    // encapsulate the test to check whether we have per-glyph transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
    private GlyphStrike getGlyphStrike(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
        if (gti == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
            return getDefaultStrike();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
            return gti.getStrike(ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
    // encapsulate access to cached default glyph strike
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
    private GlyphStrike getDefaultStrike() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
        GlyphStrike gs = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
        if (fsref != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
            gs = (GlyphStrike)fsref.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
        if (gs == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
            gs = GlyphStrike.create(this, dtx, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
            fsref = new SoftReference(gs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
        return gs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
    /////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
    // Internal utility classes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
    /////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
    // !!! I have this as a separate class instead of just inside SGV,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
    // but I previously didn't bother.  Now I'm trying this again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
    // Probably still not worth it, but I'd like to keep sgv's small in the common case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
    static final class GlyphTransformInfo {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
        StandardGlyphVector sgv;  // reference back to glyph vector - yuck
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        int[] indices;            // index into unique strikes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
        double[] transforms;      // six doubles per unique transform, because AT is a pain to manipulate
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
        SoftReference strikesRef; // ref to unique strikes, one per transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
        boolean haveAllStrikes;   // true if the strike array has been filled by getStrikes().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
        // used when first setting a transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
        GlyphTransformInfo(StandardGlyphVector sgv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
            this.sgv = sgv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
        // used when cloning a glyph vector, need to set back link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        GlyphTransformInfo(StandardGlyphVector sgv, GlyphTransformInfo rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
            this.sgv = sgv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
            this.indices = rhs.indices == null ? null : (int[])rhs.indices.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
            this.transforms = rhs.transforms == null ? null : (double[])rhs.transforms.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
            this.strikesRef = null; // can't share cache, so rather than clone, we just null out
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        // used in sgv equality
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        public boolean equals(GlyphTransformInfo rhs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
            if (rhs == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
            if (rhs == this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
            if (this.indices.length != rhs.indices.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
            if (this.transforms.length != rhs.transforms.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
            // slow since we end up processing the same transforms multiple
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
            // times, but since transforms can be in any order, we either do
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
            // this or create a mapping.  Equality tests aren't common so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
            // leave it like this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
            for (int i = 0; i < this.indices.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
                int tix = this.indices[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
                int rix = rhs.indices[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
                if ((tix == 0) != (rix == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
                if (tix != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
                    tix *= 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                    rix *= 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                    for (int j = 6; j > 0; --j) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                        if (this.indices[--tix] != rhs.indices[--rix]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
        // implements sgv.setGlyphTransform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
        void setGlyphTransform(int glyphIndex, AffineTransform newTX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
            // we store all the glyph transforms as a double array, and for each glyph there
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
            // is an entry in the txIndices array indicating which transform to use.  0 means
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
            // there's no transform, 1 means use the first transform (the 6 doubles at offset
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
            // 0), 2 means use the second transform (the 6 doubles at offset 6), etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
            //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
            // Since this can be called multiple times, and since the number of transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
            // affects the time it takes to construct the glyphs, we try to keep the arrays as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            // compact as possible, by removing transforms that are no longer used, and reusing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
            // transforms where we already have them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
            double[] temp = new double[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
            boolean isIdentity = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
            if (newTX == null || newTX.isIdentity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
                // Fill in temp
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
                temp[0] = temp[3] = 1.0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                isIdentity = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
                newTX.getMatrix(temp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
            if (indices == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                if (isIdentity) { // no change
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                    return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
                indices = new int[sgv.glyphs.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
                indices[glyphIndex] = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
                transforms = temp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
                boolean addSlot = false; // assume we're not growing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
                int newIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
                if (isIdentity) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
                    newIndex = 0; // might shrink
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
                    addSlot = true; // assume no match
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
                    int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
                loop:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
                    for (i = 0; i < transforms.length; i += 6) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
                        for (int j = 0; j < 6; ++j) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
                            if (transforms[i + j] != temp[j]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                                continue loop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
                        addSlot = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
                    newIndex = i / 6 + 1; // if no match, end of list
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
                // if we're using the same transform, nothing to do
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
                int oldIndex = indices[glyphIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
                if (newIndex != oldIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
                    // see if we are removing last use of the old slot
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                    boolean removeSlot = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                    if (oldIndex != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                        removeSlot = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                        for (int i = 0; i < indices.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                            if (indices[i] == oldIndex && i != glyphIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
                                removeSlot = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
                    if (removeSlot && addSlot) { // reuse old slot with new transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
                        newIndex = oldIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
                        System.arraycopy(temp, 0, transforms, (newIndex - 1) * 6, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
                    } else if (removeSlot) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
                        if (transforms.length == 6) { // removing last one, so clear arrays
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
                            indices = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
                            transforms = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
                            sgv.clearCaches(glyphIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
                            sgv.clearFlags(FLAG_HAS_TRANSFORMS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
                            strikesRef = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
                            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                        double[] ttemp = new double[transforms.length - 6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
                        System.arraycopy(transforms, 0, ttemp, 0, (oldIndex - 1) * 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
                        System.arraycopy(transforms, oldIndex * 6, ttemp, (oldIndex - 1) * 6,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                                         transforms.length - oldIndex * 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                        transforms = ttemp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                        // clean up indices
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
                        for (int i = 0; i < indices.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
                            if (indices[i] > oldIndex) { // ignore == oldIndex, it's going away
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
                                indices[i] -= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
                        if (newIndex > oldIndex) { // don't forget to decrement this too if we need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
                            --newIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
                    } else if (addSlot) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                        double[] ttemp = new double[transforms.length + 6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
                        System.arraycopy(transforms, 0, ttemp, 0, transforms.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
                        System.arraycopy(temp, 0, ttemp, transforms.length, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
                        transforms = ttemp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
                    indices[glyphIndex] = newIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
            sgv.clearCaches(glyphIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
            sgv.addFlags(FLAG_HAS_TRANSFORMS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
            strikesRef = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
        // implements sgv.getGlyphTransform
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
        AffineTransform getGlyphTransform(int ix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
            int index = indices[ix];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
            if (index == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
            int x = (index - 1) * 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
            return new AffineTransform(transforms[x + 0],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
                                       transforms[x + 1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
                                       transforms[x + 2],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
                                       transforms[x + 3],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
                                       transforms[x + 4],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
                                       transforms[x + 5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
        int transformCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
            if (transforms == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
            return transforms.length / 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
         * The strike cache works like this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
         * -Each glyph is thought of as having a transform, usually identity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
         * -Each request for a strike is based on a device transform, either the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
         * one in the frc or the rendering transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
         * -For general info, strikes are held with soft references.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
         * -When rendering, strikes must be held with hard references for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
         * duration of the rendering call.  GlyphList will have to hold this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
         * info along with the image and position info, but toss the strike info
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
         * when done.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
         * -Build the strike cache as needed.  If the dev transform we want to use
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
         * has changed from the last time it is built, the cache is flushed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
         * the caller before these methods are called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
         * Use a tx that doesn't include translation components of dst tx.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
        Object setupGlyphImages(long[] images, float[] positions, AffineTransform tx) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
            int len = sgv.glyphs.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
            GlyphStrike[] sl = getAllStrikes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
            for (int i = 0; i < len; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
                GlyphStrike gs = sl[indices[i]];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
                int glyphID = sgv.glyphs[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
                images[i] = gs.strike.getGlyphImagePtr(glyphID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
                gs.getGlyphPosition(glyphID, i*2, sgv.positions, positions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
            tx.transform(positions, 0, positions, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
            return sl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
        Rectangle getGlyphsPixelBounds(AffineTransform tx, float x, float y, int start, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
            Rectangle result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
            Rectangle r = new Rectangle();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
            Point2D.Float pt = new Point.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
            int n = start * 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
            while (--count >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
                GlyphStrike gs = getStrike(start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
                pt.x = x + sgv.positions[n++] + gs.dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
                pt.y = y + sgv.positions[n++] + gs.dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
                tx.transform(pt, pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
                gs.strike.getGlyphImageBounds(sgv.glyphs[start++], pt, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
                if (!r.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
                    if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
                        result = new Rectangle(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
                        result.add(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
            return result != null ? result : r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
        GlyphStrike getStrike(int glyphIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
            if (indices != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
                GlyphStrike[] strikes = getStrikeArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
                return getStrikeAtIndex(strikes, indices[glyphIndex]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
            return sgv.getDefaultStrike();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
        private GlyphStrike[] getAllStrikes() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
            if (indices == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
            GlyphStrike[] strikes = getStrikeArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
            if (!haveAllStrikes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
                for (int i = 0; i < strikes.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                    getStrikeAtIndex(strikes, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
                haveAllStrikes = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
            return strikes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
        private GlyphStrike[] getStrikeArray() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
            GlyphStrike[] strikes = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
            if (strikesRef != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
                strikes = (GlyphStrike[])strikesRef.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
            if (strikes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
                haveAllStrikes = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
                strikes = new GlyphStrike[transformCount() + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
                strikesRef = new SoftReference(strikes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
            return strikes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
        private GlyphStrike getStrikeAtIndex(GlyphStrike[] strikes, int strikeIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
            GlyphStrike strike = strikes[strikeIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
            if (strike == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
                if (strikeIndex == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
                    strike = sgv.getDefaultStrike();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
                    int ix = (strikeIndex - 1) * 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
                    AffineTransform gtx = new AffineTransform(transforms[ix],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
                                                              transforms[ix+1],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
                                                              transforms[ix+2],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
                                                              transforms[ix+3],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
                                                              transforms[ix+4],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
                                                              transforms[ix+5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
                    strike = GlyphStrike.create(sgv, sgv.dtx, gtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
                strikes[strikeIndex] = strike;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
            return strike;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
    // This adjusts the metrics by the translation components of the glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
    // transform.  It is done here since the translation is not known by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
    // strike.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
    // It adjusts the position of the image and the advance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
    public static final class GlyphStrike {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
        StandardGlyphVector sgv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
        FontStrike strike; // hard reference
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
        float dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
        float dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
        static GlyphStrike create(StandardGlyphVector sgv, AffineTransform dtx, AffineTransform gtx) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
            float dx = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
            float dy = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
            AffineTransform tx = sgv.ftx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
            if (!dtx.isIdentity() || gtx != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
                tx = new AffineTransform(sgv.ftx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
                if (gtx != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
                    tx.preConcatenate(gtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
                    dx = (float)tx.getTranslateX(); // uses ftx then gtx to get translation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
                    dy = (float)tx.getTranslateY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
                if (!dtx.isIdentity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
                    tx.preConcatenate(dtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
            int ptSize = 1; // only matters for 'gasp' case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
            Object aaHint = sgv.frc.getAntiAliasingHint();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
            if (aaHint == VALUE_TEXT_ANTIALIAS_GASP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
                /* Must pass in the calculated point size for rendering.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
                 * If the glyph tx is anything other than identity or a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
                 *  simple translate, calculate the transformed point size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
                if (!tx.isIdentity() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
                    (tx.getType() & ~AffineTransform.TYPE_TRANSLATION) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
                    double shearx = tx.getShearX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
                    if (shearx != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
                        double scaley = tx.getScaleY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
                        ptSize =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
                            (int)Math.sqrt(shearx * shearx + scaley * scaley);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
                        ptSize = (int)(Math.abs(tx.getScaleY()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
            int aa = FontStrikeDesc.getAAHintIntVal(aaHint,sgv.font2D, ptSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
            int fm = FontStrikeDesc.getFMHintIntVal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
                (sgv.frc.getFractionalMetricsHint());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
            FontStrikeDesc desc = new FontStrikeDesc(dtx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
                                                     tx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
                                                     sgv.font.getStyle(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
                                                     aa, fm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
            FontStrike strike = sgv.font2D.getStrike(desc);  // !!! getStrike(desc, false)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
            return new GlyphStrike(sgv, strike, dx, dy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
        private GlyphStrike(StandardGlyphVector sgv, FontStrike strike, float dx, float dy) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
            this.sgv = sgv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
            this.strike = strike;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
            this.dx = dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
            this.dy = dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
        void getADL(ADL result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
            StrikeMetrics sm = strike.getFontMetrics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
            Point2D.Float delta = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
            if (sgv.font.isTransformed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
                delta = new Point2D.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
                delta.x = (float)sgv.font.getTransform().getTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
                delta.y = (float)sgv.font.getTransform().getTranslateY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
            result.ascentX = -sm.ascentX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
            result.ascentY = -sm.ascentY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
            result.descentX = sm.descentX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
            result.descentY = sm.descentY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
            result.leadingX = sm.leadingX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
            result.leadingY = sm.leadingY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
        void getGlyphPosition(int glyphID, int ix, float[] positions, float[] result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
            result[ix] = positions[ix] + dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
            ++ix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
            result[ix] = positions[ix] + dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
        void addDefaultGlyphAdvance(int glyphID, Point2D.Float result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
            // !!! change this API?  Creates unnecessary garbage.  Also the name doesn't quite fit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
            // strike.addGlyphAdvance(Point2D.Float adv);  // hey, whaddya know, matches my api :-)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
            Point2D.Float adv = strike.getGlyphMetrics(glyphID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
            result.x += adv.x + dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
            result.y += adv.y + dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
        Rectangle2D getGlyphOutlineBounds(int glyphID, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
            Rectangle2D result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
            if (sgv.invdtx == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
                result = new Rectangle2D.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
                result.setRect(strike.getGlyphOutlineBounds(glyphID)); // don't mutate cached rect
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
                GeneralPath gp = strike.getGlyphOutline(glyphID, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
                gp.transform(sgv.invdtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
                result = gp.getBounds2D();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
            }
4358
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1797
            /* Since x is the logical advance of the glyph to this point.
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1798
             * Because of the way that Rectangle.union is specified, this
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1799
             * means that subsequent unioning of a rect including that
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1800
             * will be affected, even if the glyph is empty. So skip such
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1801
             * cases. This alone isn't a complete solution since x==0
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1802
             * may also not be what is wanted. The code that does the
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1803
             * unioning also needs to be aware to ignore empty glyphs.
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1804
             */
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1805
            if (!result.isEmpty()) {
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1806
                result.setRect(result.getMinX() + x + dx,
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1807
                               result.getMinY() + y + dy,
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1808
                               result.getWidth(), result.getHeight());
0549f5b9abd1 6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
prr
parents: 3928
diff changeset
  1809
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
        void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
            // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
            GeneralPath gp = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
            if (sgv.invdtx == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
                gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
                gp = strike.getGlyphOutline(glyphID, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
                gp.transform(sgv.invdtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
                gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
            PathIterator iterator = gp.getPathIterator(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
            result.append(iterator, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1827
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
        return appendString(null).toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
    StringBuffer appendString(StringBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
        if (buf == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
            buf = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
            buf.append("SGV{font: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
            buf.append(font.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
            buf.append(", frc: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
            buf.append(frc.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
            buf.append(", glyphs: (");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
            buf.append(glyphs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
            buf.append(")[");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
            for (int i = 0; i < glyphs.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
                if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
                    buf.append(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
                buf.append(Integer.toHexString(glyphs[i]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
            buf.append("]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
            if (positions != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
                buf.append(", positions: (");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
                buf.append(positions.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
                buf.append(")[");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
                for (int i = 0; i < positions.length; i += 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
                    if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
                        buf.append(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
                    buf.append(positions[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
                    buf.append("@");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
                    buf.append(positions[i+1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
                buf.append("]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
            if (charIndices != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
                buf.append(", indices: (");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
                buf.append(charIndices.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
                buf.append(")[");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
                for (int i = 0; i < charIndices.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
                    if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
                        buf.append(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
                    buf.append(charIndices[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
                buf.append("]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
            buf.append(", flags:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
            if (getLayoutFlags() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
                buf.append(" default");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
                if ((flags & FLAG_HAS_TRANSFORMS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
                    buf.append(" tx");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
                if ((flags & FLAG_HAS_POSITION_ADJUSTMENTS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
                    buf.append(" pos");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
                if ((flags & FLAG_RUN_RTL) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
                    buf.append(" rtl");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
                if ((flags & FLAG_COMPLEX_GLYPHS) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
                    buf.append(" complex");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
        catch(Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
            buf.append(" " + e.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
        buf.append("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
        return buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
    static class ADL {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
        public float ascentX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
        public float ascentY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
        public float descentX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
        public float descentY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
        public float leadingX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
        public float leadingY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
        public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
            return toStringBuffer(null).toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
        protected StringBuffer toStringBuffer(StringBuffer result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
            if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
                result = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
            result.append("ax: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
            result.append(ascentX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
            result.append(" ay: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
            result.append(ascentY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1923
            result.append(" dx: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
            result.append(descentX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
            result.append(" dy: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
            result.append(descentY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1927
            result.append(" lx: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
            result.append(leadingX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
            result.append(" ly: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
            result.append(leadingY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1935
}