gecko-dev/lib/libi18n/unicode/unifont.c

352 строки
9.3 KiB
C
Executable File

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "xp.h"
#include "prtypes.h"
#include "prlog.h"
#include "csid.h"
/* define CHARSET For Win16 */
#ifndef _WIN32
#ifndef GB2312_CHARSET
#define GB2312_CHARSET 134
#endif
#ifndef RUSSIAN_CHARSET
#define RUSSIAN_CHARSET 204
#endif
#ifndef EASTEUROPE_CHARSET
#define EASTEUROPE_CHARSET 238
#endif
#ifndef GREEK_CHARSET
#define GREEK_CHARSET 161
#endif
#ifndef TURKISH_CHARSET
#define TURKISH_CHARSET 162
#endif
#endif /* !_WIN32 */
#if defined(XP_OS2)
#ifndef CALLBACK
#defined CALLBACK
#endif
#endif
PR_PUBLIC_API(int) UNICODE_VERIFYCSIDLIST(int inNumOfItem, int16 *csidlist);
PR_PUBLIC_API(int) UNICODE_MENUFONTID();
PR_PUBLIC_API(int16) UNICODE_MENUFONTCSID();
/* Private */
static BOOL iswin95();
static UINT unicode_CsidToCodePage(int16 csid);
static BYTE unicode_CsidToCharset(int16 csid);
static int16 unicode_CharsetToCsid(BYTE charset);
static int CALLBACK DetectCharset(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param);
static BOOL unicode_CheckFontOfCsid(HDC hdc, int16 csid);
static BOOL unicode_CheckNJWINForCsid(HDC hdc, int16 csid);
static BOOL unicode_CheckNJWINForCsid(HDC hdc, int16 csid);
static int CALLBACK DetectTwinBridge(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param);
static int CALLBACK DetectUnionway(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param);
static BOOL unicode_CheckUnionwayForCsid(HDC hdc,int16 csid);
static BOOL unicode_IsCsidAvailable(HDC hdc, int16 csid);
#ifdef _WIN32
BOOL unicode_UnicodeFontOfCodePage(HDC hdc, UINT cp);
#endif
typedef struct
{
int16 csid;
UINT cp;
BYTE charset;
} csidcpmap;
static csidcpmap csidcpmaptbl[] = {
{CS_LATIN1, 1252, ANSI_CHARSET},
{CS_SJIS, 932, SHIFTJIS_CHARSET},
{CS_GB_8BIT, 936, GB2312_CHARSET},
{CS_BIG5, 950, CHINESEBIG5_CHARSET},
{CS_KSC_8BIT, 949, HANGEUL_CHARSET},
{CS_CP_1251, 1251, RUSSIAN_CHARSET},
{CS_CP_1250, 1250, EASTEUROPE_CHARSET},
{CS_CP_1253, 1253, GREEK_CHARSET},
{CS_8859_9, 1254, TURKISH_CHARSET},
{0, 0, 0}
};
/* This function do a csid to codepage conversion */
static UINT unicode_CsidToCodePage(int16 csid)
{
csidcpmap *p;
for(p = csidcpmaptbl; p->csid != 0 ; p++)
if(csid == p->csid)
return p->cp;
return 0;
}
/* This function do a csid to codepage conversion */
static BYTE unicode_CsidToCharset(int16 csid)
{
csidcpmap *p;
for(p = csidcpmaptbl; p->csid != 0 ; p++)
if(csid == p->csid)
return p->charset;
return 0;
}
/* This function do a csid to codepage conversion */
static int16 unicode_CharsetToCsid(BYTE charset)
{
csidcpmap *p;
for(p = csidcpmaptbl; p->csid != 0 ; p++)
if(charset == p->charset)
return p->csid;
return CS_DEFAULT;
}
/*========================================================================================
// For Standard Localized Windows
//========================================================================================
*/
typedef struct {
BOOL found;
int16 testparam;
} EnumFontTest;
static int CALLBACK DetectCharset(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param)
{
EnumFontTest *pTest = (EnumFontTest *)param;
if((pTest->testparam & 0x00FF) == lpelf->lfCharSet)
{
pTest->found = TRUE;
return 0; /* Done */
}
else
return 1; /* Continue */
}
static BOOL unicode_CheckFontOfCsid(HDC hdc, int16 csid)
{
EnumFontTest test;
test.found = FALSE;
test.testparam = unicode_CsidToCharset(csid);
EnumFontFamilies(hdc, NULL,(FONTENUMPROC)DetectCharset, (LPARAM)&test);
return test.found;
}
#ifdef _WIN32
/*========================================================================================
// For UnicodeFont
//========================================================================================
*/
static BOOL unicode_UnicodeFontOfCodePage(HDC hdc, UINT cp)
{
/* How can we detect Unicode font that only use those API support in
// Both Win95 and WinNT ?
*/
return FALSE;
}
#endif
/*========================================================================================
// For NJWIN
//========================================================================================
*/
static BOOL unicode_CheckNJWINForCsid(HDC hdc, int16 csid)
{
/* For NJWIN
// We should first check wheather njwin.ini is in the system directory
// It only support System Font
*/
return FALSE;
}
/*========================================================================================
// For TwinBridge
//========================================================================================
*/
static int CALLBACK DetectTwinBridge(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param)
{
EnumFontTest *pTest = (EnumFontTest *)param;
pTest->found = TRUE;
return 0; /* Done */
}
static BOOL unicode_CheckTwinBridgeForCsid(HDC hdc, int16 csid)
{
/* For 4.0
// Chinese:
// Check for twin40.ini
// Check for Font "Chn System"
// Japanese:
// Check for twinj40.ini
// Check for Font "Jpn System"
*/
switch(csid)
{
case CS_BIG5:
case CS_GB_8BIT:
case CS_SJIS:
{
EnumFontTest test;
test.found = FALSE;
EnumFontFamilies(hdc, ((csid == CS_SJIS) ? "Jpn System" : "Chn System"),
(FONTENUMPROC)DetectTwinBridge, (LPARAM)&test);
return test.found;
}
case CS_KSC_8BIT:
default:
return FALSE;
}
}
/*========================================================================================
// For Unionway
//========================================================================================
*/
static int CALLBACK DetectUnionway(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param)
{
int l ;
EnumFontTest *pTest = (EnumFontTest *)param;
if(lpelf) {
char *postfix;
switch(pTest->testparam)
{
case CS_SJIS:
postfix = "JDEF";
break;
case CS_BIG5:
postfix = "CDEF";
break;
case CS_GB_8BIT:
postfix = "PDEF";
break;
case CS_KSC_8BIT:
postfix = "UDEF";
break;
default:
return 1;
}
l = strlen(lpelf->lfFaceName) - strlen(postfix);
if(l < 0)
return 1;
if(strcmp(postfix, lpelf->lfFaceName + l) == 0)
{
pTest->found = TRUE;
return 0;
}
}
return 1;
}
static BOOL unicode_CheckUnionwayForCsid(HDC hdc,int16 csid)
{
/*
// For Uniway, we could use EnumFontFamilies to check font name.
// xxxUDEF ? Maybe Korean ?
// xxxPDEF Simplified Chinese
// xxxJDEF Japanese
// xxxCDEF Chinese
// Maybe we should first check wheather UWTOOLS.INI or uwfont.ini is
// in the Windows directory
*/
EnumFontTest test;
test.found = FALSE;
test.testparam = csid;
EnumFontFamilies(hdc, NULL,(FONTENUMPROC)DetectUnionway, (LPARAM)&test);
return test.found;
}
BOOL unicode_IsCsidAvailable(HDC hdc, int16 csid)
{
/* We always sure this three csid is available. */
if( (csid == CS_LATIN1) || (csid == CS_SYMBOL) || (csid == CS_DINGBATS))
return TRUE;
/* Check the charset in font */
if(unicode_CheckFontOfCsid(hdc, csid))
return TRUE;
/* For 32 bit Windows, we check both code page and Unicode font also */
#ifdef _WIN32
{
UINT cp = unicode_CsidToCodePage(csid);
if((cp != 0) && (IsValidCodePage(cp) || unicode_UnicodeFontOfCodePage(hdc, cp)))
return TRUE;
}
#endif
/* For Windows 3.1 and 95, we check those hacking package for Multibyte system */
#ifdef _WIN32
if((csid & MULTIBYTE) && iswin95() )
#else
if(csid & MULTIBYTE)
#endif
{
if( unicode_CheckUnionwayForCsid(hdc, csid) ||
unicode_CheckTwinBridgeForCsid(hdc, csid) ||
unicode_CheckNJWINForCsid(hdc, csid))
return TRUE;
}
return FALSE;
}
static BOOL iswin95()
{
DWORD dwVer;
int iVer;
static BOOL initialized = FALSE;
static BOOL iswin95 = FALSE;
if(initialized)
return iswin95;
// The following code are copy from styles.cpp
dwVer = GetVersion();
iVer = (LOBYTE(LOWORD(dwVer))*100) + HIBYTE(LOWORD(dwVer));
if( iVer >= 395)
iswin95 = TRUE;
else
iswin95 = FALSE;
initialized = TRUE;
return iswin95;
}
PR_PUBLIC_API(int) UNICODE_VERIFYCSIDLIST(int inNumOfItem, int16 *csidlist)
{
int iIn, iOut;
HDC hdc = CreateIC("DISPLAY", NULL,NULL, NULL);
if(hdc == NULL)
return inNumOfItem;
for(iIn=iOut=0; iIn < inNumOfItem; iIn++)
{
if(unicode_IsCsidAvailable(hdc,csidlist[iIn]))
csidlist[iOut++] = csidlist[iIn];
}
DeleteDC(hdc);
return iOut;
}
PR_PUBLIC_API(int16) UNICODE_MENUFONTCSID()
{
HDC hdc = CreateIC("DISPLAY", NULL,NULL, NULL);
if(hdc)
{
TEXTMETRIC metrics;
int16 csid;
SelectObject(hdc, GetStockObject(SYSTEM_FONT));
GetTextMetrics(hdc, &metrics);
DeleteDC(hdc);
csid = unicode_CharsetToCsid(metrics.tmCharSet);
if(csid != CS_DEFAULT)
return csid;
}
return CS_LATIN1;
}
PR_PUBLIC_API(int) UNICODE_MENUFONTID()
{
#ifdef _WIN32
if(iswin95())
return DEFAULT_GUI_FONT;
else
#endif /* _WIN32 */
return SYSTEM_FONT;
}