mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
IDEA-57233 Editor font antialising/appearance problems on Linux
Used desktop DPI instead of hard-coded 72 Compensated increased glyph bitmap size by adjusting font size Added LCD filter for sub-pixel rendering Use fontconfig library to provide right rendering options for fonts Corrected sizes passed to fontconfig library and hinting disabling policy Added logging and versioned fontconfig lib loading Resolved font rendering problem in lenses (cherry picked from commit0456745afb) IDEA-152816, IDEA-152454 fix text rendering issues (text cutoff and incorrect rendering in editor fragment components) FcMatchFont-type pattern substitutions shouldn't be invoked before specific font is selected - it can apply unrelated rules port commit e21cd635 from JBR 9 (cherry picked from commit5d704a963b) partially rollback JBR-363 fix, to apply corresponding change from OpenJDK 12 (cherry picked from commit3d7ac30072)
This commit is contained in:
committed by
alexey.ushakov@jetbrains.com
parent
b6c8116630
commit
db3c33474a
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package sun.font;
|
package sun.font;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.awt.geom.GeneralPath;
|
import java.awt.geom.GeneralPath;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
@@ -47,10 +48,10 @@ class FreetypeFontScaler extends FontScaler {
|
|||||||
/* At the moment fontmanager library depends on freetype library
|
/* At the moment fontmanager library depends on freetype library
|
||||||
and therefore no need to load it explicitly here */
|
and therefore no need to load it explicitly here */
|
||||||
FontManagerNativeLibrary.load();
|
FontManagerNativeLibrary.load();
|
||||||
initIDs(FreetypeFontScaler.class);
|
initIDs(FreetypeFontScaler.class, Toolkit.class, PhysicalFont.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void initIDs(Class<?> FFS);
|
private static native void initIDs(Class<?> FFS, Class<?> toolkitClass, Class<?> pfClass);
|
||||||
|
|
||||||
private void invalidateScaler() throws FontScalerException {
|
private void invalidateScaler() throws FontScalerException {
|
||||||
nativeScaler = 0;
|
nativeScaler = 0;
|
||||||
|
|||||||
1010
src/java.desktop/share/native/libfontmanager/fontconfig.h
Normal file
1010
src/java.desktop/share/native/libfontmanager/fontconfig.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "jni_util.h"
|
#include "jni_util.h"
|
||||||
#include "jlong.h"
|
#include "jvm_md.h"
|
||||||
#include "sunfontids.h"
|
#include "sunfontids.h"
|
||||||
#include "sun_font_FreetypeFontScaler.h"
|
#include "sun_font_FreetypeFontScaler.h"
|
||||||
|
|
||||||
@@ -33,8 +33,11 @@
|
|||||||
#if !defined(_WIN32) && !defined(__APPLE_)
|
#if !defined(_WIN32) && !defined(__APPLE_)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include "ft2build.h"
|
#include "ft2build.h"
|
||||||
|
#include FT_LCD_FILTER_H
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#include FT_GLYPH_H
|
#include FT_GLYPH_H
|
||||||
#include FT_BBOX_H
|
#include FT_BBOX_H
|
||||||
@@ -43,6 +46,10 @@
|
|||||||
#include FT_SYNTHESIS_H
|
#include FT_SYNTHESIS_H
|
||||||
#include FT_LCD_FILTER_H
|
#include FT_LCD_FILTER_H
|
||||||
#include FT_MODULE_H
|
#include FT_MODULE_H
|
||||||
|
#include FT_LCD_FILTER_H
|
||||||
|
|
||||||
|
/* Use bundled fontconfig.h for now */
|
||||||
|
#include "fontconfig.h"
|
||||||
|
|
||||||
#include "fontscaler.h"
|
#include "fontscaler.h"
|
||||||
|
|
||||||
@@ -50,6 +57,14 @@
|
|||||||
#define FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
|
#define FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
|
||||||
#define FTFixedToFloat(x) ((x) / (float)(ftFixed1))
|
#define FTFixedToFloat(x) ((x) / (float)(ftFixed1))
|
||||||
#define FT26Dot6ToFloat(x) ((x) / ((float) (1<<6)))
|
#define FT26Dot6ToFloat(x) ((x) / ((float) (1<<6)))
|
||||||
|
#define ROUND(x) ((int) ((x<0) ? (x-0.5) : (x+0.5)))
|
||||||
|
#define FT26Dot6ToDouble(x) ((x) / ((double) (1<<6)))
|
||||||
|
#define ROUND(x) ((int) (x+0.5))
|
||||||
|
#define DEFAULT_DPI 72
|
||||||
|
#define ADJUST_FONT_SIZE(X, DPI) (((X)*DEFAULT_DPI + ((DPI)>>1))/(DPI))
|
||||||
|
|
||||||
|
#define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
|
||||||
|
#define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Important note:
|
/* Important note:
|
||||||
@@ -81,7 +96,12 @@ typedef struct FTScalerContext {
|
|||||||
jint fmType; /* fractional metrics - on/off */
|
jint fmType; /* fractional metrics - on/off */
|
||||||
jboolean doBold; /* perform algorithmic bolding? */
|
jboolean doBold; /* perform algorithmic bolding? */
|
||||||
jboolean doItalize; /* perform algorithmic italicizing? */
|
jboolean doItalize; /* perform algorithmic italicizing? */
|
||||||
int renderFlags; /* configuration specific to particular engine */
|
|
||||||
|
/* Fontconfig info */
|
||||||
|
FT_Render_Mode renderFlags;
|
||||||
|
FT_Int32 loadFlags;
|
||||||
|
FT_LcdFilter lcdFilter;
|
||||||
|
|
||||||
int pathType;
|
int pathType;
|
||||||
int ptsz; /* size in points */
|
int ptsz; /* size in points */
|
||||||
} FTScalerContext;
|
} FTScalerContext;
|
||||||
@@ -97,12 +117,112 @@ void z_error(char *s) {}
|
|||||||
/**************** Error handling utilities *****************/
|
/**************** Error handling utilities *****************/
|
||||||
|
|
||||||
static jmethodID invalidateScalerMID;
|
static jmethodID invalidateScalerMID;
|
||||||
|
static jmethodID getDefaultToolkitMID;
|
||||||
|
static jclass tkClass;
|
||||||
|
static jmethodID getScreenResolutionMID;
|
||||||
|
static jfieldID platNameFID;
|
||||||
|
|
||||||
|
typedef FcBool (*FcPatternAddPtrType) (FcPattern *p, const char *object, FcValue value, FcBool append);
|
||||||
|
typedef FcBool (*FcPatternAddBoolPtrType) (FcPattern *p, const char *object, FcBool b);
|
||||||
|
typedef FcBool (*FcPatternAddDoublePtrType) (FcPattern *p, const char *object, double d);
|
||||||
|
typedef FcBool (*FcConfigSubstitutePtrType) (FcConfig *config, FcPattern *p, FcMatchKind kind);
|
||||||
|
typedef void (*FcDefaultSubstitutePtrType) (FcPattern *pattern);
|
||||||
|
typedef FcPattern* (*FcPatternCreatePtrType) ();
|
||||||
|
typedef FcPattern* (*FcFontMatchPtrType) (FcConfig *config, FcPattern *p, FcResult *result);
|
||||||
|
typedef void (*FcPatternDestroyPtrType) (FcPattern *p);
|
||||||
|
typedef FcResult (*FcPatternGetBoolPtrType) (const FcPattern *p, const char *object, int n, FcBool *b);
|
||||||
|
typedef FcResult (*FcPatternGetIntegerPtrType) (const FcPattern *p, const char *object, int n, int *i);
|
||||||
|
|
||||||
|
static void *libFontConfig = NULL;
|
||||||
|
static jboolean logFC = JNI_FALSE;
|
||||||
|
|
||||||
|
static FcPatternAddPtrType FcPatternAddPtr;
|
||||||
|
static FcPatternAddBoolPtrType FcPatternAddBoolPtr;
|
||||||
|
static FcPatternAddDoublePtrType FcPatternAddDoublePtr;
|
||||||
|
static FcConfigSubstitutePtrType FcConfigSubstitutePtr;
|
||||||
|
static FcDefaultSubstitutePtrType FcDefaultSubstitutePtr;
|
||||||
|
static FcPatternCreatePtrType FcPatternCreatePtr;
|
||||||
|
static FcFontMatchPtrType FcFontMatchPtr;
|
||||||
|
static FcPatternDestroyPtrType FcPatternDestroyPtr;
|
||||||
|
static FcPatternGetBoolPtrType FcPatternGetBoolPtr;
|
||||||
|
static FcPatternGetIntegerPtrType FcPatternGetIntegerPtr;
|
||||||
|
|
||||||
|
|
||||||
|
static void* openFontConfig() {
|
||||||
|
void* libfontconfig = NULL;
|
||||||
|
|
||||||
|
char *fcLogEnabled = getenv("OPENJDK_FFS_LOG_FC");
|
||||||
|
|
||||||
|
if (fcLogEnabled != NULL && !strcmp(fcLogEnabled, "yes")) {
|
||||||
|
logFC = JNI_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *useFC = getenv("OPENJDK_FFS_USE_FC");
|
||||||
|
if (useFC != NULL && !strcmp(useFC, "no")) {
|
||||||
|
if (logFC) fprintf(stderr, "FC_LOG: fontconfig disabled in freetypescaler\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
libfontconfig = dlopen(FONTCONFIG_DLL_VERSIONED, RTLD_LOCAL | RTLD_LAZY);
|
||||||
|
if (libfontconfig == NULL) {
|
||||||
|
libfontconfig = dlopen(FONTCONFIG_DLL, RTLD_LOCAL | RTLD_LAZY);
|
||||||
|
if (libfontconfig == NULL) {
|
||||||
|
if (logFC) fprintf(stderr, "FC_LOG: cannot open %s\n", FONTCONFIG_DLL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return libfontconfig;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_sun_font_FreetypeFontScaler_initIDs(
|
Java_sun_font_FreetypeFontScaler_initIDs(
|
||||||
JNIEnv *env, jobject scaler, jclass FFSClass) {
|
JNIEnv *env, jobject scaler, jclass FFSClass, jclass TKClass, jclass PFClass) {
|
||||||
invalidateScalerMID =
|
invalidateScalerMID =
|
||||||
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");
|
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");
|
||||||
|
getDefaultToolkitMID =
|
||||||
|
(*env)->GetStaticMethodID(env, TKClass, "getDefaultToolkit",
|
||||||
|
"()Ljava/awt/Toolkit;");
|
||||||
|
getScreenResolutionMID =
|
||||||
|
(*env)->GetMethodID(env, TKClass, "getScreenResolution", "()I");
|
||||||
|
tkClass = (*env)->NewGlobalRef(env, TKClass);
|
||||||
|
platNameFID = (*env)->GetFieldID(env, PFClass, "platName", "Ljava/lang/String;");
|
||||||
|
libFontConfig = openFontConfig();
|
||||||
|
if (libFontConfig) {
|
||||||
|
FcPatternAddPtr = (FcPatternAddPtrType) dlsym(libFontConfig, "FcPatternAdd");
|
||||||
|
FcPatternAddBoolPtr = (FcPatternAddBoolPtrType) dlsym(libFontConfig, "FcPatternAddBool");
|
||||||
|
FcPatternAddDoublePtr = (FcPatternAddDoublePtrType) dlsym(libFontConfig, "FcPatternAddDouble");
|
||||||
|
FcConfigSubstitutePtr = (FcConfigSubstitutePtrType) dlsym(libFontConfig, "FcConfigSubstitute");
|
||||||
|
FcDefaultSubstitutePtr = (FcDefaultSubstitutePtrType) dlsym(libFontConfig, "FcDefaultSubstitute");
|
||||||
|
FcPatternCreatePtr = (FcPatternCreatePtrType) dlsym(libFontConfig, "FcPatternCreate");
|
||||||
|
FcFontMatchPtr = (FcFontMatchPtrType) dlsym(libFontConfig, "FcFontMatch");
|
||||||
|
FcPatternDestroyPtr = (FcPatternDestroyPtrType) dlsym(libFontConfig, "FcPatternDestroy");
|
||||||
|
FcPatternGetBoolPtr = (FcPatternGetBoolPtrType) dlsym(libFontConfig, "FcPatternGetBool");
|
||||||
|
FcPatternGetIntegerPtr = (FcPatternGetIntegerPtrType) dlsym(libFontConfig, "FcPatternGetInteger");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* getPhysFontName(JNIEnv *env, jobject font2d) {
|
||||||
|
jstring jstr;
|
||||||
|
jstr = (*env)->GetObjectField(env, font2d, platNameFID);
|
||||||
|
char* str = (*env)->GetStringUTFChars(env, jstr, NULL);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getScreenResolution(JNIEnv *env) {
|
||||||
|
jthrowable exc;
|
||||||
|
jclass tk = (*env)->CallStaticObjectMethod(
|
||||||
|
env, tkClass, getDefaultToolkitMID);
|
||||||
|
int dpi = (*env)->CallIntMethod(env, tk, getScreenResolutionMID);
|
||||||
|
|
||||||
|
/* Test if there is no exception here (can get java.awt.HeadlessException)
|
||||||
|
* Fallback to default DPI otherwise
|
||||||
|
*/
|
||||||
|
exc = (*env)->ExceptionOccurred(env);
|
||||||
|
if (exc) {
|
||||||
|
(*env)->ExceptionClear(env);
|
||||||
|
return DEFAULT_DPI;
|
||||||
|
}
|
||||||
|
return dpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
|
static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
|
||||||
@@ -562,27 +682,234 @@ static void setupTransform(FT_Matrix* target, FTScalerContext *context) {
|
|||||||
static int setupFTContext(JNIEnv *env,
|
static int setupFTContext(JNIEnv *env,
|
||||||
jobject font2D,
|
jobject font2D,
|
||||||
FTScalerInfo *scalerInfo,
|
FTScalerInfo *scalerInfo,
|
||||||
FTScalerContext *context) {
|
FTScalerContext *context,
|
||||||
|
FT_Bool configureFont) {
|
||||||
FT_Matrix matrix;
|
FT_Matrix matrix;
|
||||||
int errCode = 0;
|
int errCode = 0;
|
||||||
|
|
||||||
scalerInfo->env = env;
|
scalerInfo->env = env;
|
||||||
scalerInfo->font2D = font2D;
|
scalerInfo->font2D = font2D;
|
||||||
|
|
||||||
if (context != NULL) {
|
if (context != NULL) {
|
||||||
setupTransform(&matrix, context);
|
setupTransform(&matrix, context);
|
||||||
FT_Set_Transform(scalerInfo->face, &matrix, NULL);
|
FT_Set_Transform(scalerInfo->face, &matrix, NULL);
|
||||||
|
FT_UInt dpi = (FT_UInt) getScreenResolution(env);
|
||||||
|
|
||||||
errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);
|
errCode = FT_Set_Char_Size(scalerInfo->face, 0, ADJUST_FONT_SIZE(context->ptsz, dpi), dpi, dpi);
|
||||||
|
if (errCode) return errCode;
|
||||||
|
|
||||||
if (errCode == 0) {
|
errCode = FT_Activate_Size(scalerInfo->face->size);
|
||||||
errCode = FT_Activate_Size(scalerInfo->face->size);
|
if (errCode) return errCode;
|
||||||
|
if (configureFont) {
|
||||||
|
context->renderFlags = FT_RENDER_MODE_NORMAL;
|
||||||
|
context->lcdFilter = FT_LCD_FILTER_NONE;
|
||||||
|
context->loadFlags = FT_LOAD_DEFAULT;
|
||||||
|
|
||||||
|
if (libFontConfig == NULL) {
|
||||||
|
if (context->aaType == TEXT_AA_OFF) {
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_MONO;
|
||||||
|
} else if (context->aaType == TEXT_AA_ON) {
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LIGHT;
|
||||||
|
} else {
|
||||||
|
context->lcdFilter = FT_LCD_FILTER_LIGHT;
|
||||||
|
if (context->aaType == TEXT_AA_LCD_HRGB ||
|
||||||
|
context->aaType == TEXT_AA_LCD_HBGR) {
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LCD;
|
||||||
|
} else {
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LCD_V;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context->renderFlags = FT_LOAD_TARGET_MODE(context->loadFlags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FcPattern *fcPattern = 0;
|
||||||
|
fcPattern = (*FcPatternCreatePtr)();
|
||||||
|
FcValue fcValue;
|
||||||
|
fcValue.type = FcTypeString;
|
||||||
|
char *fontName = getPhysFontName(env, font2D);
|
||||||
|
|
||||||
|
if (logFC) fprintf(stderr, "FC_LOG: %s ", fontName);
|
||||||
|
|
||||||
|
fcValue.u.s = (const FcChar8*)fontName;
|
||||||
|
(*FcPatternAddPtr)(fcPattern, FC_FILE, fcValue, FcTrue);
|
||||||
|
(*FcPatternAddBoolPtr)(fcPattern, FC_SCALABLE, FcTrue);
|
||||||
|
double fcSize = FT26Dot6ToDouble(ADJUST_FONT_SIZE(context->ptsz, dpi));
|
||||||
|
(*FcPatternAddDoublePtr)(fcPattern, FC_SIZE, fcSize);
|
||||||
|
|
||||||
|
if (logFC) fprintf(stderr, " size=%f", fcSize);
|
||||||
|
|
||||||
|
(*FcConfigSubstitutePtr)(0, fcPattern, FcMatchPattern);
|
||||||
|
(*FcDefaultSubstitutePtr)(fcPattern);
|
||||||
|
FcResult matchResult = FcResultNoMatch;
|
||||||
|
FcPattern *resultPattern = 0;
|
||||||
|
resultPattern = (*FcFontMatchPtr)(0, fcPattern, &matchResult);
|
||||||
|
if (matchResult != FcResultMatch) {
|
||||||
|
(*FcPatternDestroyPtr)(fcPattern);
|
||||||
|
if (logFC) fprintf(stderr, " - NOT FOUND\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (logFC) fprintf(stderr, "\nFC_LOG: ");
|
||||||
|
(*FcPatternDestroyPtr)(fcPattern);
|
||||||
|
FcPattern *pattern = resultPattern;
|
||||||
|
|
||||||
|
FcBool fcHinting = FcFalse;
|
||||||
|
FcBool fcHintingSet = (*FcPatternGetBoolPtr)(pattern, FC_HINTING, 0, &fcHinting) == FcResultMatch;
|
||||||
|
|
||||||
|
if (logFC && fcHintingSet) fprintf(stderr, "FC_HINTING(%d) ", fcHinting);
|
||||||
|
|
||||||
|
int fcHintStyle = FC_HINT_NONE;
|
||||||
|
FcBool fcHintStyleSet = (*FcPatternGetIntegerPtr)(pattern, FC_HINT_STYLE, 0, &fcHintStyle) == FcResultMatch;
|
||||||
|
|
||||||
|
if (logFC && fcHintStyleSet) {
|
||||||
|
switch (fcHintStyle) {
|
||||||
|
case FC_HINT_NONE:
|
||||||
|
fprintf(stderr, "FC_HINT_NONE ");
|
||||||
|
break;
|
||||||
|
case FC_HINT_SLIGHT:
|
||||||
|
fprintf(stderr, "FC_HINT_SLIGHT ");
|
||||||
|
break;
|
||||||
|
case FC_HINT_MEDIUM:
|
||||||
|
fprintf(stderr, "FC_HINT_MEDIUM ");
|
||||||
|
break;
|
||||||
|
case FC_HINT_FULL:
|
||||||
|
fprintf(stderr, "FC_HINT_FULL ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "FC_HINT_UNKNOWN ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcHintingSet && !fcHinting) {
|
||||||
|
fcHintStyleSet = FcTrue;
|
||||||
|
fcHintStyle = FC_HINT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcHintStyleSet && fcHintStyle == FC_HINT_NONE) {
|
||||||
|
fcHintingSet = FcTrue;
|
||||||
|
fcHinting = FcFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool fcAntialias = FcFalse;
|
||||||
|
FcBool fcAntialiasSet = (*FcPatternGetBoolPtr)(pattern, FC_ANTIALIAS, 0, &fcAntialias) == FcResultMatch;
|
||||||
|
|
||||||
|
if (logFC) {
|
||||||
|
switch(context->aaType) {
|
||||||
|
case TEXT_AA_ON:
|
||||||
|
fprintf(stderr, "JDK_AA_ON ");
|
||||||
|
break;
|
||||||
|
case TEXT_AA_OFF:
|
||||||
|
fprintf(stderr, "JDK_AA_OFF ");
|
||||||
|
break;
|
||||||
|
case TEXT_AA_LCD_HRGB:
|
||||||
|
fprintf(stderr, "JDK_AA_LCD_HRGB ");
|
||||||
|
break;
|
||||||
|
case TEXT_AA_LCD_HBGR:
|
||||||
|
fprintf(stderr, "JDK_AA_LCD_HBGR ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "JDK_AA_UNKNOWN ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fcAntialiasSet) fprintf(stderr, "FC_ANTIALIAS(%d) ", fcAntialias);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->aaType == TEXT_AA_ON) { // Greyscale AA
|
||||||
|
context->renderFlags = FT_RENDER_MODE_NORMAL;
|
||||||
|
if (fcHintingSet) {
|
||||||
|
switch (fcHintStyle) {
|
||||||
|
case FC_HINT_NONE:
|
||||||
|
context->loadFlags = FT_LOAD_NO_HINTING;
|
||||||
|
break;
|
||||||
|
case FC_HINT_SLIGHT:
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LIGHT;
|
||||||
|
break;
|
||||||
|
case FC_HINT_MEDIUM:
|
||||||
|
case FC_HINT_FULL:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (context->aaType == TEXT_AA_OFF) { // No AA
|
||||||
|
context->renderFlags = FT_RENDER_MODE_MONO;
|
||||||
|
context->loadFlags = (!fcHintingSet || fcHinting) ? FT_LOAD_TARGET_MONO : FT_LOAD_NO_HINTING;
|
||||||
|
} else {
|
||||||
|
int fcRGBA = FC_RGBA_UNKNOWN;
|
||||||
|
if (fcAntialiasSet && fcAntialias) {
|
||||||
|
if ((*FcPatternGetIntegerPtr)(pattern, FC_RGBA, 0, &fcRGBA) == FcResultMatch) {
|
||||||
|
switch (fcRGBA) {
|
||||||
|
case FC_RGBA_RGB:
|
||||||
|
case FC_RGBA_BGR:
|
||||||
|
if (logFC) fprintf(stderr, fcRGBA == FC_RGBA_RGB ? "FC_RGBA_RGB " : "FC_RGBA_BGR ");
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LCD;
|
||||||
|
context->renderFlags = FT_RENDER_MODE_LCD;
|
||||||
|
break;
|
||||||
|
case FC_RGBA_VRGB:
|
||||||
|
case FC_RGBA_VBGR:
|
||||||
|
if (logFC) fprintf(stderr, fcRGBA == FC_RGBA_VRGB ? "FC_RGBA_VRGB " : "FC_RGBA_VBGR ");
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LCD_V;
|
||||||
|
context->renderFlags = FT_RENDER_MODE_LCD_V;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (logFC) fprintf(stderr, "FC_RGBA_UNKNOWN ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fcRGBA == FC_RGBA_UNKNOWN) {
|
||||||
|
if (context->aaType == TEXT_AA_LCD_HRGB ||
|
||||||
|
context->aaType == TEXT_AA_LCD_HBGR) {
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LCD;
|
||||||
|
context->renderFlags = FT_RENDER_MODE_LCD;
|
||||||
|
} else {
|
||||||
|
context->loadFlags = FT_LOAD_TARGET_LCD_V;
|
||||||
|
context->renderFlags = FT_RENDER_MODE_LCD_V;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool fcAutohint = FcFalse;
|
||||||
|
FcBool fcAutohintSet = (*FcPatternGetBoolPtr)(pattern, FC_AUTOHINT, 0, &fcAutohint) == FcResultMatch;
|
||||||
|
|
||||||
|
if (logFC && fcAutohintSet) fprintf(stderr, "FC_AUTOHINT(%d) ", fcAutohint);
|
||||||
|
|
||||||
|
if (fcAutohintSet && fcAutohint) {
|
||||||
|
context->loadFlags |= FT_LOAD_FORCE_AUTOHINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_LcdFilter fcLCDFilter;
|
||||||
|
FcBool fcLCDFilterSet = (*FcPatternGetIntegerPtr)(pattern, FC_LCD_FILTER, 0, (int*) &fcLCDFilter) == FcResultMatch;
|
||||||
|
context->lcdFilter = FT_LCD_FILTER_DEFAULT;
|
||||||
|
if (fcLCDFilterSet) {
|
||||||
|
switch (fcLCDFilter) {
|
||||||
|
case FC_LCD_NONE:
|
||||||
|
if (logFC) fprintf(stderr, "FC_LCD_NONE");
|
||||||
|
context->lcdFilter = FT_LCD_FILTER_NONE;
|
||||||
|
break;
|
||||||
|
case FC_LCD_LIGHT:
|
||||||
|
if (logFC) fprintf(stderr, "FC_LCD_LIGHT");
|
||||||
|
context->lcdFilter = FT_LCD_FILTER_LIGHT;
|
||||||
|
break;
|
||||||
|
case FC_LCD_LEGACY:
|
||||||
|
if (logFC) fprintf(stderr, "FC_LCD_LEGACY");
|
||||||
|
context->lcdFilter = FT_LCD_FILTER_LEGACY;
|
||||||
|
break;
|
||||||
|
case FC_LCD_DEFAULT:
|
||||||
|
if (logFC) fprintf(stderr, "FC_LCD_DEFAULT");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (logFC) fprintf(stderr, "FC_LCD_UNKNOWN");
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*FcPatternDestroyPtr)(pattern);
|
||||||
|
if (logFC) fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Library_SetLcdFilter(scalerInfo->library, FT_LCD_FILTER_DEFAULT);
|
FT_Library_SetLcdFilter(scalerInfo->library, FT_LCD_FILTER_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errCode;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// using same values as for the transformation matrix
|
// using same values as for the transformation matrix
|
||||||
@@ -615,7 +942,7 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative(
|
|||||||
f0, f0, f0, f0, f0, f0, f0, f0, f0, f0);
|
f0, f0, f0, f0, f0, f0, f0, f0, f0, f0);
|
||||||
}
|
}
|
||||||
|
|
||||||
errCode = setupFTContext(env, font2D, scalerInfo, context);
|
errCode = setupFTContext(env, font2D, scalerInfo, context, FcFalse);
|
||||||
|
|
||||||
if (errCode) {
|
if (errCode) {
|
||||||
metrics = (*env)->NewObject(env,
|
metrics = (*env)->NewObject(env,
|
||||||
@@ -900,6 +1227,7 @@ static jlong
|
|||||||
GlyphInfo *glyphInfo;
|
GlyphInfo *glyphInfo;
|
||||||
int renderFlags = FT_LOAD_DEFAULT, target;
|
int renderFlags = FT_LOAD_DEFAULT, target;
|
||||||
FT_GlyphSlot ftglyph;
|
FT_GlyphSlot ftglyph;
|
||||||
|
FT_LcdFilter lcdFilter = FT_LCD_FILTER_NONE;
|
||||||
|
|
||||||
FTScalerContext* context =
|
FTScalerContext* context =
|
||||||
(FTScalerContext*) jlong_to_ptr(pScalerContext);
|
(FTScalerContext*) jlong_to_ptr(pScalerContext);
|
||||||
@@ -910,7 +1238,7 @@ static jlong
|
|||||||
return ptr_to_jlong(getNullGlyphImage());
|
return ptr_to_jlong(getNullGlyphImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
error = setupFTContext(env, font2D, scalerInfo, context);
|
error = setupFTContext(env, font2D, scalerInfo, context, FcTrue);
|
||||||
if (error) {
|
if (error) {
|
||||||
invalidateJavaScaler(env, scaler, scalerInfo);
|
invalidateJavaScaler(env, scaler, scalerInfo);
|
||||||
return ptr_to_jlong(getNullGlyphImage());
|
return ptr_to_jlong(getNullGlyphImage());
|
||||||
@@ -957,6 +1285,8 @@ static jlong
|
|||||||
}
|
}
|
||||||
|
|
||||||
ftglyph = scalerInfo->face->glyph;
|
ftglyph = scalerInfo->face->glyph;
|
||||||
|
FT_Library library = ftglyph->library;
|
||||||
|
FT_Library_SetLcdFilter (library, context->lcdFilter);
|
||||||
|
|
||||||
/* apply styles */
|
/* apply styles */
|
||||||
if (context->doBold) { /* if bold style */
|
if (context->doBold) { /* if bold style */
|
||||||
@@ -1107,7 +1437,7 @@ Java_sun_font_FreetypeFontScaler_disposeNativeScaler(
|
|||||||
/* Freetype functions *may* cause callback to java
|
/* Freetype functions *may* cause callback to java
|
||||||
that can use cached values. Make sure our cache is up to date.
|
that can use cached values. Make sure our cache is up to date.
|
||||||
NB: scaler context is not important at this point, can use NULL. */
|
NB: scaler context is not important at this point, can use NULL. */
|
||||||
int errCode = setupFTContext(env, font2D, scalerInfo, NULL);
|
int errCode = setupFTContext(env, font2D, scalerInfo, NULL, FcFalse);
|
||||||
if (errCode) {
|
if (errCode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1170,7 +1500,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphCodeNative(
|
|||||||
/* Freetype functions *may* cause callback to java
|
/* Freetype functions *may* cause callback to java
|
||||||
that can use cached values. Make sure our cache is up to date.
|
that can use cached values. Make sure our cache is up to date.
|
||||||
Scaler context is not important here, can use NULL. */
|
Scaler context is not important here, can use NULL. */
|
||||||
errCode = setupFTContext(env, font2D, scalerInfo, NULL);
|
errCode = setupFTContext(env, font2D, scalerInfo, NULL, FcFalse);
|
||||||
if (errCode) {
|
if (errCode) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1193,7 +1523,7 @@ static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = setupFTContext(env, font2D, scalerInfo, context);
|
error = setupFTContext(env, font2D, scalerInfo, context, FcTrue);
|
||||||
if (error) {
|
if (error) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1635,3 +1965,9 @@ Java_sun_font_FreetypeFontScaler_getGlyphPointNative(
|
|||||||
return (*env)->NewObject(env, sunFontIDs.pt2DFloatClass,
|
return (*env)->NewObject(env, sunFontIDs.pt2DFloatClass,
|
||||||
sunFontIDs.pt2DFloatCtr, x, y);
|
sunFontIDs.pt2DFloatCtr, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JNI_OnUnload(JavaVM *vm, void *reserved) {
|
||||||
|
if (libFontConfig != NULL) {
|
||||||
|
dlclose(libFontConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user