27 |
27 |
28 import java.awt.geom.GeneralPath; |
28 import java.awt.geom.GeneralPath; |
29 import java.awt.geom.Point2D; |
29 import java.awt.geom.Point2D; |
30 import java.awt.geom.Rectangle2D; |
30 import java.awt.geom.Rectangle2D; |
31 import java.lang.ref.WeakReference; |
31 import java.lang.ref.WeakReference; |
|
32 import java.lang.reflect.Constructor; |
|
33 |
|
34 import sun.java2d.Disposer; |
32 import sun.java2d.DisposerRecord; |
35 import sun.java2d.DisposerRecord; |
33 |
36 |
34 /* FontScaler is "internal interface" to font rasterizer library. |
37 /* FontScaler is "internal interface" to font rasterizer library. |
35 * |
38 * |
36 * Access to native rasterizers without going through this interface is |
39 * Access to native rasterizers without going through this interface is |
75 * - Eventually we may consider releasing some of the scaler resources if |
78 * - Eventually we may consider releasing some of the scaler resources if |
76 * it was not used for a while but we do not want to be too aggressive on |
79 * it was not used for a while but we do not want to be too aggressive on |
77 * this (and this is probably more important for Type1 fonts). |
80 * this (and this is probably more important for Type1 fonts). |
78 */ |
81 */ |
79 public abstract class FontScaler implements DisposerRecord { |
82 public abstract class FontScaler implements DisposerRecord { |
|
83 |
|
84 private static FontScaler nullScaler = null; |
|
85 private static Constructor<FontScaler> scalerConstructor = null; |
|
86 |
|
87 //Find preferred font scaler |
|
88 // |
|
89 //NB: we can allow property based preferences |
|
90 // (theoretically logic can be font type specific) |
|
91 static { |
|
92 Class scalerClass = null; |
|
93 Class arglst[] = new Class[] {Font2D.class, int.class, |
|
94 boolean.class, int.class}; |
|
95 |
|
96 try { |
|
97 if (FontUtilities.isOpenJDK) { |
|
98 scalerClass = Class.forName("sun.font.FreetypeFontScaler"); |
|
99 } else { |
|
100 scalerClass = Class.forName("sun.font.T2KFontScaler"); |
|
101 } |
|
102 } catch (ClassNotFoundException e) { |
|
103 scalerClass = NullFontScaler.class; |
|
104 } |
|
105 |
|
106 //NB: rewrite using factory? constructor is ugly way |
|
107 try { |
|
108 scalerConstructor = scalerClass.getConstructor(arglst); |
|
109 } catch (NoSuchMethodException e) { |
|
110 //should not happen |
|
111 } |
|
112 } |
|
113 |
|
114 /* This is the only place to instantiate new FontScaler. |
|
115 * Therefore this is very convinient place to register |
|
116 * scaler with Disposer as well as trigger deregistring bad font |
|
117 * in case when scaler reports this. |
|
118 */ |
|
119 public static FontScaler getScaler(Font2D font, |
|
120 int indexInCollection, |
|
121 boolean supportsCJK, |
|
122 int filesize) { |
|
123 FontScaler scaler = null; |
|
124 |
|
125 try { |
|
126 Object args[] = new Object[] {font, indexInCollection, |
|
127 supportsCJK, filesize}; |
|
128 scaler = scalerConstructor.newInstance(args); |
|
129 Disposer.addObjectRecord(font, scaler); |
|
130 } catch (Throwable e) { |
|
131 scaler = nullScaler; |
|
132 |
|
133 //if we can not instantiate scaler assume bad font |
|
134 //NB: technically it could be also because of internal scaler |
|
135 // error but here we are assuming scaler is ok. |
|
136 FontManager fm = FontManagerFactory.getInstance(); |
|
137 fm.deRegisterBadFont(font); |
|
138 } |
|
139 return scaler; |
|
140 } |
|
141 |
|
142 /* |
|
143 * At the moment it is harmless to create 2 null scalers so, technically, |
|
144 * syncronized keyword is not needed. |
|
145 * |
|
146 * But it is safer to keep it to avoid subtle problems if we will be adding |
|
147 * checks like whether scaler is null scaler. |
|
148 */ |
|
149 public static synchronized FontScaler getNullScaler() { |
|
150 if (nullScaler == null) { |
|
151 nullScaler = new NullFontScaler(); |
|
152 } |
|
153 return nullScaler; |
|
154 } |
|
155 |
80 protected WeakReference<Font2D> font = null; |
156 protected WeakReference<Font2D> font = null; |
81 protected long nativeScaler = 0; //used by decendants |
157 protected long nativeScaler = 0; //used by decendants |
82 //that have native state |
158 //that have native state |
83 protected boolean disposed = false; |
159 protected boolean disposed = false; |
84 |
160 |