< prev index next >

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

Print this page




  86  *
  87  * I'd expect that the majority of scripts use the default mapper for
  88  * a particular font.  Loading the hastable with 40 or so keys 30+ of
  89  * which all map to the same object is unfortunate.  It might be worth
  90  * instead having a per-font list of 'scripts with non-default
  91  * engines', e.g. the factory has a hashtable mapping fonts to 'script
  92  * lists' (the factory has this since the design potentially has other
  93  * factories, though I admit there's no client for this yet and no
  94  * public api) and then the script list is queried for the script in
  95  * question.  it can be preloaded at creation time with all the
  96  * scripts that don't have default engines-- either a list or a hash
  97  * table, so a null return from the table means 'default' and not 'i
  98  * don't know yet'.
  99  *
 100  * On the other hand, in most all cases the number of unique
 101  * script/font combinations will be small, so a flat hashtable should
 102  * suffice.
 103  * */
 104 public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory {
 105     private static native void initGVIDs();

 106     static {
 107         FontManagerNativeLibrary.load();
 108         initGVIDs();










 109     }
 110 
 111     private LayoutEngineKey key;
 112 
 113     private static LayoutEngineFactory instance;
 114 
 115     public static LayoutEngineFactory instance() {
 116         if (instance == null) {
 117             instance = new SunLayoutEngine();
 118         }
 119         return instance;
 120     }
 121 
 122     private SunLayoutEngine() {
 123         // actually a factory, key is null so layout cannot be called on it
 124     }
 125 
 126     public LayoutEngine getEngine(Font2D font, int script, int lang) {
 127         return getEngine(new LayoutEngineKey(font, script, lang));
 128     }


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













 153     public void layout(FontStrikeDesc desc, float[] mat, int gmask,
 154                        int baseIndex, TextRecord tr, int typo_flags,
 155                        Point2D.Float pt, GVData data) {
 156         Font2D font = key.font();
 157         FontStrike strike = font.getStrike(desc);
 158         long layoutTables = font.getLayoutTableCache();

 159         nativeLayout(font, strike, mat, gmask, baseIndex,
 160              tr.text, tr.start, tr.limit, tr.min, tr.max,
 161              key.script(), key.lang(), typo_flags, pt, data,
 162              font.getUnitsPerEm(), layoutTables);












 163     }
 164 

 165     private static native void
 166         nativeLayout(Font2D font, FontStrike strike, float[] mat, int gmask,
 167              int baseIndex, char[] chars, int offset, int limit,
 168              int min, int max, int script, int lang, int typo_flags,
 169              Point2D.Float pt, GVData data, long upem, long layoutTables);









 170 }


  86  *
  87  * I'd expect that the majority of scripts use the default mapper for
  88  * a particular font.  Loading the hastable with 40 or so keys 30+ of
  89  * which all map to the same object is unfortunate.  It might be worth
  90  * instead having a per-font list of 'scripts with non-default
  91  * engines', e.g. the factory has a hashtable mapping fonts to 'script
  92  * lists' (the factory has this since the design potentially has other
  93  * factories, though I admit there's no client for this yet and no
  94  * public api) and then the script list is queried for the script in
  95  * question.  it can be preloaded at creation time with all the
  96  * scripts that don't have default engines-- either a list or a hash
  97  * table, so a null return from the table means 'default' and not 'i
  98  * don't know yet'.
  99  *
 100  * On the other hand, in most all cases the number of unique
 101  * script/font combinations will be small, so a flat hashtable should
 102  * suffice.
 103  * */
 104 public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory {
 105     private static native void initGVIDs();
 106     private static final boolean useICU;
 107     static {
 108         FontManagerNativeLibrary.load();
 109         initGVIDs();
 110         String le = java.security.AccessController.doPrivileged(
 111             new sun.security.action.
 112                 GetPropertyAction("sun.font.layoutengine", ""));
 113         useICU = le.equals("icu");
 114         String verbose = java.security.AccessController.doPrivileged(
 115             new sun.security.action.
 116                 GetPropertyAction("sun.font.layoutengine.verbose", ""));
 117         if ("true".equalsIgnoreCase(verbose)) {
 118             System.out.println("Using " + (useICU ? "icu." : "harfbuzz."));
 119         }
 120     }
 121 
 122     private LayoutEngineKey key;
 123 
 124     private static LayoutEngineFactory instance;
 125 
 126     public static LayoutEngineFactory instance() {
 127         if (instance == null) {
 128             instance = new SunLayoutEngine();
 129         }
 130         return instance;
 131     }
 132 
 133     private SunLayoutEngine() {
 134         // actually a factory, key is null so layout cannot be called on it
 135     }
 136 
 137     public LayoutEngine getEngine(Font2D font, int script, int lang) {
 138         return getEngine(new LayoutEngineKey(font, script, lang));
 139     }


 144         if (cache == null) {
 145             cache = new ConcurrentHashMap<>();
 146             cacheref = new SoftReference<>(cache);
 147         }
 148 
 149         LayoutEngine e = cache.get(key);
 150         if (e == null) {
 151             LayoutEngineKey copy = key.copy();
 152             e = new SunLayoutEngine(copy);
 153             cache.put(copy, e);
 154         }
 155         return e;
 156     }
 157     private SoftReference<ConcurrentHashMap<LayoutEngineKey, LayoutEngine>> cacheref =
 158         new SoftReference<>(null);
 159 
 160     private SunLayoutEngine(LayoutEngineKey key) {
 161         this.key = key;
 162     }
 163 
 164     private boolean isAAT(Font2D font) {
 165        if (font instanceof TrueTypeFont) {
 166            TrueTypeFont ttf = (TrueTypeFont)font;
 167            return ttf.getDirectoryEntry(TrueTypeFont.morxTag) != null ||
 168                   ttf.getDirectoryEntry(TrueTypeFont.mortTag) != null;
 169        } else if (font instanceof PhysicalFont) {
 170            PhysicalFont pf = (PhysicalFont)font;
 171            return pf.getTableBytes(TrueTypeFont.morxTag) != null ||
 172                   pf.getTableBytes(TrueTypeFont.mortTag) != null;
 173        }
 174        return false;
 175     }
 176 
 177     public void layout(FontStrikeDesc desc, float[] mat, int gmask,
 178                        int baseIndex, TextRecord tr, int typo_flags,
 179                        Point2D.Float pt, GVData data) {
 180         Font2D font = key.font();
 181         FontStrike strike = font.getStrike(desc);
 182         long layoutTables = font.getLayoutTableCache();
 183         if (useICU) {
 184         nativeLayout(font, strike, mat, gmask, baseIndex,
 185              tr.text, tr.start, tr.limit, tr.min, tr.max,
 186              key.script(), key.lang(), typo_flags, pt, data,
 187              font.getUnitsPerEm(), layoutTables);
 188         } else {
 189             long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX
 190             // pScaler probably not needed long term.
 191             long pScaler = 0L;
 192             if (font instanceof FileFont) {
 193                 pScaler = ((FileFont)font).getScaler().nativeScaler;
 194             }
 195             shape(font, strike, mat, pScaler, pNativeFont, isAAT(font),
 196                   tr.text, data, key.script(),
 197                   tr.start, tr.limit, baseIndex, pt,
 198                   typo_flags, gmask);
 199          }
 200     }
 201 
 202     /* Native method to invoke ICU layout engine */
 203     private static native void
 204         nativeLayout(Font2D font, FontStrike strike, float[] mat, int gmask,
 205              int baseIndex, char[] chars, int offset, int limit,
 206              int min, int max, int script, int lang, int typo_flags,
 207              Point2D.Float pt, GVData data, long upem, long layoutTables);
 208 
 209 
 210     /* Native method to invoke harfbuzz layout engine */
 211     private static native boolean
 212         shape(Font2D font, FontStrike strike, float[] mat,
 213               long pscaler, long pNativeFont, boolean aat,
 214               char[] chars, GVData data,
 215               int script, int offset, int limit,
 216               int baseIndex, Point2D.Float pt, int typo_flags, int slot);
 217 }
< prev index next >