Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m
41152 views
1
/*
2
* Copyright (c) 2011, 2013, 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
#import "java_awt_Font.h"
27
#import "sun_awt_PlatformFont.h"
28
#import "sun_awt_FontDescriptor.h"
29
#import "sun_font_CFont.h"
30
#import "sun_font_CFontManager.h"
31
32
#import "AWTFont.h"
33
#import "AWTStrike.h"
34
#import "CoreTextSupport.h"
35
#import "JNIUtilities.h"
36
37
@implementation AWTFont
38
39
- (id) initWithFont:(NSFont *)font {
40
self = [super init];
41
if (self) {
42
fFont = [font retain];
43
fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
44
}
45
return self;
46
}
47
48
- (void) dealloc {
49
[fFont release];
50
fFont = nil;
51
52
if (fNativeCGFont) {
53
CGFontRelease(fNativeCGFont);
54
fNativeCGFont = NULL;
55
}
56
57
[super dealloc];
58
}
59
60
- (void) finalize {
61
if (fNativeCGFont) {
62
CGFontRelease(fNativeCGFont);
63
fNativeCGFont = NULL;
64
}
65
[super finalize];
66
}
67
68
static NSString* uiName = nil;
69
static NSString* uiBoldName = nil;
70
71
+ (AWTFont *) awtFontForName:(NSString *)name
72
style:(int)style
73
{
74
// create font with family & size
75
NSFont *nsFont = nil;
76
77
if ((uiName != nil && [name isEqualTo:uiName]) ||
78
(uiBoldName != nil && [name isEqualTo:uiBoldName])) {
79
if (style & java_awt_Font_BOLD) {
80
nsFont = [NSFont boldSystemFontOfSize:1.0];
81
} else {
82
nsFont = [NSFont systemFontOfSize:1.0];
83
}
84
#ifdef DEBUG
85
NSLog(@"nsFont-name is : %@", nsFont.familyName);
86
NSLog(@"nsFont-family is : %@", nsFont.fontName);
87
NSLog(@"nsFont-desc-name is : %@", nsFont.fontDescriptor.postscriptName);
88
#endif
89
90
91
} else {
92
nsFont = [NSFont fontWithName:name size:1.0];
93
}
94
95
if (nsFont == nil) {
96
// if can't get font of that name, substitute system default font
97
nsFont = [NSFont fontWithName:@"Lucida Grande" size:1.0];
98
#ifdef DEBUG
99
NSLog(@"needed to substitute Lucida Grande for: %@", name);
100
#endif
101
}
102
103
// create an italic style (if one is installed)
104
if (style & java_awt_Font_ITALIC) {
105
nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
106
}
107
108
// create a bold style (if one is installed)
109
if (style & java_awt_Font_BOLD) {
110
nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
111
}
112
113
return [[[AWTFont alloc] initWithFont:nsFont] autorelease];
114
}
115
116
+ (NSFont *) nsFontForJavaFont:(jobject)javaFont env:(JNIEnv *)env {
117
if (javaFont == NULL) {
118
#ifdef DEBUG
119
NSLog(@"nil font");
120
#endif
121
return nil;
122
}
123
124
DECLARE_CLASS_RETURN(jc_Font, "java/awt/Font", nil);
125
126
// obtain the Font2D
127
DECLARE_METHOD_RETURN(jm_Font_getFont2D, jc_Font, "getFont2D", "()Lsun/font/Font2D;", nil);
128
jobject font2d = (*env)->CallObjectMethod(env, javaFont, jm_Font_getFont2D);
129
CHECK_EXCEPTION();
130
if (font2d == NULL) {
131
#ifdef DEBUG
132
NSLog(@"nil font2d");
133
#endif
134
return nil;
135
}
136
137
// if it's not a CFont, it's likely one of TTF or OTF fonts
138
// from the Sun rendering loops
139
DECLARE_CLASS_RETURN(jc_CFont, "sun/font/CFont", nil);
140
if (!(*env)->IsInstanceOf(env, font2d, jc_CFont)) {
141
#ifdef DEBUG
142
NSLog(@"font2d !instanceof CFont");
143
#endif
144
return nil;
145
}
146
147
DECLARE_METHOD_RETURN(jm_CFont_getFontStrike, jc_CFont, "getStrike", "(Ljava/awt/Font;)Lsun/font/FontStrike;", nil);
148
jobject fontStrike = (*env)->CallObjectMethod(env, font2d, jm_CFont_getFontStrike, javaFont);
149
CHECK_EXCEPTION();
150
DECLARE_CLASS_RETURN(jc_CStrike, "sun/font/CStrike", nil);
151
if (!(*env)->IsInstanceOf(env, fontStrike, jc_CStrike)) {
152
#ifdef DEBUG
153
NSLog(@"fontStrike !instanceof CStrike");
154
#endif
155
return nil;
156
}
157
158
DECLARE_METHOD_RETURN(jm_CStrike_nativeStrikePtr, jc_CStrike, "getNativeStrikePtr", "()J", nil);
159
jlong awtStrikePtr = (*env)->CallLongMethod(env, fontStrike, jm_CStrike_nativeStrikePtr);
160
CHECK_EXCEPTION();
161
if (awtStrikePtr == 0L) {
162
#ifdef DEBUG
163
NSLog(@"nil nativeFontPtr from CFont");
164
#endif
165
return nil;
166
}
167
168
AWTStrike *strike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
169
170
return [NSFont fontWithName:[strike->fAWTFont->fFont fontName] matrix:(CGFloat *)(&(strike->fAltTx))];
171
}
172
173
@end
174
175
176
#pragma mark --- Font Discovery and Loading ---
177
178
static NSArray* sFilteredFonts = nil;
179
static NSDictionary* sFontFamilyTable = nil;
180
181
static NSString*
182
GetFamilyNameForFontName(NSString* fontname)
183
{
184
return [sFontFamilyTable objectForKey:fontname];
185
}
186
187
static void addFont(CTFontUIFontType uiType,
188
NSMutableArray *allFonts,
189
NSMutableDictionary* fontFamilyTable) {
190
191
CTFontRef font = CTFontCreateUIFontForLanguage(uiType, 0.0, NULL);
192
if (font == NULL) {
193
return;
194
}
195
CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);
196
if (desc == NULL) {
197
CFRelease(font);
198
return;
199
}
200
CFStringRef family = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);
201
if (family == NULL) {
202
CFRelease(desc);
203
CFRelease(font);
204
return;
205
}
206
CFStringRef name = CTFontDescriptorCopyAttribute(desc, kCTFontNameAttribute);
207
if (name == NULL) {
208
CFRelease(family);
209
CFRelease(desc);
210
CFRelease(font);
211
return;
212
}
213
if (uiType == kCTFontUIFontSystem) {
214
uiName = (NSString*)name;
215
}
216
if (uiType == kCTFontUIFontEmphasizedSystem) {
217
uiBoldName = (NSString*)name;
218
}
219
[allFonts addObject:name];
220
[fontFamilyTable setObject:family forKey:name];
221
#ifdef DEBUG
222
NSLog(@"name is : %@", (NSString*)name);
223
NSLog(@"family is : %@", (NSString*)family);
224
#endif
225
CFRelease(family);
226
CFRelease(name);
227
CFRelease(desc);
228
CFRelease(font);
229
}
230
231
static NSArray*
232
GetFilteredFonts()
233
{
234
if (sFilteredFonts == nil) {
235
NSFontManager *fontManager = [NSFontManager sharedFontManager];
236
NSUInteger fontCount = [[fontManager availableFonts] count];
237
238
NSMutableArray *allFonts = [[NSMutableArray alloc] initWithCapacity:fontCount];
239
NSMutableDictionary* fontFamilyTable = [[NSMutableDictionary alloc] initWithCapacity:fontCount];
240
NSArray *allFamilies = [fontManager availableFontFamilies];
241
242
NSUInteger familyCount = [allFamilies count];
243
244
NSUInteger familyIndex;
245
for (familyIndex = 0; familyIndex < familyCount; familyIndex++) {
246
NSString *family = [allFamilies objectAtIndex:familyIndex];
247
248
if ((family == nil) || [family characterAtIndex:0] == '.') {
249
continue;
250
}
251
252
NSArray *fontFaces = [fontManager availableMembersOfFontFamily:family];
253
NSUInteger faceCount = [fontFaces count];
254
255
NSUInteger faceIndex;
256
for (faceIndex = 0; faceIndex < faceCount; faceIndex++) {
257
NSString* face = [[fontFaces objectAtIndex:faceIndex] objectAtIndex:0];
258
if (face != nil) {
259
[allFonts addObject:face];
260
[fontFamilyTable setObject:family forKey:face];
261
}
262
}
263
}
264
265
/*
266
* JavaFX registers these fonts and so JDK needs to do so as well.
267
* If this isn't done we will have mis-matched rendering, since
268
* although these may include fonts that are enumerated normally
269
* they also demonstrably includes fonts that are not.
270
*/
271
addFont(kCTFontUIFontSystem, allFonts, fontFamilyTable);
272
addFont(kCTFontUIFontEmphasizedSystem, allFonts, fontFamilyTable);
273
274
sFilteredFonts = allFonts;
275
sFontFamilyTable = fontFamilyTable;
276
}
277
278
return sFilteredFonts;
279
}
280
281
#pragma mark --- sun.font.CFontManager JNI ---
282
283
static OSStatus CreateFSRef(FSRef *myFSRefPtr, NSString *inPath)
284
{
285
return FSPathMakeRef((UInt8 *)[inPath fileSystemRepresentation],
286
myFSRefPtr, NULL);
287
}
288
289
/*
290
* Class: sun_font_CFontManager
291
* Method: loadNativeFonts
292
* Signature: ()V
293
*/
294
JNIEXPORT void JNICALL
295
Java_sun_font_CFontManager_loadNativeFonts
296
(JNIEnv *env, jobject jthis)
297
{
298
DECLARE_CLASS(jc_CFontManager, "sun/font/CFontManager");
299
DECLARE_METHOD(jm_registerFont, jc_CFontManager, "registerFont", "(Ljava/lang/String;Ljava/lang/String;)V");
300
301
jint num = 0;
302
303
JNI_COCOA_ENTER(env);
304
305
NSArray *filteredFonts = GetFilteredFonts();
306
num = (jint)[filteredFonts count];
307
308
jint i;
309
for (i = 0; i < num; i++) {
310
NSString *fontname = [filteredFonts objectAtIndex:i];
311
jobject jFontName = NSStringToJavaString(env, fontname);
312
jobject jFontFamilyName =
313
NSStringToJavaString(env, GetFamilyNameForFontName(fontname));
314
315
(*env)->CallVoidMethod(env, jthis, jm_registerFont, jFontName, jFontFamilyName);
316
CHECK_EXCEPTION();
317
(*env)->DeleteLocalRef(env, jFontName);
318
(*env)->DeleteLocalRef(env, jFontFamilyName);
319
}
320
321
JNI_COCOA_EXIT(env);
322
}
323
324
/*
325
* Class: Java_sun_font_CFontManager_loadNativeDirFonts
326
* Method: loadNativeDirFonts
327
* Signature: (Ljava/lang/String;)V;
328
*/
329
JNIEXPORT void JNICALL
330
Java_sun_font_CFontManager_loadNativeDirFonts
331
(JNIEnv *env, jclass clz, jstring filename)
332
{
333
JNI_COCOA_ENTER(env);
334
335
NSString *path = JavaStringToNSString(env, filename);
336
NSURL *url = [NSURL fileURLWithPath:(NSString *)path];
337
bool res = CTFontManagerRegisterFontsForURL((CFURLRef)url, kCTFontManagerScopeProcess, nil);
338
#ifdef DEBUG
339
NSLog(@"path is : %@", (NSString*)path);
340
NSLog(@"url is : %@", (NSString*)url);
341
printf("res is %d\n", res);
342
#endif
343
JNI_COCOA_EXIT(env);
344
}
345
346
#pragma mark --- sun.font.CFont JNI ---
347
348
/*
349
* Class: sun_font_CFont
350
* Method: getPlatformFontPtrNative
351
* Signature: (JI)[B
352
*/
353
JNIEXPORT jlong JNICALL
354
Java_sun_font_CFont_getCGFontPtrNative
355
(JNIEnv *env, jclass clazz,
356
jlong awtFontPtr)
357
{
358
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
359
return (jlong)(awtFont->fNativeCGFont);
360
}
361
362
/*
363
* Class: sun_font_CFont
364
* Method: getTableBytesNative
365
* Signature: (JI)[B
366
*/
367
JNIEXPORT jbyteArray JNICALL
368
Java_sun_font_CFont_getTableBytesNative
369
(JNIEnv *env, jclass clazz,
370
jlong awtFontPtr, jint jtag)
371
{
372
jbyteArray jbytes = NULL;
373
JNI_COCOA_ENTER(env);
374
375
CTFontTableTag tag = (CTFontTableTag)jtag;
376
int i, found = 0;
377
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
378
NSFont* nsFont = awtFont->fFont;
379
CTFontRef ctfont = (CTFontRef)nsFont;
380
CFArrayRef tagsArray =
381
CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions);
382
CFIndex numTags = CFArrayGetCount(tagsArray);
383
for (i=0; i<numTags; i++) {
384
if (tag ==
385
(CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tagsArray, i)) {
386
found = 1;
387
break;
388
}
389
}
390
CFRelease(tagsArray);
391
if (!found) {
392
return NULL;
393
}
394
CFDataRef table = CTFontCopyTable(ctfont, tag, kCTFontTableOptionNoOptions);
395
if (table == NULL) {
396
return NULL;
397
}
398
399
char *tableBytes = (char*)(CFDataGetBytePtr(table));
400
size_t tableLength = CFDataGetLength(table);
401
if (tableBytes == NULL || tableLength == 0) {
402
CFRelease(table);
403
return NULL;
404
}
405
406
jbytes = (*env)->NewByteArray(env, (jsize)tableLength);
407
if (jbytes == NULL) {
408
return NULL;
409
}
410
(*env)->SetByteArrayRegion(env, jbytes, 0,
411
(jsize)tableLength,
412
(jbyte*)tableBytes);
413
CFRelease(table);
414
415
JNI_COCOA_EXIT(env);
416
417
return jbytes;
418
}
419
420
/*
421
* Class: sun_font_CFont
422
* Method: initNativeFont
423
* Signature: (Ljava/lang/String;I)J
424
*/
425
JNIEXPORT jlong JNICALL
426
Java_sun_font_CFont_createNativeFont
427
(JNIEnv *env, jclass clazz,
428
jstring nativeFontName, jint style)
429
{
430
AWTFont *awtFont = nil;
431
432
JNI_COCOA_ENTER(env);
433
434
awtFont =
435
[AWTFont awtFontForName:JavaStringToNSString(env, nativeFontName)
436
style:style]; // autoreleased
437
438
if (awtFont) {
439
CFRetain(awtFont); // GC
440
}
441
442
JNI_COCOA_EXIT(env);
443
444
return ptr_to_jlong(awtFont);
445
}
446
447
/*
448
* Class: sun_font_CFont
449
* Method: getWidthNative
450
* Signature: (J)F
451
*/
452
JNIEXPORT jfloat JNICALL
453
Java_sun_font_CFont_getWidthNative
454
(JNIEnv *env, jobject cfont, jlong awtFontPtr)
455
{
456
float widthVal;
457
JNI_COCOA_ENTER(env);
458
459
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
460
NSFont* nsFont = awtFont->fFont;
461
NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
462
NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
463
NSNumber *width = [fontTraits objectForKey : NSFontWidthTrait];
464
widthVal = (float)[width floatValue];
465
466
JNI_COCOA_EXIT(env);
467
return (jfloat)widthVal;
468
}
469
470
/*
471
* Class: sun_font_CFont
472
* Method: getWeightNative
473
* Signature: (J)F
474
*/
475
JNIEXPORT jfloat JNICALL
476
Java_sun_font_CFont_getWeightNative
477
(JNIEnv *env, jobject cfont, jlong awtFontPtr)
478
{
479
float weightVal;
480
JNI_COCOA_ENTER(env);
481
482
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
483
NSFont* nsFont = awtFont->fFont;
484
NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
485
NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
486
NSNumber *weight = [fontTraits objectForKey : NSFontWeightTrait];
487
weightVal = (float)[weight floatValue];
488
489
JNI_COCOA_EXIT(env);
490
return (jfloat)weightVal;
491
}
492
493
/*
494
* Class: sun_font_CFont
495
* Method: disposeNativeFont
496
* Signature: (J)V
497
*/
498
JNIEXPORT void JNICALL
499
Java_sun_font_CFont_disposeNativeFont
500
(JNIEnv *env, jclass clazz, jlong awtFontPtr)
501
{
502
JNI_COCOA_ENTER(env);
503
504
if (awtFontPtr) {
505
CFRelease((AWTFont *)jlong_to_ptr(awtFontPtr)); // GC
506
}
507
508
JNI_COCOA_EXIT(env);
509
}
510
511
512
#pragma mark --- Miscellaneous JNI ---
513
514
#ifndef HEADLESS
515
/*
516
* Class: sun_awt_PlatformFont
517
* Method: initIDs
518
* Signature: ()V
519
*/
520
JNIEXPORT void JNICALL
521
Java_sun_awt_PlatformFont_initIDs
522
(JNIEnv *env, jclass cls)
523
{
524
}
525
526
/*
527
* Class: sun_awt_FontDescriptor
528
* Method: initIDs
529
* Signature: ()V
530
*/
531
JNIEXPORT void JNICALL
532
Java_sun_awt_FontDescriptor_initIDs
533
(JNIEnv *env, jclass cls)
534
{
535
}
536
#endif
537
538
/*
539
* Class: sun_awt_FontDescriptor
540
* Method: initIDs
541
* Signature: ()V
542
*/
543
JNIEXPORT void JNICALL
544
Java_sun_font_CFont_getCascadeList
545
(JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
546
{
547
JNI_COCOA_ENTER(env);
548
jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
549
if (alc == NULL) return;
550
jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
551
if (addMID == NULL) return;
552
553
CFIndex i;
554
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
555
NSFont* nsFont = awtFont->fFont;
556
CTFontRef font = (CTFontRef)nsFont;
557
CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
558
559
#ifdef DEBUG
560
CFStringRef base = CTFontCopyFullName(font);
561
NSLog(@"BaseFont is : %@", (NSString*)base);
562
CFRelease(base);
563
#endif
564
CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
565
CFRelease(codes);
566
CFIndex cnt = CFArrayGetCount(fds);
567
for (i=0; i<cnt; i++) {
568
CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
569
CFStringRef fontname =
570
CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
571
#ifdef DEBUG
572
NSLog(@"Font is : %@", (NSString*)fontname);
573
#endif
574
jstring jFontName = (jstring)NSStringToJavaString(env, fontname);
575
CFRelease(fontname);
576
(*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName);
577
if ((*env)->ExceptionOccurred(env)) {
578
CFRelease(fds);
579
return;
580
}
581
(*env)->DeleteLocalRef(env, jFontName);
582
}
583
CFRelease(fds);
584
JNI_COCOA_EXIT(env);
585
}
586
587
static CFStringRef EMOJI_FONT_NAME = CFSTR("Apple Color Emoji");
588
589
bool IsEmojiFont(CTFontRef font)
590
{
591
CFStringRef name = CTFontCopyFullName(font);
592
if (name == NULL) return false;
593
bool isFixedColor = CFStringCompare(name, EMOJI_FONT_NAME, 0) == kCFCompareEqualTo;
594
CFRelease(name);
595
return isFixedColor;
596
}
597
598