src/share/classes/sun/font/FileFont.java

Print this page
rev 1297 : [mq]: fontmanager.patch


 141      * For safety we also invalidate all strike's scaler context.
 142      * So, in case they cache pointer to native scaler
 143      * it will not ever be used.
 144      *
 145      * It also appears desirable to remove all the entries from the
 146      * cache so no other code will pick them up. But we can't just
 147      * 'delete' them as code may be using them. And simply dropping
 148      * the reference to the cache will make the reference objects
 149      * unreachable and so they will not get disposed.
 150      * Since a strike may hold (via java arrays) native pointers to many
 151      * rasterised glyphs, this would be a memory leak.
 152      * The solution is :
 153      * - to move all the entries to another map where they
 154      *   are no longer locatable
 155      * - update FontStrikeDisposer to be able to distinguish which
 156      * map they are held in via a boolean flag
 157      * Since this isn't expected to be anything other than an extremely
 158      * rare maybe it is not worth doing this last part.
 159      */
 160     synchronized void deregisterFontAndClearStrikeCache() {
 161         FontManager.deRegisterBadFont(this);

 162 
 163         for (Reference strikeRef : strikeCache.values()) {
 164             if (strikeRef != null) {
 165                 /* NB we know these are all FileFontStrike instances
 166                  * because the cache is on this FileFont
 167                  */
 168                 FileFontStrike strike = (FileFontStrike)strikeRef.get();
 169                 if (strike != null && strike.pScalerContext != 0L) {
 170                     scaler.invalidateScalerContext(strike.pScalerContext);
 171                 }
 172             }
 173         }
 174         scaler.dispose();
 175         scaler = FontManager.getNullScaler();
 176     }
 177 
 178     StrikeMetrics getFontMetrics(long pScalerContext) {
 179         try {
 180             return getScaler().getFontMetrics(pScalerContext);
 181         } catch (FontScalerException fe) {
 182             scaler = FontManager.getNullScaler();
 183             return getFontMetrics(pScalerContext);
 184         }
 185     }
 186 
 187     float getGlyphAdvance(long pScalerContext, int glyphCode) {
 188         try {
 189             return getScaler().getGlyphAdvance(pScalerContext, glyphCode);
 190         } catch (FontScalerException fe) {
 191             scaler = FontManager.getNullScaler();
 192             return getGlyphAdvance(pScalerContext, glyphCode);
 193         }
 194     }
 195 
 196     void getGlyphMetrics(long pScalerContext, int glyphCode, Point2D.Float metrics) {
 197         try {
 198             getScaler().getGlyphMetrics(pScalerContext, glyphCode, metrics);
 199         } catch (FontScalerException fe) {
 200             scaler = FontManager.getNullScaler();
 201             getGlyphMetrics(pScalerContext, glyphCode, metrics);
 202         }
 203     }
 204 
 205     long getGlyphImage(long pScalerContext, int glyphCode) {
 206         try {
 207             return getScaler().getGlyphImage(pScalerContext, glyphCode);
 208         } catch (FontScalerException fe) {
 209             scaler = FontManager.getNullScaler();
 210             return getGlyphImage(pScalerContext, glyphCode);
 211         }
 212     }
 213 
 214     Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext, int glyphCode) {
 215         try {
 216             return getScaler().getGlyphOutlineBounds(pScalerContext, glyphCode);
 217         } catch (FontScalerException fe) {
 218             scaler = FontManager.getNullScaler();
 219             return getGlyphOutlineBounds(pScalerContext, glyphCode);
 220         }
 221     }
 222 
 223     GeneralPath getGlyphOutline(long pScalerContext, int glyphCode, float x, float y) {
 224         try {
 225             return getScaler().getGlyphOutline(pScalerContext, glyphCode, x, y);
 226         } catch (FontScalerException fe) {
 227             scaler = FontManager.getNullScaler();
 228             return getGlyphOutline(pScalerContext, glyphCode, x, y);
 229         }
 230     }
 231 
 232     GeneralPath getGlyphVectorOutline(long pScalerContext, int[] glyphs, int numGlyphs, float x, float y) {
 233         try {
 234             return getScaler().getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
 235         } catch (FontScalerException fe) {
 236             scaler = FontManager.getNullScaler();
 237             return getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
 238         }
 239     }
 240 
 241     /* T1 & TT implementation differ so this method is abstract.
 242        NB: null should not be returned here! */
 243     protected abstract FontScaler getScaler();
 244 
 245     protected long getUnitsPerEm() {
 246         return getScaler().getUnitsPerEm();
 247     }
 248 
 249     private static class CreatedFontFileDisposerRecord
 250         implements DisposerRecord {
 251 
 252         File fontFile = null;
 253         CreatedFontTracker tracker;
 254 
 255         private CreatedFontFileDisposerRecord(File file,
 256                                               CreatedFontTracker tracker) {


 258             this.tracker = tracker;
 259         }
 260 
 261         public void dispose() {
 262             java.security.AccessController.doPrivileged(
 263                  new java.security.PrivilegedAction() {
 264                       public Object run() {
 265                           if (fontFile != null) {
 266                               try {
 267                                   if (tracker != null) {
 268                                       tracker.subBytes((int)fontFile.length());
 269                                   }
 270                                   /* REMIND: is it possible that the file is
 271                                    * still open? It will be closed when the
 272                                    * font2D is disposed but could this code
 273                                    * execute first? If so the file would not
 274                                    * be deleted on MS-windows.
 275                                    */
 276                                   fontFile.delete();
 277                                   /* remove from delete on exit hook list : */
 278                                   FontManager.tmpFontFiles.remove(fontFile);

 279                               } catch (Exception e) {
 280                               }
 281                           }
 282                           return null;
 283                       }
 284             });
 285         }
 286     }
 287 }


 141      * For safety we also invalidate all strike's scaler context.
 142      * So, in case they cache pointer to native scaler
 143      * it will not ever be used.
 144      *
 145      * It also appears desirable to remove all the entries from the
 146      * cache so no other code will pick them up. But we can't just
 147      * 'delete' them as code may be using them. And simply dropping
 148      * the reference to the cache will make the reference objects
 149      * unreachable and so they will not get disposed.
 150      * Since a strike may hold (via java arrays) native pointers to many
 151      * rasterised glyphs, this would be a memory leak.
 152      * The solution is :
 153      * - to move all the entries to another map where they
 154      *   are no longer locatable
 155      * - update FontStrikeDisposer to be able to distinguish which
 156      * map they are held in via a boolean flag
 157      * Since this isn't expected to be anything other than an extremely
 158      * rare maybe it is not worth doing this last part.
 159      */
 160     synchronized void deregisterFontAndClearStrikeCache() {
 161         SunFontManager fm = SunFontManager.getInstance();
 162         fm.deRegisterBadFont(this);
 163 
 164         for (Reference strikeRef : strikeCache.values()) {
 165             if (strikeRef != null) {
 166                 /* NB we know these are all FileFontStrike instances
 167                  * because the cache is on this FileFont
 168                  */
 169                 FileFontStrike strike = (FileFontStrike)strikeRef.get();
 170                 if (strike != null && strike.pScalerContext != 0L) {
 171                     scaler.invalidateScalerContext(strike.pScalerContext);
 172                 }
 173             }
 174         }
 175         scaler.dispose();
 176         scaler = FontScaler.getNullScaler();
 177     }
 178 
 179     StrikeMetrics getFontMetrics(long pScalerContext) {
 180         try {
 181             return getScaler().getFontMetrics(pScalerContext);
 182         } catch (FontScalerException fe) {
 183             scaler = FontScaler.getNullScaler();
 184             return getFontMetrics(pScalerContext);
 185         }
 186     }
 187 
 188     float getGlyphAdvance(long pScalerContext, int glyphCode) {
 189         try {
 190             return getScaler().getGlyphAdvance(pScalerContext, glyphCode);
 191         } catch (FontScalerException fe) {
 192             scaler = FontScaler.getNullScaler();
 193             return getGlyphAdvance(pScalerContext, glyphCode);
 194         }
 195     }
 196 
 197     void getGlyphMetrics(long pScalerContext, int glyphCode, Point2D.Float metrics) {
 198         try {
 199             getScaler().getGlyphMetrics(pScalerContext, glyphCode, metrics);
 200         } catch (FontScalerException fe) {
 201             scaler = FontScaler.getNullScaler();
 202             getGlyphMetrics(pScalerContext, glyphCode, metrics);
 203         }
 204     }
 205 
 206     long getGlyphImage(long pScalerContext, int glyphCode) {
 207         try {
 208             return getScaler().getGlyphImage(pScalerContext, glyphCode);
 209         } catch (FontScalerException fe) {
 210             scaler = FontScaler.getNullScaler();
 211             return getGlyphImage(pScalerContext, glyphCode);
 212         }
 213     }
 214 
 215     Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext, int glyphCode) {
 216         try {
 217             return getScaler().getGlyphOutlineBounds(pScalerContext, glyphCode);
 218         } catch (FontScalerException fe) {
 219             scaler = FontScaler.getNullScaler();
 220             return getGlyphOutlineBounds(pScalerContext, glyphCode);
 221         }
 222     }
 223 
 224     GeneralPath getGlyphOutline(long pScalerContext, int glyphCode, float x, float y) {
 225         try {
 226             return getScaler().getGlyphOutline(pScalerContext, glyphCode, x, y);
 227         } catch (FontScalerException fe) {
 228             scaler = FontScaler.getNullScaler();
 229             return getGlyphOutline(pScalerContext, glyphCode, x, y);
 230         }
 231     }
 232 
 233     GeneralPath getGlyphVectorOutline(long pScalerContext, int[] glyphs, int numGlyphs, float x, float y) {
 234         try {
 235             return getScaler().getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
 236         } catch (FontScalerException fe) {
 237             scaler = FontScaler.getNullScaler();
 238             return getGlyphVectorOutline(pScalerContext, glyphs, numGlyphs, x, y);
 239         }
 240     }
 241 
 242     /* T1 & TT implementation differ so this method is abstract.
 243        NB: null should not be returned here! */
 244     protected abstract FontScaler getScaler();
 245 
 246     protected long getUnitsPerEm() {
 247         return getScaler().getUnitsPerEm();
 248     }
 249 
 250     private static class CreatedFontFileDisposerRecord
 251         implements DisposerRecord {
 252 
 253         File fontFile = null;
 254         CreatedFontTracker tracker;
 255 
 256         private CreatedFontFileDisposerRecord(File file,
 257                                               CreatedFontTracker tracker) {


 259             this.tracker = tracker;
 260         }
 261 
 262         public void dispose() {
 263             java.security.AccessController.doPrivileged(
 264                  new java.security.PrivilegedAction() {
 265                       public Object run() {
 266                           if (fontFile != null) {
 267                               try {
 268                                   if (tracker != null) {
 269                                       tracker.subBytes((int)fontFile.length());
 270                                   }
 271                                   /* REMIND: is it possible that the file is
 272                                    * still open? It will be closed when the
 273                                    * font2D is disposed but could this code
 274                                    * execute first? If so the file would not
 275                                    * be deleted on MS-windows.
 276                                    */
 277                                   fontFile.delete();
 278                                   /* remove from delete on exit hook list : */
 279                                   // FIXME: still need to be refactored
 280                                   SunFontManager.getInstance().tmpFontFiles.remove(fontFile);
 281                               } catch (Exception e) {
 282                               }
 283                           }
 284                           return null;
 285                       }
 286             });
 287         }
 288     }
 289 }