Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifdef WIN32
#include
#include
#include
#include
#include
#include
#define BSIZE (max(512, MAX_PATH+1))
JNIEXPORT jbyteArray JNICALL
Java_com_sun_javafx_font_PrismFontFactory_getFontPath(JNIEnv *env, jobject thiz)
{
char windir[BSIZE];
char sysdir[BSIZE];
char fontpath[BSIZE*2];
char *end;
jbyteArray byteArrObj;
int pathLen;
unsigned char *data;
/* Locate fonts directories relative to the Windows System directory.
* If Windows System location is different than the user's window
* directory location, as in a shared Windows installation,
* return both locations as potential font directories
*/
GetSystemDirectory(sysdir, BSIZE);
end = strrchr(sysdir,'\\');
if (end && (stricmp(end,"\\System") || stricmp(end,"\\System32"))) {
*end = 0;
strcat(sysdir, "\\Fonts");
}
GetWindowsDirectory(windir, BSIZE);
if (strlen(windir) > BSIZE-7) {
*windir = 0;
} else {
strcat(windir, "\\Fonts");
}
strcpy(fontpath,sysdir);
if (stricmp(sysdir,windir)) {
strcat(fontpath,";");
strcat(fontpath,windir);
}
pathLen = strlen(fontpath);
byteArrObj = (*env)->NewByteArray(env, pathLen);
if (byteArrObj == NULL) {
return (jbyteArray)NULL;
}
data = (*env)->GetByteArrayElements(env, byteArrObj, NULL);
if (data == NULL) {
return byteArrObj;
}
memcpy(data, fontpath, pathLen);
(*env)->ReleaseByteArrayElements(env, byteArrObj, (jbyte*) data, (jint)0);
return byteArrObj;
}
/* The code below is used to obtain information from the windows font APIS
* and registry on which fonts are available and what font files hold those
* fonts. The results are used to speed font lookup.
*/
typedef struct GdiFontMapInfo {
JNIEnv *env;
jstring family;
jobject fontToFamilyMap;
jobject familyToFontListMap;
jobject list;
jmethodID putMID;
jmethodID containsKeyMID;
jclass arrayListClass;
jmethodID arrayListCtr;
jmethodID addMID;
jmethodID toLowerCaseMID;
jobject locale;
HDC screenDC;
} GdiFontMapInfo;
/* NT is W2K & XP, Vista, Win 7 etc. ie anything later than win9x */
static const char FONTKEY_NT[] =
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
typedef struct CheckFamilyInfo {
wchar_t *family;
wchar_t* fullName;
int isDifferent;
} CheckFamilyInfo;
static int CALLBACK CheckFontFamilyProcW(
ENUMLOGFONTEXW *lpelfe,
NEWTEXTMETRICEX *lpntme,
int FontType,
LPARAM lParam)
{
CheckFamilyInfo *info = (CheckFamilyInfo*)lParam;
info->isDifferent = wcscmp(lpelfe->elfLogFont.lfFaceName, info->family);
/* if (!info->isDifferent) { */
/* wprintf(LFor font %s expected family=%s instead got %s\n", */
/* lpelfe->elfFullName, */
/* info->family, */
/* lpelfe->elfLogFont.lfFaceName); */
/* fflush(stdout); */
/* } */
return 0;
}
static int DifferentFamily(wchar_t *family, wchar_t* fullName,
GdiFontMapInfo *fmi) {
LOGFONTW lfw;
CheckFamilyInfo info;
/* If fullName can't be stored in the struct, assume correct family */
if (wcslen((LPWSTR)fullName) >= LF_FACESIZE) {
return 0;
}
memset(&info, 0, sizeof(CheckFamilyInfo));
info.family = family;
info.fullName = fullName;
info.isDifferent = 0;
memset(&lfw, 0, sizeof(lfw));
wcscpy(lfw.lfFaceName, fullName);
lfw.lfCharSet = DEFAULT_CHARSET;
EnumFontFamiliesExW(fmi->screenDC, &lfw,
(FONTENUMPROCW)CheckFontFamilyProcW,
(LPARAM)(&info), 0L);
return info.isDifferent;
}
/* Callback for call to EnumFontFamiliesEx in the EnumFamilyNames function.
* Expects to be called once for each face name in the family specified
* in the call. We extract the full name for the font which is expected
* to be in the "system encoding" and create canonical and lower case
* Java strings for the name which are added to the maps. The lower case
* name is used as key to the family name value in the font to family map,
* the canonical name is one of the"list" of members of the family.
*/
static int CALLBACK EnumFontFacesInFamilyProcW(
ENUMLOGFONTEXW *lpelfe,
NEWTEXTMETRICEX *lpntme,
int FontType,
LPARAM lParam)
{
GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
JNIEnv *env = fmi->env;
jstring fullname, fullnameLC;
/* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
return 1;
}
/* Windows has font aliases and so may enumerate fonts from
* the aliased family if any actual font of that family is installed.
* To protect against it ignore fonts which aren't enumerated under
* their true family.
*/
if (DifferentFamily(lpelfe->elfLogFont.lfFaceName,
lpelfe->elfFullName, fmi)) {
return 1;
}
fullname = (*env)->NewString(env, lpelfe->elfFullName,
wcslen((LPWSTR)lpelfe->elfFullName));
fullnameLC = (*env)->CallObjectMethod(env, fullname,
fmi->toLowerCaseMID, fmi->locale);
(*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname);
(*env)->CallObjectMethod(env, fmi->fontToFamilyMap,
fmi->putMID, fullnameLC, fmi->family);
return 1;
}
/* Callback for EnumFontFamiliesEx in populateFontFileNameMap.
* Expects to be called for every charset of every font family.
* If this is the first time we have been called for this family,
* add a new mapping to the familyToFontListMap from this family to a
* list of its members. To populate that list, further enumerate all faces
* in this family for the matched charset. This assumes that all fonts
* in a family support the same charset, which is a fairly safe assumption
* and saves time as the call we make here to EnumFontFamiliesEx will
* enumerate the members of this family just once each.
* Because we set fmi->list to be the newly created list the call back
* can safely add to that list without a search.
*/
static int CALLBACK EnumFamilyNamesW(
ENUMLOGFONTEXW *lpelfe, /* pointer to logical-font data */
NEWTEXTMETRICEX *lpntme, /* pointer to physical-font data */
int FontType, /* type of font */
LPARAM lParam ) /* application-defined data */
{
GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
JNIEnv *env = fmi->env;
jstring familyLC;
int slen;
LOGFONTW lfw;
/* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
return 1;
}
/* wprintf(L"FAMILY=%s charset=%d FULL=%s\n", */
/* lpelfe->elfLogFont.lfFaceName, */
/* lpelfe->elfLogFont.lfCharSet, */
/* lpelfe->elfFullName); */
/* fflush(stdout); */
/* Windows lists fonts which have a vmtx (vertical metrics) table twice.
* Once using their normal name, and again preceded by '@'. These appear
* in font lists in some windows apps, such as wordpad. We don't want
* these so we skip any font where the first character is '@'
*/
if (lpelfe->elfLogFont.lfFaceName[0] == L'@') {
return 1;
}
slen = wcslen(lpelfe->elfLogFont.lfFaceName);
fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, slen);
familyLC = (*env)->CallObjectMethod(env, fmi->family,
fmi->toLowerCaseMID, fmi->locale);
/* check if already seen this family with a different charset */
if ((*env)->CallBooleanMethod(env,fmi->familyToFontListMap,
fmi->containsKeyMID, familyLC)) {
return 1;
}
fmi->list = (*env)->NewObject(env,
fmi->arrayListClass, fmi->arrayListCtr, 4);
(*env)->CallObjectMethod(env, fmi->familyToFontListMap,
fmi->putMID, familyLC, fmi->list);
memset(&lfw, 0, sizeof(lfw));
wcscpy(lfw.lfFaceName, lpelfe->elfLogFont.lfFaceName);
lfw.lfCharSet = lpelfe->elfLogFont.lfCharSet;
EnumFontFamiliesExW(fmi->screenDC, &lfw,
(FONTENUMPROCW)EnumFontFacesInFamilyProcW,
lParam, 0L);
return 1;
}
/* It looks like TrueType fonts have " (TrueType)" tacked on the end of their
* name, so we can try to use that to distinguish TT from other fonts.
* However if a program "installed" a font in the registry the key may
* not include that. We could also try to "pass" fonts which have no "(..)"
* at the end. But that turns out to pass a few .FON files that MS supply.
* If there's no parenthesised type string, we could next try to infer
* the file type from the file name extension. Since the MS entries that
* have no type string are very few, and have odd names like "MS-DOS CP 437"
* and would never return a Java Font anyway its currently OK to put these
* in the font map, although clearly the returned names must never percolate
* up into a list of available fonts returned to the application.
* Additionally for TTC font files the key looks like
* Font 1 & Font 2 (TrueType)
* or sometimes even :
* Font 1 & Font 2 & Font 3 (TrueType)
* Also if a Font has a name for this locale that name also
* exists in the registry using the appropriate platform encoding.
* What do we do then?
*
* Note: OpenType fonts seems to have " (TrueType)" suffix on Vista
* but " (OpenType)" on XP.
*/
static BOOL RegistryToBaseTTNameW(LPWSTR name) {
static const wchar_t TTSUFFIX[] = L" (TrueType)";
static const wchar_t OTSUFFIX[] = L" (OpenType)";
int TTSLEN = wcslen(TTSUFFIX);
wchar_t *suffix;
int len = wcslen(name);
if (len == 0) {
return FALSE;
}
if (name[len-1] != L')') {
return FALSE;
}
if (len <= TTSLEN) {
return FALSE;
}
/* suffix length is the same for truetype and opentype fonts */
suffix = name + (len - TTSLEN);
// REMIND : renable OpenType (.otf) some day.
if (wcscmp(suffix, TTSUFFIX) == 0 /*|| wcscmp(suffix, OTSUFFIX) == 0*/) {
suffix[0] = L'\0'; /* truncate name */
return TRUE;
}
return FALSE;
}
static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap,
LPWSTR name, LPWSTR data) {
wchar_t *ptr1, *ptr2;
jstring fontStr;
JNIEnv *env = fmi->env;
int dslen = wcslen(data);
jstring fileStr = (*env)->NewString(env, data, dslen);
/* TTC or ttc means it may be a collection. Need to parse out
* multiple font face names separated by " & "
* By only doing this for fonts which look like collections based on
* file name we are adhering to MS recommendations for font file names
* so it seems that we can be sure that this identifies precisely
* the MS-supplied truetype collections.
* This avoids any potential issues if a TTF file happens to have
* a & in the font name (I can't find anything which prohibits this)
* and also means we only parse the key in cases we know to be
* worthwhile.
*/
if ((data[dslen-1] == L'C' || data[dslen-1] == L'c') &&
(ptr1 = wcsstr(name, L" & ")) != NULL) {
ptr1+=3;
while (ptr1 >= name) { /* marginally safer than while (true) */
while ((ptr2 = wcsstr(ptr1, L" & ")) != NULL) {
ptr1 = ptr2+3;
}
fontStr = (*env)->NewString(env, ptr1, wcslen(ptr1));
fontStr = (*env)->CallObjectMethod(env, fontStr,
fmi->toLowerCaseMID,
fmi->locale);
(*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
fontStr, fileStr);
if (ptr1 == name) {
break;
} else {
*(ptr1-3) = L'\0';
ptr1 = name;
}
}
} else {
fontStr = (*env)->NewString(env, name, wcslen(name));
fontStr = (*env)->CallObjectMethod(env, fontStr,
fmi->toLowerCaseMID, fmi->locale);
(*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
fontStr, fileStr);
}
}
/* Obtain all the fontname -> filename mappings.
* This is called once and the results returned to Java code which can
* use it for lookups to reduce or avoid the need to search font files.
*/
JNIEXPORT void JNICALL
Java_com_sun_javafx_font_PrismFontFactory_populateFontFileNameMap
(JNIEnv *env, jclass obj, jobject fontToFileMap,
jobject fontToFamilyMap, jobject familyToFontListMap, jobject locale)
{
#define MAX_BUFFER (FILENAME_MAX+1)
const wchar_t wname[MAX_BUFFER];
const char data[MAX_BUFFER];
DWORD type;
LONG ret;
HKEY hkeyFonts;
DWORD dwNameSize;
DWORD dwDataValueSize;
DWORD nval;
LPCSTR fontKeyName;
DWORD dwNumValues, dwMaxValueNameLen, dwMaxValueDataLen;
DWORD numValues = 0;
jclass classID;
jmethodID putMID;
GdiFontMapInfo fmi;
LOGFONTW lfw;
/* Check we were passed all the maps we need, and do lookup of
* methods for JNI up-calls
*/
if (fontToFileMap == NULL ||
fontToFamilyMap == NULL ||
familyToFontListMap == NULL) {
return;
}
classID = (*env)->FindClass(env, "java/util/HashMap");
if (classID == NULL) {
return;
}
putMID = (*env)->GetMethodID(env, classID, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
if (putMID == NULL) {
return;
}
fmi.env = env;
fmi.fontToFamilyMap = fontToFamilyMap;
fmi.familyToFontListMap = familyToFontListMap;
fmi.putMID = putMID;
fmi.locale = locale;
fmi.containsKeyMID = (*env)->GetMethodID(env, classID, "containsKey",
"(Ljava/lang/Object;)Z");
if (fmi.containsKeyMID == NULL) {
return;
}
fmi.arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
if (fmi.arrayListClass == NULL) {
return;
}
fmi.arrayListCtr = (*env)->GetMethodID(env, fmi.arrayListClass,
"", "(I)V");
if (fmi.arrayListCtr == NULL) {
return;
}
fmi.addMID = (*env)->GetMethodID(env, fmi.arrayListClass,
"add", "(Ljava/lang/Object;)Z");
if (fmi.addMID == NULL) {
return;
}
classID = (*env)->FindClass(env, "java/lang/String");
if (classID == NULL) {
return;
}
fmi.toLowerCaseMID =
(*env)->GetMethodID(env, classID, "toLowerCase",
"(Ljava/util/Locale;)Ljava/lang/String;");
if (fmi.toLowerCaseMID == NULL) {
return;
}
/* This HDC is initialised and released in this populate family map
* JNI entry point, and used within the call which would otherwise
* create many DCs.
*/
fmi.screenDC = GetDC(NULL);
if (fmi.screenDC == NULL) {
return;
}
/* Enumerate fonts via GDI to build maps of fonts and families */
memset(&lfw, 0, sizeof(lfw));
lfw.lfCharSet = DEFAULT_CHARSET; /* all charsets */
wcscpy(lfw.lfFaceName, L""); /* one face per family (CHECK) */
EnumFontFamiliesExW(fmi.screenDC, &lfw,
(FONTENUMPROCW)EnumFamilyNamesW,
(LPARAM)(&fmi), 0L);
/* Use the windows registry to map font names to files */
fontKeyName = FONTKEY_NT;
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
fontKeyName, 0L, KEY_READ, &hkeyFonts);
if (ret != ERROR_SUCCESS) {
ReleaseDC(NULL, fmi.screenDC);
fmi.screenDC = NULL;
return;
}
ret = RegQueryInfoKeyW(hkeyFonts, NULL, NULL, NULL, NULL, NULL, NULL,
&dwNumValues, &dwMaxValueNameLen,
&dwMaxValueDataLen, NULL, NULL);
if (ret != ERROR_SUCCESS ||
dwMaxValueNameLen >= MAX_BUFFER ||
dwMaxValueDataLen >= MAX_BUFFER) {
RegCloseKey(hkeyFonts);
ReleaseDC(NULL, fmi.screenDC);
fmi.screenDC = NULL;
return;
}
for (nval = 0; nval < dwNumValues; nval++ ) {
dwNameSize = MAX_BUFFER;
dwDataValueSize = MAX_BUFFER;
ret = RegEnumValueW(hkeyFonts, nval, (LPWSTR)wname, &dwNameSize,
NULL, &type, (LPBYTE)data, &dwDataValueSize);
if (ret != ERROR_SUCCESS) {
break;
}
if (type != REG_SZ) { /* REG_SZ means a null-terminated string */
continue;
}
if (!RegistryToBaseTTNameW((LPWSTR)wname) ) {
/* If the filename ends with ".ttf" or ".otf" also accept it.
* REMIND : in fact not accepting .otf's for now as the
* upstream code isn't expecting them.
* Not expecting to need to do this for .ttc files.
* Also note this code is not mirrored in the "A" (win9x) path.
*/
LPWSTR dot = wcsrchr((LPWSTR)data, L'.');
if (dot == NULL || ((wcsicmp(dot, L".ttf") != 0)
/* && (wcsicmp(dot, L".otf") != 0) */)) {
continue; /* not a TT font... */
}
}
registerFontW(&fmi, fontToFileMap, (LPWSTR)wname, (LPWSTR)data);
}
RegCloseKey(hkeyFonts);
ReleaseDC(NULL, fmi.screenDC);
fmi.screenDC = NULL;
}
JNIEXPORT jstring JNICALL
Java_com_sun_javafx_font_PrismFontFactory_regReadFontLink(JNIEnv *env, jclass obj, jstring lpFontName)
{
LONG lResult;
BYTE* buf;
DWORD dwBufSize = sizeof(buf);
DWORD dwType = REG_MULTI_SZ;
HKEY hKey;
LPCWSTR fontpath = NULL;
jstring linkStr;
LPWSTR lpSubKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink";
lResult = RegOpenKeyExW (HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS)
{
return (jstring)NULL;
}
fontpath = (*env)->GetStringChars(env, lpFontName, (jboolean*) NULL);
//get the buffer size
lResult = RegQueryValueExW(hKey, fontpath, 0, &dwType, NULL, &dwBufSize);
if ((lResult == ERROR_SUCCESS) && (dwBufSize > 0)) {
buf = malloc( dwBufSize );
if (buf == NULL) {
(*env)->ReleaseStringChars(env, lpFontName, fontpath);
RegCloseKey (hKey);
return (jstring)NULL;
}
lResult = RegQueryValueExW(hKey, fontpath, 0, &dwType, (BYTE*)buf,
&dwBufSize);
(*env)->ReleaseStringChars(env, lpFontName, fontpath);
RegCloseKey (hKey);
if (lResult != ERROR_SUCCESS) {
free(buf);
return (jstring)NULL;
}
} else {
return (jstring)NULL;
}
linkStr = (*env)->NewString(env, (LPWSTR)buf, dwBufSize/sizeof(WCHAR));
free(buf);
return linkStr;
}
typedef unsigned short LANGID;
#define LANGID_JA_JP 0x411
#define LANGID_ZH_CN 0x0804
#define LANGID_ZH_SG 0x1004
#define LANGID_ZH_TW 0x0404
#define LANGID_ZH_HK 0x0c04
#define LANGID_ZH_MO 0x1404
#define LANGID_KO_KR 0x0412
#define LANGID_US 0x409
static const wchar_t EUDCKEY_JA_JP[] = L"EUDC\\932";
static const wchar_t EUDCKEY_ZH_CN[] = L"EUDC\\936";
static const wchar_t EUDCKEY_ZH_TW[] = L"EUDC\\950";
static const wchar_t EUDCKEY_KO_KR[] = L"EUDC\\949";
static const wchar_t EUDCKEY_DEFAULT[] = L"EUDC\\1252";
JNIEXPORT jstring JNICALL
Java_com_sun_javafx_font_PrismFontFactory_getEUDCFontFile(JNIEnv *env, jclass cl) {
int rc;
HKEY key;
DWORD type;
WCHAR fontPathBuf[MAX_PATH + 1];
DWORD fontPathLen = MAX_PATH + 1;
WCHAR tmpPath[MAX_PATH + 1];
LPWSTR fontPath = fontPathBuf;
LPWSTR eudcKey = NULL;
LANGID langID = GetSystemDefaultLangID();
//lookup for encoding ID, EUDC only supported in
//codepage 932, 936, 949, 950 (and unicode)
if (langID == LANGID_JA_JP) {
eudcKey = EUDCKEY_JA_JP;
} else if (langID == LANGID_ZH_CN || langID == LANGID_ZH_SG) {
eudcKey = EUDCKEY_ZH_CN;
} else if (langID == LANGID_ZH_HK || langID == LANGID_ZH_TW ||
langID == LANGID_ZH_MO) {
eudcKey = EUDCKEY_ZH_TW;
} else if (langID == LANGID_KO_KR) {
eudcKey = EUDCKEY_KO_KR;
} else if (langID == LANGID_US) {
eudcKey = EUDCKEY_DEFAULT;
} else {
return NULL;
}
rc = RegOpenKeyExW(HKEY_CURRENT_USER, eudcKey, 0, KEY_READ, &key);
if (rc != ERROR_SUCCESS) {
return NULL;
}
rc = RegQueryValueExW(key,
L"SystemDefaultEUDCFont",
0,
&type,
(LPBYTE)fontPath,
&fontPathLen);
RegCloseKey(key);
fontPathLen /= sizeof(WCHAR);
if (rc != ERROR_SUCCESS || type != REG_SZ ||
(fontPathLen > MAX_PATH)) {
return NULL;
}
fontPath[fontPathLen] = L'\0';
if (wcsstr(fontPath, L"%SystemRoot%") == fontPath) {
//if the fontPath includes %SystemRoot%
LPWSTR systemRoot = _wgetenv(L"SystemRoot");
// Subtract 12, being the length of "SystemRoot".
if ((systemRoot == NULL) ||
(fontPathLen-12 +wcslen(systemRoot) > MAX_PATH)) {
return NULL;
}
wcscpy(tmpPath, systemRoot);
wcscat(tmpPath, (wchar_t *)(fontPath+12));
fontPath = tmpPath;
fontPathLen = wcslen(tmpPath);
} else if (wcscmp(fontPath, L"EUDC.TTE") == 0) {
//else to see if it only inludes "EUDC.TTE"
WCHAR systemRoot[MAX_PATH];
UINT ret = GetWindowsDirectoryW(systemRoot, MAX_PATH);
if ( ret != 0) {
if (ret + 16 > MAX_PATH) {
return NULL;
}
wcscpy(fontPath, systemRoot);
wcscat(fontPath, L"\\FONTS\\EUDC.TTE");
fontPathLen = wcslen(fontPath);
}
else {
return NULL;
}
}
return (*env)->NewString(env, (LPWSTR)fontPath, fontPathLen);
}
static BOOL getSysParams(NONCLIENTMETRICSW* ncmetrics) {
OSVERSIONINFOEX osvi;
int cbsize;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (!(GetVersionEx((OSVERSIONINFO *)&osvi))) {
return FALSE;
}
// See JDK bug 6944516: specify correct size for ncmetrics on Windows XP
// Microsoft recommend to subtract the size of the 'iPaddedBorderWidth'
// field when running on XP. Yuck.
if (osvi.dwMajorVersion < 6) { // 5 is XP, 6 is Vista.
cbsize = offsetof(NONCLIENTMETRICSW, iPaddedBorderWidth);
} else {
cbsize = sizeof(*ncmetrics);
}
ZeroMemory(ncmetrics, cbsize);
ncmetrics->cbSize = cbsize;
return SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
ncmetrics->cbSize, ncmetrics, FALSE);
}
/*
* Class: Java_com_sun_javafx_font_PrismFontFactory
* Method: getLCDContrast
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_sun_javafx_font_PrismFontFactory_getLCDContrast
(JNIEnv *env, jobject klass) {
unsigned int fontSmoothingContrast;
static const int fontSmoothingContrastDefault = 1300;
return SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0,
&fontSmoothingContrast, 0) ? fontSmoothingContrast : fontSmoothingContrastDefault;
}
JNIEXPORT jint JNICALL
Java_com_sun_javafx_font_PrismFontFactory_getSystemFontSizeNative(JNIEnv *env, jclass cl)
{
NONCLIENTMETRICSW ncmetrics;
if (getSysParams(&ncmetrics)) {
return -ncmetrics.lfMessageFont.lfHeight;
} else {
return 12;
}
}
JNIEXPORT jstring JNICALL
Java_com_sun_javafx_font_PrismFontFactory_getSystemFontNative(JNIEnv *env, jclass cl) {
NONCLIENTMETRICSW ncmetrics;
if (getSysParams(&ncmetrics)) {
int len = wcslen(ncmetrics.lfMessageFont.lfFaceName);
return (*env)->NewString(env, ncmetrics.lfMessageFont.lfFaceName, len);
} else {
return NULL;
}
}
JNIEXPORT jshort JNICALL
Java_com_sun_javafx_font_PrismFontFactory_getSystemLCID(JNIEnv *env, jclass cl)
{
LCID lcid = GetSystemDefaultLCID();
DWORD value;
int ret = GetLocaleInfoW(lcid,
LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER,
(LPTSTR)&value,
sizeof(value) / sizeof(TCHAR));
return (jshort)value;
}
#endif /* WIN32 */