Unicode Font Support for Qt Mozilla. Bugzilla #78939.

Also works around anti-alias font bug in Qt v2.3.x
This commit is contained in:
jcgriggs%sympatico.ca 2001-06-18 16:13:51 +00:00
Родитель 63a8ecff6a
Коммит 6869f1a18b
3 изменённых файлов: 398 добавлений и 341 удалений

Просмотреть файл

@ -18,7 +18,8 @@
* Rights Reserved.
*
* Contributor(s):
* John C. Griggs <johng@corel.com>
* John C. Griggs <jcgriggs@sympatico.ca>
* Jean Claude Batista <jcb@macadamian.com>
*
*/
@ -35,6 +36,7 @@
#include "nsHashtable.h"
#include "nsDrawingSurfaceQT.h"
#include "nsRenderingContextQT.h"
#include "nsILanguageAtomService.h"
#include <qapplication.h>
#include <qfont.h>
@ -73,19 +75,22 @@ static nsHashtable *gSpecialCharSets = nsnull;
static nsIAtom *gUnicode = nsnull;
static nsIAtom *gUserDefined = nsnull;
static nsIAtom *gUsersLocale = nsnull;
static NS_DEFINE_IID(kIFontMetricsIID,NS_IFONT_METRICS_IID);
static NS_DEFINE_CID(kCharSetManagerCID,NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_CID(kPrefCID,NS_PREF_CID);
static NS_DEFINE_CID(kSaveAsCharsetCID,NS_SAVEASCHARSET_CID);
#define NSQ_DOUBLEBYTE 1
struct nsFontCharSetInfo
{
const char *mCharSet;
nsFontCharSetConverter Convert;
PRUint32 *mMap;
nsIUnicodeEncoder *mConverter;
nsIAtom *mCharsetAtom;
nsIAtom *mLangGroup;
PRUint32 *mMap;
PRUint8 mType;
};
struct nsFontCharSetMap
@ -94,107 +99,105 @@ struct nsFontCharSetMap
nsFontCharSetInfo *mInfo;
};
static int SingleByteConvert(nsFontCharSetInfo *aSelf,
QFontMetrics *aFontMetrics,
const PRUnichar *aSrcBuf,PRInt32 aSrcLen,
char *aDestBuf,PRInt32 aDestLen);
static int DoubleByteConvert(nsFontCharSetInfo *aSelf,
QFontMetrics *aFontMetrics,
const PRUnichar *aSrcBuf,PRInt32 aSrcLen,
char *aDestBuf,PRInt32 aDestLen);
static int ISO10646Convert(nsFontCharSetInfo *aSelf,
QFontMetrics *aFontMetrics,
const PRUnichar *aSrcBuf,PRInt32 aSrcLen,
char *aDestBuf,PRInt32 aDestLen);
static nsFontCharSetInfo Unknown = { nsnull };
static nsFontCharSetInfo Special = { nsnull };
static nsFontCharSetInfo Unknown =
{ nsnull, nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Special =
{ nsnull, nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO106461 =
{ nsnull, nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo CP1251 =
{ "windows-1251", SingleByteConvert };
{ "windows-1251", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88591 =
{ "ISO-8859-1", SingleByteConvert };
{ "ISO-8859-1", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88592 =
{ "ISO-8859-2", SingleByteConvert };
{ "ISO-8859-2", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88593 =
{ "ISO-8859-3", SingleByteConvert };
{ "ISO-8859-3", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88594 =
{ "ISO-8859-4", SingleByteConvert };
{ "ISO-8859-4", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88595 =
{ "ISO-8859-5", SingleByteConvert };
{ "ISO-8859-5", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88596 =
{ "ISO-8859-6", SingleByteConvert };
{ "ISO-8859-6", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88597 =
{ "ISO-8859-7", SingleByteConvert };
{ "ISO-8859-7", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88598 =
{ "ISO-8859-8", SingleByteConvert };
// change from
// { "ISO-8859-8", SingleByteConvertReverse };
// untill we fix the layout and ensure we only call this with pure RTL text
{ "ISO-8859-8", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO88599 =
{ "ISO-8859-9", SingleByteConvert };
{ "ISO-8859-9", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO885913 =
{ "ISO-8859-13", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo ISO885915 =
{ "ISO-8859-15", SingleByteConvert };
{ "ISO-8859-15", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo JISX0201 =
{ "jis_0201", SingleByteConvert };
{ "jis_0201", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo KOI8R =
{ "KOI8-R", SingleByteConvert };
{ "KOI8-R", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo KOI8U =
{ "KOI8-U", SingleByteConvert };
{ "KOI8-U", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo TIS620 =
{ "TIS-620", SingleByteConvert };
{ "TIS-620", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Big5 =
{ "x-x-big5", DoubleByteConvert };
{ "x-x-big5", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116431 =
{ "x-cns-11643-1", DoubleByteConvert };
{ "x-cns-11643-1", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116432 =
{ "x-cns-11643-2", DoubleByteConvert };
{ "x-cns-11643-2", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116433 =
{ "x-cns-11643-3", DoubleByteConvert };
{ "x-cns-11643-3", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116434 =
{ "x-cns-11643-4", DoubleByteConvert };
{ "x-cns-11643-4", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116435 =
{ "x-cns-11643-5", DoubleByteConvert };
{ "x-cns-11643-5", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116436 =
{ "x-cns-11643-6", DoubleByteConvert };
{ "x-cns-11643-6", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo CNS116437 =
{ "x-cns-11643-7", DoubleByteConvert };
{ "x-cns-11643-7", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo GB2312 =
{ "gb_2312-80", DoubleByteConvert };
{ "gb_2312-80", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo GB18030_0 =
{ "gb18030.2000-0", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo GB18030_1 =
{ "gb18030.2000-1", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo GBK =
{ "x-gbk", DoubleByteConvert};
{ "x-gbk", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo HKSCS =
{ "hkscs-1", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo JISX0208 =
{ "jis_0208-1983", DoubleByteConvert };
{ "jis_0208-1983", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo JISX0212 =
{ "jis_0212-1990", DoubleByteConvert };
{ "jis_0212-1990", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo KSC5601 =
{ "ks_c_5601-1987", DoubleByteConvert };
{ "ks_c_5601-1987", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo X11Johab =
{ "x-x11johab", DoubleByteConvert };
static nsFontCharSetInfo ISO106461 =
{ nsnull, ISO10646Convert };
{ "x-x11johab", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo Johab =
{ "x-johab", nsnull, nsnull, nsnull, NSQ_DOUBLEBYTE };
static nsFontCharSetInfo AdobeSymbol =
{ "Adobe-Symbol-Encoding", SingleByteConvert };
static nsFontCharSetInfo CMCMEX =
{ "x-t1-cmex", SingleByteConvert };
static nsFontCharSetInfo CMCMSY =
{ "x-t1-cmsy", SingleByteConvert };
{ "Adobe-Symbol-Encoding", nsnull, nsnull, nsnull, 0 };
#ifdef MOZ_MATHML
static nsFontCharSetInfo CMCMEX =
{ "x-t1-cmex", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo CMCMSY =
{ "x-t1-cmsy", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo CMCMR =
{ "x-t1-cmr", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo CMCMMI =
{ "x-t1-cmmi", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Mathematica1 =
{ "x-mathematica1", SingleByteConvert };
{ "x-mathematica1", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Mathematica2 =
{ "x-mathematica2", SingleByteConvert };
{ "x-mathematica2", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Mathematica3 =
{ "x-mathematica3", SingleByteConvert };
{ "x-mathematica3", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Mathematica4 =
{ "x-mathematica4", SingleByteConvert };
{ "x-mathematica4", nsnull, nsnull, nsnull, 0 };
static nsFontCharSetInfo Mathematica5 =
{ "x-mathematica5", SingleByteConvert };
{ "x-mathematica5", nsnull, nsnull, nsnull, 0 };
#endif
static nsFontCharSetMap gCharSetMap[] =
@ -228,6 +231,13 @@ static nsFontCharSetMap gCharSetMap[] =
{ "cns11643.1992-6", &CNS116436 },
{ "cns11643.1992.7-0", &CNS116437 },
{ "cns11643.1992-7", &CNS116437 },
{ "cns11643-1", &CNS116431 },
{ "cns11643-2", &CNS116432 },
{ "cns11643-3", &CNS116433 },
{ "cns11643-4", &CNS116434 },
{ "cns11643-5", &CNS116435 },
{ "cns11643-6", &CNS116436 },
{ "cns11643-7", &CNS116437 },
{ "cp1251-1", &CP1251 },
{ "dec-dectech", &Unknown },
{ "dtsymbol-1", &Unknown },
@ -235,6 +245,10 @@ static nsFontCharSetMap gCharSetMap[] =
{ "gb2312.1980-0", &GB2312 },
{ "gb2312.1980-1", &GB2312 },
{ "gb13000.1993-1", &GBK },
{ "gb18030.2000-0", &GB18030_0 },
{ "gb18030.2000-1", &GB18030_1 },
{ "gbk-0", &GBK },
{ "hkscs-1", &HKSCS },
{ "hp-japanese15", &Unknown },
{ "hp-japaneseeuc", &Unknown },
{ "hp-roman8", &Unknown },
@ -255,6 +269,7 @@ static nsFontCharSetMap gCharSetMap[] =
{ "ibm-udctw", &Unknown },
{ "iso646.1991-irv", &Unknown },
{ "iso8859-1", &ISO88591 },
{ "iso8859-13", &ISO885913 },
{ "iso8859-15", &ISO885915 },
{ "iso8859-1@cn", &Unknown },
{ "iso8859-1@kr", &Unknown },
@ -280,6 +295,7 @@ static nsFontCharSetMap gCharSetMap[] =
{ "johabs-1", &X11Johab },
{ "johabsh-1", &X11Johab },
{ "ksc5601.1987-0", &KSC5601 },
{ "ksc5601.1992-3", &Johab },
{ "microsoft-cp1251", &CP1251 },
{ "misc-fontspecific", &Unknown },
{ "sgi-fontspecific", &Unknown },
@ -287,6 +303,10 @@ static nsFontCharSetMap gCharSetMap[] =
{ "sunolcursor-1", &Unknown },
{ "sunolglyph-1", &Unknown },
{ "tis620.2529-1", &TIS620 },
{ "tis620.2533-0", &TIS620 },
{ "tis620.2533-1", &TIS620 },
{ "tis620-0", &TIS620 },
{ "iso8859-11", &TIS620 },
{ "ucs2.cjk-0", &Unknown },
{ "ucs2.cjk_japan-0", &Unknown },
{ "ucs2.cjk_taiwan-0", &Unknown },
@ -297,10 +317,13 @@ static nsFontCharSetMap gCharSetMap[] =
static nsFontCharSetMap gSpecialCharSetMap[] =
{
{ "symbol-adobe-fontspecific", &AdobeSymbol },
{ "cmex10-adobe-fontspecific", &CMCMEX },
{ "cmsy10-adobe-fontspecific", &CMCMSY },
#ifdef MOZ_MATHML
{ "cmex10-adobe-fontspecific", &CMCMEX },
{ "cmsy10-adobe-fontspecific", &CMCMSY },
{ "cmr10-adobe-fontspecific", &CMCMR },
{ "cmmi10-adobe-fontspecific", &CMCMMI },
{ "math1-adobe-fontspecific", &Mathematica1 },
{ "math2-adobe-fontspecific", &Mathematica2 },
{ "math3-adobe-fontspecific", &Mathematica3 },
@ -372,7 +395,7 @@ public:
virtual ~nsFontQTSubstitute();
virtual QFont *GetQFont(void);
virtual PRBool GetQFontIs10646(void);
virtual int SupportsChar(PRUnichar aChar);
virtual int GetWidth(const PRUnichar *aString,PRUint32 aLength);
virtual int DrawString(nsRenderingContextQT *aContext,
nsDrawingSurfaceQT *aSurface,nscoord aX,
@ -401,6 +424,7 @@ public:
nsFontQTUserDefined();
virtual ~nsFontQTUserDefined();
virtual PRUint32 *GetCharSetMap() { return mMap; };
virtual PRBool Init(nsFontQT *aFont);
virtual int GetWidth(const PRUnichar *aString,PRUint32 aLength);
virtual int DrawString(nsRenderingContextQT *aContext,
@ -414,6 +438,8 @@ public:
#endif
virtual PRUint32 Convert(const PRUnichar *aSrc,PRInt32 aSrcLen,
char *aDest,PRInt32 aDestLen);
PRUint32 *mMap;
};
QFontDatabase *nsFontMetricsQT::mQFontDB = nsnull;
@ -423,9 +449,8 @@ FreeCharSet(nsHashKey *aKey,void *aData,void *aClosure)
{
nsFontCharSetInfo *charset = (nsFontCharSetInfo*)aData;
NS_IF_RELEASE(charset->mConverter);
NS_IF_RELEASE(charset->mCharsetAtom);
NS_IF_RELEASE(charset->mLangGroup);
PR_FREEIF(charset->mMap);
return PR_TRUE;
}
@ -448,6 +473,7 @@ FreeGlobals(void)
NS_IF_RELEASE(gUnicode);
NS_IF_RELEASE(gUserDefined);
NS_IF_RELEASE(gUserDefinedConverter);
NS_IF_RELEASE(gUsersLocale);
}
static nsresult
@ -504,75 +530,23 @@ InitGlobals(void)
return NS_ERROR_OUT_OF_MEMORY;
}
memset(gUserDefinedMap,0,sizeof(gUserDefinedMap));
nsCOMPtr<nsILanguageAtomService> langService;
langService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
if (langService) {
langService->GetLocaleLanguageGroup(&gUsersLocale);
}
if (!gUsersLocale) {
gUsersLocale = NS_NewAtom("x-western");
}
if (!gUsersLocale) {
FreeGlobals();
return NS_ERROR_OUT_OF_MEMORY;
}
gInitialized = 1;
return NS_OK;
}
static int
SingleByteConvert(nsFontCharSetInfo *aSelf,QFontMetrics *aFontMetrics,
const PRUnichar *aSrcBuf,PRInt32 aSrcLen,
char *aDestBuf,PRInt32 aDestLen)
{
int count = 0;
if (aSelf->mConverter) {
aSelf->mConverter->Convert(aSrcBuf,&aSrcLen,aDestBuf,&aDestLen);
count = aDestLen;
}
return count;
}
static int
DoubleByteConvert(nsFontCharSetInfo *aSelf,QFontMetrics *aFontMetrics,
const PRUnichar *aSrcBuf,PRInt32 aSrcLen,
char *aDestBuf,PRInt32 aDestLen)
{
int count = 0;
if (aSelf->mConverter) {
aSelf->mConverter->Convert(aSrcBuf,&aSrcLen,aDestBuf,&aDestLen);
count = aDestLen;
if (count > 0) {
if ((aDestBuf[0] & 0x80) && !aFontMetrics->inFont(QChar(aDestBuf[0]))) {
//JCG if ((aDestBuf[0] & 0x80) && (!(aFont->max_byte1 & 0x80))) {
for (PRInt32 i = 0; i < aDestLen; i++) {
aDestBuf[i] &= 0x7F;
}
}
else if (!(aDestBuf[0] & 0x80)
&& !aFontMetrics->inFont(QChar(aDestBuf[0]))) {
//JCG else if (!(aDestBuf[0] & 0x80) && (aFont->min_byte1 & 0x80)) {
for (PRInt32 i = 0; i < aDestLen; i++) {
aDestBuf[i] |= 0x80;
}
}
}
}
return count;
}
static int
ISO10646Convert(nsFontCharSetInfo *aSelf,QFontMetrics *aFontMetrics,
const PRUnichar *aSrcBuf,PRInt32 aSrcLen,
char *aDestBuf,PRInt32 aDestLen)
{
#if 0 //JCG
aDestLen /= 2;
if (aSrcLen > aDestLen) {
aSrcLen = aDestLen;
}
if (aSrcLen < 0) {
aSrcLen = 0;
}
XChar2b *dest = (XChar2b*)aDestBuf;
for (PRInt32 i = 0; i < aSrcLen; i++) {
dest[i].byte1 = (aSrcBuf[i] >> 8);
dest[i].byte2 = (aSrcBuf[i] & 0xFF);
}
return (int)aSrcLen * 2;
#endif //JCG
return 0;
}
static void ParseFontPref(nsCAutoString &aPrefValue,QString &aFontName,
QString &aFontFoundryName,QString &aCharSet)
{
@ -749,6 +723,24 @@ FontEnumCallback(const nsString &aFamily,PRBool aGeneric,void *aData)
return PR_TRUE; // continue
}
#if (QT_VERSION >= 230)
static int use_qt_xft()
{
static int use_xft = 0;
static int chkd_env = 0;
if (!chkd_env) {
char *e = getenv ("QT_XFT");
if (e && (*e == '1' || *e == 'y' || *e == 'Y'
|| *e == 't' || *e == 'T' ))
use_xft = 1;
chkd_env = 1;
}
return use_xft;
}
#endif
NS_IMETHODIMP nsFontMetricsQT::Init(const nsFont &aFont,nsIAtom *aLangGroup,
nsIDeviceContext *aContext)
{
@ -773,8 +765,16 @@ NS_IMETHODIMP nsFontMetricsQT::Init(const nsFont &aFont,nsIAtom *aLangGroup,
aContext->GetTextZoom(textZoom);
mPixelSize = NSToIntRound(a2d * textZoom * mFont->size);
if (mFont->style == NS_FONT_STYLE_NORMAL) {
#if (QT_VERSION >= 230)
if (use_qt_xft())
mQStyle = new QString("Regular");
else
#endif
mQStyle = new QString("Normal");
}
else if (mFont->style == NS_FONT_STYLE_OBLIQUE) {
mQStyle = new QString("Oblique");
}
else {
mQStyle = new QString("Italic");
}
@ -1084,7 +1084,6 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
{
nsFontQT *newFont = nsnull;
QFont *qFont;
PRUint32 *map;
nsIUnicodeEncoder *converter;
nsCStringKey charSetKey(aCharSet.latin1());
@ -1110,7 +1109,8 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
else {
#ifdef NOISY_FONTS
#ifdef DEBUG
printf("cannot find charset %s-%s\n",aName.latin1(),aCharSet.latin1());
printf("cannot find charset %s-%s\n",aName.latin1(),
aCharSet.latin1());
#endif
#endif
return nsnull;
@ -1118,55 +1118,65 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
}
if (charSetInfo->mCharSet) {
if (charSetInfo->mMap) {
map = charSetInfo->mMap;
for (int i = 0; i < mLoadedFontsCount; i++) {
if (mLoadedFonts[i]->mMap == map) {
if (mLoadedFonts[i]->GetCharSetMap() == charSetInfo->mMap) {
return nsnull;
}
}
}
else {
charSetInfo->mMap = (PRUint32*)PR_Calloc(2048,4);
if (nsnull == charSetInfo->mMap) {
nsresult res;
if (!charSetInfo->mCharsetAtom) {
res
= gCharSetManager->GetCharsetAtom2(charSetInfo->mCharSet,
&charSetInfo->mCharsetAtom);
if (NS_FAILED(res)) {
#ifdef NOISY_FONTS
#ifdef DEBUG
printf("=== cannot get Charset Atom for %s\n",
charSetInfo->mCharSet);
#endif
#endif
return nsnull;
}
nsCOMPtr<nsIAtom> charset;
nsresult res = gCharSetManager->GetCharsetAtom2(charSetInfo->mCharSet,
getter_AddRefs(charset));
if (NS_SUCCEEDED(res)) {
res = gCharSetManager->GetCharsetLangGroup(charset,
}
if (!charSetInfo->mLangGroup) {
res
= gCharSetManager->GetCharsetLangGroup(charSetInfo->mCharsetAtom,
&charSetInfo->mLangGroup);
if (NS_FAILED(res)) {
#ifdef NOISY_FONTS
#ifdef DEBUG
printf("=== cannot get lang group for %s\n",charSetInfo->mCharSet);
printf("=== cannot get lang group for %s\n",
charSetInfo->mCharSet);
#endif
#endif
PR_Free(charSetInfo->mMap);
charSetInfo->mMap = nsnull;
return nsnull;
}
}
else {
#ifdef NOISY_FONTS
#ifdef DEBUG
printf("=== cannot get Charset Atom for %s\n",charSetInfo->mCharSet);
#endif
#endif
PR_Free(charSetInfo->mMap);
charSetInfo->mMap = nsnull;
return nsnull;
}
nsCOMPtr<nsIAtom> charsetAtom
= getter_AddRefs(NS_NewAtom(charSetInfo->mCharSet));
if (charsetAtom) {
if (!charsetAtom) {
NS_WARNING("cannot get atom");
return nsnull;
}
res = gCharSetManager->GetUnicodeEncoder(charsetAtom,&converter);
if (NS_SUCCEEDED(res)) {
charSetInfo->mConverter = converter;
if (NS_FAILED(res)) {
NS_WARNING("cannot get Unicode converter");
return nsnull;
}
res = converter->SetOutputErrorBehavior(converter->kOnError_Replace,
nsnull,'?');
nsCOMPtr<nsICharRepresentable> mapper = do_QueryInterface(converter);
if (mapper) {
nsCOMPtr<nsICharRepresentable> mapper
= do_QueryInterface(converter);
if (!mapper) {
NS_WARNING("cannot get nsICharRepresentable");
return nsnull;
}
charSetInfo->mMap = (PRUint32*)PR_Calloc(2048,4);
if (nsnull == charSetInfo->mMap) {
return nsnull;
}
res = mapper->FillInfo(charSetInfo->mMap);
/*
@ -1176,8 +1186,8 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
* happen to be in these large double byte fonts. So, we disable
* those characters here. Revisit this decision later.
*/
if (charSetInfo->Convert == DoubleByteConvert) {
map = charSetInfo->mMap;
if (charSetInfo->mType == NSQ_DOUBLEBYTE) {
PRUint32 *map = charSetInfo->mMap;
#undef REMOVE_CHAR
#define REMOVE_CHAR(map,c) (map)[(c) >> 5] &= ~(1L << ((c) & 0x1f))
REMOVE_CHAR(map,0x20AC);
@ -1209,32 +1219,23 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
REMOVE_CHAR(map,0x0178);
}
}
else {
NS_WARNING("cannot get nsICharRepresentable");
PR_Free(charSetInfo->mMap);
charSetInfo->mMap = nsnull;
if (!FONT_HAS_GLYPH(charSetInfo->mMap,aChar)) {
return nsnull;
}
}
else {
NS_WARNING("cannot get Unicode converter");
PR_Free(charSetInfo->mMap);
charSetInfo->mMap = nsnull;
return nsnull;
}
}
else {
NS_WARNING("cannot get atom");
PR_Free(charSetInfo->mMap);
charSetInfo->mMap = nsnull;
return nsnull;
}
}
}
if ((charSetInfo == &Unknown && mIsUserDefined)
|| (charSetInfo->mMap && FONT_HAS_GLYPH(charSetInfo->mMap,aChar))) {
qFont = LoadQFont(aName,aCharSet);
if (qFont) {
newFont = new nsFontQTNormal(qFont);
if (!newFont) {
delete qFont;
return nsnull;
}
if (charSetInfo == &ISO106461) {
if (!newFont->HasChar(aChar)) {
delete newFont;
return nsnull;
}
}
if (mLoadedFontsCount == mLoadedFontsAlloc) {
int newSize;
if (mLoadedFontsAlloc) {
@ -1243,23 +1244,19 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
else {
newSize = 1;
}
nsFontQT **newPointer = (nsFontQT**)PR_Realloc(mLoadedFonts,
nsFontQT **newPointer
= (nsFontQT**)PR_Realloc(mLoadedFonts,
newSize * sizeof(nsFontQT*));
if (newPointer) {
mLoadedFonts = newPointer;
mLoadedFontsAlloc = newSize;
}
else {
delete qFont;
delete newFont;
return nsnull;
}
}
newFont = new nsFontQTNormal(qFont);
if (!newFont) {
delete qFont;
return nsnull;
}
if (charSetInfo == &Unknown) {
if (mIsUserDefined) {
mUserDefinedFont = new nsFontQTUserDefined();
if (nsnull == mUserDefinedFont) {
delete newFont;
@ -1270,11 +1267,9 @@ nsFontMetricsQT::LoadFont(QString &aName,const QString &aCharSet,
}
else {
newFont->mCharSetInfo = charSetInfo;
newFont->mMap = charSetInfo->mMap;
}
mLoadedFonts[mLoadedFontsCount++] = newFont;
}
}
return newFont;
}
@ -1418,46 +1413,96 @@ PrefEnumCallback(const char *aName,void *aClosure)
}
nsFontQT*
nsFontMetricsQT::FindGenericFont(PRUnichar aChar)
nsFontMetricsQT::FindLangGroupPrefFont(nsIAtom *aLangGroup,
PRUnichar aChar)
{
if (mTriedAllGenerics) {
return nsnull;
}
QString fontName,foundryName,charSetName;
nsCAutoString prefix("font.name.");
prefix.Append(*mGeneric);
if (mLangGroup) {
nsCAutoString pref = prefix;
pref.Append(char('.'));
const PRUnichar *langGroup = nsnull;
mLangGroup->GetUnicode(&langGroup);
pref.AppendWithConversion(langGroup);
char *value = nsnull;
gPref->CopyCharPref(pref.get(),&value);
nsCAutoString str;
nsFontQT *font = nsnull;
nsCAutoString prefix("font.name.");
prefix.Append(*mGeneric);
if (aLangGroup) {
// check user set pref
nsCAutoString pref = prefix;
const PRUnichar *langGroup = nsnull;
char *value = nsnull;
nsCAutoString str;
nsCAutoString str_user;
pref.Append(char('.'));
aLangGroup->GetUnicode(&langGroup);
pref.AppendWithConversion(langGroup);
gPref->CopyCharPref(pref.get(), &value);
if (value) {
str = value;
str_user = value;
nsMemory::Free(value);
value = nsnull;
font = LookUpFontPref(str,aChar);
if (font) {
NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
return font;
}
}
if (!font) {
value = nsnull;
// check factory set pref
gPref->CopyDefaultCharPref(pref.get(), &value);
if (value) {
str = value;
// check if we already tried this name
if (str != str_user) {
nsMemory::Free(value);
value = nsnull;
font = LookUpFontPref(str,aChar);
if (font) {
NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
return font;
}
}
if (font)
}
}
return nsnull;
}
nsFontQT*
nsFontMetricsQT::FindGenericFont(PRUnichar aChar)
{
nsFontQT *font = nsnull;
if (mTriedAllGenerics) {
return nsnull;
}
if (mLangGroup) {
font = FindLangGroupPrefFont(mLangGroup,aChar);
if (font) {
NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
return(font);
}
}
if (mLangGroup != gUsersLocale) {
font = FindLangGroupPrefFont(gUsersLocale,aChar);
if (font) {
NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char");
return(font);
}
}
nsCAutoString prefix("font.name.");
nsFontSearch search = { this,aChar,nsnull };
prefix.Append(*mGeneric);
gPref->EnumerateChildren(prefix.get(),PrefEnumCallback,&search);
if (search.mFont) {
NS_ASSERTION(search.mFont->SupportsChar(aChar), "font supposed to support this char");
return search.mFont;
}
//
// Search all font prefs
//
// find based on all prefs (no generic part (eg: sans-serif))
nsCAutoString allPrefs("font.name.");
search.mFont = nsnull;
gPref->EnumerateChildren(allPrefs.get(), PrefEnumCallback, &search);
if (search.mFont) {
NS_ASSERTION(search.mFont->SupportsChar(aChar), "font supposed to support this char");
return search.mFont;
}
mTriedAllGenerics = 1;
@ -1510,7 +1555,7 @@ nsFontMetricsQT::FindSubstituteFont(PRUnichar aChar)
{
if (!mSubstituteFont) {
for (int i = 0; i < mLoadedFontsCount; i++) {
if (FONT_HAS_GLYPH(mLoadedFonts[i]->mMap,'a')) {
if (mLoadedFonts[i]->SupportsChar('a')) {
mSubstituteFont = new nsFontQTSubstitute(mLoadedFonts[i]);
break;
}
@ -1626,16 +1671,28 @@ nsFontQT::~nsFontQT()
}
}
PRUint32 *nsFontQT::GetCharSetMap()
{
return mCharSetInfo->mMap;
}
QFont*
nsFontQT::GetQFont(void)
{
return mFont;
}
PRBool
nsFontQT::GetQFontIs10646(void)
int nsFontQT::SupportsChar(PRUnichar aChar)
{
return((PRBool)(mCharSetInfo == &ISO106461));
if (IsUnicodeFont())
return HasChar(aChar);
else
return (mFont && FONT_HAS_GLYPH(GetCharSetMap(),aChar));
}
PRBool nsFontQT::IsUnicodeFont()
{
return(mCharSetInfo == &ISO106461);
}
nsFontQTNormal::nsFontQTNormal()
@ -1702,10 +1759,6 @@ nsFontQTNormal::GetBoundingMetrics(const PRUnichar *aString,
return NS_ERROR_FAILURE;
}
if (aString && 0 < aLength) {
char strBuf[1024];
int len = mCharSetInfo->Convert(mCharSetInfo,mFontMetrics,aString,
aLength,strBuf,sizeof(strBuf));
QChar *buf = new QChar[aLength + 1];
for (int i = 0; i < aLength; i++) {
@ -1833,14 +1886,14 @@ nsFontQTSubstitute::GetQFont(void)
return mSubstituteFont->GetQFont();
}
PRBool
nsFontQTSubstitute::GetQFontIs10646(void)
int nsFontQTSubstitute::SupportsChar(PRUnichar aChar)
{
return mSubstituteFont->GetQFontIs10646();
return mSubstituteFont->SupportsChar(aChar);
}
nsFontQTUserDefined::nsFontQTUserDefined()
{
mMap = nsnull;
}
nsFontQTUserDefined::~nsFontQTUserDefined()
@ -1852,6 +1905,8 @@ PRBool
nsFontQTUserDefined::Init(nsFontQT *aFont)
{
mFont = aFont->GetQFont();
mFontInfo = new QFontInfo(*mFont);
mFontMetrics = new QFontMetrics(*mFont);
mMap = gUserDefinedMap;
return PR_TRUE;
}
@ -2002,24 +2057,25 @@ static nsresult EnumFonts(nsIAtom *aLangGroup,const char *aGeneric,
continue;
}
if (aLangGroup != gUnicode) {
nsCOMPtr<nsIAtom> charset;
nsIAtom *langGroup;
nsresult res;
if (!charSetInfo->mCharsetAtom) {
res = gCharSetManager->GetCharsetAtom2(charSetInfo->mCharSet,
getter_AddRefs(charset));
if (NS_SUCCEEDED(res)) {
res = gCharSetManager->GetCharsetLangGroup(charset,
&langGroup);
&charSetInfo->mCharsetAtom);
if (NS_FAILED(res)) {
continue;
}
}
if (aLangGroup != langGroup) {
NS_IF_RELEASE(langGroup);
if (!charSetInfo->mLangGroup) {
res = gCharSetManager->GetCharsetLangGroup(charSetInfo->mCharsetAtom,
&charSetInfo->mLangGroup);
if (NS_FAILED(res)) {
continue;
}
}
if (aLangGroup != charSetInfo->mLangGroup) {
continue;
}
NS_IF_RELEASE(langGroup);
}
nsCAutoString name((*famIt).latin1());
FontEnumNode *node = (FontEnumNode*)nsMemory::Alloc(sizeof(FontEnumNode));

Просмотреть файл

@ -18,7 +18,8 @@
* Rights Reserved.
*
* Contributor(s):
* John C. Griggs <johng@corel.com>
* John C. Griggs <jcgriggs@sympatico.ca>
* Jean Claude Batista <jcb@macadamian.com>
*
*/
@ -35,6 +36,7 @@
#include "nsICharsetConverterManager2.h"
#include <qintdict.h>
#include <qfontmetrics.h>
class nsFont;
class nsString;
@ -45,7 +47,6 @@ class nsFontQTUserDefined;
class QString;
class QFont;
class QFontInfo;
class QFontMetrics;
class QFontDatabase;
#undef FONT_HAS_GLYPH
@ -53,11 +54,6 @@ class QFontDatabase;
typedef struct nsFontCharSetInfo nsFontCharSetInfo;
typedef int (*nsFontCharSetConverter)(nsFontCharSetInfo* aSelf,
QFontMetrics *aFontMetrics,
const PRUnichar* aSrcBuf,PRInt32 aSrcLen,
char* aDestBuf,PRInt32 aDestLen);
class nsFontQT
{
public:
@ -67,9 +63,14 @@ public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
virtual QFont *GetQFont(void);
virtual PRBool GetQFontIs10646(void);
inline int SupportsChar(PRUnichar aChar)
{ return (mFont && FONT_HAS_GLYPH(mMap,aChar)); };
virtual PRUint32 *GetCharSetMap();
PRBool IsUnicodeFont();
inline int HasChar(PRUnichar aChar)
{
return(mFontMetrics && mFontMetrics->inFont(QChar(aChar)));
};
virtual int SupportsChar(PRUnichar aChar);
virtual int GetWidth(const PRUnichar* aString, PRUint32 aLength) = 0;
virtual int DrawString(nsRenderingContextQT* aContext,
@ -89,7 +90,6 @@ public:
QFontInfo* mFontInfo;
QFontMetrics* mFontMetrics;
nsFontCharSetInfo* mCharSetInfo;
PRUint32* mMap;
};
class nsFontMetricsQT : public nsIFontMetrics
@ -130,6 +130,7 @@ public:
nsFontQT* FindFont(PRUnichar aChar);
nsFontQT* FindUserDefinedFont(PRUnichar aChar);
nsFontQT* FindLangGroupPrefFont(nsIAtom *aLangGroup,PRUnichar aChar);
nsFontQT* FindLocalFont(PRUnichar aChar);
nsFontQT* FindGenericFont(PRUnichar aChar);
nsFontQT* FindGlobalFont(PRUnichar aChar);

Просмотреть файл

@ -18,7 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* John C. Griggs <johng@corel.com>
* John C. Griggs <jcgriggs@sympatico.ca>
*/
#include "nsFontMetricsQT.h"
@ -1072,7 +1072,7 @@ NS_IMETHODIMP nsRenderingContextQT::GetWidth(const PRUnichar *aString,
nsFontQT **font = metrics->mLoadedFonts;
nsFontQT **lastFont = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
while (font < lastFont) {
if (IS_REPRESENTABLE((*font)->mMap,c)) {
if ((*font)->SupportsChar(c)) {
currFont = *font;
goto FoundFont; // for speed -- avoid "if" statement
}
@ -1186,7 +1186,7 @@ NS_IMETHODIMP nsRenderingContextQT::DrawString(const PRUnichar *aString,
nsFontQT **font = metrics->mLoadedFonts;
nsFontQT **lastFont = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
while (font < lastFont) {
if (IS_REPRESENTABLE((*font)->mMap,c)) {
if ((*font)->SupportsChar(c)) {
currFont = *font;
goto FoundFont; // for speed -- avoid "if" statement
}
@ -1481,7 +1481,7 @@ nsRenderingContextQT::GetBoundingMetrics(const PRUnichar *aString,
nsFontQT **font = metrics->mLoadedFonts;
nsFontQT **end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
while (font < end) {
if (IS_REPRESENTABLE((*font)->mMap, c)) {
if ((*font)->SupportsChar( c)) {
currFont = *font;
goto FoundFont; // for speed -- avoid "if" statement
}