mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
IDEA-57233, IDEA-152816, IDEA-152454 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 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 partially rollback JBR-363 fix, to apply corresponding change from OpenJDK 12 (cherry picked from commit5d704a963b) (cherry picked from commit3d7ac30072) (cherry picked from commit0456745afb) (cherry picked from commit3d7ac30072) (cherry picked from commit4c8351fecf) (cherry picked from commit5faebc73d5) (cherry picked from commitd1ed8ab118) (cherry picked from commit20487c7515)
This commit is contained in:
@@ -348,6 +348,7 @@ else
|
||||
endif
|
||||
|
||||
LIBFONTMANAGER_EXTRA_HEADER_DIRS := \
|
||||
java.base:libjvm \
|
||||
common/awt \
|
||||
common/awt/utility \
|
||||
common/font \
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package sun.font;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
@@ -47,10 +48,10 @@ class FreetypeFontScaler extends FontScaler {
|
||||
/* At the moment fontmanager library depends on freetype library
|
||||
and therefore no need to load it explicitly here */
|
||||
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 {
|
||||
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_util.h"
|
||||
#include "jlong.h"
|
||||
#include "jvm_md.h"
|
||||
#include "sunfontids.h"
|
||||
#include "sun_font_FreetypeFontScaler.h"
|
||||
|
||||
@@ -34,8 +34,10 @@
|
||||
#include <dlfcn.h>
|
||||
#include "jvm.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "ft2build.h"
|
||||
#include FT_LCD_FILTER_H
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include FT_BBOX_H
|
||||
@@ -44,6 +46,12 @@
|
||||
#include FT_SYNTHESIS_H
|
||||
#include FT_LCD_FILTER_H
|
||||
#include FT_MODULE_H
|
||||
#include FT_LCD_FILTER_H
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Use bundled fontconfig.h for now */
|
||||
#include "fontconfig.h"
|
||||
#endif
|
||||
|
||||
#include "fontscaler.h"
|
||||
|
||||
@@ -57,6 +65,23 @@
|
||||
#define FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
|
||||
#define FTFixedToFloat(x) ((x) / (float)(ftFixed1))
|
||||
#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 FT26Dot6ToInt(x) (((int)(x)) >> 6)
|
||||
#define DEFAULT_DPI 72
|
||||
#define ADJUST_FONT_SIZE(X, DPI) (((X)*DEFAULT_DPI + ((DPI)>>1))/(DPI))
|
||||
|
||||
#ifndef _WIN32
|
||||
#define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
|
||||
#define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
/* Important note:
|
||||
@@ -88,7 +113,12 @@ typedef struct FTScalerContext {
|
||||
jint fmType; /* fractional metrics - on/off */
|
||||
jboolean doBold; /* perform algorithmic bolding? */
|
||||
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 ptsz; /* size in points */
|
||||
} FTScalerContext;
|
||||
@@ -105,10 +135,70 @@ void z_error(char *s) {}
|
||||
|
||||
static jmethodID invalidateScalerMID;
|
||||
static jboolean debugFonts; // Stores the value of FontUtilities.debugFonts()
|
||||
static jmethodID getDefaultToolkitMID;
|
||||
static jclass tkClass;
|
||||
static jmethodID getScreenResolutionMID;
|
||||
static jfieldID platNameFID;
|
||||
|
||||
#ifndef _WIN32
|
||||
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);
|
||||
#endif
|
||||
|
||||
static void *libFontConfig = NULL;
|
||||
static jboolean logFC = JNI_FALSE;
|
||||
|
||||
#ifndef _WIN32
|
||||
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;
|
||||
#endif
|
||||
|
||||
static void* openFontConfig() {
|
||||
void* libfontconfig = NULL;
|
||||
#ifndef _WIN32
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return libfontconfig;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_font_FreetypeFontScaler_initIDs(
|
||||
JNIEnv *env, jobject scaler, jclass FFSClass) {
|
||||
JNIEnv *env, jobject scaler, jclass FFSClass, jclass TKClass, jclass PFClass) {
|
||||
invalidateScalerMID =
|
||||
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");
|
||||
|
||||
@@ -116,6 +206,51 @@ Java_sun_font_FreetypeFontScaler_initIDs(
|
||||
debugFonts = JNU_CallStaticMethodByName(env, &ignoreException,
|
||||
"sun/font/FontUtilities",
|
||||
"debugFonts", "()Z").z;
|
||||
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();
|
||||
#ifndef _WIN32
|
||||
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");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static char* getPhysFontName(JNIEnv *env, jobject font2d) {
|
||||
jstring jstr;
|
||||
jstr = (*env)->GetObjectField(env, font2d, platNameFID);
|
||||
return (char*)(*env)->GetStringUTFChars(env, jstr, NULL);
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -609,27 +744,236 @@ static void setupTransform(FT_Matrix* target, FTScalerContext *context) {
|
||||
static int setupFTContext(JNIEnv *env,
|
||||
jobject font2D,
|
||||
FTScalerInfo *scalerInfo,
|
||||
FTScalerContext *context) {
|
||||
FTScalerContext *context,
|
||||
FT_Bool configureFont) {
|
||||
FT_Matrix matrix;
|
||||
int errCode = 0;
|
||||
|
||||
scalerInfo->env = env;
|
||||
scalerInfo->font2D = font2D;
|
||||
|
||||
if (context != NULL) {
|
||||
setupTransform(&matrix, context);
|
||||
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;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
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");
|
||||
#endif
|
||||
}
|
||||
|
||||
FT_Library_SetLcdFilter(scalerInfo->library, FT_LCD_FILTER_DEFAULT);
|
||||
}
|
||||
|
||||
return errCode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// using same values as for the transformation matrix
|
||||
@@ -662,7 +1006,7 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative(
|
||||
f0, f0, f0, f0, f0, f0, f0, f0, f0, f0);
|
||||
}
|
||||
|
||||
errCode = setupFTContext(env, font2D, scalerInfo, context);
|
||||
errCode = setupFTContext(env, font2D, scalerInfo, context, FALSE);
|
||||
|
||||
if (errCode) {
|
||||
metrics = (*env)->NewObject(env,
|
||||
@@ -945,8 +1289,10 @@ static jlong
|
||||
int error, imageSize;
|
||||
UInt16 width, height, rowBytes;
|
||||
GlyphInfo *glyphInfo;
|
||||
int renderFlags = FT_LOAD_DEFAULT, target;
|
||||
int target;
|
||||
FT_GlyphSlot ftglyph;
|
||||
FT_LcdFilter lcdFilter = FT_LCD_FILTER_NONE;
|
||||
FT_Library library;
|
||||
|
||||
FTScalerContext* context =
|
||||
(FTScalerContext*) jlong_to_ptr(pScalerContext);
|
||||
@@ -957,7 +1303,7 @@ static jlong
|
||||
return ptr_to_jlong(getNullGlyphImage());
|
||||
}
|
||||
|
||||
error = setupFTContext(env, font2D, scalerInfo, context);
|
||||
error = setupFTContext(env, font2D, scalerInfo, context, TRUE);
|
||||
if (error) {
|
||||
invalidateJavaScaler(env, scaler, scalerInfo);
|
||||
return ptr_to_jlong(getNullGlyphImage());
|
||||
@@ -971,11 +1317,11 @@ static jlong
|
||||
* which did not use freetype.
|
||||
*/
|
||||
if (context->aaType == TEXT_AA_ON && context->fmType == TEXT_FM_ON) {
|
||||
renderFlags |= FT_LOAD_NO_HINTING;
|
||||
}
|
||||
context->loadFlags |= FT_LOAD_NO_HINTING;
|
||||
}
|
||||
|
||||
if (!context->useSbits) {
|
||||
renderFlags |= FT_LOAD_NO_BITMAP;
|
||||
context->loadFlags |= FT_LOAD_NO_BITMAP;
|
||||
}
|
||||
|
||||
/* NB: in case of non identity transform
|
||||
@@ -994,9 +1340,9 @@ static jlong
|
||||
} else {
|
||||
target = FT_LOAD_TARGET_LCD_V;
|
||||
}
|
||||
renderFlags |= target;
|
||||
context->loadFlags |= target;
|
||||
|
||||
error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags);
|
||||
error = FT_Load_Glyph(scalerInfo->face, glyphCode, context->loadFlags);
|
||||
if (error) {
|
||||
//do not destroy scaler yet.
|
||||
//this can be problem of particular context (e.g. with bad transform)
|
||||
@@ -1004,6 +1350,8 @@ static jlong
|
||||
}
|
||||
|
||||
ftglyph = scalerInfo->face->glyph;
|
||||
library = ftglyph->library;
|
||||
FT_Library_SetLcdFilter (library, context->lcdFilter);
|
||||
|
||||
/* apply styles */
|
||||
if (context->doBold) { /* if bold style */
|
||||
@@ -1021,7 +1369,7 @@ static jlong
|
||||
glyphInfo = getNullGlyphImage();
|
||||
return ptr_to_jlong(glyphInfo);
|
||||
}
|
||||
error = FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target));
|
||||
error = FT_Render_Glyph(ftglyph, context->renderFlags);
|
||||
if (error != 0) {
|
||||
return ptr_to_jlong(getNullGlyphImage());
|
||||
}
|
||||
@@ -1154,7 +1502,7 @@ Java_sun_font_FreetypeFontScaler_disposeNativeScaler(
|
||||
/* Freetype functions *may* cause callback to java
|
||||
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. */
|
||||
int errCode = setupFTContext(env, font2D, scalerInfo, NULL);
|
||||
int errCode = setupFTContext(env, font2D, scalerInfo, NULL, FALSE);
|
||||
if (errCode) {
|
||||
return;
|
||||
}
|
||||
@@ -1217,7 +1565,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphCodeNative(
|
||||
/* Freetype functions *may* cause callback to java
|
||||
that can use cached values. Make sure our cache is up to date.
|
||||
Scaler context is not important here, can use NULL. */
|
||||
errCode = setupFTContext(env, font2D, scalerInfo, NULL);
|
||||
errCode = setupFTContext(env, font2D, scalerInfo, NULL, FALSE);
|
||||
if (errCode) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1240,7 +1588,7 @@ static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = setupFTContext(env, font2D, scalerInfo, context);
|
||||
error = setupFTContext(env, font2D, scalerInfo, context, TRUE);
|
||||
if (error) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1681,3 +2029,11 @@ Java_sun_font_FreetypeFontScaler_getGlyphPointNative(
|
||||
return (*env)->NewObject(env, sunFontIDs.pt2DFloatClass,
|
||||
sunFontIDs.pt2DFloatCtr, x, y);
|
||||
}
|
||||
|
||||
void JNI_OnUnload(JavaVM *vm, void *reserved) {
|
||||
if (libFontConfig != NULL) {
|
||||
#ifndef _WIN32
|
||||
dlclose(libFontConfig);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user