Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc
41149 views
1
/*
2
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "jlong.h"
27
#include "sun_font_SunLayoutEngine.h"
28
29
#include "hb.h"
30
#include "hb-jdk.h"
31
#include <stdlib.h>
32
33
#if defined(__GNUC__) && __GNUC__ >= 4
34
#define HB_UNUSED __attribute__((unused))
35
#else
36
#define HB_UNUSED
37
#endif
38
39
40
static hb_bool_t
41
hb_jdk_get_nominal_glyph (hb_font_t *font HB_UNUSED,
42
void *font_data,
43
hb_codepoint_t unicode,
44
hb_codepoint_t *glyph,
45
void *user_data HB_UNUSED)
46
{
47
48
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
49
JNIEnv* env = jdkFontInfo->env;
50
jobject font2D = jdkFontInfo->font2D;
51
*glyph = (hb_codepoint_t)env->CallIntMethod(
52
font2D, sunFontIDs.f2dCharToGlyphMID, unicode);
53
if (env->ExceptionOccurred())
54
{
55
env->ExceptionClear();
56
}
57
if ((int)*glyph < 0) {
58
*glyph = 0;
59
}
60
return (*glyph != 0);
61
}
62
63
static hb_bool_t
64
hb_jdk_get_variation_glyph (hb_font_t *font HB_UNUSED,
65
void *font_data,
66
hb_codepoint_t unicode,
67
hb_codepoint_t variation_selector,
68
hb_codepoint_t *glyph,
69
void *user_data HB_UNUSED)
70
{
71
72
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
73
JNIEnv* env = jdkFontInfo->env;
74
jobject font2D = jdkFontInfo->font2D;
75
*glyph = (hb_codepoint_t)env->CallIntMethod(
76
font2D, sunFontIDs.f2dCharToVariationGlyphMID,
77
unicode, variation_selector);
78
if (env->ExceptionOccurred())
79
{
80
env->ExceptionClear();
81
}
82
if ((int)*glyph < 0) {
83
*glyph = 0;
84
}
85
return (*glyph != 0);
86
}
87
88
static hb_position_t
89
hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
90
void *font_data,
91
hb_codepoint_t glyph,
92
void *user_data HB_UNUSED)
93
{
94
95
float fadv = 0.0f;
96
if ((glyph & 0xfffe) == 0xfffe) {
97
return 0; // JDK uses this glyph code.
98
}
99
100
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
101
JNIEnv* env = jdkFontInfo->env;
102
jobject fontStrike = jdkFontInfo->fontStrike;
103
jobject pt = env->CallObjectMethod(fontStrike,
104
sunFontIDs.getGlyphMetricsMID, glyph);
105
106
if (pt == NULL) {
107
return 0;
108
}
109
fadv = env->GetFloatField(pt, sunFontIDs.xFID);
110
fadv *= jdkFontInfo->devScale;
111
env->DeleteLocalRef(pt);
112
113
return HBFloatToFixed(fadv);
114
}
115
116
static hb_position_t
117
hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
118
void *font_data,
119
hb_codepoint_t glyph,
120
void *user_data HB_UNUSED)
121
{
122
123
float fadv = 0.0f;
124
if ((glyph & 0xfffe) == 0xfffe) {
125
return 0; // JDK uses this glyph code.
126
}
127
128
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
129
JNIEnv* env = jdkFontInfo->env;
130
jobject fontStrike = jdkFontInfo->fontStrike;
131
jobject pt = env->CallObjectMethod(fontStrike,
132
sunFontIDs.getGlyphMetricsMID, glyph);
133
134
if (pt == NULL) {
135
return 0;
136
}
137
fadv = env->GetFloatField(pt, sunFontIDs.yFID);
138
env->DeleteLocalRef(pt);
139
140
return HBFloatToFixed(fadv);
141
142
}
143
144
static hb_bool_t
145
hb_jdk_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
146
void *font_data HB_UNUSED,
147
hb_codepoint_t glyph HB_UNUSED,
148
hb_position_t *x HB_UNUSED,
149
hb_position_t *y HB_UNUSED,
150
void *user_data HB_UNUSED)
151
{
152
/* We always work in the horizontal coordinates. */
153
return true;
154
}
155
156
static hb_bool_t
157
hb_jdk_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
158
void *font_data,
159
hb_codepoint_t glyph,
160
hb_position_t *x,
161
hb_position_t *y,
162
void *user_data HB_UNUSED)
163
{
164
return false;
165
}
166
167
static hb_position_t
168
hb_jdk_get_glyph_h_kerning (hb_font_t *font,
169
void *font_data,
170
hb_codepoint_t lejdk_glyph,
171
hb_codepoint_t right_glyph,
172
void *user_data HB_UNUSED)
173
{
174
/* Not implemented. This seems to be in the HB API
175
* as a way to fall back to Freetype's kerning support
176
* which could be based on some on-the fly glyph analysis.
177
* But more likely it reads the kern table. That is easy
178
* enough code to add if we find a need to fall back
179
* to that instead of using gpos. It seems like if
180
* there is a gpos table at all, the practice is to
181
* use that and ignore kern, no matter that gpos does
182
* not implement the kern feature.
183
*/
184
return 0;
185
}
186
187
static hb_position_t
188
hb_jdk_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
189
void *font_data HB_UNUSED,
190
hb_codepoint_t top_glyph HB_UNUSED,
191
hb_codepoint_t bottom_glyph HB_UNUSED,
192
void *user_data HB_UNUSED)
193
{
194
/* OpenType doesn't have vertical-kerning other than GPOS. */
195
return 0;
196
}
197
198
static hb_bool_t
199
hb_jdk_get_glyph_extents (hb_font_t *font HB_UNUSED,
200
void *font_data,
201
hb_codepoint_t glyph,
202
hb_glyph_extents_t *extents,
203
void *user_data HB_UNUSED)
204
{
205
/* TODO */
206
return false;
207
}
208
209
static hb_bool_t
210
hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
211
void *font_data,
212
hb_codepoint_t glyph,
213
unsigned int point_index,
214
hb_position_t *x,
215
hb_position_t *y,
216
void *user_data HB_UNUSED)
217
{
218
if ((glyph & 0xfffe) == 0xfffe) {
219
*x = 0; *y = 0;
220
return true;
221
}
222
223
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
224
JNIEnv* env = jdkFontInfo->env;
225
jobject fontStrike = jdkFontInfo->fontStrike;
226
jobject pt = env->CallObjectMethod(fontStrike,
227
sunFontIDs.getGlyphPointMID,
228
glyph, point_index);
229
230
if (pt == NULL) {
231
*x = 0; *y = 0;
232
return true;
233
}
234
*x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
235
*y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
236
env->DeleteLocalRef(pt);
237
238
return true;
239
}
240
241
static hb_bool_t
242
hb_jdk_get_glyph_name (hb_font_t *font HB_UNUSED,
243
void *font_data,
244
hb_codepoint_t glyph,
245
char *name, unsigned int size,
246
void *user_data HB_UNUSED)
247
{
248
return false;
249
}
250
251
static hb_bool_t
252
hb_jdk_get_glyph_from_name (hb_font_t *font HB_UNUSED,
253
void *font_data,
254
const char *name, int len,
255
hb_codepoint_t *glyph,
256
void *user_data HB_UNUSED)
257
{
258
return false;
259
}
260
261
// remind : can we initialise this from the code we call
262
// from the class static method in Java to make it
263
// completely thread safe.
264
static hb_font_funcs_t *
265
_hb_jdk_get_font_funcs (void)
266
{
267
static hb_font_funcs_t *jdk_ffuncs = NULL;
268
hb_font_funcs_t *ff;
269
270
if (!jdk_ffuncs) {
271
ff = hb_font_funcs_create();
272
273
hb_font_funcs_set_nominal_glyph_func(ff, hb_jdk_get_nominal_glyph, NULL, NULL);
274
hb_font_funcs_set_variation_glyph_func(ff, hb_jdk_get_variation_glyph, NULL, NULL);
275
hb_font_funcs_set_glyph_h_advance_func(ff,
276
hb_jdk_get_glyph_h_advance, NULL, NULL);
277
hb_font_funcs_set_glyph_v_advance_func(ff,
278
hb_jdk_get_glyph_v_advance, NULL, NULL);
279
hb_font_funcs_set_glyph_h_origin_func(ff,
280
hb_jdk_get_glyph_h_origin, NULL, NULL);
281
hb_font_funcs_set_glyph_v_origin_func(ff,
282
hb_jdk_get_glyph_v_origin, NULL, NULL);
283
hb_font_funcs_set_glyph_h_kerning_func(ff,
284
hb_jdk_get_glyph_h_kerning, NULL, NULL);
285
hb_font_funcs_set_glyph_v_kerning_func(ff,
286
hb_jdk_get_glyph_v_kerning, NULL, NULL);
287
hb_font_funcs_set_glyph_extents_func(ff,
288
hb_jdk_get_glyph_extents, NULL, NULL);
289
hb_font_funcs_set_glyph_contour_point_func(ff,
290
hb_jdk_get_glyph_contour_point, NULL, NULL);
291
hb_font_funcs_set_glyph_name_func(ff,
292
hb_jdk_get_glyph_name, NULL, NULL);
293
hb_font_funcs_set_glyph_from_name_func(ff,
294
hb_jdk_get_glyph_from_name, NULL, NULL);
295
hb_font_funcs_make_immutable(ff); // done setting functions.
296
jdk_ffuncs = ff;
297
}
298
return jdk_ffuncs;
299
}
300
301
static void _do_nothing(void) {
302
}
303
304
struct Font2DPtr {
305
JavaVM* vmPtr;
306
jweak font2DRef;
307
};
308
309
static void cleanupFontInfo(void* data) {
310
Font2DPtr* fontInfo;
311
JNIEnv* env;
312
313
fontInfo = (Font2DPtr*) data;
314
fontInfo->vmPtr->GetEnv((void**)&env, JNI_VERSION_1_1);
315
env->DeleteWeakGlobalRef(fontInfo->font2DRef);
316
free(data);
317
}
318
319
static hb_blob_t *
320
reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) {
321
322
Font2DPtr *fontInfo;
323
JNIEnv* env;
324
jobject font2D;
325
jsize length;
326
void* buffer;
327
328
// HB_TAG_NONE is 0 and is used to get the whole font file.
329
// It is not expected to be needed for JDK.
330
if (tag == 0) {
331
return NULL;
332
}
333
334
fontInfo = (Font2DPtr*)user_data;
335
fontInfo->vmPtr->GetEnv((void**)&env, JNI_VERSION_1_1);
336
if (env == NULL) {
337
return NULL;
338
}
339
font2D = fontInfo->font2DRef;
340
341
jbyteArray tableBytes = (jbyteArray)
342
env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag);
343
if (tableBytes == NULL) {
344
return NULL;
345
}
346
length = env->GetArrayLength(tableBytes);
347
buffer = calloc(length, sizeof(jbyte));
348
if (buffer == NULL) {
349
return NULL;
350
}
351
env->GetByteArrayRegion(tableBytes, 0, length, (jbyte*)buffer);
352
353
return hb_blob_create((const char *)buffer, length,
354
HB_MEMORY_MODE_WRITABLE,
355
buffer, free);
356
}
357
358
extern "C" {
359
360
/*
361
* Class: sun_font_SunLayoutEngine
362
* Method: createFace
363
* Signature: (Lsun/font/Font2D;JJ)J
364
*/
365
JNIEXPORT jlong JNICALL Java_sun_font_SunLayoutEngine_createFace(JNIEnv *env,
366
jclass cls,
367
jobject font2D,
368
jlong platformFontPtr) {
369
Font2DPtr *fi = (Font2DPtr*)malloc(sizeof(Font2DPtr));
370
if (!fi) {
371
return 0;
372
}
373
JavaVM* vmPtr;
374
env->GetJavaVM(&vmPtr);
375
fi->vmPtr = vmPtr;
376
fi->font2DRef = env->NewWeakGlobalRef(font2D);
377
if (!fi->font2DRef) {
378
free(fi);
379
return 0;
380
}
381
hb_face_t *face = hb_face_create_for_tables(reference_table, fi,
382
cleanupFontInfo);
383
return ptr_to_jlong(face);
384
}
385
386
/*
387
* Class: sun_font_SunLayoutEngine
388
* Method: disposeFace
389
* Signature: (J)V
390
*/
391
JNIEXPORT void JNICALL Java_sun_font_SunLayoutEngine_disposeFace(JNIEnv *env,
392
jclass cls,
393
jlong ptr) {
394
hb_face_t* face = (hb_face_t*) jlong_to_ptr(ptr);
395
hb_face_destroy(face);
396
}
397
398
} // extern "C"
399
400
static hb_font_t* _hb_jdk_font_create(hb_face_t* face,
401
JDKFontInfo *jdkFontInfo,
402
hb_destroy_func_t destroy) {
403
404
hb_font_t *font;
405
406
font = hb_font_create(face);
407
hb_font_set_funcs (font,
408
_hb_jdk_get_font_funcs (),
409
jdkFontInfo, (hb_destroy_func_t) _do_nothing);
410
hb_font_set_scale (font,
411
HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale),
412
HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale));
413
return font;
414
}
415
416
#ifdef MACOSX
417
static hb_font_t* _hb_jdk_ct_font_create(hb_face_t* face,
418
JDKFontInfo *jdkFontInfo) {
419
420
hb_font_t *font = NULL;
421
font = hb_font_create(face);
422
hb_font_set_scale(font,
423
HBFloatToFixed(jdkFontInfo->ptSize),
424
HBFloatToFixed(jdkFontInfo->ptSize));
425
return font;
426
}
427
#endif
428
429
hb_font_t* hb_jdk_font_create(hb_face_t* hbFace,
430
JDKFontInfo *jdkFontInfo,
431
hb_destroy_func_t destroy) {
432
433
return _hb_jdk_font_create(hbFace, jdkFontInfo, destroy);
434
}
435
436