86 boolean isRegistered = true; 87 88 /* The glyph image data is stored only in a texture, and we 89 * manage how much of that is kept around. We clearly want 90 * to keep a reference to the strike that created that data. 91 */ 92 Map<FontStrikeDesc, WeakReference<PrismFontStrike>> strikeMap = 93 new ConcurrentHashMap<FontStrikeDesc, WeakReference<PrismFontStrike>>(); 94 95 protected PrismFontFile(String name, String filename, int fIndex, 96 boolean register, boolean embedded, 97 boolean copy, boolean tracked) throws Exception { 98 this.filename = filename; 99 this.isRegistered = register; 100 this.isEmbedded = embedded; 101 this.isCopy = copy; 102 this.isTracked = tracked; 103 init(name, fIndex); 104 } 105 106 WeakReference<PrismFontFile> createFileDisposer(PrismFontFactory factory) { 107 FileDisposer disposer = new FileDisposer(filename, isTracked); 108 WeakReference<PrismFontFile> ref = Disposer.addRecord(this, disposer); 109 disposer.setFactory(factory, ref); 110 return ref; 111 } 112 113 void setIsDecoded(boolean decoded) { 114 isDecoded = decoded; 115 } 116 117 /* This is called only for fonts where a temp file was created 118 */ 119 protected synchronized void disposeOnShutdown() { 120 if (isCopy || isDecoded) { 121 AccessController.doPrivileged( 122 (PrivilegedAction<Void>) () -> { 123 try { 124 boolean delOK = (new File(filename)).delete(); 125 if (!delOK && PrismFontFactory.debugFonts) { 126 System.err.println("Temp file not deleted : " 127 + filename); 128 } 129 /* Embedded fonts (copy) can also be decoded. 130 * Set both flags to false to avoid double deletes. 131 */ 132 isCopy = isDecoded = false; 133 } catch (Exception e) { 134 } 135 return null; 136 } 137 ); 138 if (PrismFontFactory.debugFonts) { 139 System.err.println("Temp file deleted: " + filename); 140 } 141 } 142 } 143 144 public int getDefaultAAMode() { 145 return AA_GREYSCALE; 146 } 147 148 public boolean isInstalledFont() { 149 if (fontInstallationType == -1) { 150 PrismFontFactory factory = PrismFontFactory.getFontFactory(); 151 fontInstallationType = factory.isInstalledFont(filename) ? 1 : 0; 152 } 153 return fontInstallationType > 0; 154 } 155 156 static class FileDisposer implements DisposerRecord { 157 String fileName; 158 boolean isTracked; 159 PrismFontFactory factory; 160 WeakReference<PrismFontFile> refKey; 161 162 public FileDisposer(String fileName, boolean isTracked) { 163 this.fileName = fileName; 164 this.isTracked = isTracked; 165 } 166 167 public void setFactory(PrismFontFactory factory, 168 WeakReference<PrismFontFile> refKey) { 169 this.factory = factory; 170 this.refKey = refKey; 171 } 172 173 public synchronized void dispose() { 174 if (fileName != null) { 175 AccessController.doPrivileged( 176 (PrivilegedAction<Void>) () -> { 177 try { 178 File file = new File(fileName); 179 int size = (int)file.length(); 180 file.delete(); 181 // decrement tracker only after 182 // successful deletion. 183 if (isTracked) { 184 FontFileWriter.FontTracker. 185 getTracker().subBytes(size); 186 } 187 if (factory != null && refKey != null) { 188 Object o = refKey.get(); 189 if (o == null) { 190 factory.removeTmpFont(refKey); 191 factory = null; 192 refKey = null; 193 } 194 } 195 if (PrismFontFactory.debugFonts) { 196 System.err.println("FileDisposer=" + fileName); 197 } | 86 boolean isRegistered = true; 87 88 /* The glyph image data is stored only in a texture, and we 89 * manage how much of that is kept around. We clearly want 90 * to keep a reference to the strike that created that data. 91 */ 92 Map<FontStrikeDesc, WeakReference<PrismFontStrike>> strikeMap = 93 new ConcurrentHashMap<FontStrikeDesc, WeakReference<PrismFontStrike>>(); 94 95 protected PrismFontFile(String name, String filename, int fIndex, 96 boolean register, boolean embedded, 97 boolean copy, boolean tracked) throws Exception { 98 this.filename = filename; 99 this.isRegistered = register; 100 this.isEmbedded = embedded; 101 this.isCopy = copy; 102 this.isTracked = tracked; 103 init(name, fIndex); 104 } 105 106 WeakReference<PrismFontFile> createFileDisposer(PrismFontFactory factory, 107 FileRefCounter rc) { 108 FileDisposer disposer = new FileDisposer(filename, isTracked, rc); 109 WeakReference<PrismFontFile> ref = Disposer.addRecord(this, disposer); 110 disposer.setFactory(factory, ref); 111 return ref; 112 } 113 114 void setIsDecoded(boolean decoded) { 115 isDecoded = decoded; 116 } 117 118 /* This is called only for fonts where a temp file was created 119 */ 120 protected synchronized void disposeOnShutdown() { 121 if (isCopy || isDecoded) { 122 AccessController.doPrivileged( 123 (PrivilegedAction<Void>) () -> { 124 try { 125 /* Although there is likely no harm in calling 126 * delete on a file > once, we want to refrain 127 * from deleting it until the shutdown hook 128 * code in subclasses has had an opportunity 129 * to clean up native accesses on the resource. 130 */ 131 if (decFileRefCount() > 0) { 132 return null; 133 } 134 boolean delOK = (new File(filename)).delete(); 135 if (!delOK && PrismFontFactory.debugFonts) { 136 System.err.println("Temp file not deleted : " 137 + filename); 138 } 139 /* Embedded fonts (copy) can also be decoded. 140 * Set both flags to false to avoid double deletes. 141 */ 142 isCopy = isDecoded = false; 143 } catch (Exception e) { 144 } 145 return null; 146 } 147 ); 148 if (PrismFontFactory.debugFonts) { 149 System.err.println("Temp file deleted: " + filename); 150 } 151 } 152 } 153 154 public int getDefaultAAMode() { 155 return AA_GREYSCALE; 156 } 157 158 public boolean isInstalledFont() { 159 if (fontInstallationType == -1) { 160 PrismFontFactory factory = PrismFontFactory.getFontFactory(); 161 fontInstallationType = factory.isInstalledFont(filename) ? 1 : 0; 162 } 163 return fontInstallationType > 0; 164 } 165 166 167 /* A TTC file resource is shared, so reference count and delete 168 * only when no longer using the file from any PrismFontFile instance 169 */ 170 static class FileRefCounter { 171 private int refCnt = 1; // start with 1. 172 173 synchronized int getRefCount() { 174 return refCnt; 175 } 176 177 synchronized int increment() { 178 return ++refCnt; 179 } 180 181 synchronized int decrement() { 182 return (refCnt == 0) ? 0 : --refCnt; 183 } 184 } 185 186 private FileRefCounter refCounter = null; 187 188 FileRefCounter getFileRefCounter() { 189 return refCounter; 190 } 191 192 FileRefCounter createFileRefCounter() { 193 refCounter = new FileRefCounter(); 194 return refCounter; 195 } 196 197 void setAndIncFileRefCounter(FileRefCounter rc) { 198 this.refCounter = rc; 199 this.refCounter.increment(); 200 } 201 202 int decFileRefCount() { 203 if (refCounter == null) { 204 return 0; 205 } else { 206 return refCounter.decrement(); 207 } 208 } 209 210 static class FileDisposer implements DisposerRecord { 211 String fileName; 212 boolean isTracked; 213 FileRefCounter refCounter; 214 PrismFontFactory factory; 215 WeakReference<PrismFontFile> refKey; 216 217 public FileDisposer(String fileName, boolean isTracked, 218 FileRefCounter rc) { 219 this.fileName = fileName; 220 this.isTracked = isTracked; 221 this.refCounter = rc; 222 } 223 224 public void setFactory(PrismFontFactory factory, 225 WeakReference<PrismFontFile> refKey) { 226 this.factory = factory; 227 this.refKey = refKey; 228 } 229 230 public synchronized void dispose() { 231 if (fileName != null) { 232 AccessController.doPrivileged( 233 (PrivilegedAction<Void>) () -> { 234 try { 235 if (refCounter != null && 236 refCounter.decrement() > 0) 237 { 238 return null; 239 } 240 File file = new File(fileName); 241 int size = (int)file.length(); 242 file.delete(); 243 // decrement tracker only after 244 // successful deletion. 245 if (isTracked) { 246 FontFileWriter.FontTracker. 247 getTracker().subBytes(size); 248 } 249 if (factory != null && refKey != null) { 250 Object o = refKey.get(); 251 if (o == null) { 252 factory.removeTmpFont(refKey); 253 factory = null; 254 refKey = null; 255 } 256 } 257 if (PrismFontFactory.debugFonts) { 258 System.err.println("FileDisposer=" + fileName); 259 } |