1 /*
2  * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.font;
27 
28 import java.awt.Font;
29 import java.awt.geom.AffineTransform;
30 import java.awt.geom.GeneralPath;
31 import java.awt.geom.Point2D;
32 import java.awt.geom.Rectangle2D;
33 import java.util.concurrent.ConcurrentHashMap;
34 
35 
36 public abstract class PhysicalStrike extends FontStrike {
37 
38     static final long INTMASK = 0xffffffffL;
39     static boolean longAddresses;
40     static {
41         switch (StrikeCache.nativeAddressSize) {
42         case 8: longAddresses = true; break;
43         case 4: longAddresses = false; break;
44         default: throw new RuntimeException("Unexpected address size");
45         }
46     }
47 
48     private PhysicalFont physicalFont;
49     protected CharToGlyphMapper mapper;
50     /* the ScalerContext is a native structure pre-filled with the
51      * info needed to setup the scaler for this strike. Its immutable
52      * so we set it up when the strike is created and free it when the
53      * strike is disposed. There's then no need to pass the info down
54      * separately to native on every call to the scaler.
55      */
56     protected long pScalerContext;
57 
58     /* Only one of these two arrays is non-null.
59      * use the one that matches size of an address (32 or 64 bits)
60      */
61     protected long[] longGlyphImages;
62     protected int[] intGlyphImages;
63 
64     /* Used by the TrueTypeFont subclass, which is the only client
65      * of getGlyphPoint(). The field and method are here because
66      * there is no TrueTypeFontStrike subclass.
67      * This map is a cache of the positions of points on the outline
68      * of a TrueType glyph. It is used by the OpenType layout engine
69      * to perform mark positioning. Without this cache every position
70      * request involves scaling and hinting the glyph outline potentially
71      * over and over again.
72      */
73     ConcurrentHashMap<Integer, Point2D.Float> glyphPointMapCache;
74 
75     protected boolean getImageWithAdvance;
76     protected static final int complexTX =
77         AffineTransform.TYPE_FLIP |
78         AffineTransform.TYPE_GENERAL_SCALE |
79         AffineTransform.TYPE_GENERAL_ROTATION |
80         AffineTransform.TYPE_GENERAL_TRANSFORM |
81         AffineTransform.TYPE_QUADRANT_ROTATION;
82 
PhysicalStrike(PhysicalFont physicalFont, FontStrikeDesc desc)83     PhysicalStrike(PhysicalFont physicalFont, FontStrikeDesc desc) {
84         this.physicalFont = physicalFont;
85         this.desc = desc;
86     }
87 
PhysicalStrike()88     protected PhysicalStrike() {
89     }
90     /* A number of methods are delegated by the strike to the scaler
91      * context which is a shared resource on a physical font.
92      */
93 
getNumGlyphs()94     public int getNumGlyphs() {
95         return physicalFont.getNumGlyphs();
96     }
97 
98     /* These 3 metrics methods below should be implemented to return
99      * values in user space.
100      */
getFontMetrics()101     StrikeMetrics getFontMetrics() {
102         if (strikeMetrics == null) {
103             strikeMetrics =
104                 physicalFont.getFontMetrics(pScalerContext);
105         }
106         return strikeMetrics;
107     }
108 
getCodePointAdvance(int cp)109     float getCodePointAdvance(int cp) {
110         return getGlyphAdvance(physicalFont.getMapper().charToGlyph(cp));
111     }
112 
getCharMetrics(char ch)113    Point2D.Float getCharMetrics(char ch) {
114         return getGlyphMetrics(physicalFont.getMapper().charToGlyph(ch));
115     }
116 
getSlot0GlyphImagePtrs(int[] glyphCodes, long[] images, int len)117     int getSlot0GlyphImagePtrs(int[] glyphCodes, long[] images, int  len) {
118         return 0;
119     }
120 
121     /* Used by the OpenType engine for mark positioning.
122      */
getGlyphPoint(int glyphCode, int ptNumber)123     Point2D.Float getGlyphPoint(int glyphCode, int ptNumber) {
124         Point2D.Float gp = null;
125         Integer ptKey = Integer.valueOf(glyphCode<<16|ptNumber);
126         if (glyphPointMapCache == null) {
127             synchronized (this) {
128                 if (glyphPointMapCache == null) {
129                     glyphPointMapCache =
130                         new ConcurrentHashMap<Integer, Point2D.Float>();
131                 }
132             }
133         } else {
134             gp = glyphPointMapCache.get(ptKey);
135         }
136 
137         if (gp == null) {
138             gp = (physicalFont.getGlyphPoint(pScalerContext, glyphCode, ptNumber));
139             adjustPoint(gp);
140             glyphPointMapCache.put(ptKey, gp);
141         }
142         return gp;
143     }
144 
adjustPoint(Point2D.Float pt)145     protected void adjustPoint(Point2D.Float pt) {
146     }
147 }
148