r=mkaply, a=brendan
FontEnumerator implementation for OS/2


git-svn-id: svn://10.0.0.236/trunk@79223 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mkaply%us.ibm.com
2000-09-14 23:17:20 +00:00
parent 35223fe774
commit 0bd52d518e
3 changed files with 417 additions and 2 deletions

View File

@@ -27,6 +27,62 @@
#include "nsFontMetricsOS2.h"
#include "nsString.h"
#include "nsFont.h"
#include "nsQuickSort.h"
#include "prmem.h"
enum nsCharSet
{
eCharSet_DEFAULT = 0,
eCharSet_ANSI,
eCharSet_EASTEUROPE,
eCharSet_RUSSIAN,
eCharSet_GREEK,
eCharSet_TURKISH,
eCharSet_HEBREW,
eCharSet_ARABIC,
eCharSet_BALTIC,
eCharSet_THAI,
eCharSet_SHIFTJIS,
eCharSet_GB2312,
eCharSet_HANGEUL,
eCharSet_CHINESEBIG5,
eCharSet_JOHAB,
eCharSet_COUNT
};
struct nsCharSetInfo
{
char* mName;
USHORT mMask;
PRUint16 mCodePage;
char* mLangGroup;
PRUint32* mMap;
};
static PRUint32 gUserDefinedMap[2048];
nsGlobalFont* nsFontMetricsOS2::gGlobalFonts = nsnull;
static int gGlobalFontsAlloc = 0;
int nsFontMetricsOS2::gGlobalFontsCount = 0;
static nsCharSetInfo gCharSetInfo[eCharSet_COUNT] =
{
{ "DEFAULT", 0, 0, "" },
{ "ANSI", FM_DEFN_LATIN1, 1252, "x-western" },
{ "EASTEUROPE", FM_DEFN_LATIN2, 1250, "x-central-euro" },
{ "RUSSIAN", FM_DEFN_CYRILLIC, 1251, "x-cyrillic" },
{ "GREEK", FM_DEFN_GREEK, 1253, "el" },
{ "TURKISH", 0, 1254, "tr" },
{ "HEBREW", FM_DEFN_HEBREW, 1255, "he" },
{ "ARABIC", FM_DEFN_ARABIC, 1256, "ar" },
{ "BALTIC", 0, 1257, "x-baltic" },
{ "THAI", FM_DEFN_THAI, 874, "th" },
{ "SHIFTJIS", FM_DEFN_KANA, 932, "ja" },
{ "GB2312", FM_DEFN_KANA, 936, "zh-CN" },
{ "HANGEUL", FM_DEFN_KANA, 949, "ko" },
{ "CHINESEBIG5", FM_DEFN_KANA, 950, "zh-TW" },
{ "JOHAB", FM_DEFN_KANA, 1361, "ko-XXX", }
};
// font handle
nsFontHandleOS2::nsFontHandleOS2()
@@ -499,3 +555,322 @@ nsFontMetricsOS2::GetMaxHeight(nscoord &aHeight)
aHeight = mMaxHeight;
return NS_OK;
}
nsGlobalFont*
nsFontMetricsOS2::InitializeGlobalFonts(HPS aPS)
{
static int gInitializedGlobalFonts = 0;
if (!gInitializedGlobalFonts) {
LONG lRemFonts = 0, lNumFonts;
lNumFonts = GpiQueryFonts(aPS, QF_PUBLIC, NULL, &lRemFonts, 0, 0);
PFONTMETRICS pFontMetrics = (PFONTMETRICS) nsMemory::Alloc(lNumFonts * sizeof(FONTMETRICS));
lRemFonts = GpiQueryFonts(aPS, QF_PUBLIC, NULL, &lNumFonts, sizeof(FONTMETRICS), pFontMetrics);
for (int i=0; i < lNumFonts; i++) {
BOOL fAlreadyFound = FALSE;
for (int j = 0; j < nsFontMetricsOS2::gGlobalFontsCount && !fAlreadyFound; j++) {
if (!strcmp(nsFontMetricsOS2::gGlobalFonts[j].fontMetrics.szFamilyname,
pFontMetrics[i].szFamilyname)) {
fAlreadyFound = TRUE;
}
}
if (fAlreadyFound) {
continue;
} /* endif */
#ifdef MOZ_MATHML
// XXX need a better way to deal with non-TrueType fonts?
if (!(fontType & TRUETYPE_FONTTYPE)) {
//printf("rejecting %s\n", logFont->lfFaceName);
return 1;
}
#endif
// XXX ignore vertical fonts
if (pFontMetrics[i].szFamilyname[0] == '@') {
continue;
}
#ifdef OLDCODE
for (int j = 0; j < nsFontMetricsOS2::gGlobalFontsCount; j++) {
if (!strcmp(nsFontMetricsOS2::gGlobalFonts[i].logFont.szFamilyname,
logFont->lfFaceName)) {
//work-around for Win95/98 problem
int charSetSigBit = charSetToBit[gCharSetToIndex[logFont->lfCharSet]];
if (charSetSigBit >= 0) {
DWORD charsetSigAdd = 1 << charSetSigBit;
nsFontMetricsOS2::gGlobalFonts[i].signature.fsCsb[0] |= charsetSigAdd;
}
return 1;
}
}
#endif
// XXX make this smarter: don't add font to list if we already have a font
// with the same font signature -- erik
if (nsFontMetricsOS2::gGlobalFontsCount == gGlobalFontsAlloc) {
int newSize = 2 * (gGlobalFontsAlloc ? gGlobalFontsAlloc : 1);
nsGlobalFont* newPointer = (nsGlobalFont*)
PR_Realloc(nsFontMetricsOS2::gGlobalFonts, newSize*sizeof(nsGlobalFont));
if (newPointer) {
nsFontMetricsOS2::gGlobalFonts = newPointer;
gGlobalFontsAlloc = newSize;
}
}
nsGlobalFont* font = &nsFontMetricsOS2::gGlobalFonts[nsFontMetricsOS2::gGlobalFontsCount++];
// PRUnichar name[FACESIZE*2];
// name[0] = 0;
// strcpy(name, pFontMetrics[i].szFamilyname);
font->name = new nsString();
font->name->AssignWithConversion(pFontMetrics[i].szFamilyname);
if (!font->name) {
nsFontMetricsOS2::gGlobalFontsCount--;
}
font->map = nsnull;
font->fontMetrics = pFontMetrics[i];
font->skip = 0;
nsFontMetricsOS2::gGlobalFonts[i].signature = pFontMetrics[i].fsDefn;
} /* endwhile */
gInitializedGlobalFonts = 1;
}
return gGlobalFonts;
}
// The Font Enumerator
nsFontEnumeratorOS2::nsFontEnumeratorOS2()
{
NS_INIT_REFCNT();
}
NS_IMPL_ISUPPORTS(nsFontEnumeratorOS2,
NS_GET_IID(nsIFontEnumerator));
static int gInitializedFontEnumerator = 0;
static int
InitializeFontEnumerator(void)
{
gInitializedFontEnumerator = 1;
if (!nsFontMetricsOS2::gGlobalFonts) {
HPS ps = ::WinGetScreenPS(HWND_DESKTOP);
if (!nsFontMetricsOS2::InitializeGlobalFonts(ps)) {
::WinReleasePS(ps);
return 0;
}
::WinReleasePS(ps);
}
return 1;
}
static int PR_CALLBACK
CompareFontNames(const void* aArg1, const void* aArg2, void* aClosure)
{
const PRUnichar* str1 = *((const PRUnichar**) aArg1);
const PRUnichar* str2 = *((const PRUnichar**) aArg2);
// XXX add nsICollation stuff
return nsCRT::strcmp(str1, str2);
}
NS_IMETHODIMP
nsFontEnumeratorOS2::EnumerateAllFonts(PRUint32* aCount, PRUnichar*** aResult)
{
if (aCount) {
*aCount = 0;
}
else {
return NS_ERROR_NULL_POINTER;
}
if (aResult) {
*aResult = nsnull;
}
else {
return NS_ERROR_NULL_POINTER;
}
if (!gInitializedFontEnumerator) {
if (!InitializeFontEnumerator()) {
return NS_ERROR_FAILURE;
}
}
PRUnichar** array = (PRUnichar**)
nsMemory::Alloc(nsFontMetricsOS2::gGlobalFontsCount * sizeof(PRUnichar*));
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (int i = 0; i < nsFontMetricsOS2::gGlobalFontsCount; i++) {
PRUnichar* str = nsFontMetricsOS2::gGlobalFonts[i].name->ToNewUnicode();
if (!str) {
for (i = i - 1; i >= 0; i--) {
nsMemory::Free(array[i]);
}
nsMemory::Free(array);
return NS_ERROR_OUT_OF_MEMORY;
}
array[i] = str;
}
NS_QuickSort(array, nsFontMetricsOS2::gGlobalFontsCount, sizeof(PRUnichar*),
CompareFontNames, nsnull);
*aCount = nsFontMetricsOS2::gGlobalFontsCount;
*aResult = array;
return NS_OK;
}
static int
SignatureMatchesLangGroup(USHORT* aSignature,
const char* aLangGroup)
{
return 1;
for (int i=0; i < eCharSet_COUNT; i++ ) {
if (aLangGroup[0] == gCharSetInfo[i].mLangGroup[0]) {
if (!strcmp(aLangGroup, gCharSetInfo[i].mLangGroup)) {
if (*aSignature & gCharSetInfo[i].mMask) {
return 1;
} /* endif */
} /* endif */
} /* endif */
} /* endfor */
return 0;
}
static int
FontMatchesGenericType(nsGlobalFont* aFont, const char* aGeneric,
const char* aLangGroup)
{
return 1;
if (!strcmp(aLangGroup, "ja")) {
return 1;
}
else if (!strcmp(aLangGroup, "zh-TW")) {
return 1;
}
else if (!strcmp(aLangGroup, "zh-CN")) {
return 1;
}
else if (!strcmp(aLangGroup, "ko")) {
return 1;
}
else if (!strcmp(aLangGroup, "th")) {
return 1;
}
else if (!strcmp(aLangGroup, "he")) {
return 1;
}
else if (!strcmp(aLangGroup, "ar")) {
return 1;
}
#ifdef OLDCODE
switch (aFont->logFont.lfPitchAndFamily & 0xF0) {
case FF_DONTCARE:
return 0;
case FF_ROMAN:
if (!strcmp(aGeneric, "serif")) {
return 1;
}
return 0;
case FF_SWISS:
if (!strcmp(aGeneric, "sans-serif")) {
return 1;
}
return 0;
case FF_MODERN:
if (!strcmp(aGeneric, "monospace")) {
return 1;
}
return 0;
case FF_SCRIPT:
if (!strcmp(aGeneric, "cursive")) {
return 1;
}
return 0;
case FF_DECORATIVE:
if (!strcmp(aGeneric, "fantasy")) {
return 1;
}
return 0;
default:
return 0;
}
#endif
return 0;
}
NS_IMETHODIMP
nsFontEnumeratorOS2::EnumerateFonts(const char* aLangGroup,
const char* aGeneric, PRUint32* aCount, PRUnichar*** aResult)
{
if ((!aLangGroup) || (!aGeneric)) {
return NS_ERROR_NULL_POINTER;
}
if (aCount) {
*aCount = 0;
}
else {
return NS_ERROR_NULL_POINTER;
}
if (aResult) {
*aResult = nsnull;
}
else {
return NS_ERROR_NULL_POINTER;
}
return EnumerateAllFonts(aCount, aResult);
if ((!strcmp(aLangGroup, "x-unicode")) ||
(!strcmp(aLangGroup, "x-user-def"))) {
}
if (!gInitializedFontEnumerator) {
if (!InitializeFontEnumerator()) {
return NS_ERROR_FAILURE;
}
}
PRUnichar** array = (PRUnichar**)
nsMemory::Alloc(nsFontMetricsOS2::gGlobalFontsCount * sizeof(PRUnichar*));
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
}
int j = 0;
for (int i = 0; i < nsFontMetricsOS2::gGlobalFontsCount; i++) {
if (SignatureMatchesLangGroup(&nsFontMetricsOS2::gGlobalFonts[i].signature,
aLangGroup) &&
FontMatchesGenericType(&nsFontMetricsOS2::gGlobalFonts[i], aGeneric,
aLangGroup)) {
PRUnichar* str = nsFontMetricsOS2::gGlobalFonts[i].name->ToNewUnicode();
if (!str) {
for (j = j - 1; j >= 0; j--) {
nsMemory::Free(array[j]);
}
nsMemory::Free(array);
return NS_ERROR_OUT_OF_MEMORY;
}
array[j] = str;
j++;
}
}
NS_QuickSort(array, j, sizeof(PRUnichar*), CompareFontNames, nsnull);
*aCount = j;
*aResult = array;
return NS_OK;
}

View File

@@ -31,6 +31,7 @@
#define _nsFontMetricsOS2_h
#include "nsIFontMetrics.h"
#include "nsIFontEnumerator.h"
#include "nsFont.h"
#include "nsCRT.h"
#include "nsIAtom.h"
@@ -51,6 +52,33 @@ struct nsFontHandleOS2
void SelectIntoPS( HPS hps, long lcid);
};
#ifndef FM_DEFN_LATIN1
#define FM_DEFN_LATIN1 0x0010 /* Base latin character set */
#define FM_DEFN_PC 0x0020 /* PC characters */
#define FM_DEFN_LATIN2 0x0040 /* Extended latin character set */
#define FM_DEFN_CYRILLIC 0x0080 /* Cyrillic character set */
#define FM_DEFN_HEBREW 0x0100 /* Base Hebrew characters */
#define FM_DEFN_GREEK 0x0200 /* Base Greek characters */
#define FM_DEFN_ARABIC 0x0400 /* Base Arabic characters */
#define FM_DEFN_UGLEXT 0x0800 /* Additional UGL chars */
#define FM_DEFN_KANA 0x1000 /* Katakana and hiragana chars */
#define FM_DEFN_THAI 0x2000 /* Thai characters */
#define FM_DEFN_UGL383 0x0070 /* Chars in OS/2 2.1 */
#define FM_DEFN_UGL504 0x00F0 /* Chars in OS/2 Warp 4 */
#define FM_DEFN_UGL767 0x0FF0 /* Chars in ATM fonts */
#define FM_DEFN_UGL1105 0x3FF0 /* Chars in bitmap fonts */
#endif
typedef struct nsGlobalFont
{
nsString* name;
FONTMETRICS fontMetrics;
PRUint32* map;
PRUint8 skip;
USHORT signature;
} nsGlobalFont;
class nsFontMetricsOS2 : public nsIFontMetrics
{
public:
@@ -88,6 +116,12 @@ class nsFontMetricsOS2 : public nsIFontMetrics
// for drawing text
PRUint32 GetDevMaxAscender() const { return mDevMaxAscent; }
nscoord GetSpaceWidth( nsIRenderingContext *aRContext);
static PLHashTable* gFontMaps;
static nsGlobalFont* gGlobalFonts;
static int gGlobalFontsCount;
static nsGlobalFont* InitializeGlobalFonts(HPS aPS);
protected:
nsresult RealizeFont();
@@ -120,4 +154,12 @@ class nsFontMetricsOS2 : public nsIFontMetrics
};
class nsFontEnumeratorOS2 : public nsIFontEnumerator
{
public:
nsFontEnumeratorOS2();
NS_DECL_ISUPPORTS
NS_DECL_NSIFONTENUMERATOR
};
#endif

View File

@@ -224,11 +224,9 @@ nsresult nsGfxFactoryOS2::CreateInstance(nsISupports *aOuter,
}
}
else if (mClassID.Equals(kCFontEnumerator)) {
/* OS2TODO
nsFontEnumeratorOS2* fe;
NS_NEWXPCOM(fe, nsFontEnumeratorOS2);
inst = (nsISupports *)fe;
*/
}
else if (mClassID.Equals(kCScreenManager)) {
NS_NEWXPCOM(inst, nsScreenManagerOS2);