jdk/src/macosx/classes/sun/font/CStrike.java
author serb
Wed, 04 Jul 2012 14:38:14 +0400
changeset 13233 4d45f7ebc0d7
parent 12047 320a714614e9
child 15973 ea0278a3c432
permissions -rw-r--r--
7124244: [macosx] Shaped windows support Reviewed-by: anthony, art
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     1
/*
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     2
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     4
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    10
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    15
 * accompanied this code).
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    16
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    20
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    23
 * questions.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    24
 */
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    25
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    26
package sun.font;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    27
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    28
import java.awt.Rectangle;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    29
import java.awt.geom.*;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    30
import java.util.*;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    31
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    32
import sun.awt.SunHints;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    33
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    34
public class CStrike extends FontStrike {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    35
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    36
    // Creates the native strike
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    37
    private static native long createNativeStrikePtr(long nativeFontPtr,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    38
                                                     double[] glyphTx,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    39
                                                     double[] invDevTxMatrix,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    40
                                                     int aaHint,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    41
                                                     int fmHint);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    42
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    43
    // Disposes the native strike
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    44
    private static native void disposeNativeStrikePtr(long nativeStrikePtr);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    45
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    46
    // Creates a StrikeMetrics from the underlying native system fonts
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    47
    private static native StrikeMetrics getFontMetrics(long nativeStrikePtr);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    48
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    49
    // Returns native struct pointers used by the Sun 2D Renderer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    50
    private static native void getGlyphImagePtrsNative(long nativeStrikePtr,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    51
                                                       long[] glyphInfos,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    52
                                                       int[] uniCodes, int len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    53
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    54
    // Returns the advance give a glyph code. It should be used only
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    55
    // when the glyph code belongs to the CFont passed in.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    56
    private static native float getNativeGlyphAdvance(long nativeStrikePtr,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    57
                                                      int glyphCode);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    58
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    59
    // Returns the outline shape of a glyph
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    60
    private static native GeneralPath getNativeGlyphOutline(long nativeStrikePtr,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    61
                                                            int glyphCode,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    62
                                                            double x,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    63
                                                            double y);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    64
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    65
    // returns the bounding rect for a glyph
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    66
    private static native void getNativeGlyphImageBounds(long nativeStrikePtr,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    67
                                                         int glyphCode,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    68
                                                         Rectangle2D.Float result,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    69
                                                         double x, double y);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    70
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    71
    private CFont nativeFont;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    72
    private AffineTransform invDevTx;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    73
    private GlyphInfoCache glyphInfoCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    74
    private GlyphAdvanceCache glyphAdvanceCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    75
    private long nativeStrikePtr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    76
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    77
    CStrike(final CFont font, final FontStrikeDesc inDesc) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    78
        nativeFont = font;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    79
        desc = inDesc;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    80
        glyphInfoCache = new GlyphInfoCache(font, desc);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    81
        glyphAdvanceCache = new GlyphAdvanceCache();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    82
        disposer = glyphInfoCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    83
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    84
        // Normally the device transform should be the identity transform
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    85
        // for screen operations.  The device transform only becomes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    86
        // interesting when we are outputting between different dpi surfaces,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    87
        // like when we are printing to postscript.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    88
        if (inDesc.devTx != null && !inDesc.devTx.isIdentity()) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    89
            try {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    90
                invDevTx = inDesc.devTx.createInverse();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    91
            } catch (NoninvertibleTransformException e) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    92
                // ignored, since device transforms should not be that
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    93
                // complicated, and if they are - there is nothing we can do,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    94
                // so we won't worry about it.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    95
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    96
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    97
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    98
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    99
    public long getNativeStrikePtr() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   100
        if (nativeStrikePtr != 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   101
            return nativeStrikePtr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   102
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   103
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   104
        final double[] glyphTx = new double[6];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   105
        desc.glyphTx.getMatrix(glyphTx);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   106
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   107
        final double[] invDevTxMatrix = new double[6];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   108
        if (invDevTx == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   109
            invDevTxMatrix[0] = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   110
            invDevTxMatrix[3] = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   111
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   112
            invDevTx.getMatrix(invDevTxMatrix);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   113
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   114
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   115
        final int aaHint = desc.aaHint;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   116
        final int fmHint = desc.fmHint;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   117
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   118
        synchronized (this) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   119
            if (nativeStrikePtr != 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   120
                return nativeStrikePtr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   121
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   122
            nativeStrikePtr =
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   123
                createNativeStrikePtr(nativeFont.getNativeFontPtr(),
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   124
                                      glyphTx, invDevTxMatrix, aaHint, fmHint);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   125
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   126
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   127
        return nativeStrikePtr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   128
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   129
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   130
    protected synchronized void finalize() throws Throwable {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   131
        if (nativeStrikePtr != 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   132
            disposeNativeStrikePtr(nativeStrikePtr);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   133
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   134
        nativeStrikePtr = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   135
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   136
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   137
    // the fractional metrics default on our platform is OFF
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   138
    private boolean useFractionalMetrics() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   139
        return desc.fmHint == SunHints.INTVAL_FRACTIONALMETRICS_ON;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   140
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   141
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   142
    public int getNumGlyphs() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   143
        return nativeFont.getNumGlyphs();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   144
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   145
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   146
    StrikeMetrics getFontMetrics() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   147
        if (strikeMetrics == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   148
            StrikeMetrics metrics = getFontMetrics(getNativeStrikePtr());
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   149
            if (invDevTx != null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   150
                metrics.convertToUserSpace(invDevTx);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   151
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   152
            metrics.convertToUserSpace(desc.glyphTx);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   153
            strikeMetrics = metrics;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   154
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   155
        return strikeMetrics;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   156
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   157
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   158
    float getGlyphAdvance(int glyphCode) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   159
        return getScaledAdvanceForAdvance(getCachedNativeGlyphAdvance(glyphCode));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   160
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   161
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   162
    float getCodePointAdvance(int cp) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   163
        float advance = getCachedNativeGlyphAdvance(nativeFont.getMapper().charToGlyph(cp));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   164
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   165
        double glyphScaleX = desc.glyphTx.getScaleX();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   166
        double devScaleX = desc.devTx.getScaleX();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   167
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   168
        if (devScaleX == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   169
            glyphScaleX = Math.sqrt(desc.glyphTx.getDeterminant());
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   170
            devScaleX = Math.sqrt(desc.devTx.getDeterminant());
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   171
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   172
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   173
        if (devScaleX == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   174
            devScaleX = Double.NaN; // this an undefined graphics state
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   175
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   176
        advance = (float) (advance * glyphScaleX / devScaleX);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   177
        return useFractionalMetrics() ? advance : Math.round(advance);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   178
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   179
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   180
    // calculate an advance, and round if not using fractional metrics
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   181
    private float getScaledAdvanceForAdvance(float advance) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   182
        if (invDevTx != null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   183
            advance *= invDevTx.getScaleX();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   184
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   185
        advance *= desc.glyphTx.getScaleX();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   186
        return useFractionalMetrics() ? advance : Math.round(advance);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   187
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   188
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   189
    Point2D.Float getCharMetrics(char ch) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   190
        return getScaledPointForAdvance(getCachedNativeGlyphAdvance(nativeFont.getMapper().charToGlyph(ch)));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   191
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   192
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   193
    Point2D.Float getGlyphMetrics(int glyphCode) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   194
        return getScaledPointForAdvance(getCachedNativeGlyphAdvance(glyphCode));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   195
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   196
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   197
    // calculate an advance point, and round if not using fractional metrics
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   198
    private Point2D.Float getScaledPointForAdvance(float advance) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   199
        Point2D.Float pt = new Point2D.Float(advance, 0);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   200
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   201
        if (!desc.glyphTx.isIdentity()) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   202
            return scalePoint(pt);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   203
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   204
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   205
        if (!useFractionalMetrics()) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   206
            pt.x = Math.round(pt.x);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   207
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   208
        return pt;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   209
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   210
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   211
    private Point2D.Float scalePoint(Point2D.Float pt) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   212
        if (invDevTx != null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   213
            // transform the point out of the device space first
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   214
            invDevTx.transform(pt, pt);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   215
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   216
        desc.glyphTx.transform(pt, pt);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   217
        pt.x -= desc.glyphTx.getTranslateX();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   218
        pt.y -= desc.glyphTx.getTranslateY();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   219
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   220
        if (!useFractionalMetrics()) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   221
            pt.x = Math.round(pt.x);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   222
            pt.y = Math.round(pt.y);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   223
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   224
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   225
        return pt;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   226
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   227
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   228
    Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   229
        GeneralPath gp = getGlyphOutline(glyphCode, 0f, 0f);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   230
        Rectangle2D r2d = gp.getBounds2D();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   231
        Rectangle2D.Float r2df;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   232
        if (r2d instanceof Rectangle2D.Float) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   233
            r2df = (Rectangle2D.Float)r2d;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   234
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   235
            float x = (float)r2d.getX();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   236
            float y = (float)r2d.getY();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   237
            float w = (float)r2d.getWidth();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   238
            float h = (float)r2d.getHeight();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   239
            r2df = new Rectangle2D.Float(x, y, w, h);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   240
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   241
        return r2df;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   242
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   243
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   244
    // pt, result in device space
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   245
    void getGlyphImageBounds(int glyphCode, Point2D.Float pt, Rectangle result) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   246
        Rectangle2D.Float floatRect = new Rectangle2D.Float();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   247
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   248
        if (invDevTx != null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   249
            invDevTx.transform(pt, pt);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   250
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   251
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   252
        getGlyphImageBounds(glyphCode, pt.x, pt.y, floatRect);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   253
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   254
        if (floatRect.width == 0 && floatRect.height == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   255
            result.setRect(0, 0, -1, -1);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   256
            return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   257
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   258
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   259
        result.setRect(floatRect.x + pt.x, floatRect.y + pt.y, floatRect.width, floatRect.height);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   260
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   261
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   262
    private void getGlyphImageBounds(int glyphCode, float x, float y, Rectangle2D.Float floatRect) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   263
        getNativeGlyphImageBounds(getNativeStrikePtr(), glyphCode, floatRect, x, y);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   264
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   265
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   266
    GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   267
        return getNativeGlyphOutline(getNativeStrikePtr(), glyphCode, x, y);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   268
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   269
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   270
    // should implement, however not called though any path that is publicly exposed
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   271
    GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   272
        throw new Error("not implemented yet");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   273
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   274
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   275
    // called from the Sun2D renderer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   276
    long getGlyphImagePtr(int glyphCode) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   277
        synchronized (glyphInfoCache) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   278
            long ptr = glyphInfoCache.get(glyphCode);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   279
            if (ptr != 0L) return ptr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   280
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   281
            long[] ptrs = new long[1];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   282
            int[] codes = new int[1];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   283
            codes[0] = glyphCode;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   284
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   285
            getGlyphImagePtrs(codes, ptrs, 1);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   286
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   287
            ptr = ptrs[0];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   288
            glyphInfoCache.put(glyphCode, ptr);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   289
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   290
            return ptr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   291
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   292
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   293
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   294
    // called from the Sun2D renderer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   295
    void getGlyphImagePtrs(int[] glyphCodes, long[] images, int len) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   296
        synchronized (glyphInfoCache) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   297
            // fill the image pointer array with existing pointers
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   298
            // from the cache
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   299
            int missed = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   300
            for (int i = 0; i < len; i++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   301
                int code = glyphCodes[i];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   302
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   303
                final long ptr = glyphInfoCache.get(code);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   304
                if (ptr != 0L) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   305
                    images[i] = ptr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   306
                } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   307
                    // zero this element out, because the caller does not
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   308
                    // promise to keep it clean
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   309
                    images[i] = 0L;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   310
                    missed++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   311
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   312
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   313
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   314
            if (missed == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   315
                return; // horray! we got away without touching native!
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   316
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   317
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   318
            // all distinct glyph codes requested (partially filled)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   319
            final int[] filteredCodes = new int[missed];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   320
            // indices into filteredCodes array (totally filled)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   321
            final int[] filteredIndicies = new int[missed];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   322
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   323
            // scan, mark, and store the requested glyph codes again to
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   324
            // send into native
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   325
            int j = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   326
            int dupes = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   327
            for (int i = 0; i < len; i++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   328
                if (images[i] != 0L) continue; // already filled
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   329
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   330
                final int code = glyphCodes[i];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   331
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   332
                // we have already promised to strike this glyph - this is
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   333
                // a dupe
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   334
                if (glyphInfoCache.get(code) == -1L) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   335
                    filteredIndicies[j] = -1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   336
                    dupes++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   337
                    j++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   338
                    continue;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   339
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   340
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   341
                // this is a distinct glyph we have not struck before, or
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   342
                // promised to strike mark this one as "promise to strike"
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   343
                // in the global cache with a -1L
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   344
                final int k = j - dupes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   345
                filteredCodes[k] = code;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   346
                glyphInfoCache.put(code, -1L);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   347
                filteredIndicies[j] = k;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   348
                j++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   349
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   350
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   351
            final int filteredRunLen = j - dupes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   352
            final long[] filteredImages = new long[filteredRunLen];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   353
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   354
            // bulk call to fill in the distinct glyph pointers from native
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   355
            getFilteredGlyphImagePtrs(filteredImages, filteredCodes, filteredRunLen);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   356
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   357
            // scan the requested glyph list, and fill in pointers from our
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   358
            // distinct glyph list which has been filled from native
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   359
            j = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   360
            for (int i = 0; i < len; i++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   361
                if (images[i] != 0L && images[i] != -1L) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   362
                    continue; // already placed
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   363
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   364
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   365
                // index into filteredImages array
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   366
                final int k = filteredIndicies[j];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   367
                final int code = glyphCodes[i];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   368
                if (k == -1L) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   369
                    // we should have already filled the cache with this pointer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   370
                    images[i] = glyphInfoCache.get(code);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   371
                } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   372
                    // fill the particular glyph code request, and store
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   373
                    // in the cache
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   374
                    final long ptr = filteredImages[k];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   375
                    images[i] = ptr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   376
                    glyphInfoCache.put(code, ptr);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   377
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   378
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   379
                j++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   380
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   381
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   382
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   383
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   384
    private void getFilteredGlyphImagePtrs(long[] glyphInfos,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   385
                                           int[] uniCodes, int len)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   386
    {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   387
        getGlyphImagePtrsNative(getNativeStrikePtr(), glyphInfos, uniCodes, len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   388
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   389
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   390
    private float getCachedNativeGlyphAdvance(int glyphCode) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   391
        synchronized(glyphAdvanceCache) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   392
            float advance = glyphAdvanceCache.get(glyphCode);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   393
            if (advance != 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   394
                return advance;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   395
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   396
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   397
            advance = getNativeGlyphAdvance(getNativeStrikePtr(), glyphCode);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   398
            glyphAdvanceCache.put(glyphCode, advance);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   399
            return advance;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   400
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   401
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   402
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   403
    // This class stores glyph pointers, and is indexed based on glyph codes,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   404
    // and negative unicode values.  See the comments in
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   405
    // CCharToGlyphMapper for more details on our glyph code strategy.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   406
    private static class GlyphInfoCache extends CStrikeDisposer {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   407
        private static final int FIRST_LAYER_SIZE = 256;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   408
        private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   409
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   410
        // rdar://problem/5204197
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   411
        private boolean disposed = false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   412
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   413
        private final long[] firstLayerCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   414
        private SparseBitShiftingTwoLayerArray secondLayerCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   415
        private HashMap<Integer, Long> generalCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   416
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   417
        public GlyphInfoCache(final Font2D nativeFont,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   418
                              final FontStrikeDesc desc)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   419
        {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   420
            super(nativeFont, desc);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   421
            firstLayerCache = new long[FIRST_LAYER_SIZE];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   422
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   423
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   424
        public synchronized long get(final int index) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   425
            if (index < 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   426
                if (-index < SECOND_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   427
                    // catch common unicodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   428
                    if (secondLayerCache == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   429
                        return 0L;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   430
                    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   431
                    return secondLayerCache.get(-index);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   432
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   433
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   434
                if (index < FIRST_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   435
                    // catch common glyphcodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   436
                    return firstLayerCache[index];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   437
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   438
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   439
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   440
            if (generalCache == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   441
                return 0L;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   442
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   443
            final Long value = generalCache.get(new Integer(index));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   444
            if (value == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   445
                return 0L;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   446
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   447
            return value.longValue();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   448
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   449
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   450
        public synchronized void put(final int index, final long value) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   451
            if (index < 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   452
                if (-index < SECOND_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   453
                    // catch common unicodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   454
                    if (secondLayerCache == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   455
                        secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   456
                    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   457
                    secondLayerCache.put(-index, value);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   458
                    return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   459
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   460
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   461
                if (index < FIRST_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   462
                    // catch common glyphcodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   463
                    firstLayerCache[index] = value;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   464
                    return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   465
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   466
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   467
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   468
            if (generalCache == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   469
                generalCache = new HashMap<Integer, Long>();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   470
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   471
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   472
            generalCache.put(new Integer(index), new Long(value));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   473
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   474
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   475
        public synchronized void dispose() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   476
            // rdar://problem/5204197
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   477
            // Note that sun.font.Font2D.getStrike() actively disposes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   478
            // cleared strikeRef.  We need to check the disposed flag to
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   479
            // prevent double frees of native resources.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   480
            if (disposed) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   481
                return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   482
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   483
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   484
            super.dispose();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   485
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   486
            // clean out the first array
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   487
            disposeLongArray(firstLayerCache);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   488
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   489
            // clean out the two layer arrays
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   490
            if (secondLayerCache != null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   491
                final long[][] secondLayerLongArrayArray = secondLayerCache.cache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   492
                for (int i = 0; i < secondLayerLongArrayArray.length; i++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   493
                    final long[] longArray = secondLayerLongArrayArray[i];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   494
                    if (longArray != null) disposeLongArray(longArray);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   495
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   496
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   497
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   498
            // clean up everyone else
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   499
            if (generalCache != null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   500
                final Iterator<Long> i = generalCache.values().iterator();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   501
                while (i.hasNext()) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   502
                    final long longValue = i.next().longValue();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   503
                    if (longValue != -1 && longValue != 0) StrikeCache.freeLongPointer(longValue);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   504
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   505
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   506
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   507
            // rdar://problem/5204197
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   508
            // Finally, set the flag.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   509
            disposed = true;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   510
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   511
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   512
        private static void disposeLongArray(final long[] longArray) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   513
            for (int i = 0; i < longArray.length; i++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   514
                final long ptr = longArray[i];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   515
                if (ptr != 0 && ptr != -1) StrikeCache.freeLongPointer(ptr); // free's the native struct pointer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   516
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   517
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   518
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   519
        private static class SparseBitShiftingTwoLayerArray {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   520
            final long[][] cache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   521
            final int shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   522
            final int secondLayerLength;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   523
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   524
            public SparseBitShiftingTwoLayerArray(final int size, final int shift) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   525
                this.shift = shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   526
                this.cache = new long[1 << shift][];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   527
                this.secondLayerLength = size >> shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   528
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   529
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   530
            public long get(final int index) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   531
                final int firstIndex = index >> shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   532
                final long[] firstLayerRow = cache[firstIndex];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   533
                if (firstLayerRow == null) return 0L;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   534
                return firstLayerRow[index - (firstIndex * (1 << shift))];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   535
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   536
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   537
            public void put(final int index, final long value) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   538
                final int firstIndex = index >> shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   539
                long[] firstLayerRow = cache[firstIndex];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   540
                if (firstLayerRow == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   541
                    cache[firstIndex] = firstLayerRow = new long[secondLayerLength];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   542
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   543
                firstLayerRow[index - (firstIndex * (1 << shift))] = value;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   544
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   545
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   546
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   547
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   548
    private static class GlyphAdvanceCache {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   549
        private static final int FIRST_LAYER_SIZE = 256;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   550
        private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   551
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   552
        private final float[] firstLayerCache = new float[FIRST_LAYER_SIZE];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   553
        private SparseBitShiftingTwoLayerArray secondLayerCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   554
        private HashMap<Integer, Float> generalCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   555
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   556
        public synchronized float get(final int index) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   557
            if (index < 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   558
                if (-index < SECOND_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   559
                    // catch common unicodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   560
                    if (secondLayerCache == null) return 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   561
                    return secondLayerCache.get(-index);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   562
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   563
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   564
                if (index < FIRST_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   565
                    // catch common glyphcodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   566
                    return firstLayerCache[index];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   567
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   568
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   569
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   570
            if (generalCache == null) return 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   571
            final Float value = generalCache.get(new Integer(index));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   572
            if (value == null) return 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   573
            return value.floatValue();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   574
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   575
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   576
        public synchronized void put(final int index, final float value) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   577
            if (index < 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   578
                if (-index < SECOND_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   579
                    // catch common unicodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   580
                    if (secondLayerCache == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   581
                        secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   582
                    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   583
                    secondLayerCache.put(-index, value);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   584
                    return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   585
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   586
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   587
                if (index < FIRST_LAYER_SIZE) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   588
                    // catch common glyphcodes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   589
                    firstLayerCache[index] = value;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   590
                    return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   591
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   592
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   593
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   594
            if (generalCache == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   595
                generalCache = new HashMap<Integer, Float>();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   596
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   597
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   598
            generalCache.put(new Integer(index), new Float(value));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   599
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   600
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   601
        private static class SparseBitShiftingTwoLayerArray {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   602
            final float[][] cache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   603
            final int shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   604
            final int secondLayerLength;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   605
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   606
            public SparseBitShiftingTwoLayerArray(final int size,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   607
                                                  final int shift)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   608
            {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   609
                this.shift = shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   610
                this.cache = new float[1 << shift][];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   611
                this.secondLayerLength = size >> shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   612
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   613
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   614
            public float get(final int index) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   615
                final int firstIndex = index >> shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   616
                final float[] firstLayerRow = cache[firstIndex];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   617
                if (firstLayerRow == null) return 0L;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   618
                return firstLayerRow[index - (firstIndex * (1 << shift))];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   619
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   620
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   621
            public void put(final int index, final float value) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   622
                final int firstIndex = index >> shift;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   623
                float[] firstLayerRow = cache[firstIndex];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   624
                if (firstLayerRow == null) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   625
                    cache[firstIndex] = firstLayerRow =
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   626
                        new float[secondLayerLength];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   627
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   628
                firstLayerRow[index - (firstIndex * (1 << shift))] = value;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   629
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   630
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   631
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   632
}