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/AWTStrike.m
41152 views
1
/*
2
* Copyright (c) 2011, 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
#import "java_awt_geom_PathIterator.h"
27
#import "sun_font_CStrike.h"
28
#import "sun_font_CStrikeDisposer.h"
29
#import "CGGlyphImages.h"
30
#import "CGGlyphOutlines.h"
31
#import "CoreTextSupport.h"
32
#import "JNIUtilities.h"
33
#include "fontscalerdefs.h"
34
35
@implementation AWTStrike
36
37
static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
38
39
- (id) initWithFont:(AWTFont *)awtFont
40
tx:(CGAffineTransform)tx
41
invDevTx:(CGAffineTransform)invDevTx
42
style:(JRSFontRenderingStyle)style
43
aaStyle:(jint)aaStyle {
44
45
self = [super init];
46
if (self) {
47
fAWTFont = [awtFont retain];
48
fStyle = style;
49
fAAStyle = aaStyle;
50
51
fTx = tx; // composited glyph and device transform
52
53
fAltTx = tx;
54
fAltTx.b *= -1;
55
fAltTx.d *= -1;
56
57
invDevTx.b *= -1;
58
invDevTx.c *= -1;
59
fFontTx = CGAffineTransformConcat(CGAffineTransformConcat(tx, invDevTx), sInverseTX);
60
fDevTx = CGAffineTransformInvert(CGAffineTransformConcat(invDevTx, sInverseTX));
61
62
// the "font size" is the square root of the determinant of the matrix
63
fSize = sqrt(fabs(fFontTx.a * fFontTx.d - fFontTx.b * fFontTx.c));
64
}
65
return self;
66
}
67
68
- (void) dealloc {
69
[fAWTFont release];
70
fAWTFont = nil;
71
72
[super dealloc];
73
}
74
75
+ (AWTStrike *) awtStrikeForFont:(AWTFont *)awtFont
76
tx:(CGAffineTransform)tx
77
invDevTx:(CGAffineTransform)invDevTx
78
style:(JRSFontRenderingStyle)style
79
aaStyle:(jint)aaStyle {
80
81
return [[[AWTStrike alloc] initWithFont:awtFont
82
tx:tx invDevTx:invDevTx
83
style:style
84
aaStyle:aaStyle] autorelease];
85
}
86
87
@end
88
89
90
#define AWT_FONT_CLEANUP_SETUP \
91
BOOL _fontThrowJavaException = NO;
92
93
#define AWT_FONT_CLEANUP_CHECK(a) \
94
if ((a) == NULL) { \
95
_fontThrowJavaException = YES; \
96
goto cleanup; \
97
} \
98
if ((*env)->ExceptionCheck(env) == JNI_TRUE) { \
99
goto cleanup; \
100
}
101
102
#define AWT_FONT_CLEANUP_FINISH \
103
if (_fontThrowJavaException == YES) { \
104
char s[512]; \
105
sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \
106
JNU_ThrowByName(env, "java/lang/RuntimeException", s); \
107
}
108
109
110
/*
111
* Creates an affine transform from the corresponding doubles sent
112
* from CStrike.getGlyphTx().
113
*/
114
static inline CGAffineTransform
115
GetTxFromDoubles(JNIEnv *env, jdoubleArray txArray)
116
{
117
if (txArray == NULL) {
118
return CGAffineTransformIdentity;
119
}
120
121
jdouble *txPtr = (*env)->GetPrimitiveArrayCritical(env, txArray, NULL);
122
if (txPtr == NULL) {
123
return CGAffineTransformIdentity;
124
}
125
126
CGAffineTransform tx =
127
CGAffineTransformMake(txPtr[0], txPtr[1], txPtr[2],
128
txPtr[3], txPtr[4], txPtr[5]);
129
tx = CGAffineTransformConcat(sInverseTX, tx);
130
131
(*env)->ReleasePrimitiveArrayCritical(env, txArray, txPtr, JNI_ABORT);
132
133
return tx;
134
}
135
136
/*
137
* Class: sun_font_CStrike
138
* Method: getNativeGlyphAdvance
139
* Signature: (JI)F
140
*/
141
JNIEXPORT jfloat JNICALL
142
Java_sun_font_CStrike_getNativeGlyphAdvance
143
(JNIEnv *env, jclass clazz, jlong awtStrikePtr, jint glyphCode)
144
{
145
CGSize advance;
146
JNI_COCOA_ENTER(env);
147
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
148
AWTFont *awtFont = awtStrike->fAWTFont;
149
150
// negative glyph codes are really unicodes, which were placed there by the mapper
151
// to indicate we should use CoreText to substitute the character
152
CGGlyph glyph;
153
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
154
CGGlyphImages_GetGlyphMetrics(fallback, &awtStrike->fAltTx, awtStrike->fStyle, &glyph, 1, NULL, &advance);
155
CFRelease(fallback);
156
advance = CGSizeApplyAffineTransform(advance, awtStrike->fFontTx);
157
if (!JRSFontStyleUsesFractionalMetrics(awtStrike->fStyle)) {
158
advance.width = round(advance.width);
159
}
160
161
JNI_COCOA_EXIT(env);
162
return advance.width;
163
}
164
165
/*
166
* Class: sun_font_CStrike
167
* Method: getNativeGlyphImageBounds
168
* Signature: (JJILjava/awt/geom/Rectangle2D/Float;DD)V
169
*/
170
JNIEXPORT void JNICALL
171
Java_sun_font_CStrike_getNativeGlyphImageBounds
172
(JNIEnv *env, jclass clazz,
173
jlong awtStrikePtr, jint glyphCode,
174
jobject result /*Rectangle*/, jdouble x, jdouble y)
175
{
176
JNI_COCOA_ENTER(env);
177
178
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
179
AWTFont *awtFont = awtStrike->fAWTFont;
180
181
CGAffineTransform tx = awtStrike->fAltTx;
182
tx.tx += x;
183
tx.ty += y;
184
185
// negative glyph codes are really unicodes, which were placed there by the mapper
186
// to indicate we should use CoreText to substitute the character
187
CGGlyph glyph;
188
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
189
190
CGRect bbox;
191
CGGlyphImages_GetGlyphMetrics(fallback, &tx, awtStrike->fStyle, &glyph, 1, &bbox, NULL);
192
CFRelease(fallback);
193
194
// the origin of this bounding box is relative to the bottom-left corner baseline
195
CGFloat decender = -bbox.origin.y;
196
bbox.origin.y = -bbox.size.height + decender;
197
198
// Rectangle2D.Float.setRect(float x, float y, float width, float height);
199
DECLARE_CLASS(sjc_Rectangle2D_Float, "java/awt/geom/Rectangle2D$Float"); // cache class id for Rectangle
200
DECLARE_METHOD(sjr_Rectangle2DFloat_setRect, sjc_Rectangle2D_Float, "setRect", "(FFFF)V");
201
(*env)->CallVoidMethod(env, result, sjr_Rectangle2DFloat_setRect,
202
(jfloat)bbox.origin.x, (jfloat)bbox.origin.y, (jfloat)bbox.size.width, (jfloat)bbox.size.height);
203
CHECK_EXCEPTION();
204
205
JNI_COCOA_EXIT(env);
206
}
207
208
/*
209
* Class: sun_font_CStrike
210
* Method: getNativeGlyphOutline
211
* Signature: (JJIDD)Ljava/awt/geom/GeneralPath;
212
*/
213
JNIEXPORT jobject JNICALL
214
Java_sun_font_CStrike_getNativeGlyphOutline
215
(JNIEnv *env, jclass clazz,
216
jlong awtStrikePtr, jint glyphCode, jdouble xPos, jdouble yPos)
217
{
218
jobject generalPath = NULL;
219
220
JNI_COCOA_ENTER(env);
221
222
AWTPathRef path = NULL;
223
jfloatArray pointCoords = NULL;
224
jbyteArray pointTypes = NULL;
225
226
DECLARE_CLASS_RETURN(jc_GeneralPath, "java/awt/geom/GeneralPath", NULL);
227
DECLARE_METHOD_RETURN(jc_GeneralPath_ctor, jc_GeneralPath, "<init>", "(I[BI[FI)V", NULL);
228
229
AWT_FONT_CLEANUP_SETUP;
230
231
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
232
AWTFont *awtfont = awtStrike->fAWTFont;
233
234
AWT_FONT_CLEANUP_CHECK(awtfont);
235
236
// inverting the shear order and sign to compensate for the flipped coordinate system
237
CGAffineTransform tx = awtStrike->fTx;
238
tx.tx += xPos;
239
tx.ty += yPos;
240
241
// get the right font and glyph for this "Java GlyphCode"
242
243
CGGlyph glyph;
244
const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtfont, glyphCode, &glyph);
245
246
// get the advance of this glyph
247
CGSize advance;
248
CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &glyph, &advance, 1);
249
250
// Create AWTPath
251
path = AWTPathCreate(CGSizeMake(xPos, yPos));
252
AWT_FONT_CLEANUP_CHECK(path);
253
254
// Get the paths
255
tx = awtStrike->fTx;
256
tx = CGAffineTransformConcat(tx, sInverseTX);
257
AWTGetGlyphOutline(&glyph, (NSFont *)font, &advance, &tx, 0, 1, &path);
258
CFRelease(font);
259
260
pointCoords = (*env)->NewFloatArray(env, path->fNumberOfDataElements);
261
AWT_FONT_CLEANUP_CHECK(pointCoords);
262
263
(*env)->SetFloatArrayRegion(env, pointCoords, 0, path->fNumberOfDataElements, (jfloat*)path->fSegmentData);
264
265
// Copy the pointTypes to the general path
266
pointTypes = (*env)->NewByteArray(env, path->fNumberOfSegments);
267
AWT_FONT_CLEANUP_CHECK(pointTypes);
268
269
(*env)->SetByteArrayRegion(env, pointTypes, 0, path->fNumberOfSegments, (jbyte*)path->fSegmentType);
270
271
generalPath = (*env)->NewObject(env, jc_GeneralPath, jc_GeneralPath_ctor, java_awt_geom_PathIterator_WIND_NON_ZERO, pointTypes,
272
path->fNumberOfSegments, pointCoords, path->fNumberOfDataElements); // AWT_THREADING Safe (known object)
273
274
// Cleanup
275
cleanup:
276
if (path != NULL) {
277
AWTPathFree(path);
278
path = NULL;
279
}
280
281
if (pointCoords != NULL) {
282
(*env)->DeleteLocalRef(env, pointCoords);
283
pointCoords = NULL;
284
}
285
286
if (pointTypes != NULL) {
287
(*env)->DeleteLocalRef(env, pointTypes);
288
pointTypes = NULL;
289
}
290
291
AWT_FONT_CLEANUP_FINISH;
292
JNI_COCOA_EXIT(env);
293
return generalPath;
294
}
295
296
/*
297
* Class: sun_font_CStrike
298
* Method: getGlyphImagePtrsNative
299
* Signature: (JJ[J[II)V
300
*/
301
JNIEXPORT void JNICALL
302
Java_sun_font_CStrike_getGlyphImagePtrsNative
303
(JNIEnv *env, jclass clazz,
304
jlong awtStrikePtr, jlongArray glyphInfoLongArray,
305
jintArray glyphCodes, jint len)
306
{
307
JNI_COCOA_ENTER(env);
308
309
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
310
311
jlong *glyphInfos =
312
(*env)->GetPrimitiveArrayCritical(env, glyphInfoLongArray, NULL);
313
314
jint *rawGlyphCodes =
315
(*env)->GetPrimitiveArrayCritical(env, glyphCodes, NULL);
316
@try {
317
if (rawGlyphCodes != NULL && glyphInfos != NULL) {
318
CGGlyphImages_GetGlyphImagePtrs(glyphInfos, awtStrike,
319
rawGlyphCodes, len);
320
}
321
}
322
@finally {
323
if (rawGlyphCodes != NULL) {
324
(*env)->ReleasePrimitiveArrayCritical(env, glyphCodes,
325
rawGlyphCodes, JNI_ABORT);
326
}
327
if (glyphInfos != NULL) {
328
// Do not use JNI_COMMIT, as that will not free the buffer copy
329
// when +ProtectJavaHeap is on.
330
(*env)->ReleasePrimitiveArrayCritical(env, glyphInfoLongArray,
331
glyphInfos, 0);
332
}
333
}
334
335
JNI_COCOA_EXIT(env);
336
}
337
338
/*
339
* Class: sun_font_CStrike
340
* Method: createNativeStrikePtr
341
* Signature: (J[D[DII)J
342
*/
343
JNIEXPORT jlong JNICALL Java_sun_font_CStrike_createNativeStrikePtr
344
(JNIEnv *env, jclass clazz, jlong nativeFontPtr, jdoubleArray glyphTxArray, jdoubleArray invDevTxArray, jint aaStyle, jint fmHint)
345
{
346
AWTStrike *awtStrike = nil;
347
JNI_COCOA_ENTER(env);
348
349
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(nativeFontPtr);
350
JRSFontRenderingStyle style = JRSFontGetRenderingStyleForHints(fmHint, aaStyle);
351
352
CGAffineTransform glyphTx = GetTxFromDoubles(env, glyphTxArray);
353
CGAffineTransform invDevTx = GetTxFromDoubles(env, invDevTxArray);
354
355
awtStrike = [AWTStrike awtStrikeForFont:awtFont tx:glyphTx invDevTx:invDevTx style:style aaStyle:aaStyle]; // autoreleased
356
357
if (awtStrike)
358
{
359
CFRetain(awtStrike); // GC
360
}
361
362
JNI_COCOA_EXIT(env);
363
return ptr_to_jlong(awtStrike);
364
}
365
366
/*
367
* Class: sun_font_CStrike
368
* Method: disposeNativeStrikePtr
369
* Signature: (J)V
370
*/
371
JNIEXPORT void JNICALL
372
Java_sun_font_CStrike_disposeNativeStrikePtr
373
(JNIEnv *env, jclass clazz, jlong awtStrike)
374
{
375
JNI_COCOA_ENTER(env);
376
377
if (awtStrike) {
378
CFRelease((AWTStrike *)jlong_to_ptr(awtStrike)); // GC
379
}
380
381
JNI_COCOA_EXIT(env);
382
}
383
384
/*
385
* Class: sun_font_CStrike
386
* Method: getFontMetrics
387
* Signature: (J)Lsun/font/StrikeMetrics;
388
*/
389
JNIEXPORT jobject JNICALL
390
Java_sun_font_CStrike_getFontMetrics
391
(JNIEnv *env, jclass clazz, jlong awtStrikePtr)
392
{
393
jobject metrics = NULL;
394
395
JNI_COCOA_ENTER(env);
396
AWT_FONT_CLEANUP_SETUP;
397
398
AWTFont *awtfont = ((AWTStrike *)jlong_to_ptr(awtStrikePtr))->fAWTFont;
399
AWT_FONT_CLEANUP_CHECK(awtfont);
400
401
CGFontRef cgFont = awtfont->fNativeCGFont;
402
403
jfloat ay=0.0, dy=0.0, mx=0.0, ly=0.0;
404
int unitsPerEm = CGFontGetUnitsPerEm(cgFont);
405
CGFloat scaleX = (1.0 / unitsPerEm);
406
CGFloat scaleY = (1.0 / unitsPerEm);
407
408
// Ascent
409
ay = -(CGFloat)CGFontGetAscent(cgFont) * scaleY;
410
411
// Descent
412
dy = -(CGFloat)CGFontGetDescent(cgFont) * scaleY;
413
414
// Leading
415
ly = (CGFloat)CGFontGetLeading(cgFont) * scaleY;
416
417
// Max Advance for Font Direction (Strictly horizontal)
418
mx = [awtfont->fFont maximumAdvancement].width;
419
420
/*
421
* ascent: no need to set ascentX - it will be zero.
422
* descent: no need to set descentX - it will be zero.
423
* baseline: old releases "made up" a number and also seemed to
424
* make it up for "X" and set "Y" to 0.
425
* leadingX: no need to set leadingX - it will be zero.
426
* leadingY: made-up number, but being compatible with what 1.4.x did.
427
* advance: no need to set yMaxLinearAdvanceWidth - it will be zero.
428
*/
429
430
DECLARE_CLASS_RETURN(sjc_StrikeMetrics, "sun/font/StrikeMetrics", NULL);
431
DECLARE_METHOD_RETURN(strikeMetricsCtr, sjc_StrikeMetrics, "<init>", "(FFFFFFFFFF)V", NULL);
432
metrics = (*env)->NewObject(env, sjc_StrikeMetrics, strikeMetricsCtr,
433
0.0, ay, 0.0, dy, 1.0,
434
0.0, 0.0, ly, mx, 0.0);
435
436
cleanup:
437
AWT_FONT_CLEANUP_FINISH;
438
JNI_COCOA_EXIT(env);
439
440
return metrics;
441
}
442
443
extern void AccelGlyphCache_RemoveAllInfos(GlyphInfo* glyph);
444
/*
445
* Class: sun_font_CStrikeDisposer
446
* Method: removeGlyphInfoFromCache
447
* Signature: (J)V
448
*/
449
JNIEXPORT void JNICALL Java_sun_font_CStrikeDisposer_removeGlyphInfoFromCache
450
(JNIEnv *env, jclass cls, jlong glyphInfo)
451
{
452
JNI_COCOA_ENTER(env);
453
454
AccelGlyphCache_RemoveAllCellInfos((GlyphInfo*)jlong_to_ptr(glyphInfo));
455
456
JNI_COCOA_EXIT(env);
457
}
458
459