1 /* 2 * Copyright (c) 2011, 2013, 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 com.sun.javafx.font; 27 28 import java.lang.ref.WeakReference; 29 import java.util.concurrent.ConcurrentHashMap; 30 import java.util.Map; 31 32 import com.sun.javafx.geom.transform.BaseTransform; 33 34 35 /* 36 * Wraps a physical font and adds an appropriate fallback resource. 37 */ 38 39 class PrismCompositeFontResource implements CompositeFontResource { 40 41 private FontResource primaryResource; 42 private FallbackResource fallbackResource; // is a composite too. 43 44 PrismCompositeFontResource(FontResource primaryResource, 45 String lookupName) { 46 // remind go through and make the typing better. 47 if (!(primaryResource instanceof PrismFontFile)) { 48 Thread.dumpStack(); 49 throw new IllegalStateException("wrong resource type"); 50 } 51 if (lookupName != null) { 52 PrismFontFactory factory = PrismFontFactory.getFontFactory(); 53 factory.compResourceMap.put(lookupName, this); 54 } 55 this.primaryResource = primaryResource; 56 int aaMode = primaryResource.getDefaultAAMode(); 57 boolean bold = primaryResource.isBold(); 58 boolean italic = primaryResource.isItalic(); 59 fallbackResource = 60 FallbackResource.getFallbackResource(bold, italic, aaMode); 61 } 62 63 public int getNumSlots() { 64 return fallbackResource.getNumSlots()+1; 65 } 66 67 public int getSlotForFont(String fontName) { 68 if (primaryResource.getFullName().equalsIgnoreCase(fontName)) { 69 return 0; 70 } 71 return fallbackResource.getSlotForFont(fontName) + 1; 72 } 73 74 public FontResource getSlotResource(int slot) { 75 if (slot == 0) { 76 return primaryResource; 77 } else { 78 FontResource fb = fallbackResource.getSlotResource(slot-1); 79 if (fb != null) { 80 return fb; 81 } else { 82 return primaryResource; 83 } 84 } 85 } 86 87 public String getFullName() { 88 return primaryResource.getFullName(); 89 } 90 91 public String getPSName() { 92 return primaryResource.getPSName(); 93 } 94 95 public String getFamilyName() { 96 return primaryResource.getFamilyName(); 97 } 98 99 public String getStyleName() { 100 return primaryResource.getStyleName(); 101 } 102 103 public String getLocaleFullName() { 104 return primaryResource.getLocaleFullName(); 105 } 106 107 public String getLocaleFamilyName() { 108 return primaryResource.getLocaleFamilyName(); 109 } 110 111 public String getLocaleStyleName() { 112 return primaryResource.getLocaleStyleName(); 113 } 114 115 public String getFileName() { 116 return primaryResource.getFileName(); 117 } 118 119 public int getFeatures() { 120 return primaryResource.getFeatures(); 121 } 122 123 public Object getPeer() { 124 return primaryResource.getPeer(); 125 } 126 127 public void setPeer(Object peer) { 128 throw new UnsupportedOperationException("Not supported"); 129 } 130 131 public boolean isEmbeddedFont() { 132 return primaryResource.isEmbeddedFont(); 133 } 134 135 public boolean isBold() { 136 return primaryResource.isBold(); 137 } 138 139 public boolean isItalic() { 140 return primaryResource.isItalic(); 141 } 142 143 CompositeGlyphMapper mapper; 144 public CharToGlyphMapper getGlyphMapper() { 145 if (mapper == null) { 146 mapper = new CompositeGlyphMapper(this); 147 } 148 return mapper; 149 } 150 151 public float[] getGlyphBoundingBox(int glyphCode, 152 float size, float[] retArr) { 153 int slot = (glyphCode >>> 24); 154 int slotglyphCode = glyphCode & CompositeGlyphMapper.GLYPHMASK; 155 FontResource slotResource = getSlotResource(slot); 156 return slotResource.getGlyphBoundingBox(slotglyphCode, size, retArr); 157 } 158 159 public float getAdvance(int glyphCode, float size) { 160 int slot = (glyphCode >>> 24); 161 int slotglyphCode = glyphCode & CompositeGlyphMapper.GLYPHMASK; 162 FontResource slotResource = getSlotResource(slot); 163 return slotResource.getAdvance(slotglyphCode, size); 164 } 165 166 Map<FontStrikeDesc, WeakReference<FontStrike>> strikeMap = 167 new ConcurrentHashMap<FontStrikeDesc, WeakReference<FontStrike>>(); 168 169 public Map<FontStrikeDesc, WeakReference<FontStrike>> getStrikeMap() { 170 return strikeMap; 171 } 172 173 public int getDefaultAAMode() { 174 return getSlotResource(0).getDefaultAAMode(); 175 } 176 177 public FontStrike getStrike(float size, BaseTransform transform) { 178 return getStrike(size, transform, getDefaultAAMode()); 179 } 180 181 public FontStrike getStrike(float size, BaseTransform transform, 182 int aaMode) { 183 FontStrikeDesc desc = new FontStrikeDesc(size, transform, aaMode); 184 WeakReference<FontStrike> ref = strikeMap.get(desc); 185 CompositeStrike strike = null; 186 if (ref != null) { 187 strike = (CompositeStrike)ref.get(); 188 } 189 if (strike == null) { 190 strike = new CompositeStrike(this, size, transform, aaMode, desc); 191 if (strike.disposer != null) { 192 ref = Disposer.addRecord(strike, strike.disposer); 193 } else { 194 ref = new WeakReference<FontStrike>(strike); 195 } 196 strikeMap.put(desc, ref); 197 } 198 return strike; 199 } 200 201 @Override 202 public boolean equals(Object obj) { 203 if (obj == null) { 204 return false; 205 } 206 if (!(obj instanceof PrismCompositeFontResource)) { 207 return false; 208 } 209 final PrismCompositeFontResource other = (PrismCompositeFontResource)obj; 210 return primaryResource.equals(other.primaryResource); 211 } 212 213 @Override 214 public int hashCode() { 215 return primaryResource.hashCode(); 216 } 217 }