< prev index next >

src/java.desktop/share/classes/sun/font/SunLayoutEngine.java

Print this page




  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 /*
  27  *
  28  * (C) Copyright IBM Corp. 2003 - All Rights Reserved
  29  */
  30 
  31 package sun.font;
  32 
  33 import sun.font.GlyphLayout.*;



  34 import java.awt.geom.Point2D;
  35 import java.lang.ref.SoftReference;
  36 import java.util.concurrent.ConcurrentHashMap;
  37 import java.util.Locale;
  38 import java.util.WeakHashMap;
  39 
  40 /*
  41  * different ways to do this
  42  * 1) each physical font2d keeps a hashtable mapping scripts to layout
  43  * engines, we query and fill this cache.
  44  * 2) we keep a mapping independent of font using the key Most likely
  45  * few fonts will be used, so option 2 seems better
  46  *
  47  * Once we know which engine to use for a font, we always know, so we
  48  * shouldn't have to recheck each time we do layout.  So the cache is
  49  * ok.
  50  *
  51  * Should we reuse engines?  We could instantiate an engine for each
  52  * font/script pair.  The engine would hold onto the table(s) from the
  53  * font that it needs.  If we have multiple threads using the same
  54  * engine, we still need to keep the state separate, so the native
  55  * engines would still need to be allocated for each call, since they
  56  * keep their state in themselves.  If they used the passed-in GVData
  57  * arrays directly (with some checks for space) then since each GVData


 133             cache = new ConcurrentHashMap<>();
 134             cacheref = new SoftReference<>(cache);
 135         }
 136 
 137         LayoutEngine e = cache.get(key);
 138         if (e == null) {
 139             LayoutEngineKey copy = key.copy();
 140             e = new SunLayoutEngine(copy);
 141             cache.put(copy, e);
 142         }
 143         return e;
 144     }
 145     private SoftReference<ConcurrentHashMap<LayoutEngineKey, LayoutEngine>> cacheref =
 146         new SoftReference<>(null);
 147 
 148     private SunLayoutEngine(LayoutEngineKey key) {
 149         this.key = key;
 150     }
 151 
 152     static WeakHashMap<Font2D, Boolean> aatInfo = new WeakHashMap<>();


 153 
 154     private boolean isAAT(Font2D font) {
 155        Boolean aatObj;
 156        synchronized (aatInfo) {
 157            aatObj = aatInfo.get(font);
 158        }
 159        if (aatObj != null) {
 160           return aatObj.booleanValue();
 161        }
 162        boolean aat = false;
 163        if (font instanceof TrueTypeFont) {
 164            TrueTypeFont ttf = (TrueTypeFont)font;
 165            aat =  ttf.getDirectoryEntry(TrueTypeFont.morxTag) != null ||
 166                   ttf.getDirectoryEntry(TrueTypeFont.mortTag) != null;
 167        } else if (font instanceof PhysicalFont) {
 168            PhysicalFont pf = (PhysicalFont)font;
 169            aat =  pf.getTableBytes(TrueTypeFont.morxTag) != null ||
 170                   pf.getTableBytes(TrueTypeFont.mortTag) != null;
 171        }
 172        synchronized (aatInfo) {
 173            aatInfo.put(font, Boolean.valueOf(aat));
 174        }
 175        return aat;
 176     }
 177 








 178     public void layout(FontStrikeDesc desc, float[] mat, float ptSize, int gmask,
 179                        int baseIndex, TextRecord tr, int typo_flags,
 180                        Point2D.Float pt, GVData data) {
 181         Font2D font = key.font();
 182         FontStrike strike = font.getStrike(desc);
 183         long layoutTables = font.getLayoutTableCache();
 184         long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX
 185         // pScaler probably not needed long term.
 186         long pScaler = 0L;
 187         if (font instanceof FileFont) {
 188             pScaler = ((FileFont)font).getScaler().nativeScaler;
 189         }


 190         shape(font, strike, ptSize, mat, pScaler, pNativeFont,
 191               layoutTables, isAAT(font),
 192               tr.text, data, key.script(),
 193               tr.start, tr.limit, baseIndex, pt,
 194               typo_flags, gmask);
 195     }

 196 
 197     /* Native method to invoke harfbuzz layout engine */
 198     private static native boolean
 199         shape(Font2D font, FontStrike strike, float ptSize, float[] mat,
 200               long pscaler, long pNativeFont, long layoutTables, boolean aat,
 201               char[] chars, GVData data,
 202               int script, int offset, int limit,
 203               int baseIndex, Point2D.Float pt, int typo_flags, int slot);


































 204 }


  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 /*
  27  *
  28  * (C) Copyright IBM Corp. 2003 - All Rights Reserved
  29  */
  30 
  31 package sun.font;
  32 
  33 import sun.font.GlyphLayout.*;
  34 import sun.java2d.Disposer;
  35 import sun.java2d.DisposerRecord;
  36 
  37 import java.awt.geom.Point2D;
  38 import java.lang.ref.SoftReference;
  39 import java.util.concurrent.ConcurrentHashMap;

  40 import java.util.WeakHashMap;
  41 
  42 /*
  43  * different ways to do this
  44  * 1) each physical font2d keeps a hashtable mapping scripts to layout
  45  * engines, we query and fill this cache.
  46  * 2) we keep a mapping independent of font using the key Most likely
  47  * few fonts will be used, so option 2 seems better
  48  *
  49  * Once we know which engine to use for a font, we always know, so we
  50  * shouldn't have to recheck each time we do layout.  So the cache is
  51  * ok.
  52  *
  53  * Should we reuse engines?  We could instantiate an engine for each
  54  * font/script pair.  The engine would hold onto the table(s) from the
  55  * font that it needs.  If we have multiple threads using the same
  56  * engine, we still need to keep the state separate, so the native
  57  * engines would still need to be allocated for each call, since they
  58  * keep their state in themselves.  If they used the passed-in GVData
  59  * arrays directly (with some checks for space) then since each GVData


 135             cache = new ConcurrentHashMap<>();
 136             cacheref = new SoftReference<>(cache);
 137         }
 138 
 139         LayoutEngine e = cache.get(key);
 140         if (e == null) {
 141             LayoutEngineKey copy = key.copy();
 142             e = new SunLayoutEngine(copy);
 143             cache.put(copy, e);
 144         }
 145         return e;
 146     }
 147     private SoftReference<ConcurrentHashMap<LayoutEngineKey, LayoutEngine>> cacheref =
 148         new SoftReference<>(null);
 149 
 150     private SunLayoutEngine(LayoutEngineKey key) {
 151         this.key = key;
 152     }
 153 
 154     static WeakHashMap<Font2D, Boolean> aatInfo = new WeakHashMap<>();
 155     private static final WeakHashMap<Font2D, FaceRef> facePtr =
 156             new WeakHashMap<>();
 157 
 158     private static boolean isAAT(Font2D font) {
 159        Boolean aatObj;
 160        synchronized (aatInfo) {
 161            aatObj = aatInfo.get(font);
 162        }
 163        if (aatObj != null) {
 164           return aatObj.booleanValue();
 165        }
 166        boolean aat = false;
 167        if (font instanceof TrueTypeFont) {
 168            TrueTypeFont ttf = (TrueTypeFont)font;
 169            aat =  ttf.getDirectoryEntry(TrueTypeFont.morxTag) != null ||
 170                   ttf.getDirectoryEntry(TrueTypeFont.mortTag) != null;
 171        } else if (font instanceof PhysicalFont) {
 172            PhysicalFont pf = (PhysicalFont)font;
 173            aat =  pf.getTableBytes(TrueTypeFont.morxTag) != null ||
 174                   pf.getTableBytes(TrueTypeFont.mortTag) != null;
 175        }
 176        synchronized (aatInfo) {
 177            aatInfo.put(font, Boolean.valueOf(aat));
 178        }
 179        return aat;
 180     }
 181 
 182     private long getFacePtr(Font2D font2D) {
 183         FaceRef ref;
 184         synchronized (facePtr) {
 185             ref = facePtr.computeIfAbsent(font2D, FaceRef::new);
 186         }
 187         return ref.getNativePtr();
 188     }
 189 
 190     public void layout(FontStrikeDesc desc, float[] mat, float ptSize, int gmask,
 191                        int baseIndex, TextRecord tr, int typo_flags,
 192                        Point2D.Float pt, GVData data) {
 193         Font2D font = key.font();
 194         FontStrike strike = font.getStrike(desc);

 195         long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX
 196         // pScaler probably not needed long term.
 197         long pScaler = 0L;
 198         if (font instanceof FileFont) {
 199             pScaler = ((FileFont)font).getScaler().nativeScaler;
 200         }
 201         long pFace = getFacePtr(font);
 202         if (pFace != 0) {
 203             shape(font, strike, ptSize, mat, pScaler, pNativeFont,
 204                     pFace, isAAT(font),
 205                     tr.text, data, key.script(),
 206                     tr.start, tr.limit, baseIndex, pt,
 207                     typo_flags, gmask);
 208         }
 209     }
 210 
 211     /* Native method to invoke harfbuzz layout engine */
 212     private static native boolean
 213         shape(Font2D font, FontStrike strike, float ptSize, float[] mat,
 214               long pscaler, long pNativeFont, long pFace, boolean aat,
 215               char[] chars, GVData data,
 216               int script, int offset, int limit,
 217               int baseIndex, Point2D.Float pt, int typo_flags, int slot);
 218 
 219     private static native long createFace(Font2D font,
 220                                           boolean aat,
 221                                           long platformNativeFontPtr,
 222                                           long layoutTables);
 223 
 224     private static native void disposeFace(long facePtr);
 225 
 226     private static class FaceRef implements DisposerRecord {
 227         private Font2D font;
 228         private Long facePtr;
 229 
 230         private FaceRef(Font2D font) {
 231             this.font = font;
 232         }
 233 
 234         private synchronized long getNativePtr() {
 235             if (facePtr == null) {
 236                 facePtr = createFace(font, isAAT(font),
 237                         font.getPlatformNativeFontPtr(),
 238                         font.getLayoutTableCache());
 239                 if (facePtr != 0) {
 240                     Disposer.addObjectRecord(font, this);
 241                 }
 242                 font = null;
 243             }
 244             return facePtr;
 245         }
 246 
 247         @Override
 248         public void dispose() {
 249             disposeFace(facePtr);
 250         }
 251     }
 252 }
< prev index next >