jdk/src/share/classes/sun/font/FileFontStrike.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 7940 7d20d72dd3b9
child 9759 90976a831a86
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 7940
diff changeset
     2
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2
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
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
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
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    23
 * questions.
2
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.lang.ref.SoftReference;
2393
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
    29
import java.lang.ref.WeakReference;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.Font;
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
    31
import java.awt.GraphicsEnvironment;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.geom.AffineTransform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.geom.GeneralPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.geom.NoninvertibleTransformException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.geom.Point2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.geom.Rectangle2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.concurrent.ConcurrentHashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import static sun.awt.SunHints.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
public class FileFontStrike extends PhysicalStrike {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    /* fffe and ffff are values we specially interpret as meaning
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
     * invisible glyphs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    static final int INVISIBLE_GLYPHS = 0x0fffe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private FileFont fileFont;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    /* REMIND: replace this scheme with one that installs a cache
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
     * instance of the appropriate type. It will require changes in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
     * FontStrikeDisposer and NativeStrike etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    private static final int UNINITIALISED = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private static final int INTARRAY      = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private static final int LONGARRAY     = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    private static final int SEGINTARRAY   = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private static final int SEGLONGARRAY  = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
    61
    private volatile int glyphCacheFormat = UNINITIALISED;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
7757
451411eff24b 6891551: Font rasterisation uses more heap than needed for some strikes.
prr
parents: 7750
diff changeset
    63
    /* segmented arrays are blocks of 32 */
451411eff24b 6891551: Font rasterisation uses more heap than needed for some strikes.
prr
parents: 7750
diff changeset
    64
    private static final int SEGSHIFT = 5;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private static final int SEGSIZE  = 1 << SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    private boolean segmentedCache;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    private int[][] segIntGlyphImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    private long[][] segLongGlyphImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    /* The "metrics" information requested by clients is usually nothing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     * more than the horizontal advance of the character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * In most cases this advance and other metrics information is stored
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     * in the glyph image cache.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     * But in some cases we do not automatically retrieve the glyph
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     * image when the advance is requested. In those cases we want to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     * cache the advances since this has been shown to be important for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * performance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * The segmented cache is used in cases when the single array
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * would be too large.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private float[] horizontalAdvances;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private float[][] segHorizontalAdvances;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    /* Outline bounds are used when printing and when drawing outlines
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     * to the screen. On balance the relative rarity of these cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     * and the fact that getting this requires generating a path at
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
     * the scaler level means that its probably OK to store these
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
     * in a Java-level hashmap as the trade-off between time and space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * Later can revisit whether to cache these at all, or elsewhere.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * Should also profile whether subsequent to getting the bounds, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * outline itself is also requested. The 1.4 implementation doesn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * cache outlines so you could generate the path twice - once to get
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * the bounds and again to return the outline to the client.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * If the two uses are coincident then also look into caching outlines.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * One simple optimisation is that we could store the last single
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     * outline retrieved. This assumes that bounds then outline will always
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * be retrieved for a glyph rather than retrieving bounds for all glyphs
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * then outlines for all glyphs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    ConcurrentHashMap<Integer, Rectangle2D.Float> boundsMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    SoftReference<ConcurrentHashMap<Integer, Point2D.Float>>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        glyphMetricsMapRef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    AffineTransform invertDevTx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    boolean useNatives;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    NativeStrike[] nativeStrikes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   110
    /* Used only for communication to native layer */
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   111
    private int intPtSize;
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   112
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   113
    /* Perform global initialisation needed for Windows native rasterizer */
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   114
    private static native boolean initNative();
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   115
    private static boolean isXPorLater = false;
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   116
    static {
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   117
        if (FontUtilities.isWindows && !FontUtilities.useT2K &&
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   118
            !GraphicsEnvironment.isHeadless()) {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   119
            isXPorLater = initNative();
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   120
        }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   121
    }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   122
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    FileFontStrike(FileFont fileFont, FontStrikeDesc desc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        super(fileFont, desc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        this.fileFont = fileFont;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        if (desc.style != fileFont.style) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
          /* If using algorithmic styling, the base values are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
           * boldness = 1.0, italic = 0.0. The superclass constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
           * initialises these.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
           */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            if ((desc.style & Font.ITALIC) == Font.ITALIC &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                (fileFont.style & Font.ITALIC) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                algoStyle = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                italic = 0.7f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            if ((desc.style & Font.BOLD) == Font.BOLD &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                ((fileFont.style & Font.BOLD) == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                algoStyle = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                boldness = 1.33f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        double[] matrix = new double[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        AffineTransform at = desc.glyphTx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        at.getMatrix(matrix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        if (!desc.devTx.isIdentity() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            desc.devTx.getType() != AffineTransform.TYPE_TRANSLATION) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                invertDevTx = desc.devTx.createInverse();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            } catch (NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
7940
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   154
        /* Amble fonts are better rendered unhinted although there's the
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   155
         * inevitable fuzziness that accompanies this due to no longer
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   156
         * snapping stems to the pixel grid. The exception is that in B&W
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   157
         * mode they are worse without hinting. The down side to that is that
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   158
         * B&W metrics will differ which normally isn't the case, although
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   159
         * since AA mode is part of the measuring context that should be OK.
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   160
         * We don't expect Amble to be installed in the Windows fonts folder.
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   161
         * If we were to, then we'd also might want to disable using the
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   162
         * native rasteriser path which is used for LCD mode for platform
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   163
         * fonts. since we have no way to disable hinting by GDI.
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   164
         * In the case of Amble, since its 'gasp' table says to disable
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   165
         * hinting, I'd expect GDI to follow that, so likely it should
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   166
         * all be consistent even if GDI used.
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   167
         */
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   168
        boolean disableHinting = desc.aaHint != INTVAL_TEXT_ANTIALIAS_OFF &&
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   169
                                 fileFont.familyName.startsWith("Amble");
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   170
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        /* If any of the values is NaN then substitute the null scaler context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
         * This will return null images, zero advance, and empty outlines
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         * as no rendering need take place in this case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         * We pass in the null scaler as the singleton null context
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         * requires it. However
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        if (Double.isNaN(matrix[0]) || Double.isNaN(matrix[1]) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            Double.isNaN(matrix[2]) || Double.isNaN(matrix[3]) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            fileFont.getScaler() == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            pScalerContext = NullFontScaler.getNullScalerContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            pScalerContext = fileFont.getScaler().createScalerContext(matrix,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                                    fileFont instanceof TrueTypeFont,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                                    desc.aaHint, desc.fmHint,
7940
7d20d72dd3b9 6930980: Disable TrueType hinting for fonts known not to hint well
prr
parents: 7938
diff changeset
   185
                                    boldness, italic, disableHinting);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        mapper = fileFont.getMapper();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        int numGlyphs = mapper.getNumGlyphs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
7757
451411eff24b 6891551: Font rasterisation uses more heap than needed for some strikes.
prr
parents: 7750
diff changeset
   191
        /* Always segment for fonts with > 256 glyphs, but also for smaller
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
         * fonts with non-typical sizes and transforms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
         * Segmenting for all non-typical pt sizes helps to minimise memory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
         * usage when very many distinct strikes are created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
         * The size range of 0->5 and 37->INF for segmenting is arbitrary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
         * but the intention is that typical GUI integer point sizes (6->36)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
         * should not segment unless there's another reason to do so.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        float ptSize = (float)matrix[3]; // interpreted only when meaningful.
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   200
        int iSize = intPtSize = (int)ptSize;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        boolean isSimpleTx = (at.getType() & complexTX) == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        segmentedCache =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            (numGlyphs > SEGSIZE << 3) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            ((numGlyphs > SEGSIZE << 1) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
             (!isSimpleTx || ptSize != iSize || iSize < 6 || iSize > 36));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        /* This can only happen if we failed to allocate memory for context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
         * NB: in such case we may still have some memory in java heap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
         *     but subsequent attempt to allocate null scaler context
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
         *     may fail too (cause it is allocate in the native heap).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
         *     It is not clear how to make this more robust but on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
         *     other hand getting NULL here seems to be extremely unlikely.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        if (pScalerContext == 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            /* REMIND: when the code is updated to install cache objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
             * rather than using a switch this will be more efficient.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            this.disposer = new FontStrikeDisposer(fileFont, desc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            initGlyphCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            pScalerContext = NullFontScaler.getNullScalerContext();
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   221
            SunFontManager.getInstance().deRegisterBadFont(fileFont);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        }
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   224
        /* First, see if native code should be used to create the glyph.
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   225
         * GDI will return the integer metrics, not fractional metrics, which
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   226
         * may be requested for this strike, so we would require here that :
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   227
         * desc.fmHint != INTVAL_FRACTIONALMETRICS_ON
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   228
         * except that the advance returned by GDI is always overwritten by
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   229
         * the JDK rasteriser supplied one (see getGlyphImageFromWindows()).
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   230
         */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   231
        if (FontUtilities.isWindows && isXPorLater &&
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   232
            !FontUtilities.useT2K &&
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   233
            !GraphicsEnvironment.isHeadless() &&
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   234
            !fileFont.useJavaRasterizer &&
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   235
            (desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   236
             desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) &&
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   237
            (matrix[1] == 0.0 && matrix[2] == 0.0 &&
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   238
             matrix[0] == matrix[3] &&
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   239
             matrix[0] >= 3.0 && matrix[0] <= 100.0) &&
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   240
            !((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   241
            useNatives = true;
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   242
        }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   243
        else if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
            /* Check its a simple scale of a pt size in the range
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
             * where native bitmaps typically exist (6-36 pts) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            if (matrix[1] == 0.0 && matrix[2] == 0.0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                matrix[0] >= 6.0 && matrix[0] <= 36.0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                matrix[0] == matrix[3]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                useNatives = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                int numNatives = fileFont.nativeFonts.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                nativeStrikes = new NativeStrike[numNatives];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                /* Maybe initialise these strikes lazily?. But we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                 * know we need at least one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                for (int i=0; i<numNatives; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                    nativeStrikes[i] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                        new NativeStrike(fileFont.nativeFonts[i], desc, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   261
        if (FontUtilities.isLogging() && FontUtilities.isWindows) {
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   262
            FontUtilities.getLogger().info
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   263
                ("Strike for " + fileFont + " at size = " + intPtSize +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   264
                 " use natives = " + useNatives +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   265
                 " useJavaRasteriser = " + fileFont.useJavaRasterizer +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   266
                 " AAHint = " + desc.aaHint +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   267
                 " Has Embedded bitmaps = " +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   268
                 ((TrueTypeFont)fileFont).
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   269
                 useEmbeddedBitmapsForSize(intPtSize));
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   270
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        /* Always get the image and the advance together for smaller sizes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
         * that are likely to be important to rendering performance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
         * The pixel size of 48.0 can be thought of as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
         * "maximumSizeForGetImageWithAdvance".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         * This should be no greater than OutlineTextRender.THRESHOLD.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         */
546
06253731a445 6692979: VM Crash when shearing text + rect over a range of values
prr
parents: 2
diff changeset
   279
        double maxSz = 48.0;
06253731a445 6692979: VM Crash when shearing text + rect over a range of values
prr
parents: 2
diff changeset
   280
        getImageWithAdvance =
06253731a445 6692979: VM Crash when shearing text + rect over a range of values
prr
parents: 2
diff changeset
   281
            Math.abs(at.getScaleX()) <= maxSz &&
06253731a445 6692979: VM Crash when shearing text + rect over a range of values
prr
parents: 2
diff changeset
   282
            Math.abs(at.getScaleY()) <= maxSz &&
06253731a445 6692979: VM Crash when shearing text + rect over a range of values
prr
parents: 2
diff changeset
   283
            Math.abs(at.getShearX()) <= maxSz &&
06253731a445 6692979: VM Crash when shearing text + rect over a range of values
prr
parents: 2
diff changeset
   284
            Math.abs(at.getShearY()) <= maxSz;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        /* Some applications request advance frequently during layout.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
         * If we are not getting and caching the image with the advance,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
         * there is a potentially significant performance penalty if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
         * advance is repeatedly requested before requesting the image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
         * We should at least cache the horizontal advance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
         * REMIND: could use info in the font, eg hmtx, to retrieve some
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
         * advances. But still want to cache it here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        if (!getImageWithAdvance) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            if (!segmentedCache) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                horizontalAdvances = new float[numGlyphs];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                /* use max float as uninitialised advance */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                for (int i=0; i<numGlyphs; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                    horizontalAdvances[i] = Float.MAX_VALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                segHorizontalAdvances = new float[numSegments][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    /* A number of methods are delegated by the strike to the scaler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * context which is a shared resource on a physical font.
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 getNumGlyphs() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        return fileFont.getNumGlyphs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   317
    long getGlyphImageFromNative(int glyphCode) {
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   318
        if (FontUtilities.isWindows) {
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   319
            return getGlyphImageFromWindows(glyphCode);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   320
        } else {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   321
            return getGlyphImageFromX11(glyphCode);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   322
        }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   323
    }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   324
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   325
    /* There's no global state conflicts, so this method is not
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   326
     * presently synchronized.
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   327
     */
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   328
    private native long _getGlyphImageFromWindows(String family,
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   329
                                                  int style,
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   330
                                                  int size,
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   331
                                                  int glyphCode,
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   332
                                                  boolean fracMetrics);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   333
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   334
    long getGlyphImageFromWindows(int glyphCode) {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   335
        String family = fileFont.getFamilyName(null);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   336
        int style = desc.style & Font.BOLD | desc.style & Font.ITALIC
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   337
            | fileFont.getStyle();
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   338
        int size = intPtSize;
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   339
        long ptr = _getGlyphImageFromWindows
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   340
            (family, style, size, glyphCode,
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   341
             desc.fmHint == INTVAL_FRACTIONALMETRICS_ON);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   342
        if (ptr != 0) {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   343
            /* Get the advance from the JDK rasterizer. This is mostly
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   344
             * necessary for the fractional metrics case, but there are
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   345
             * also some very small number (<0.25%) of marginal cases where
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   346
             * there is some rounding difference between windows and JDK.
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   347
             * After these are resolved, we can restrict this extra
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   348
             * work to the FM case.
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   349
             */
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   350
            float advance = getGlyphAdvance(glyphCode, false);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   351
            StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset,
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   352
                                        advance);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   353
            return ptr;
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   354
        } else {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   355
            return fileFont.getGlyphImage(pScalerContext, glyphCode);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   356
        }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   357
    }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   358
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    /* Try the native strikes first, then try the fileFont strike */
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   360
    long getGlyphImageFromX11(int glyphCode) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        long glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        char charCode = fileFont.glyphToCharMap[glyphCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        for (int i=0;i<nativeStrikes.length;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            CharToGlyphMapper mapper = fileFont.nativeFonts[i].getMapper();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
            int gc = mapper.charToGlyph(charCode)&0xffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            if (gc != mapper.getMissingGlyphCode()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                glyphPtr = nativeStrikes[i].getGlyphImagePtrNoCache(gc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                if (glyphPtr != 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                    return glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        return fileFont.getGlyphImage(pScalerContext, glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    long getGlyphImagePtr(int glyphCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        if (glyphCode >= INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            return StrikeCache.invisibleGlyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        }
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   380
        long glyphPtr = 0L;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            return glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            if (useNatives) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                glyphPtr = getGlyphImageFromNative(glyphCode);
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   386
                if (glyphPtr == 0L && FontUtilities.isLogging()) {
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   387
                    FontUtilities.getLogger().info
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   388
                        ("Strike for " + fileFont +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   389
                         " at size = " + intPtSize +
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   390
                         " couldn't get native glyph for code = " + glyphCode);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   391
                 }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   392
            } if (glyphPtr == 0L) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                glyphPtr = fileFont.getGlyphImage(pScalerContext,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                                                  glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            return setCachedGlyphPtr(glyphCode, glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    void getGlyphImagePtrs(int[] glyphCodes, long[] images, int  len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        for (int i=0; i<len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            int glyphCode = glyphCodes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            if (glyphCode >= INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                images[i] = StrikeCache.invisibleGlyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            } else {
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   410
                long glyphPtr = 0L;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                if (useNatives) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    glyphPtr = getGlyphImageFromNative(glyphCode);
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   413
                } if (glyphPtr == 0L) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                    glyphPtr = fileFont.getGlyphImage(pScalerContext,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                                                      glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                images[i] = setCachedGlyphPtr(glyphCode, glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    /* The following method is called from CompositeStrike as a special case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    private static final int SLOTZEROMAX = 0xffffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    int getSlot0GlyphImagePtrs(int[] glyphCodes, long[] images, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        int convertedCnt = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        for (int i=0; i<len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            int glyphCode = glyphCodes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            if (glyphCode >= SLOTZEROMAX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                return convertedCnt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                convertedCnt++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            if (glyphCode >= INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                images[i] = StrikeCache.invisibleGlyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            } else {
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   442
                long glyphPtr = 0L;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                if (useNatives) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                    glyphPtr = getGlyphImageFromNative(glyphCode);
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   445
                }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   446
                if (glyphPtr == 0L) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                    glyphPtr = fileFont.getGlyphImage(pScalerContext,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                                                      glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                images[i] = setCachedGlyphPtr(glyphCode, glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        return convertedCnt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    /* Only look in the cache */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    long getCachedGlyphPtr(int glyphCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        switch (glyphCacheFormat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            case INTARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                return intGlyphImages[glyphCode] & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            case SEGINTARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                int segIndex = glyphCode >> SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                if (segIntGlyphImages[segIndex] != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                    int subIndex = glyphCode % SEGSIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                    return segIntGlyphImages[segIndex][subIndex] & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                    return 0L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            case LONGARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                return longGlyphImages[glyphCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            case SEGLONGARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                segIndex = glyphCode >> SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                if (segLongGlyphImages[segIndex] != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                    int subIndex = glyphCode % SEGSIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                    return segLongGlyphImages[segIndex][subIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                    return 0L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        /* If reach here cache is UNINITIALISED. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        return 0L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    private synchronized long setCachedGlyphPtr(int glyphCode, long glyphPtr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        switch (glyphCacheFormat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            case INTARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                if (intGlyphImages[glyphCode] == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                    intGlyphImages[glyphCode] = (int)glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                    return glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                    StrikeCache.freeIntPointer((int)glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                    return intGlyphImages[glyphCode] & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            case SEGINTARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                int segIndex = glyphCode >> SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                int subIndex = glyphCode % SEGSIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                if (segIntGlyphImages[segIndex] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                    segIntGlyphImages[segIndex] = new int[SEGSIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                if (segIntGlyphImages[segIndex][subIndex] == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                    segIntGlyphImages[segIndex][subIndex] = (int)glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                    return glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                    StrikeCache.freeIntPointer((int)glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                    return segIntGlyphImages[segIndex][subIndex] & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            case LONGARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                if (longGlyphImages[glyphCode] == 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                    longGlyphImages[glyphCode] = glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                    return glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                    StrikeCache.freeLongPointer(glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                    return longGlyphImages[glyphCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
           case SEGLONGARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                segIndex = glyphCode >> SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                subIndex = glyphCode % SEGSIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                if (segLongGlyphImages[segIndex] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                    segLongGlyphImages[segIndex] = new long[SEGSIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                if (segLongGlyphImages[segIndex][subIndex] == 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
                    segLongGlyphImages[segIndex][subIndex] = glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                    return glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                    StrikeCache.freeLongPointer(glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                    return segLongGlyphImages[segIndex][subIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        /* Reach here only when the cache is not initialised which is only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
         * for the first glyph to be initialised in the strike.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
         * Initialise it and recurse. Note that we are already synchronized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        initGlyphCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        return setCachedGlyphPtr(glyphCode, glyphPtr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    /* Called only from synchronized code or constructor */
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   542
    private synchronized void initGlyphCache() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        int numGlyphs = mapper.getNumGlyphs();
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   545
        int tmpFormat = UNINITIALISED;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        if (segmentedCache) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE;
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   548
            if (longAddresses) {
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   549
                tmpFormat = SEGLONGARRAY;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                segLongGlyphImages = new long[numSegments][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                this.disposer.segLongGlyphImages = segLongGlyphImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
             } else {
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   553
                 tmpFormat = SEGINTARRAY;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                 segIntGlyphImages = new int[numSegments][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                 this.disposer.segIntGlyphImages = segIntGlyphImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        } else {
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2393
diff changeset
   558
            if (longAddresses) {
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   559
                tmpFormat = LONGARRAY;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                longGlyphImages = new long[numGlyphs];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                this.disposer.longGlyphImages = longGlyphImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            } else {
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   563
                tmpFormat = INTARRAY;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                intGlyphImages = new int[numGlyphs];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                this.disposer.intGlyphImages = intGlyphImages;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        }
7750
cb72c76bfec8 7007299: FileFontStrike appears not to be threadsafe?
prr
parents: 5506
diff changeset
   568
        glyphCacheFormat = tmpFormat;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   571
    float getGlyphAdvance(int glyphCode) {
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   572
        return getGlyphAdvance(glyphCode, true);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   573
    }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   574
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    /* Metrics info is always retrieved. If the GlyphInfo address is non-zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     * then metrics info there is valid and can just be copied.
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   577
     * This is in user space coordinates unless getUserAdv == false.
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   578
     * Device space advance should not be propagated out of this class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     */
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   580
    private float getGlyphAdvance(int glyphCode, boolean getUserAdv) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        float advance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        if (glyphCode >= INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            return 0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        }
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   586
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   587
        /* Notes on the (getUserAdv == false) case.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   588
         *
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   589
         * Setting getUserAdv == false is internal to this class.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   590
         * If there's no graphics transform we can let
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   591
         * getGlyphAdvance take its course, and potentially caching in
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   592
         * advances arrays, except for signalling that
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   593
         * getUserAdv == false means there is no need to create an image.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   594
         * It is possible that code already calculated the user advance,
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   595
         * and it is desirable to take advantage of that work.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   596
         * But, if there's a transform and we want device advance, we
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   597
         * can't use any values cached in the advances arrays - unless
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   598
         * first re-transform them into device space using 'desc.devTx'.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   599
         * invertDevTx is null if the graphics transform is identity,
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   600
         * a translate, or non-invertible. The latter case should
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   601
         * not ever occur in the getUserAdv == false path.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   602
         * In other words its either null, or the inversion of a
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   603
         * simple uniform scale. If its null, we can populate and
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   604
         * use the advance caches as normal.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   605
         *
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   606
         * If we don't find a cached value, obtain the device advance and
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   607
         * return it. This will get stashed on the image by the caller and any
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   608
         * subsequent metrics calls will be able to use it as is the case
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   609
         * whenever an image is what is initially requested.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   610
         *
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   611
         * Don't query if there's a value cached on the image, since this
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   612
         * getUserAdv==false code path is entered solely when none exists.
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   613
         */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        if (horizontalAdvances != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            advance = horizontalAdvances[glyphCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            if (advance != Float.MAX_VALUE) {
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   617
                if (!getUserAdv && invertDevTx != null) {
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   618
                    Point2D.Float metrics = new Point2D.Float(advance, 0f);
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   619
                    desc.devTx.deltaTransform(metrics, metrics);
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   620
                    return metrics.x;
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   621
                } else {
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   622
                    return advance;
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   623
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        } else if (segmentedCache && segHorizontalAdvances != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            int segIndex = glyphCode >> SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
            float[] subArray = segHorizontalAdvances[segIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            if (subArray != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                advance = subArray[glyphCode % SEGSIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                if (advance != Float.MAX_VALUE) {
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   631
                    if (!getUserAdv && invertDevTx != null) {
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   632
                        Point2D.Float metrics = new Point2D.Float(advance, 0f);
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   633
                        desc.devTx.deltaTransform(metrics, metrics);
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   634
                        return metrics.x;
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   635
                    } else {
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   636
                        return advance;
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   637
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   642
        if (!getUserAdv && invertDevTx != null) {
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   643
            Point2D.Float metrics = new Point2D.Float();
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   644
            fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics);
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   645
            return metrics.x;
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   646
        }
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   647
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   648
        if (invertDevTx != null || !getUserAdv) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            /* If there is a device transform need x & y advance to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
             * transform back into user space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
             */
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   652
            advance = getGlyphMetrics(glyphCode, getUserAdv).x;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            long glyphPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            if (getImageWithAdvance) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                /* A heuristic optimisation says that for most cases its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                 * worthwhile retrieving the image at the same time as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                 * advance. So here we get the image data even if its not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                 * already cached.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                glyphPtr = getGlyphImagePtr(glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                glyphPtr = getCachedGlyphPtr(glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            if (glyphPtr != 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                advance = StrikeCache.unsafe.getFloat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                    (glyphPtr + StrikeCache.xAdvanceOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                advance = fileFont.getGlyphAdvance(pScalerContext, glyphCode);
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
        if (horizontalAdvances != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            horizontalAdvances[glyphCode] = advance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        } else if (segmentedCache && segHorizontalAdvances != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            int segIndex = glyphCode >> SEGSHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            int subIndex = glyphCode % SEGSIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            if (segHorizontalAdvances[segIndex] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                segHorizontalAdvances[segIndex] = new float[SEGSIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                for (int i=0; i<SEGSIZE; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                     segHorizontalAdvances[segIndex][i] = Float.MAX_VALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            segHorizontalAdvances[segIndex][subIndex] = advance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        return advance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    float getCodePointAdvance(int cp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        return getGlyphAdvance(mapper.charToGlyph(cp));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * Result and pt are both in device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    void getGlyphImageBounds(int glyphCode, Point2D.Float pt,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                             Rectangle result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        long ptr = getGlyphImagePtr(glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        float topLeftX, topLeftY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        /* With our current design NULL ptr is not possible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
           but if we eventually allow scalers to return NULL pointers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
           this check might be actually useful. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        if (ptr == 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            result.x = (int) Math.floor(pt.x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            result.y = (int) Math.floor(pt.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            result.width = result.height = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        topLeftX = StrikeCache.unsafe.getFloat(ptr+StrikeCache.topLeftXOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        topLeftY = StrikeCache.unsafe.getFloat(ptr+StrikeCache.topLeftYOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        result.x = (int)Math.floor(pt.x + topLeftX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        result.y = (int)Math.floor(pt.y + topLeftY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        result.width =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            StrikeCache.unsafe.getShort(ptr+StrikeCache.widthOffset)  &0x0ffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        result.height =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            StrikeCache.unsafe.getShort(ptr+StrikeCache.heightOffset) &0x0ffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        /* HRGB LCD text may have padding that is empty. This is almost always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
         * going to be when topLeftX is -2 or less.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
         * Try to return a tighter bounding box in that case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
         * If the first three bytes of every row are all zero, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
         * add 1 to "x" and reduce "width" by 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        if ((desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
             desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            && topLeftX <= -2.0f) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            int minx = getGlyphImageMinX(ptr, (int)result.x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            if (minx > result.x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                result.x += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                result.width -=1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
    private int getGlyphImageMinX(long ptr, int origMinX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        int width = StrikeCache.unsafe.getChar(ptr+StrikeCache.widthOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        int height = StrikeCache.unsafe.getChar(ptr+StrikeCache.heightOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        int rowBytes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
            StrikeCache.unsafe.getChar(ptr+StrikeCache.rowBytesOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        if (rowBytes == width) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            return origMinX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        long pixelData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        if (StrikeCache.nativeAddressSize == 4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            pixelData = 0xffffffff &
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                StrikeCache.unsafe.getInt(ptr + StrikeCache.pixelDataOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            pixelData =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                StrikeCache.unsafe.getLong(ptr + StrikeCache.pixelDataOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        if (pixelData == 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
            return origMinX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        for (int y=0;y<height;y++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            for (int x=0;x<3;x++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                if (StrikeCache.unsafe.getByte(pixelData+y*rowBytes+x) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                    return origMinX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        return origMinX+1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    /* These 3 metrics methods below should be implemented to return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     * values in user space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    StrikeMetrics getFontMetrics() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        if (strikeMetrics == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            strikeMetrics =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                fileFont.getFontMetrics(pScalerContext);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            if (invertDevTx != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                strikeMetrics.convertToUserSpace(invertDevTx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        return strikeMetrics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    Point2D.Float getGlyphMetrics(int glyphCode) {
550
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   788
        return getGlyphMetrics(glyphCode, true);
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   789
    }
e85f91b9bb95 6656651: Windows Look and Feel LCD glyph images have some differences from native applications.
prr
parents: 546
diff changeset
   790
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   791
    private Point2D.Float getGlyphMetrics(int glyphCode, boolean getImage) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        Point2D.Float metrics = new Point2D.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        // !!! or do we force sgv user glyphs?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        if (glyphCode >= INVISIBLE_GLYPHS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            return metrics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        long glyphPtr;
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   799
        if (getImageWithAdvance && getImage) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
            /* A heuristic optimisation says that for most cases its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
             * worthwhile retrieving the image at the same time as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
             * metrics. So here we get the image data even if its not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
             * already cached.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            glyphPtr = getGlyphImagePtr(glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
             glyphPtr = getCachedGlyphPtr(glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        if (glyphPtr != 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            metrics = new Point2D.Float();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
            metrics.x = StrikeCache.unsafe.getFloat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                (glyphPtr + StrikeCache.xAdvanceOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            metrics.y = StrikeCache.unsafe.getFloat
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                (glyphPtr + StrikeCache.yAdvanceOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            /* advance is currently in device space, need to convert back
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   816
             * into user space.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
             * This must not include the translation component. */
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   818
            if (invertDevTx != null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                invertDevTx.deltaTransform(metrics, metrics);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            /* We sometimes cache these metrics as they are expensive to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
             * generate for large glyphs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
             * We never reach this path if we obtain images with advances.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
             * But if we do not obtain images with advances its possible that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
             * we first obtain this information, then the image, and never
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
             * will access this value again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
             */
438
2ae294e4518c 6613529: Avoid duplicate object creation within JDK packages
dav
parents: 2
diff changeset
   829
            Integer key = Integer.valueOf(glyphCode);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            Point2D.Float value = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            ConcurrentHashMap<Integer, Point2D.Float> glyphMetricsMap = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            if (glyphMetricsMapRef != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                glyphMetricsMap = glyphMetricsMapRef.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
            if (glyphMetricsMap != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                value = glyphMetricsMap.get(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                if (value != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                    metrics.x = value.x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                    metrics.y = value.y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                    /* already in user space */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                    return metrics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            if (value == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                /* advance is currently in device space, need to convert back
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   847
                 * into user space.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                 */
7938
970d0e025e57 6925760: Scaled graphics can cause overlapped LCD mode strings on Windows for pixel size > 48
prr
parents: 7757
diff changeset
   849
                if (invertDevTx != null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                    invertDevTx.deltaTransform(metrics, metrics);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                value = new Point2D.Float(metrics.x, metrics.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                /* We aren't synchronizing here so it is possible to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                 * overwrite the map with another one but this is harmless.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                if (glyphMetricsMap == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                    glyphMetricsMap =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                        new ConcurrentHashMap<Integer, Point2D.Float>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    glyphMetricsMapRef =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                        new SoftReference<ConcurrentHashMap<Integer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                        Point2D.Float>>(glyphMetricsMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                glyphMetricsMap.put(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
        return metrics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    Point2D.Float getCharMetrics(char ch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        return getGlyphMetrics(mapper.charToGlyph(ch));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    /* The caller of this can be trusted to return a copy of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     * return value rectangle to public API. In fact frequently it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
     * can't use use this return value directly anyway.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
     * This returns bounds in device space. Currently the only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     * caller is SGV and it converts back to user space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     * We could change things so that this code does the conversion so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     * that all coords coming out of the font system are converted back
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * into user space even if they were measured in device space.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     * The same applies to the other methods that return outlines (below)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     * But it may make particular sense for this method that caches its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
     * results.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
     * There'd be plenty of exceptions, to this too, eg getGlyphPoint needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
     * device coords as its called from native layout and getGlyphImageBounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     * is used by GlyphVector.getGlyphPixelBounds which is specified to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
     * return device coordinates, the image pointers aren't really used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
     * up in Java code either.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
    Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        if (boundsMap == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            boundsMap = new ConcurrentHashMap<Integer, Rectangle2D.Float>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
438
2ae294e4518c 6613529: Avoid duplicate object creation within JDK packages
dav
parents: 2
diff changeset
   896
        Integer key = Integer.valueOf(glyphCode);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        Rectangle2D.Float bounds = boundsMap.get(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        if (bounds == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
            bounds = fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
            boundsMap.put(key, bounds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
        return bounds;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    public Rectangle2D getOutlineBounds(int glyphCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        return fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
2393
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   910
    private
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   911
        WeakReference<ConcurrentHashMap<Integer,GeneralPath>> outlineMapRef;
2390
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   912
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
2393
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   914
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   915
        GeneralPath gp = null;
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   916
        ConcurrentHashMap<Integer, GeneralPath> outlineMap = null;
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   917
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   918
        if (outlineMapRef != null) {
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   919
            outlineMap = outlineMapRef.get();
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   920
            if (outlineMap != null) {
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   921
                gp = (GeneralPath)outlineMap.get(glyphCode);
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   922
            }
2390
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   923
        }
2393
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   924
2390
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   925
        if (gp == null) {
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   926
            gp = fileFont.getGlyphOutline(pScalerContext, glyphCode, 0, 0);
2393
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   927
            if (outlineMap == null) {
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   928
                outlineMap = new ConcurrentHashMap<Integer, GeneralPath>();
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   929
                outlineMapRef =
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   930
                   new WeakReference
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   931
                       <ConcurrentHashMap<Integer,GeneralPath>>(outlineMap);
ea28f24e1708 6745225: Memory leak while drawing Attributed String
prr
parents: 2390
diff changeset
   932
            }
2390
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   933
            outlineMap.put(glyphCode, gp);
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   934
        }
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   935
        gp = (GeneralPath)gp.clone(); // mutable!
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   936
        if (x != 0f || y != 0f) {
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   937
            gp.transform(AffineTransform.getTranslateInstance(x, y));
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   938
        }
080fb3a8be94 6727719: Performance of TextLayout.getBounds()
prr
parents: 715
diff changeset
   939
        return gp;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
    GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
        return fileFont.getGlyphVectorOutline(pScalerContext,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
                                              glyphs, glyphs.length, x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    protected void adjustPoint(Point2D.Float pt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        if (invertDevTx != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
            invertDevTx.deltaTransform(pt, pt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
}