25
26 #include "jlong.h"
27 #include "sun_font_SunLayoutEngine.h"
28
29 #include "hb.h"
30 #include "hb-jdk.h"
31 #ifdef MACOSX
32 #include "hb-coretext.h"
33 #endif
34 #include <stdlib.h>
35
36 #if defined(__GNUC__) && __GNUC__ >= 4
37 #define HB_UNUSED __attribute__((unused))
38 #else
39 #define HB_UNUSED
40 #endif
41
42
43 static hb_bool_t
44 hb_jdk_get_nominal_glyph (hb_font_t *font HB_UNUSED,
45 void *font_data,
46 hb_codepoint_t unicode,
47 hb_codepoint_t *glyph,
48 void *user_data HB_UNUSED)
49 {
50
51 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
52 JNIEnv* env = jdkFontInfo->env;
53 jobject font2D = jdkFontInfo->font2D;
54 *glyph = (hb_codepoint_t)env->CallIntMethod(
55 font2D, sunFontIDs.f2dCharToGlyphMID, unicode);
56 if (env->ExceptionOccurred())
57 {
58 env->ExceptionClear();
59 }
60 if ((int)*glyph < 0) {
61 *glyph = 0;
62 }
63 return (*glyph != 0);
64 }
65
66 static hb_bool_t
67 hb_jdk_get_variation_glyph (hb_font_t *font HB_UNUSED,
68 void *font_data,
69 hb_codepoint_t unicode,
70 hb_codepoint_t variation_selector,
71 hb_codepoint_t *glyph,
72 void *user_data HB_UNUSED)
73 {
74
75 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
76 JNIEnv* env = jdkFontInfo->env;
77 jobject font2D = jdkFontInfo->font2D;
78 *glyph = (hb_codepoint_t)env->CallIntMethod(
79 font2D, sunFontIDs.f2dCharToVariationGlyphMID,
80 unicode, variation_selector);
81 if (env->ExceptionOccurred())
82 {
83 env->ExceptionClear();
84 }
85 if ((int)*glyph < 0) {
86 *glyph = 0;
87 }
88 return (*glyph != 0);
89 }
90
91 static hb_position_t
92 hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
93 void *font_data,
94 hb_codepoint_t glyph,
95 void *user_data HB_UNUSED)
96 {
97
98 float fadv = 0.0f;
99 if ((glyph & 0xfffe) == 0xfffe) {
100 return 0; // JDK uses this glyph code.
101 }
102
103 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
104 JNIEnv* env = jdkFontInfo->env;
105 jobject fontStrike = jdkFontInfo->fontStrike;
106 jobject pt = env->CallObjectMethod(fontStrike,
107 sunFontIDs.getGlyphMetricsMID, glyph);
108
109 if (pt == NULL) {
110 return 0;
111 }
112 fadv = env->GetFloatField(pt, sunFontIDs.xFID);
113 fadv *= jdkFontInfo->devScale;
114 env->DeleteLocalRef(pt);
115
116 return HBFloatToFixed(fadv);
117 }
118
119 static hb_position_t
120 hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
121 void *font_data,
122 hb_codepoint_t glyph,
123 void *user_data HB_UNUSED)
124 {
125
126 float fadv = 0.0f;
127 if ((glyph & 0xfffe) == 0xfffe) {
128 return 0; // JDK uses this glyph code.
129 }
130
131 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
132 JNIEnv* env = jdkFontInfo->env;
133 jobject fontStrike = jdkFontInfo->fontStrike;
134 jobject pt = env->CallObjectMethod(fontStrike,
135 sunFontIDs.getGlyphMetricsMID, glyph);
136
137 if (pt == NULL) {
138 return 0;
139 }
140 fadv = env->GetFloatField(pt, sunFontIDs.yFID);
141 env->DeleteLocalRef(pt);
142
143 return HBFloatToFixed(fadv);
144
145 }
146
147 static hb_bool_t
148 hb_jdk_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
149 void *font_data HB_UNUSED,
150 hb_codepoint_t glyph HB_UNUSED,
151 hb_position_t *x HB_UNUSED,
152 hb_position_t *y HB_UNUSED,
153 void *user_data HB_UNUSED)
154 {
155 /* We always work in the horizontal coordinates. */
156 return true;
157 }
158
159 static hb_bool_t
160 hb_jdk_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
161 void *font_data,
162 hb_codepoint_t glyph,
163 hb_position_t *x,
164 hb_position_t *y,
165 void *user_data HB_UNUSED)
166 {
167 return false;
168 }
169
170 static hb_position_t
171 hb_jdk_get_glyph_h_kerning (hb_font_t *font,
172 void *font_data,
173 hb_codepoint_t lejdk_glyph,
174 hb_codepoint_t right_glyph,
175 void *user_data HB_UNUSED)
176 {
177 /* Not implemented. This seems to be in the HB API
178 * as a way to fall back to Freetype's kerning support
179 * which could be based on some on-the fly glyph analysis.
180 * But more likely it reads the kern table. That is easy
181 * enough code to add if we find a need to fall back
182 * to that instead of using gpos. It seems like if
183 * there is a gpos table at all, the practice is to
184 * use that and ignore kern, no matter that gpos does
185 * not implement the kern feature.
186 */
187 return 0;
188 }
189
190 static hb_position_t
191 hb_jdk_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
192 void *font_data HB_UNUSED,
193 hb_codepoint_t top_glyph HB_UNUSED,
194 hb_codepoint_t bottom_glyph HB_UNUSED,
195 void *user_data HB_UNUSED)
196 {
197 /* OpenType doesn't have vertical-kerning other than GPOS. */
198 return 0;
199 }
200
201 static hb_bool_t
202 hb_jdk_get_glyph_extents (hb_font_t *font HB_UNUSED,
203 void *font_data,
204 hb_codepoint_t glyph,
205 hb_glyph_extents_t *extents,
206 void *user_data HB_UNUSED)
207 {
208 /* TODO */
209 return false;
210 }
211
212 static hb_bool_t
213 hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
214 void *font_data,
215 hb_codepoint_t glyph,
216 unsigned int point_index,
217 hb_position_t *x,
218 hb_position_t *y,
219 void *user_data HB_UNUSED)
220 {
221 if ((glyph & 0xfffe) == 0xfffe) {
222 *x = 0; *y = 0;
223 return true;
224 }
225
226 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
227 JNIEnv* env = jdkFontInfo->env;
228 jobject fontStrike = jdkFontInfo->fontStrike;
229 jobject pt = env->CallObjectMethod(fontStrike,
230 sunFontIDs.getGlyphPointMID,
231 glyph, point_index);
232
233 if (pt == NULL) {
234 *x = 0; *y = 0;
235 return true;
236 }
237 *x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
238 *y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
239 env->DeleteLocalRef(pt);
240
241 return true;
242 }
243
244 static hb_bool_t
245 hb_jdk_get_glyph_name (hb_font_t *font HB_UNUSED,
246 void *font_data,
247 hb_codepoint_t glyph,
248 char *name, unsigned int size,
249 void *user_data HB_UNUSED)
250 {
251 return false;
252 }
253
254 static hb_bool_t
255 hb_jdk_get_glyph_from_name (hb_font_t *font HB_UNUSED,
256 void *font_data,
257 const char *name, int len,
258 hb_codepoint_t *glyph,
259 void *user_data HB_UNUSED)
260 {
261 return false;
262 }
263
264 // remind : can we initialise this from the code we call
265 // from the class static method in Java to make it
266 // completely thread safe.
267 static hb_font_funcs_t *
268 _hb_jdk_get_font_funcs (void)
269 {
270 static hb_font_funcs_t *jdk_ffuncs = NULL;
271 hb_font_funcs_t *ff;
272
273 if (!jdk_ffuncs) {
274 ff = hb_font_funcs_create();
275
276 hb_font_funcs_set_nominal_glyph_func(ff, hb_jdk_get_nominal_glyph, NULL, NULL);
277 hb_font_funcs_set_variation_glyph_func(ff, hb_jdk_get_variation_glyph, NULL, NULL);
278 hb_font_funcs_set_glyph_h_advance_func(ff,
279 hb_jdk_get_glyph_h_advance, NULL, NULL);
|
25
26 #include "jlong.h"
27 #include "sun_font_SunLayoutEngine.h"
28
29 #include "hb.h"
30 #include "hb-jdk.h"
31 #ifdef MACOSX
32 #include "hb-coretext.h"
33 #endif
34 #include <stdlib.h>
35
36 #if defined(__GNUC__) && __GNUC__ >= 4
37 #define HB_UNUSED __attribute__((unused))
38 #else
39 #define HB_UNUSED
40 #endif
41
42
43 static hb_bool_t
44 hb_jdk_get_nominal_glyph (hb_font_t *font HB_UNUSED,
45 void *font_data,
46 hb_codepoint_t unicode,
47 hb_codepoint_t *glyph,
48 void *user_data HB_UNUSED)
49 {
50
51 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
52 JNIEnv* env = jdkFontInfo->env;
53 jobject font2D = jdkFontInfo->font2D;
54 *glyph = (hb_codepoint_t)env->CallIntMethod(
55 font2D, sunFontIDs.f2dCharToGlyphMID, unicode);
56 if (env->ExceptionOccurred())
57 {
58 env->ExceptionClear();
59 }
60 if ((int)*glyph < 0) {
61 *glyph = 0;
62 }
63 return (*glyph != 0);
64 }
65
66 static hb_bool_t
67 hb_jdk_get_variation_glyph (hb_font_t *font HB_UNUSED,
68 void *font_data,
69 hb_codepoint_t unicode,
70 hb_codepoint_t variation_selector,
71 hb_codepoint_t *glyph,
72 void *user_data HB_UNUSED)
73 {
74
75 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
76 JNIEnv* env = jdkFontInfo->env;
77 jobject font2D = jdkFontInfo->font2D;
78 *glyph = (hb_codepoint_t)env->CallIntMethod(
79 font2D, sunFontIDs.f2dCharToVariationGlyphMID,
80 unicode, variation_selector);
81 if (env->ExceptionOccurred())
82 {
83 env->ExceptionClear();
84 }
85 if ((int)*glyph < 0) {
86 *glyph = 0;
87 }
88 return (*glyph != 0);
89 }
90
91 static hb_position_t
92 hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
93 void *font_data,
94 hb_codepoint_t glyph,
95 void *user_data HB_UNUSED)
96 {
97
98 float fadv = 0.0f;
99 if ((glyph & 0xfffe) == 0xfffe) {
100 return 0; // JDK uses this glyph code.
101 }
102
103 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
104 JNIEnv* env = jdkFontInfo->env;
105 jobject fontStrike = jdkFontInfo->fontStrike;
106 jobject pt = env->CallObjectMethod(fontStrike,
107 sunFontIDs.getGlyphMetricsMID, glyph);
108
109 if (pt == NULL) {
110 return 0;
111 }
112 fadv = env->GetFloatField(pt, sunFontIDs.xFID);
113 fadv *= jdkFontInfo->devScale;
114 env->DeleteLocalRef(pt);
115
116 return HBFloatToFixed(fadv);
117 }
118
119 static hb_position_t
120 hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
121 void *font_data,
122 hb_codepoint_t glyph,
123 void *user_data HB_UNUSED)
124 {
125
126 float fadv = 0.0f;
127 if ((glyph & 0xfffe) == 0xfffe) {
128 return 0; // JDK uses this glyph code.
129 }
130
131 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
132 JNIEnv* env = jdkFontInfo->env;
133 jobject fontStrike = jdkFontInfo->fontStrike;
134 jobject pt = env->CallObjectMethod(fontStrike,
135 sunFontIDs.getGlyphMetricsMID, glyph);
136
137 if (pt == NULL) {
138 return 0;
139 }
140 fadv = env->GetFloatField(pt, sunFontIDs.yFID);
141 env->DeleteLocalRef(pt);
142
143 return HBFloatToFixed(fadv);
144
145 }
146
147 static hb_bool_t
148 hb_jdk_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
149 void *font_data HB_UNUSED,
150 hb_codepoint_t glyph HB_UNUSED,
151 hb_position_t *x HB_UNUSED,
152 hb_position_t *y HB_UNUSED,
153 void *user_data HB_UNUSED)
154 {
155 /* We always work in the horizontal coordinates. */
156 return true;
157 }
158
159 static hb_bool_t
160 hb_jdk_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
161 void *font_data,
162 hb_codepoint_t glyph,
163 hb_position_t *x,
164 hb_position_t *y,
165 void *user_data HB_UNUSED)
166 {
167 return false;
168 }
169
170 static hb_position_t
171 hb_jdk_get_glyph_h_kerning (hb_font_t *font,
172 void *font_data,
173 hb_codepoint_t lejdk_glyph,
174 hb_codepoint_t right_glyph,
175 void *user_data HB_UNUSED)
176 {
177 /* Not implemented. This seems to be in the HB API
178 * as a way to fall back to Freetype's kerning support
179 * which could be based on some on-the fly glyph analysis.
180 * But more likely it reads the kern table. That is easy
181 * enough code to add if we find a need to fall back
182 * to that instead of using gpos. It seems like if
183 * there is a gpos table at all, the practice is to
184 * use that and ignore kern, no matter that gpos does
185 * not implement the kern feature.
186 */
187 return 0;
188 }
189
190 static hb_position_t
191 hb_jdk_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
192 void *font_data HB_UNUSED,
193 hb_codepoint_t top_glyph HB_UNUSED,
194 hb_codepoint_t bottom_glyph HB_UNUSED,
195 void *user_data HB_UNUSED)
196 {
197 /* OpenType doesn't have vertical-kerning other than GPOS. */
198 return 0;
199 }
200
201 static hb_bool_t
202 hb_jdk_get_glyph_extents (hb_font_t *font HB_UNUSED,
203 void *font_data,
204 hb_codepoint_t glyph,
205 hb_glyph_extents_t *extents,
206 void *user_data HB_UNUSED)
207 {
208 /* TODO */
209 return false;
210 }
211
212 static hb_bool_t
213 hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
214 void *font_data,
215 hb_codepoint_t glyph,
216 unsigned int point_index,
217 hb_position_t *x,
218 hb_position_t *y,
219 void *user_data HB_UNUSED)
220 {
221 if ((glyph & 0xfffe) == 0xfffe) {
222 *x = 0; *y = 0;
223 return true;
224 }
225
226 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
227 JNIEnv* env = jdkFontInfo->env;
228 jobject fontStrike = jdkFontInfo->fontStrike;
229 jobject pt = env->CallObjectMethod(fontStrike,
230 sunFontIDs.getGlyphPointMID,
231 glyph, point_index);
232
233 if (pt == NULL) {
234 *x = 0; *y = 0;
235 return true;
236 }
237 *x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
238 *y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
239 env->DeleteLocalRef(pt);
240
241 return true;
242 }
243
244 static hb_bool_t
245 hb_jdk_get_glyph_name (hb_font_t *font HB_UNUSED,
246 void *font_data,
247 hb_codepoint_t glyph,
248 char *name, unsigned int size,
249 void *user_data HB_UNUSED)
250 {
251 return false;
252 }
253
254 static hb_bool_t
255 hb_jdk_get_glyph_from_name (hb_font_t *font HB_UNUSED,
256 void *font_data,
257 const char *name, int len,
258 hb_codepoint_t *glyph,
259 void *user_data HB_UNUSED)
260 {
261 return false;
262 }
263
264 // remind : can we initialise this from the code we call
265 // from the class static method in Java to make it
266 // completely thread safe.
267 static hb_font_funcs_t *
268 _hb_jdk_get_font_funcs (void)
269 {
270 static hb_font_funcs_t *jdk_ffuncs = NULL;
271 hb_font_funcs_t *ff;
272
273 if (!jdk_ffuncs) {
274 ff = hb_font_funcs_create();
275
276 hb_font_funcs_set_nominal_glyph_func(ff, hb_jdk_get_nominal_glyph, NULL, NULL);
277 hb_font_funcs_set_variation_glyph_func(ff, hb_jdk_get_variation_glyph, NULL, NULL);
278 hb_font_funcs_set_glyph_h_advance_func(ff,
279 hb_jdk_get_glyph_h_advance, NULL, NULL);
|