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