Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/awt/awt_Font.c
32287 views
1
/*
2
* Copyright (c) 1995, 2014, 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
#ifndef HEADLESS
27
28
#include "awt_p.h"
29
#include <string.h>
30
#include "java_awt_Component.h"
31
#include "java_awt_Font.h"
32
#include "java_awt_FontMetrics.h"
33
#include "sun_awt_X11GraphicsEnvironment.h"
34
35
#include "awt_Font.h"
36
37
#include "java_awt_Dimension.h"
38
#include "multi_font.h"
39
#include "Disposer.h"
40
#endif /* !HEADLESS */
41
#include <jni.h>
42
#ifndef HEADLESS
43
#include <jni_util.h>
44
45
#define defaultXLFD "-*-helvetica-*-*-*-*-12-*-*-*-*-*-iso8859-1"
46
47
struct FontIDs fontIDs;
48
struct PlatformFontIDs platformFontIDs;
49
50
static void pDataDisposeMethod(JNIEnv *env, jlong pData);
51
52
/* #define FONT_DEBUG 2 */
53
/* 1- print failures, 2- print all, 3- terminate on failure */
54
#if FONT_DEBUG
55
static XFontStruct *XLoadQueryFontX(Display *display, char *name)
56
{
57
XFontStruct *result = NULL;
58
result = XLoadQueryFont(display, name);
59
#if FONT_DEBUG < 2
60
if (result == NULL)
61
#endif
62
fprintf(stderr, "XLoadQueryFont(\"%s\") -> 0x%x.\n", name, result);
63
#if FONT_DEBUG >= 3
64
if (result == NULL)
65
exit(-1);
66
#endif
67
return result;
68
}
69
#define XLoadQueryFont XLoadQueryFontX
70
#endif
71
#endif /* !HEADLESS */
72
73
/*
74
* Class: java_awt_Font
75
* Method: initIDs
76
* Signature: ()V
77
*/
78
79
/* This function gets called from the static initializer for Font.java
80
to initialize the fieldIDs for fields that may be accessed from C */
81
82
JNIEXPORT void JNICALL
83
Java_java_awt_Font_initIDs
84
(JNIEnv *env, jclass cls)
85
{
86
#ifndef HEADLESS
87
/** We call "NoClientCode" methods because they won't invoke client
88
code on the privileged toolkit thread **/
89
CHECK_NULL(fontIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J"));
90
CHECK_NULL(fontIDs.style = (*env)->GetFieldID(env, cls, "style", "I"));
91
CHECK_NULL(fontIDs.size = (*env)->GetFieldID(env, cls, "size", "I"));
92
CHECK_NULL(fontIDs.getPeer = (*env)->GetMethodID(env, cls, "getPeer_NoClientCode",
93
"()Ljava/awt/peer/FontPeer;"));
94
CHECK_NULL(fontIDs.getFamily = (*env)->GetMethodID(env, cls, "getFamily_NoClientCode",
95
"()Ljava/lang/String;"));
96
#endif /* !HEADLESS */
97
}
98
99
#ifndef HEADLESS
100
/* fieldIDs for FontDescriptor fields that may be accessed from C */
101
static struct FontDescriptorIDs {
102
jfieldID nativeName;
103
jfieldID charsetName;
104
} fontDescriptorIDs;
105
#endif /* !HEADLESS */
106
107
/*
108
* Class: sun_awt_FontDescriptor
109
* Method: initIDs
110
* Signature: ()V
111
*/
112
113
/* This function gets called from the static initializer for
114
FontDescriptor.java to initialize the fieldIDs for fields
115
that may be accessed from C */
116
117
JNIEXPORT void JNICALL
118
Java_sun_awt_FontDescriptor_initIDs
119
(JNIEnv *env, jclass cls)
120
{
121
#ifndef HEADLESS
122
CHECK_NULL(fontDescriptorIDs.nativeName =
123
(*env)->GetFieldID(env, cls, "nativeName", "Ljava/lang/String;"));
124
CHECK_NULL(fontDescriptorIDs.charsetName =
125
(*env)->GetFieldID(env, cls, "charsetName", "Ljava/lang/String;"));
126
#endif /* !HEADLESS */
127
}
128
129
/*
130
* Class: sun_awt_PlatformFont
131
* Method: initIDs
132
* Signature: ()V
133
*/
134
135
/* This function gets called from the static initializer for
136
PlatformFont.java to initialize the fieldIDs for fields
137
that may be accessed from C */
138
139
JNIEXPORT void JNICALL
140
Java_sun_awt_PlatformFont_initIDs
141
(JNIEnv *env, jclass cls)
142
{
143
#ifndef HEADLESS
144
CHECK_NULL(platformFontIDs.componentFonts =
145
(*env)->GetFieldID(env, cls, "componentFonts",
146
"[Lsun/awt/FontDescriptor;"));
147
CHECK_NULL(platformFontIDs.fontConfig =
148
(*env)->GetFieldID(env,cls, "fontConfig",
149
"Lsun/awt/FontConfiguration;"));
150
CHECK_NULL(platformFontIDs.makeConvertedMultiFontString =
151
(*env)->GetMethodID(env, cls, "makeConvertedMultiFontString",
152
"(Ljava/lang/String;)[Ljava/lang/Object;"));
153
CHECK_NULL(platformFontIDs.makeConvertedMultiFontChars =
154
(*env)->GetMethodID(env, cls, "makeConvertedMultiFontChars",
155
"([CII)[Ljava/lang/Object;"));
156
#endif /* !HEADLESS */
157
}
158
159
#ifndef HEADLESS
160
XFontStruct *
161
loadFont(Display * display, char *name, int32_t pointSize)
162
{
163
XFontStruct *f = NULL;
164
165
/* try the exact xlfd name in font configuration file */
166
f = XLoadQueryFont(display, name);
167
if (f != NULL) {
168
return f;
169
}
170
171
/*
172
* try nearly font
173
*
174
* 1. specify FAMILY_NAME, WEIGHT_NAME, SLANT, POINT_SIZE,
175
* CHARSET_REGISTRY and CHARSET_ENCODING.
176
* 2. change POINT_SIZE to PIXEL_SIZE
177
* 3. change FAMILY_NAME to *
178
* 4. specify only PIXEL_SIZE and CHARSET_REGISTRY/ENCODING
179
* 5. change PIXEL_SIZE +1/-1/+2/-2...+4/-4
180
* 6. default font pattern
181
*/
182
{
183
/*
184
* This code assumes the name contains exactly 14 '-' delimiter.
185
* If not use default pattern.
186
*/
187
int32_t i, length, pixelSize;
188
Boolean useDefault = FALSE;
189
190
char buffer[BUFSIZ], buffer2[BUFSIZ];
191
char *family = NULL, *style = NULL, *slant = NULL, *encoding = NULL;
192
char *start = NULL, *end = NULL;
193
194
if (strlen(name) > BUFSIZ - 1) {
195
useDefault = TRUE;
196
} else {
197
strcpy(buffer, name);
198
}
199
200
#define NEXT_HYPHEN\
201
start = end + 1;\
202
end = strchr(start, '-');\
203
if (end == NULL) {\
204
useDefault = TRUE;\
205
break;\
206
}\
207
*end = '\0'
208
209
do {
210
end = buffer;
211
212
/* skip FOUNDRY */
213
NEXT_HYPHEN;
214
215
/* set FAMILY_NAME */
216
NEXT_HYPHEN;
217
family = start;
218
219
/* set STYLE_NAME */
220
NEXT_HYPHEN;
221
style = start;
222
223
/* set SLANT */
224
NEXT_HYPHEN;
225
slant = start;
226
227
/* skip SETWIDTH_NAME, ADD_STYLE_NAME, PIXEL_SIZE
228
POINT_SIZE, RESOLUTION_X, RESOLUTION_Y, SPACING
229
and AVERAGE_WIDTH */
230
NEXT_HYPHEN;
231
NEXT_HYPHEN;
232
NEXT_HYPHEN;
233
NEXT_HYPHEN;
234
NEXT_HYPHEN;
235
NEXT_HYPHEN;
236
NEXT_HYPHEN;
237
NEXT_HYPHEN;
238
239
/* set CHARSET_REGISTRY and CHARSET_ENCODING */
240
encoding = end + 1;
241
}
242
while (0);
243
244
#define TRY_LOAD\
245
f = XLoadQueryFont(display, buffer2);\
246
if (f != NULL) {\
247
strcpy(name, buffer2);\
248
return f;\
249
}
250
251
if (!useDefault) {
252
char *altstyle = NULL;
253
254
/* Regular is the style for TrueType fonts -- Type1, F3 use roman */
255
if (strcmp(style, "regular") == 0) {
256
altstyle = "roman";
257
}
258
#if defined(__linux__) || defined(MACOSX)
259
if (!strcmp(family, "lucidasans")) {
260
family = "lucida";
261
}
262
#endif
263
/* try 1. */
264
jio_snprintf(buffer2, sizeof(buffer2),
265
"-*-%s-%s-%s-*-*-*-%d-*-*-*-*-%s",
266
family, style, slant, pointSize, encoding);
267
TRY_LOAD;
268
269
if (altstyle != NULL) {
270
jio_snprintf(buffer2, sizeof(buffer2),
271
"-*-%s-%s-%s-*-*-*-%d-*-*-*-*-%s",
272
family, altstyle, slant, pointSize, encoding);
273
TRY_LOAD;
274
}
275
276
/* search bitmap font */
277
pixelSize = pointSize / 10;
278
279
/* try 2. */
280
jio_snprintf(buffer2, sizeof(buffer2),
281
"-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
282
family, style, slant, pixelSize, encoding);
283
TRY_LOAD;
284
285
if (altstyle != NULL) {
286
jio_snprintf(buffer2, sizeof(buffer2),
287
"-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
288
family, altstyle, slant, pixelSize, encoding);
289
TRY_LOAD;
290
}
291
292
/* try 3 */
293
jio_snprintf(buffer2, sizeof(buffer2),
294
"-*-*-%s-%s-*-*-%d-*-*-*-*-*-%s",
295
style, slant, pixelSize, encoding);
296
TRY_LOAD;
297
if (altstyle != NULL) {
298
jio_snprintf(buffer2, sizeof(buffer2),
299
"-*-*-%s-%s-*-*-%d-*-*-*-*-*-%s",
300
altstyle, slant, pixelSize, encoding);
301
TRY_LOAD;
302
}
303
304
/* try 4 */
305
jio_snprintf(buffer2, sizeof(buffer2),
306
"-*-*-*-%s-*-*-%d-*-*-*-*-*-%s",
307
slant, pixelSize, encoding);
308
309
TRY_LOAD;
310
311
/* try 5. */
312
jio_snprintf(buffer2, sizeof(buffer2),
313
"-*-*-*-*-*-*-%d-*-*-*-*-*-%s",
314
pixelSize, encoding);
315
TRY_LOAD;
316
317
/* try 6. */
318
for (i = 1; i < 4; i++) {
319
if (pixelSize < i)
320
break;
321
jio_snprintf(buffer2, sizeof(buffer2),
322
"-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
323
family, style, slant, pixelSize + i, encoding);
324
TRY_LOAD;
325
326
jio_snprintf(buffer2, sizeof(buffer2),
327
"-*-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
328
family, style, slant, pixelSize - i, encoding);
329
TRY_LOAD;
330
331
jio_snprintf(buffer2, sizeof(buffer2),
332
"-*-*-*-*-*-*-%d-*-*-*-*-*-%s",
333
pixelSize + i, encoding);
334
TRY_LOAD;
335
336
jio_snprintf(buffer2, sizeof(buffer2),
337
"-*-*-*-*-*-*-%d-*-*-*-*-*-%s",
338
pixelSize - i, encoding);
339
TRY_LOAD;
340
}
341
}
342
}
343
344
strcpy(name, defaultXLFD);
345
return XLoadQueryFont(display, defaultXLFD);
346
}
347
348
/*
349
* Hardwired list of mappings for generic font names "Helvetica",
350
* "TimesRoman", "Courier", "Dialog", and "DialogInput".
351
*/
352
static char *defaultfontname = "fixed";
353
static char *defaultfoundry = "misc";
354
static char *anyfoundry = "*";
355
static char *anystyle = "*-*";
356
static char *isolatin1 = "iso8859-1";
357
358
static char *
359
Style(int32_t s)
360
{
361
switch (s) {
362
case java_awt_Font_ITALIC:
363
return "medium-i";
364
case java_awt_Font_BOLD:
365
return "bold-r";
366
case java_awt_Font_BOLD + java_awt_Font_ITALIC:
367
return "bold-i";
368
case java_awt_Font_PLAIN:
369
default:
370
return "medium-r";
371
}
372
}
373
374
static int32_t
375
awtJNI_FontName(JNIEnv * env, jstring name, char **foundry, char **facename, char **encoding)
376
{
377
char *cname = NULL;
378
379
if (JNU_IsNull(env, name)) {
380
return 0;
381
}
382
cname = (char *) JNU_GetStringPlatformChars(env, name, NULL);
383
if (cname == NULL) {
384
(*env)->ExceptionClear(env);
385
JNU_ThrowOutOfMemoryError(env, "Could not create font name");
386
return 0;
387
}
388
389
/* additional default font names */
390
if (strcmp(cname, "serif") == 0) {
391
*foundry = "adobe";
392
*facename = "times";
393
*encoding = isolatin1;
394
} else if (strcmp(cname, "sansserif") == 0) {
395
*foundry = "adobe";
396
*facename = "helvetica";
397
*encoding = isolatin1;
398
} else if (strcmp(cname, "monospaced") == 0) {
399
*foundry = "adobe";
400
*facename = "courier";
401
*encoding = isolatin1;
402
} else if (strcmp(cname, "helvetica") == 0) {
403
*foundry = "adobe";
404
*facename = "helvetica";
405
*encoding = isolatin1;
406
} else if (strcmp(cname, "timesroman") == 0) {
407
*foundry = "adobe";
408
*facename = "times";
409
*encoding = isolatin1;
410
} else if (strcmp(cname, "courier") == 0) {
411
*foundry = "adobe";
412
*facename = "courier";
413
*encoding = isolatin1;
414
} else if (strcmp(cname, "dialog") == 0) {
415
*foundry = "b&h";
416
*facename = "lucida";
417
*encoding = isolatin1;
418
} else if (strcmp(cname, "dialoginput") == 0) {
419
*foundry = "b&h";
420
*facename = "lucidatypewriter";
421
*encoding = isolatin1;
422
} else if (strcmp(cname, "zapfdingbats") == 0) {
423
*foundry = "itc";
424
*facename = "zapfdingbats";
425
*encoding = "*-*";
426
} else {
427
#ifdef DEBUG
428
jio_fprintf(stderr, "Unknown font: %s\n", cname);
429
#endif
430
*foundry = defaultfoundry;
431
*facename = defaultfontname;
432
*encoding = isolatin1;
433
}
434
435
if (cname != NULL)
436
JNU_ReleaseStringPlatformChars(env, name, (const char *) cname);
437
438
return 1;
439
}
440
441
struct FontData *
442
awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg)
443
{
444
/* We are going to create at most 4 outstanding local refs in this
445
* function. */
446
if ((*env)->EnsureLocalCapacity(env, 4) < 0) {
447
return NULL;
448
}
449
450
if (!JNU_IsNull(env, font) && awtJNI_IsMultiFont(env, font)) {
451
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
452
453
struct FontData *fdata = NULL;
454
int32_t i, size;
455
char *fontsetname = NULL;
456
char *nativename = NULL;
457
jobjectArray componentFonts = NULL;
458
jobject peer = NULL;
459
jobject fontDescriptor = NULL;
460
jstring fontDescriptorName = NULL;
461
jstring charsetName = NULL;
462
463
fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,
464
fontIDs.pData);
465
466
if (fdata != NULL && fdata->flist != NULL) {
467
return fdata;
468
}
469
size = (*env)->GetIntField(env, font, fontIDs.size);
470
fdata = (struct FontData *) malloc(sizeof(struct FontData));
471
472
peer = (*env)->CallObjectMethod(env, font, fontIDs.getPeer);
473
474
componentFonts =
475
(*env)->GetObjectField(env, peer, platformFontIDs.componentFonts);
476
/* We no longer need peer */
477
(*env)->DeleteLocalRef(env, peer);
478
479
fdata->charset_num = (*env)->GetArrayLength(env, componentFonts);
480
481
fdata->flist = (awtFontList *) malloc(sizeof(awtFontList)
482
* fdata->charset_num);
483
fdata->xfont = NULL;
484
for (i = 0; i < fdata->charset_num; i++) {
485
/*
486
* set xlfd name
487
*/
488
489
fontDescriptor = (*env)->GetObjectArrayElement(env, componentFonts, i);
490
fontDescriptorName =
491
(*env)->GetObjectField(env, fontDescriptor,
492
fontDescriptorIDs.nativeName);
493
494
if (!JNU_IsNull(env, fontDescriptorName)) {
495
nativename = (char *) JNU_GetStringPlatformChars(env, fontDescriptorName, NULL);
496
} else {
497
nativename = "";
498
}
499
500
fdata->flist[i].xlfd = malloc(strlen(nativename)
501
+ strlen(defaultXLFD));
502
jio_snprintf(fdata->flist[i].xlfd, strlen(nativename) + 10,
503
nativename, size * 10);
504
505
if (nativename != NULL && nativename != "")
506
JNU_ReleaseStringPlatformChars(env, fontDescriptorName, (const char *) nativename);
507
508
/*
509
* set charset_name
510
*/
511
512
charsetName =
513
(*env)->GetObjectField(env, fontDescriptor,
514
fontDescriptorIDs.charsetName);
515
516
fdata->flist[i].charset_name = (char *)
517
JNU_GetStringPlatformChars(env, charsetName, NULL);
518
if (fdata->flist[i].charset_name == NULL) {
519
(*env)->ExceptionClear(env);
520
JNU_ThrowOutOfMemoryError(env, "Could not create charset name");
521
return NULL;
522
}
523
524
/* We are done with the objects. */
525
(*env)->DeleteLocalRef(env, fontDescriptor);
526
(*env)->DeleteLocalRef(env, fontDescriptorName);
527
(*env)->DeleteLocalRef(env, charsetName);
528
529
/*
530
* set load & XFontStruct
531
*/
532
fdata->flist[i].load = 0;
533
534
/*
535
* This appears to be a bogus check. The actual intent appears
536
* to be to find out whether this is the "base" font in a set,
537
* rather than iso8859_1 explicitly. Note that iso8859_15 will
538
* and must also pass this test.
539
*/
540
541
if (fdata->xfont == NULL &&
542
strstr(fdata->flist[i].charset_name, "8859_1")) {
543
fdata->flist[i].xfont =
544
loadFont(awt_display, fdata->flist[i].xlfd, size * 10);
545
if (fdata->flist[i].xfont != NULL) {
546
fdata->flist[i].load = 1;
547
fdata->xfont = fdata->flist[i].xfont;
548
fdata->flist[i].index_length = 1;
549
} else {
550
/* Free any already allocated storage and fonts */
551
int j = i;
552
for (j = 0; j <= i; j++) {
553
free((void *)fdata->flist[j].xlfd);
554
JNU_ReleaseStringPlatformChars(env, NULL,
555
fdata->flist[j].charset_name);
556
if (fdata->flist[j].load) {
557
XFreeFont(awt_display, fdata->flist[j].xfont);
558
}
559
}
560
free((void *)fdata->flist);
561
free((void *)fdata);
562
563
if (errmsg != NULL) {
564
*errmsg = "java/lang" "NullPointerException";
565
}
566
(*env)->DeleteLocalRef(env, componentFonts);
567
return NULL;
568
}
569
}
570
}
571
(*env)->DeleteLocalRef(env, componentFonts);
572
/*
573
* XFontSet will create if the peer of TextField/TextArea
574
* are used.
575
*/
576
fdata->xfs = NULL;
577
578
JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata);
579
Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata));
580
return fdata;
581
} else {
582
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
583
Display *display = NULL;
584
struct FontData *fdata = NULL;
585
char fontSpec[1024];
586
int32_t height;
587
int32_t oheight;
588
int32_t above = 0; /* tries above height */
589
int32_t below = 0; /* tries below height */
590
char *foundry = NULL;
591
char *name = NULL;
592
char *encoding = NULL;
593
char *style = NULL;
594
XFontStruct *xfont = NULL;
595
jstring family = NULL;
596
597
if (JNU_IsNull(env, font)) {
598
if (errmsg != NULL) {
599
*errmsg = "java/lang" "NullPointerException";
600
}
601
return (struct FontData *) NULL;
602
}
603
display = XDISPLAY;
604
605
fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,fontIDs.pData);
606
if (fdata != NULL && fdata->xfont != NULL) {
607
return fdata;
608
}
609
610
family = (*env)->CallObjectMethod(env, font, fontIDs.getFamily);
611
612
if (!awtJNI_FontName(env, family, &foundry, &name, &encoding)) {
613
if (errmsg != NULL) {
614
*errmsg = "java/lang" "NullPointerException";
615
}
616
(*env)->DeleteLocalRef(env, family);
617
return (struct FontData *) NULL;
618
}
619
style = Style((*env)->GetIntField(env, font, fontIDs.style));
620
oheight = height = (*env)->GetIntField(env, font, fontIDs.size);
621
622
while (1) {
623
jio_snprintf(fontSpec, sizeof(fontSpec), "-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
624
foundry,
625
name,
626
style,
627
height,
628
encoding);
629
630
/*fprintf(stderr,"LoadFont: %s\n", fontSpec); */
631
xfont = XLoadQueryFont(display, fontSpec);
632
633
/* XXX: sometimes XLoadQueryFont returns a bogus font structure */
634
/* with negative ascent. */
635
if (xfont == (Font) NULL || xfont->ascent < 0) {
636
if (xfont != NULL) {
637
XFreeFont(display, xfont);
638
}
639
if (foundry != anyfoundry) { /* Use ptr comparison here, not strcmp */
640
/* Try any other foundry before messing with the sizes */
641
foundry = anyfoundry;
642
continue;
643
}
644
/* We couldn't find the font. We'll try to find an */
645
/* alternate by searching for heights above and below our */
646
/* preferred height. We try for 4 heights above and below. */
647
/* If we still can't find a font we repeat the algorithm */
648
/* using misc-fixed as the font. If we then fail, then we */
649
/* give up and signal an error. */
650
if (above == below) {
651
above++;
652
height = oheight + above;
653
} else {
654
below++;
655
if (below > 4) {
656
if (name != defaultfontname || style != anystyle) {
657
name = defaultfontname;
658
foundry = defaultfoundry;
659
height = oheight;
660
style = anystyle;
661
encoding = isolatin1;
662
above = below = 0;
663
continue;
664
} else {
665
if (errmsg != NULL) {
666
*errmsg = "java/io/" "FileNotFoundException";
667
}
668
(*env)->DeleteLocalRef(env, family);
669
return (struct FontData *) NULL;
670
}
671
}
672
height = oheight - below;
673
}
674
continue;
675
} else {
676
fdata = ZALLOC(FontData);
677
678
if (fdata == NULL) {
679
if (errmsg != NULL) {
680
*errmsg = "java/lang" "OutOfMemoryError";
681
}
682
} else {
683
fdata->xfont = xfont;
684
JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata);
685
Disposer_AddRecord(env, font, pDataDisposeMethod,
686
ptr_to_jlong(fdata));
687
}
688
(*env)->DeleteLocalRef(env, family);
689
return fdata;
690
}
691
}
692
/* not reached */
693
}
694
}
695
696
/*
697
* Registered with the 2D disposer to be called after the Font is GC'd.
698
*/
699
static void pDataDisposeMethod(JNIEnv *env, jlong pData)
700
{
701
struct FontData *fdata = NULL;
702
int32_t i = 0;
703
Display *display = XDISPLAY;
704
705
AWT_LOCK();
706
fdata = (struct FontData *)pData;
707
708
if (fdata == NULL) {
709
AWT_UNLOCK();
710
return;
711
}
712
713
if (fdata->xfs != NULL) {
714
XFreeFontSet(display, fdata->xfs);
715
}
716
717
/* AWT fonts are always "multifonts" and probably have been in
718
* all post 1.0 releases, so this test test for multi fonts is
719
* probably not needed, and the singleton xfont is probably never used.
720
*/
721
if (fdata->charset_num > 0) {
722
for (i = 0; i < fdata->charset_num; i++) {
723
free((void *)fdata->flist[i].xlfd);
724
JNU_ReleaseStringPlatformChars(env, NULL,
725
fdata->flist[i].charset_name);
726
if (fdata->flist[i].load) {
727
XFreeFont(display, fdata->flist[i].xfont);
728
}
729
}
730
731
free((void *)fdata->flist);
732
733
/* Don't free fdata->xfont because it is equal to fdata->flist[i].xfont
734
for some 'i' */
735
} else {
736
if (fdata->xfont != NULL) {
737
XFreeFont(display, fdata->xfont);
738
}
739
}
740
741
free((void *)fdata);
742
743
AWT_UNLOCK();
744
}
745
#endif /* !HEADLESS */
746
747