зеркало из https://github.com/mozilla/gecko-dev.git
r=pedemonte, a=blizzard OK, here's the major font checkin. There's some debug code in here.
This commit is contained in:
Родитель
69cf2ac5bc
Коммит
37770f863b
|
@ -23,12 +23,20 @@
|
|||
// Revision by someone who *really* understands OS/2 fonts.
|
||||
|
||||
#include "nsGfxDefs.h"
|
||||
#include "nsDeviceContextOS2.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsICharsetConverterManager2.h"
|
||||
#include "nsICharRepresentable.h"
|
||||
#include "nsFontMetricsOS2.h"
|
||||
#include "nsString.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsQuickSort.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "prmem.h"
|
||||
#include "plhash.h"
|
||||
#include "prprf.h"
|
||||
|
||||
#undef USER_DEFINED
|
||||
#define USER_DEFINED "x-user-def"
|
||||
|
||||
enum nsCharSet
|
||||
{
|
||||
|
@ -59,26 +67,53 @@ struct nsCharSetInfo
|
|||
PRUint32* mMap;
|
||||
};
|
||||
|
||||
static PRUint32 gUserDefinedMap[2048];
|
||||
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
|
||||
static NS_DEFINE_IID(kIFontMetricsIID, NS_IFONT_METRICS_IID);
|
||||
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
|
||||
nsGlobalFont* nsFontMetricsOS2::gGlobalFonts = nsnull;
|
||||
static int gGlobalFontsAlloc = 0;
|
||||
int nsFontMetricsOS2::gGlobalFontsCount = 0;
|
||||
|
||||
PLHashTable* nsFontMetricsOS2::gFontMaps = nsnull;
|
||||
|
||||
PLHashTable* nsFontMetricsOS2::gFamilyNames = nsnull;
|
||||
|
||||
//-- Font weight
|
||||
PLHashTable* nsFontMetricsOS2::gFontWeights = nsnull;
|
||||
|
||||
#define NS_MAX_FONT_WEIGHT 900
|
||||
#define NS_MIN_FONT_WEIGHT 100
|
||||
|
||||
#undef CHAR_BUFFER_SIZE
|
||||
#define CHAR_BUFFER_SIZE 1024
|
||||
|
||||
static nsICharsetConverterManager2* gCharSetManager = nsnull;
|
||||
static nsIPref* gPref = nsnull;
|
||||
static nsIUnicodeEncoder* gUserDefinedConverter = nsnull;
|
||||
|
||||
static nsIAtom* gUserDefined = nsnull;
|
||||
|
||||
static int gFontMetricsOS2Count = 0;
|
||||
static int gInitialized = 0;
|
||||
|
||||
static PRUint32 gUserDefinedMap[2048];
|
||||
|
||||
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" },
|
||||
{ "GREEK", FM_DEFN_GREEK, 813, "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" },
|
||||
// { "GB2312", FM_DEFN_KANA, 936, "zh-CN" },
|
||||
{ "GB2312", FM_DEFN_KANA, 1386, "zh-CN" },
|
||||
{ "HANGEUL", FM_DEFN_KANA, 949, "ko" },
|
||||
{ "CHINESEBIG5", FM_DEFN_KANA, 950, "zh-TW" },
|
||||
{ "JOHAB", FM_DEFN_KANA, 1361, "ko-XXX", }
|
||||
|
@ -100,10 +135,52 @@ void nsFontHandleOS2::SelectIntoPS( HPS hps, long lcid)
|
|||
PMERROR("GpiSetCharSet");
|
||||
}
|
||||
|
||||
static void
|
||||
FreeGlobals(void)
|
||||
{
|
||||
// XXX complete this
|
||||
|
||||
gInitialized = 0;
|
||||
|
||||
NS_IF_RELEASE(gCharSetManager);
|
||||
NS_IF_RELEASE(gPref);
|
||||
NS_IF_RELEASE(gUserDefined);
|
||||
NS_IF_RELEASE(gUserDefinedConverter);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
InitGlobals(void)
|
||||
{
|
||||
nsServiceManager::GetService(kCharsetConverterManagerCID,
|
||||
NS_GET_IID(nsICharsetConverterManager2), (nsISupports**) &gCharSetManager);
|
||||
if (!gCharSetManager) {
|
||||
FreeGlobals();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsServiceManager::GetService(kPrefCID, NS_GET_IID(nsIPref),
|
||||
(nsISupports**) &gPref);
|
||||
if (!gPref) {
|
||||
FreeGlobals();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
gUserDefined = NS_NewAtom(USER_DEFINED);
|
||||
if (!gUserDefined) {
|
||||
FreeGlobals();
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
gInitialized = 1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsFontMetricsOS2::nsFontMetricsOS2()
|
||||
{
|
||||
// members are zeroed by new operator (hmm)
|
||||
NS_INIT_REFCNT();
|
||||
++gFontMetricsOS2Count;
|
||||
// members are zeroed by new operator (hmm) - yeah right
|
||||
mTriedAllGenerics = 0;
|
||||
}
|
||||
|
||||
nsFontMetricsOS2::~nsFontMetricsOS2()
|
||||
|
@ -112,16 +189,26 @@ nsFontMetricsOS2::~nsFontMetricsOS2()
|
|||
|
||||
delete mFont;
|
||||
delete mFontHandle;
|
||||
if (0 == --gFontMetricsOS2Count) {
|
||||
FreeGlobals();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS( nsFontMetricsOS2, nsIFontMetrics::GetIID())
|
||||
|
||||
nsresult nsFontMetricsOS2::Init( const nsFont &aFont, nsIAtom* aLangGroup, nsIDeviceContext *aContext)
|
||||
{
|
||||
nsresult res;
|
||||
if (!gInitialized) {
|
||||
res = InitGlobals();
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
mFont = new nsFont( aFont);
|
||||
mLangGroup = aLangGroup;
|
||||
// mIndexOfSubstituteFont = -1;
|
||||
mContext = (nsDeviceContextOS2 *) aContext;
|
||||
mDeviceContext = (nsDeviceContextOS2 *) aContext;
|
||||
nsresult rv = RealizeFont();
|
||||
return rv;
|
||||
}
|
||||
|
@ -131,73 +218,287 @@ nsresult nsFontMetricsOS2::Destroy()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Map CSS font names to something we can understand locally.
|
||||
// Some conversions are a bit dodgy (fantasy) but there's little option, I
|
||||
// guess.
|
||||
// Surely this should be in XP code somewhere?
|
||||
static void MapGenericFamilyToFont( const nsString &aGenericFamily,
|
||||
nsIDeviceContext *aDC,
|
||||
nsString &aFontFace)
|
||||
static PLHashNumber PR_CALLBACK
|
||||
HashKey(const void* aString)
|
||||
{
|
||||
// the CSS generic names (conversions from Nav for now)
|
||||
// XXX this need to check availability with the dc
|
||||
PRBool aliased;
|
||||
nsAutoString timesRoman; timesRoman.AssignWithConversion("Tms Rmn");
|
||||
nsAutoString helv; helv.AssignWithConversion("Helv");
|
||||
nsAutoString script; script.AssignWithConversion("Script");
|
||||
nsAutoString arial; arial.AssignWithConversion("Arial");
|
||||
nsAutoString courier; courier.AssignWithConversion("Courier");
|
||||
|
||||
if( aGenericFamily.EqualsIgnoreCase( "serif"))
|
||||
aDC->GetLocalFontName( timesRoman, aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "sans-serif"))
|
||||
aDC->GetLocalFontName( helv, aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "Helv")) // !!
|
||||
aDC->GetLocalFontName( script, aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "fantasy")) // !!
|
||||
aDC->GetLocalFontName( arial, aFontFace, aliased);
|
||||
else if( aGenericFamily.EqualsIgnoreCase( "monospace"))
|
||||
aDC->GetLocalFontName( courier, aFontFace, aliased);
|
||||
else
|
||||
aFontFace.Truncate();
|
||||
const nsString* str = (const nsString*)aString;
|
||||
return (PLHashNumber)
|
||||
nsCRT::HashCode(str->GetUnicode());
|
||||
}
|
||||
|
||||
struct FontEnumData
|
||||
static PRIntn PR_CALLBACK
|
||||
CompareKeys(const void* aStr1, const void* aStr2)
|
||||
{
|
||||
FontEnumData( nsIDeviceContext* aContext, char* aFaceName)
|
||||
: mContext( aContext), mFaceName( aFaceName)
|
||||
{}
|
||||
return nsCRT::strcmp(((const nsString*) aStr1)->GetUnicode(),
|
||||
((const nsString*) aStr2)->GetUnicode()) == 0;
|
||||
}
|
||||
nsFontOS2*
|
||||
nsFontMetricsOS2::LoadFont(HPS aPS, nsString* aName)
|
||||
{
|
||||
nsFontOS2* font = nsnull;
|
||||
char fontName[FACESIZE];
|
||||
WideCharToMultiByte(0, aName->GetUnicode(), aName->Length() + 1,
|
||||
fontName, sizeof(fontName));
|
||||
long lWant = 0;
|
||||
long lFonts = GpiQueryFonts( aPS, QF_PUBLIC | QF_PRIVATE,
|
||||
fontName, &lWant, 0, 0);
|
||||
if (lFonts > 0) {
|
||||
font = new nsFontOS2();
|
||||
aName->ToCString(font->mName, sizeof(font->mName));
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
nsIDeviceContext *mContext;
|
||||
char *mFaceName;
|
||||
|
||||
nsFontOS2*
|
||||
nsFontMetricsOS2::FindUserDefinedFont(HPS aPS, PRUnichar aChar)
|
||||
{
|
||||
if (mIsUserDefined) {
|
||||
nsFontOS2* font = LoadFont(aPS, &mUserDefined);
|
||||
#ifdef XP_OS2
|
||||
if (font) {
|
||||
#else
|
||||
if (font && FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
#endif
|
||||
return font;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
typedef struct nsFontFamilyName
|
||||
{
|
||||
char* mName;
|
||||
char* mWinName;
|
||||
} nsFontFamilyName;
|
||||
|
||||
static nsFontFamilyName gFamilyNameTable[] =
|
||||
{
|
||||
#ifdef MOZ_MATHML
|
||||
{ "-moz-math-text", "Times New Roman" },
|
||||
{ "-moz-math-symbol", "Symbol" },
|
||||
#endif
|
||||
{ "times", "Times New Roman" },
|
||||
{ "times roman", "Times New Roman" },
|
||||
{ "times new roman", "Times New Roman" },
|
||||
{ "arial", "Arial" },
|
||||
{ "helvetica", "Helv" },
|
||||
{ "courier", "Courier" },
|
||||
{ "courier new", "Courier New" },
|
||||
|
||||
{ nsnull, nsnull }
|
||||
};
|
||||
|
||||
// callback for each of the faces in the nsFont (use the first we can match)
|
||||
static PRBool FontEnumCallback( const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
PLHashTable*
|
||||
nsFontMetricsOS2::InitializeFamilyNames(void)
|
||||
{
|
||||
FontEnumData *data = (FontEnumData*)aData;
|
||||
PRBool rc = PR_TRUE;
|
||||
|
||||
if( aGeneric)
|
||||
{
|
||||
nsAutoString realFace;
|
||||
MapGenericFamilyToFont( aFamily, data->mContext, realFace);
|
||||
realFace.ToCString( data->mFaceName, FACESIZE);
|
||||
rc = PR_FALSE; // stop
|
||||
}
|
||||
else
|
||||
{
|
||||
nsAutoString realFace;
|
||||
PRBool aliased;
|
||||
data->mContext->GetLocalFontName( aFamily, realFace, aliased);
|
||||
if( aliased || (NS_OK == data->mContext->CheckFontExistence( realFace)))
|
||||
{
|
||||
realFace.ToCString(data->mFaceName, FACESIZE);
|
||||
rc = PR_FALSE; // stop
|
||||
static int gInitializedFamilyNames = 0;
|
||||
if (!gInitializedFamilyNames) {
|
||||
gInitializedFamilyNames = 1;
|
||||
gFamilyNames = PL_NewHashTable(0, HashKey, CompareKeys, nsnull, nsnull,
|
||||
nsnull);
|
||||
if (!gFamilyNames) {
|
||||
return nsnull;
|
||||
}
|
||||
nsFontFamilyName* f = gFamilyNameTable;
|
||||
while (f->mName) {
|
||||
nsString* name = new nsString;
|
||||
nsString* winName = new nsString;
|
||||
if (name && winName) {
|
||||
name->AssignWithConversion(f->mName);
|
||||
winName->AssignWithConversion(f->mWinName);
|
||||
PL_HashTableAdd(gFamilyNames, name, (void*) winName);
|
||||
}
|
||||
}
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
return gFamilyNames;
|
||||
}
|
||||
|
||||
nsFontOS2*
|
||||
nsFontMetricsOS2::FindLocalFont(HPS aPS, PRUnichar aChar)
|
||||
{
|
||||
if (!gFamilyNames) {
|
||||
if (!InitializeFamilyNames()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
while (mFontsIndex < mFonts.Count()) {
|
||||
if (mFontIsGeneric[mFontsIndex]) {
|
||||
return nsnull;
|
||||
}
|
||||
nsString* name = mFonts.StringAt(mFontsIndex++);
|
||||
nsAutoString low(*name);
|
||||
low.ToLowerCase();
|
||||
nsString* winName = (nsString*) PL_HashTableLookup(gFamilyNames, &low);
|
||||
if (!winName) {
|
||||
winName = name;
|
||||
}
|
||||
nsFontOS2* font = LoadFont(aPS, winName);
|
||||
#ifdef XP_OS2
|
||||
if (font) {
|
||||
#else
|
||||
if (font && FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
#endif
|
||||
return font;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsFontOS2*
|
||||
nsFontMetricsOS2::LoadGenericFont(HPS aPS, PRUnichar aChar, char** aName)
|
||||
{
|
||||
if (*aName) {
|
||||
int found = 0;
|
||||
int i;
|
||||
#ifndef XP_OS2
|
||||
for (i = 0; i < mLoadedFontsCount; i++) {
|
||||
nsFontOS2* font = mLoadedFonts[i];
|
||||
if (!strcmp(font->mName, *aName)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
nsMemory::Free(*aName);
|
||||
*aName = nsnull;
|
||||
return nsnull;
|
||||
}
|
||||
#endif
|
||||
PRUnichar name[FACESIZE] = { 0 };
|
||||
PRUnichar format[] = { '%', 's', 0 };
|
||||
PRUint32 n = nsTextFormatter::snprintf(name, FACESIZE, format, *aName);
|
||||
nsMemory::Free(*aName);
|
||||
*aName = nsnull;
|
||||
if (n && (n != (PRUint32) -1)) {
|
||||
nsAutoString fontName(name);
|
||||
|
||||
nsFontOS2* font = LoadFont(aPS, &fontName);
|
||||
#ifdef XP_OS2
|
||||
if (font) {
|
||||
#else
|
||||
if (font && FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
#endif
|
||||
return font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
typedef struct PrefEnumInfo
|
||||
{
|
||||
PRUnichar mChar;
|
||||
HPS mPS;
|
||||
nsFontOS2* mFont;
|
||||
nsFontMetricsOS2* mMetrics;
|
||||
} PrefEnumInfo;
|
||||
|
||||
void
|
||||
PrefEnumCallback(const char* aName, void* aClosure)
|
||||
{
|
||||
PrefEnumInfo* info = (PrefEnumInfo*) aClosure;
|
||||
if (info->mFont) {
|
||||
return;
|
||||
}
|
||||
PRUnichar ch = info->mChar;
|
||||
HPS ps = info->mPS;
|
||||
nsFontMetricsOS2* metrics = info->mMetrics;
|
||||
char* value = nsnull;
|
||||
gPref->CopyCharPref(aName, &value);
|
||||
nsFontOS2* font = metrics->LoadGenericFont(ps, ch, &value);
|
||||
if (font) {
|
||||
info->mFont = font;
|
||||
}
|
||||
else {
|
||||
gPref->CopyDefaultCharPref(aName, &value);
|
||||
font = metrics->LoadGenericFont(ps, ch, &value);
|
||||
if (font) {
|
||||
info->mFont = font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsFontOS2*
|
||||
nsFontMetricsOS2::FindGenericFont(HDC aPS, PRUnichar aChar)
|
||||
{
|
||||
if (mTriedAllGenerics) {
|
||||
return nsnull;
|
||||
}
|
||||
nsAutoString prefix;
|
||||
prefix.AssignWithConversion("font.name.");
|
||||
prefix.Append(*mGeneric);
|
||||
char name[128];
|
||||
if (mLangGroup) {
|
||||
nsAutoString pref = prefix;
|
||||
pref.AppendWithConversion('.');
|
||||
const PRUnichar* langGroup = nsnull;
|
||||
mLangGroup->GetUnicode(&langGroup);
|
||||
pref.Append(langGroup);
|
||||
pref.ToCString(name, sizeof(name));
|
||||
char* value = nsnull;
|
||||
gPref->CopyCharPref(name, &value);
|
||||
nsFontOS2* font = LoadGenericFont(aPS, aChar, &value);
|
||||
if (font) {
|
||||
return font;
|
||||
}
|
||||
gPref->CopyDefaultCharPref(name, &value);
|
||||
font = LoadGenericFont(aPS, aChar, &value);
|
||||
if (font) {
|
||||
return font;
|
||||
}
|
||||
}
|
||||
prefix.ToCString(name, sizeof(name));
|
||||
PrefEnumInfo info = { aChar, aPS, nsnull, this };
|
||||
gPref->EnumerateChildren(name, PrefEnumCallback, &info);
|
||||
if (info.mFont) {
|
||||
return info.mFont;
|
||||
}
|
||||
mTriedAllGenerics = 1;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsFontOS2*
|
||||
nsFontMetricsOS2::FindFont(HPS aPS, PRUnichar aChar)
|
||||
{
|
||||
nsFontOS2* font = FindUserDefinedFont(aPS, aChar);
|
||||
if (!font) {
|
||||
font = FindLocalFont(aPS, aChar);
|
||||
if (!font) {
|
||||
font = FindGenericFont(aPS, aChar);
|
||||
#ifndef XP_OS2
|
||||
if (!font) {
|
||||
font = FindGlobalFont(aPS, aChar);
|
||||
if (!font) {
|
||||
font = FindSubstituteFont(aPS, aChar);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
static PRBool
|
||||
FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
{
|
||||
nsFontMetricsOS2* metrics = (nsFontMetricsOS2*) aData;
|
||||
metrics->mFonts.AppendString(aFamily);
|
||||
metrics->mFontIsGeneric.AppendElement((void*) aGeneric);
|
||||
if (aGeneric) {
|
||||
metrics->mGeneric = metrics->mFonts.StringAt(metrics->mFonts.Count() - 1);
|
||||
return PR_FALSE; // stop
|
||||
}
|
||||
|
||||
return PR_TRUE; // don't stop
|
||||
}
|
||||
|
||||
// Current strategy wrt. image/outline fonts:
|
||||
|
@ -231,26 +532,99 @@ static PFONTMETRICS getMetrics( long &lFonts, PCSZ facename, HPS hps)
|
|||
|
||||
nsresult nsFontMetricsOS2::RealizeFont()
|
||||
{
|
||||
nsresult res;
|
||||
HWND win = NULL;
|
||||
HDC ps = NULL;
|
||||
|
||||
if (NULL != mDeviceContext->mDC){
|
||||
ps = mDeviceContext->mPS;
|
||||
} else {
|
||||
win = (HWND)mDeviceContext->mWidget;
|
||||
ps = ::WinGetPS(win);
|
||||
}
|
||||
|
||||
mFont->EnumerateFamilies(FontEnumCallback, this);
|
||||
PRUnichar* value = nsnull;
|
||||
if (!mGeneric) {
|
||||
gPref->CopyUnicharPref("font.default", &value);
|
||||
if (value) {
|
||||
mDefaultFont = value;
|
||||
nsMemory::Free(value);
|
||||
value = nsnull;
|
||||
}
|
||||
else {
|
||||
mDefaultFont.AssignWithConversion("serif");
|
||||
}
|
||||
mGeneric = &mDefaultFont;
|
||||
}
|
||||
|
||||
#ifndef XP_OS2
|
||||
if (mLangGroup.get() == gUserDefined) {
|
||||
if (!gUserDefinedConverter) {
|
||||
nsCOMPtr<nsIAtom> charset;
|
||||
res = gCharSetManager->GetCharsetAtom2("x-user-defined",
|
||||
getter_AddRefs(charset));
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = gCharSetManager->GetUnicodeEncoder(charset,
|
||||
&gUserDefinedConverter);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = gUserDefinedConverter->SetOutputErrorBehavior(
|
||||
gUserDefinedConverter->kOnError_Replace, nsnull, '?');
|
||||
nsCOMPtr<nsICharRepresentable> mapper =
|
||||
do_QueryInterface(gUserDefinedConverter);
|
||||
if (mapper) {
|
||||
res = mapper->FillInfo(gUserDefinedMap);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
nsCAutoString name("font.name.");
|
||||
name.AppendWithConversion(*mGeneric);
|
||||
name.Append('.');
|
||||
name.Append(USER_DEFINED);
|
||||
gPref->CopyUnicharPref(name.GetBuffer(), &value);
|
||||
if (value) {
|
||||
mUserDefined = value;
|
||||
nsMemory::Free(value);
|
||||
value = nsnull;
|
||||
mIsUserDefined = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsFontOS2* font = FindFont(ps, 'a');
|
||||
if (!font) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char szFamily[FACESIZE] = "";
|
||||
|
||||
strcpy(szFamily, font->mName);
|
||||
|
||||
delete font;
|
||||
|
||||
if (!strcmp(szFamily, "Verdana")) {
|
||||
return NS_ERROR_FAILURE;
|
||||
} /* endif */
|
||||
|
||||
nsFontHandleOS2 *fh = new nsFontHandleOS2;
|
||||
if (!fh)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// 1) Find family name
|
||||
char szFamily[ FACESIZE] = "";
|
||||
FontEnumData data( mContext, szFamily);
|
||||
mFont->EnumerateFamilies( FontEnumCallback, &data);
|
||||
|
||||
// sanity check - no way of telling whether we want a fixed or prop font..
|
||||
if( !szFamily[0])
|
||||
strcpy( szFamily, "System Proportional");
|
||||
|
||||
// 2) Get a representative PS for doing font queries into
|
||||
HPS hps;
|
||||
|
||||
if (NULL != mContext->mDC){
|
||||
hps = mContext->mPS;
|
||||
if (NULL != mDeviceContext->mDC){
|
||||
hps = mDeviceContext->mPS;
|
||||
} else {
|
||||
hps = WinGetPS((HWND)mContext->mWidget);
|
||||
hps = WinGetPS((HWND)mDeviceContext->mWidget);
|
||||
}
|
||||
|
||||
// 3) Work out what our options are wrt. image/outline, prefer image.
|
||||
|
@ -293,19 +667,32 @@ nsresult nsFontMetricsOS2::RealizeFont()
|
|||
// 6) Encoding
|
||||
// There doesn't seem to be any encoding stuff yet, so guess.
|
||||
// (XXX unicode hack; use same codepage as converter!)
|
||||
fh->fattrs.usCodePage = gModuleData.ulCodepage;
|
||||
char name[128];
|
||||
const PRUnichar* langGroup = nsnull;
|
||||
mLangGroup->GetUnicode(&langGroup);
|
||||
nsAutoString langName = langGroup;
|
||||
langName.ToCString(name, sizeof(name));
|
||||
for (int j=0; j < eCharSet_COUNT; j++ ) {
|
||||
if (name[0] == gCharSetInfo[j].mLangGroup[0]) {
|
||||
if (!strcmp(name, gCharSetInfo[j].mLangGroup)) {
|
||||
fh->fattrs.usCodePage = gCharSetInfo[j].mCodePage;
|
||||
mCodePage = gCharSetInfo[j].mCodePage;
|
||||
} /* endif */
|
||||
} /* endif */
|
||||
} /* endfor */
|
||||
// fh->fattrs.usCodePage = gModuleData.ulCodepage;
|
||||
|
||||
// 7) Find the point size for the font, and set up the charbox too
|
||||
float app2dev, app2twip, twip2dev;
|
||||
mContext->GetAppUnitsToDevUnits( app2dev);
|
||||
mContext->GetDevUnitsToTwips( app2twip);
|
||||
mContext->GetTwipsToDevUnits( twip2dev);
|
||||
mDeviceContext->GetAppUnitsToDevUnits( app2dev);
|
||||
mDeviceContext->GetDevUnitsToTwips( app2twip);
|
||||
mDeviceContext->GetTwipsToDevUnits( twip2dev);
|
||||
|
||||
// !! Windows wants to mply up here. I don't think I do. If fonts
|
||||
// !! ever begin to look `squished', try enabling the following code
|
||||
#if 0
|
||||
float scale;
|
||||
mContext->GetCanonicalPixelScale(scale);
|
||||
mDeviceContext->GetCanonicalPixelScale(scale);
|
||||
app2twip *= app2dev * scale;
|
||||
#else
|
||||
app2twip *= app2dev;
|
||||
|
@ -378,7 +765,7 @@ nsresult nsFontMetricsOS2::RealizeFont()
|
|||
GpiQueryFontMetrics( hps, sizeof fm, &fm);
|
||||
|
||||
float dev2app;
|
||||
mContext->GetDevUnitsToAppUnits( dev2app);
|
||||
mDeviceContext->GetDevUnitsToAppUnits( dev2app);
|
||||
|
||||
// PM includes the internal leading in the max ascender. So the max
|
||||
// ascender we tell raptor about should be lMaxAscent - lInternalLeading.
|
||||
|
@ -416,7 +803,7 @@ nsresult nsFontMetricsOS2::RealizeFont()
|
|||
GpiSetCharSet( hps, LCID_DEFAULT);
|
||||
if( !GpiDeleteSetId( hps, 1))
|
||||
PMERROR( "GpiDeleteSetID (FM)");
|
||||
if (NULL == mContext->mDC)
|
||||
if (NULL == mDeviceContext->mDC)
|
||||
WinReleasePS(hps);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -618,7 +1005,8 @@ nsFontMetricsOS2::InitializeGlobalFonts(HPS aPS)
|
|||
}
|
||||
}
|
||||
|
||||
nsGlobalFont* font = &nsFontMetricsOS2::gGlobalFonts[nsFontMetricsOS2::gGlobalFontsCount++];
|
||||
nsGlobalFont* font = &nsFontMetricsOS2::gGlobalFonts[nsFontMetricsOS2::gGlobalFontsCount];
|
||||
nsFontMetricsOS2::gGlobalFontsCount++;
|
||||
|
||||
// PRUnichar name[FACESIZE*2];
|
||||
// name[0] = 0;
|
||||
|
@ -627,6 +1015,7 @@ nsFontMetricsOS2::InitializeGlobalFonts(HPS aPS)
|
|||
font->name->AssignWithConversion(pFontMetrics[i].szFamilyname);
|
||||
if (!font->name) {
|
||||
nsFontMetricsOS2::gGlobalFontsCount--;
|
||||
continue;
|
||||
}
|
||||
font->map = nsnull;
|
||||
font->fontMetrics = pFontMetrics[i];
|
||||
|
@ -635,6 +1024,7 @@ nsFontMetricsOS2::InitializeGlobalFonts(HPS aPS)
|
|||
nsFontMetricsOS2::gGlobalFonts[i].signature = pFontMetrics[i].fsDefn;
|
||||
} /* endwhile */
|
||||
gInitializedGlobalFonts = 1;
|
||||
nsMemory::Free(pFontMetrics);
|
||||
}
|
||||
|
||||
return gGlobalFonts;
|
||||
|
@ -683,6 +1073,32 @@ CompareFontNames(const void* aArg1, const void* aArg2, void* aClosure)
|
|||
NS_IMETHODIMP
|
||||
nsFontEnumeratorOS2::EnumerateAllFonts(PRUint32* aCount, PRUnichar*** aResult)
|
||||
{
|
||||
#ifndef XP_OS2
|
||||
*aCount = 18;
|
||||
PRUnichar** newarray = (PRUnichar**)
|
||||
nsMemory::Alloc(18 * sizeof(PRUnichar*));
|
||||
newarray[0] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[1] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[2] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[3] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[4] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[5] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[6] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[7] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[8] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[9] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[10] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[11] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[12] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[13] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[14] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[15] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[16] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[17] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
*aResult = newarray;
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
if (aCount) {
|
||||
*aCount = 0;
|
||||
}
|
||||
|
@ -816,6 +1232,33 @@ NS_IMETHODIMP
|
|||
nsFontEnumeratorOS2::EnumerateFonts(const char* aLangGroup,
|
||||
const char* aGeneric, PRUint32* aCount, PRUnichar*** aResult)
|
||||
{
|
||||
#ifndef XP_OS2
|
||||
*aCount = 18;
|
||||
PRUnichar** newarray = (PRUnichar**)
|
||||
nsMemory::Alloc(18 * sizeof(PRUnichar*));
|
||||
newarray[0] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[1] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[2] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[3] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[4] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[5] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[6] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[7] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[8] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[9] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[10] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[11] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[12] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[13] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[14] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[15] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[16] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
newarray[17] = nsString(NS_ConvertASCIItoUCS2("Tms Rmn")).ToNewUnicode();
|
||||
*aResult = newarray;
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
|
||||
if ((!aLangGroup) || (!aGeneric)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
|
|
@ -30,16 +30,21 @@
|
|||
#ifndef _nsFontMetricsOS2_h
|
||||
#define _nsFontMetricsOS2_h
|
||||
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#include <os2.h>
|
||||
|
||||
#include "plhash.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIFontEnumerator.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUnitConversion.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCOMPtr.h" //HCT-M15
|
||||
|
||||
class nsIRenderingContext;
|
||||
class nsDeviceContextOS2;
|
||||
class nsString;
|
||||
#include "nsDeviceContextOS2.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
// An nsFontHandle is actually a pointer to one of these.
|
||||
// It knows how to select itself into a ps.
|
||||
|
@ -70,6 +75,13 @@ struct nsFontHandleOS2
|
|||
#define FM_DEFN_UGL1105 0x3FF0 /* Chars in bitmap fonts */
|
||||
#endif
|
||||
|
||||
class nsFontOS2
|
||||
{
|
||||
public:
|
||||
char mName[FACESIZE];
|
||||
};
|
||||
|
||||
|
||||
typedef struct nsGlobalFont
|
||||
{
|
||||
nsString* name;
|
||||
|
@ -113,6 +125,16 @@ class nsFontMetricsOS2 : public nsIFontMetrics
|
|||
NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup);
|
||||
NS_IMETHOD GetFontHandle( nsFontHandle &aHandle);
|
||||
|
||||
#ifndef XP_OS2
|
||||
virtual nsFontOS2* FindGlobalFont(HPS aPS, PRUnichar aChar);
|
||||
#endif
|
||||
virtual nsFontOS2* FindGenericFont(HPS aPS, PRUnichar aChar);
|
||||
virtual nsFontOS2* FindLocalFont(HPS aPS, PRUnichar aChar);
|
||||
virtual nsFontOS2* FindUserDefinedFont(HPS aPS, PRUnichar aChar);
|
||||
nsFontOS2* FindFont(HPS aPS, PRUnichar aChar);
|
||||
virtual nsFontOS2* LoadGenericFont(HPS aPS, PRUnichar aChar, char** aName);
|
||||
virtual nsFontOS2* LoadFont(HPS aPS, nsString* aName);
|
||||
|
||||
// for drawing text
|
||||
PRUint32 GetDevMaxAscender() const { return mDevMaxAscent; }
|
||||
nscoord GetSpaceWidth( nsIRenderingContext *aRContext);
|
||||
|
@ -122,6 +144,7 @@ class nsFontMetricsOS2 : public nsIFontMetrics
|
|||
static int gGlobalFontsCount;
|
||||
|
||||
static nsGlobalFont* InitializeGlobalFonts(HPS aPS);
|
||||
int mCodePage;
|
||||
|
||||
protected:
|
||||
nsresult RealizeFont();
|
||||
|
@ -148,10 +171,24 @@ class nsFontMetricsOS2 : public nsIFontMetrics
|
|||
PRUint32 mDevMaxAscent;
|
||||
|
||||
nsFontHandleOS2 *mFontHandle;
|
||||
nsDeviceContextOS2 *mContext; // sigh.. broken broken broken XP interfaces...
|
||||
nsDeviceContextOS2 *mDeviceContext;
|
||||
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
public:
|
||||
nsStringArray mFonts;
|
||||
PRUint16 mFontsIndex;
|
||||
nsVoidArray mFontIsGeneric;
|
||||
|
||||
nsAutoString mDefaultFont;
|
||||
nsString *mGeneric;
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
nsAutoString mUserDefined;
|
||||
|
||||
PRUint8 mTriedAllGenerics;
|
||||
PRUint8 mIsUserDefined;
|
||||
protected:
|
||||
static PLHashTable* InitializeFamilyNames(void);
|
||||
static PLHashTable* gFamilyNames;
|
||||
static PLHashTable* gFontWeights;
|
||||
};
|
||||
|
||||
class nsFontEnumeratorOS2 : public nsIFontEnumerator
|
||||
|
|
|
@ -39,6 +39,33 @@ void PMERROR(const char *str);
|
|||
class nsString;
|
||||
class nsIDeviceContext;
|
||||
|
||||
struct nsUconvInfo
|
||||
{
|
||||
char* mCharset;
|
||||
PRUint16 mCodePage;
|
||||
UconvObject mConverter;
|
||||
};
|
||||
|
||||
static nsUconvInfo gUconvInfo[15 /* eCharSet_COUNT from nsFontMetricsOS2.cpp */ ] =
|
||||
{
|
||||
{ "DEFAULT", 0, NULL },
|
||||
{ "ANSI", 1252, NULL },
|
||||
{ "EASTEUROPE", 1250, NULL },
|
||||
{ "RUSSIAN", 1251, NULL },
|
||||
{ "GREEK", 1253, NULL },
|
||||
{ "TURKISH", 1254, NULL },
|
||||
{ "HEBREW", 1255, NULL },
|
||||
{ "ARABIC", 1256, NULL },
|
||||
{ "BALTIC", 1257, NULL },
|
||||
{ "THAI", 874, NULL },
|
||||
{ "SHIFTJIS", 932, NULL },
|
||||
{ "GB2312", 936, NULL },
|
||||
{ "HANGEUL", 949, NULL },
|
||||
{ "CHINESEBIG5", 950, NULL },
|
||||
{ "JOHAB", 1361, NULL }
|
||||
};
|
||||
|
||||
|
||||
// Module data
|
||||
struct nsGfxModuleData
|
||||
{
|
||||
|
@ -49,25 +76,11 @@ struct nsGfxModuleData
|
|||
nsGfxModuleData();
|
||||
~nsGfxModuleData();
|
||||
|
||||
// XXX XXX XXX this is a hack copied from the widget library (where it's
|
||||
// not a hack but perfectly valid) until font-switching comes
|
||||
// on-line.
|
||||
// Unicode->local cp. conversions
|
||||
char *ConvertFromUcs( const PRUnichar *pText, ULONG ulLength, char *szBuffer, ULONG ulSize);
|
||||
char *ConvertFromUcs( const nsString &aStr, char *szBuffer, ULONG ulSize);
|
||||
// these methods use a single static buffer
|
||||
const char *ConvertFromUcs( const PRUnichar *pText, ULONG ulLength);
|
||||
const char *ConvertFromUcs( const nsString &aStr);
|
||||
|
||||
UconvObject converter;
|
||||
BOOL supplantConverter;
|
||||
PRUint32 renderingHints;
|
||||
ULONG ulCodepage;
|
||||
// XXX XXX XXX end hack
|
||||
|
||||
void Init();
|
||||
};
|
||||
|
||||
int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize );
|
||||
|
||||
extern nsGfxModuleData gModuleData;
|
||||
|
||||
#ifndef min
|
||||
|
|
|
@ -304,150 +304,63 @@ void nsGfxModuleData::Init()
|
|||
hpsScreen = WinGetScreenPS( HWND_DESKTOP);
|
||||
HDC hdc = GpiQueryDevice( hpsScreen);
|
||||
DevQueryCaps( hdc, CAPS_COLOR_BITCOUNT, 1, &lDisplayDepth);
|
||||
|
||||
// XXX XXX temp hack XXX XXX XXX
|
||||
converter = 0;
|
||||
supplantConverter = FALSE;
|
||||
if( !getenv( "MOZ_DONT_DRAW_UNICODE"))
|
||||
{
|
||||
ULONG ulDummy = 0;
|
||||
renderingHints = 0;
|
||||
DosQueryCp( 4, &ulCodepage, &ulDummy);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderingHints = NS_RENDERING_HINT_FAST_8BIT_TEXT;
|
||||
ulCodepage = 1004;
|
||||
}
|
||||
// XXX XXX end temp hack XXX XXX XXX
|
||||
}
|
||||
|
||||
nsGfxModuleData::~nsGfxModuleData()
|
||||
{
|
||||
// XXX XXX temp hack XXX XXX XXX
|
||||
if( converter)
|
||||
UniFreeUconvObject( converter);
|
||||
// XXX XXX end temp hack XXX XXX XXX
|
||||
/* Free any converters that were created */
|
||||
for (int i=0; i < 15 /* eCharSet_COUNT from nsFontMetricsOS2.cpp */ ; i++ ) {
|
||||
if (gUconvInfo[i].mConverter) {
|
||||
UniFreeUconvObject(gUconvInfo[i].mConverter);
|
||||
} /* endif */
|
||||
} /* endfor */
|
||||
|
||||
PrnTerminate();
|
||||
if( hModResources)
|
||||
DosFreeModule( hModResources);
|
||||
WinReleasePS( hpsScreen);
|
||||
PrnTerminate();
|
||||
if( hModResources)
|
||||
DosFreeModule( hModResources);
|
||||
WinReleasePS( hpsScreen);
|
||||
}
|
||||
|
||||
nsGfxModuleData gModuleData;
|
||||
|
||||
// XXX XXX XXX XXX Temp hack until font-switching comes on-line XXX XXX XXX XXX
|
||||
|
||||
// Conversion from unicode to appropriate codepage
|
||||
char *nsGfxModuleData::ConvertFromUcs( const PRUnichar *pText, ULONG ulLength,
|
||||
char *szBuffer, ULONG ulSize)
|
||||
int WideCharToMultiByte( int CodePage, const PRUnichar *pText, ULONG ulLength, char* szBuffer, ULONG ulSize )
|
||||
{
|
||||
if( supplantConverter)
|
||||
{
|
||||
// We couldn't create a converter for some reason, so do this 'by hand'.
|
||||
// Note this algorithm is fine for most of most western charsets, but
|
||||
// fails dismally for various glyphs, baltic, points east...
|
||||
ULONG ulCount = 0;
|
||||
char *szSave = szBuffer;
|
||||
while( *pText && ulCount < ulSize - 1) // (one for terminator)
|
||||
{
|
||||
*szBuffer = (char) *pText;
|
||||
szBuffer++;
|
||||
pText++;
|
||||
ulCount++;
|
||||
}
|
||||
UconvObject* pConverter = 0;
|
||||
/* Free any converters that were created */
|
||||
for (int i=0; i < 15 /* eCharSet_COUNT from nsFontMetricsOS2.cpp */ ; i++ ) {
|
||||
if (gUconvInfo[i].mCodePage == CodePage) {
|
||||
if (!gUconvInfo[i].mConverter) {
|
||||
UniChar codepage[20];
|
||||
int unirc = UniMapCpToUcsCp( CodePage, codepage, 20);
|
||||
UniCreateUconvObject( codepage, &gUconvInfo[i].mConverter);
|
||||
break;
|
||||
} /* endif */
|
||||
pConverter = &gUconvInfo[i].mConverter;
|
||||
} /* endif */
|
||||
} /* endfor */
|
||||
if (!pConverter) {
|
||||
pConverter = &gUconvInfo[0].mConverter;
|
||||
} /* endif */
|
||||
|
||||
// terminate string
|
||||
*szBuffer = '\0';
|
||||
UniChar *ucsString = (UniChar*) pText;
|
||||
size_t ucsLen = ulLength;
|
||||
size_t cplen = ulSize;
|
||||
size_t cSubs = 0;
|
||||
|
||||
return szSave;
|
||||
}
|
||||
char *tmp = szBuffer; // function alters the out pointer
|
||||
|
||||
if( !converter)
|
||||
{
|
||||
// Create a converter from unicode to a codepage which PM can display.
|
||||
UniChar codepage[20];
|
||||
int unirc = UniMapCpToUcsCp( 0, codepage, 20);
|
||||
if( unirc == ULS_SUCCESS)
|
||||
{
|
||||
unirc = UniCreateUconvObject( codepage, &converter);
|
||||
// XXX do we need to set substitution options here?
|
||||
}
|
||||
if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
supplantConverter = TRUE;
|
||||
renderingHints = NS_RENDERING_HINT_FAST_8BIT_TEXT;
|
||||
ulCodepage = 1004;
|
||||
printf( "Couldn't create gfx unicode converter.\n");
|
||||
return ConvertFromUcs( nsString(pText), szBuffer, ulSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Have converter, now get it to work...
|
||||
|
||||
UniChar *ucsString = (UniChar*) pText;
|
||||
size_t ucsLen = ulLength;
|
||||
size_t cplen = ulSize;
|
||||
size_t cSubs = 0;
|
||||
|
||||
char *tmp = szBuffer; // function alters the out pointer
|
||||
|
||||
int unirc = UniUconvFromUcs( converter, &ucsString, &ucsLen,
|
||||
int unirc = UniUconvFromUcs( *pConverter, &ucsString, &ucsLen,
|
||||
(void**) &tmp, &cplen, &cSubs);
|
||||
|
||||
if( unirc == UCONV_E2BIG) // k3w1
|
||||
{
|
||||
// terminate output string (truncating)
|
||||
*(szBuffer + ulSize - 1) = '\0';
|
||||
}
|
||||
else if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
printf( "UniUconvFromUcs failed, rc %X\n", unirc);
|
||||
supplantConverter = TRUE;
|
||||
szBuffer = ConvertFromUcs( nsString(pText), szBuffer, ulSize);
|
||||
supplantConverter = FALSE;
|
||||
}
|
||||
|
||||
return szBuffer;
|
||||
if( unirc == UCONV_E2BIG) // k3w1
|
||||
{
|
||||
// terminate output string (truncating)
|
||||
*(szBuffer + ulSize - 1) = '\0';
|
||||
}
|
||||
else if( unirc != ULS_SUCCESS)
|
||||
{
|
||||
printf("very bad");
|
||||
}
|
||||
return ulSize - cplen;
|
||||
}
|
||||
|
||||
char *nsGfxModuleData::ConvertFromUcs( const nsString &aString,
|
||||
char *szBuffer, ULONG ulSize)
|
||||
{
|
||||
char *szRet = 0;
|
||||
const PRUnichar *pUnicode = aString.GetUnicode();
|
||||
|
||||
if( pUnicode)
|
||||
szRet = ConvertFromUcs( pUnicode, aString.Length() + 1, szBuffer, ulSize);
|
||||
else
|
||||
szRet = aString.ToCString( szBuffer, ulSize);
|
||||
|
||||
return szRet;
|
||||
}
|
||||
|
||||
const char *nsGfxModuleData::ConvertFromUcs( const PRUnichar *pText, ULONG ulLength)
|
||||
{
|
||||
// This is probably okay; longer strings will be truncated but istr there's
|
||||
// a PM limit on things like windowtext
|
||||
// (which these routines are usually used for)
|
||||
|
||||
static char buffer[1024]; // XXX (multithread)
|
||||
*buffer = '\0';
|
||||
return ConvertFromUcs( pText, ulLength, buffer, 1024);
|
||||
}
|
||||
|
||||
const char *nsGfxModuleData::ConvertFromUcs( const nsString &aString)
|
||||
{
|
||||
const char *szRet = 0;
|
||||
const PRUnichar *pUnicode = aString.GetUnicode();
|
||||
|
||||
if( pUnicode)
|
||||
szRet = ConvertFromUcs( pUnicode, aString.Length() + 1);
|
||||
else
|
||||
szRet = aString.GetBuffer(); // hrm.
|
||||
|
||||
return szRet;
|
||||
}
|
||||
|
||||
// XXX XXX XXX XXX End Temp hack until font-switching comes on-line XXX XXX XXX
|
||||
|
|
|
@ -321,7 +321,8 @@ nsresult nsRenderingContextOS2::CommonInit()
|
|||
::GpiSelectPalette(mSurface->mPS, (HPAL)palInfo.palette);
|
||||
::WinRealizePalette((HWND)mDCOwner->GetNativeData(NS_NATIVE_WINDOW),mSurface->mPS, &cclr);
|
||||
} else if (!palInfo.isPaletteDevice && palInfo.palette) {
|
||||
GpiCreateLogColorTable( mSurface->mPS, LCOL_RESET | LCOL_PURECOLOR,
|
||||
// GpiCreateLogColorTable( mSurface->mPS, LCOL_RESET | LCOL_PURECOLOR,
|
||||
GpiCreateLogColorTable( mSurface->mPS, LCOL_RESET,
|
||||
LCOLF_CONSECRGB, 0,
|
||||
palInfo.sizePalette, (PLONG) palInfo.palette);
|
||||
free(palInfo.palette);
|
||||
|
@ -329,7 +330,8 @@ nsresult nsRenderingContextOS2::CommonInit()
|
|||
}
|
||||
else
|
||||
{
|
||||
GpiCreateLogColorTable( mSurface->mPS, LCOL_PURECOLOR,
|
||||
// GpiCreateLogColorTable( mSurface->mPS, LCOL_PURECOLOR,
|
||||
GpiCreateLogColorTable( mSurface->mPS, 0,
|
||||
LCOLF_RGB, 0, 0, 0);
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -888,8 +890,10 @@ void nsRenderingContextOS2::SetupDrawingColor( BOOL bForce)
|
|||
areaBundle.lBackColor = 0x00FFFFFF; //OS2TODO
|
||||
lineBundle.lBackColor = 0x00FFFFFF;
|
||||
|
||||
areaBundle.usMixMode = FM_LEAVEALONE;
|
||||
areaBundle.usBackMixMode = BM_LEAVEALONE;
|
||||
// areaBundle.usMixMode = FM_LEAVEALONE;
|
||||
// areaBundle.usBackMixMode = BM_LEAVEALONE;
|
||||
areaBundle.usMixMode = FM_OVERPAINT;
|
||||
areaBundle.usBackMixMode = BM_OVERPAINT;
|
||||
|
||||
|
||||
lLineFlags = lLineFlags | LBB_BACK_COLOR ;
|
||||
|
@ -1226,8 +1230,11 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled,
|
|||
|
||||
NS_IMETHODIMP nsRenderingContextOS2::GetHints(PRUint32& aResult)
|
||||
{
|
||||
aResult = gModuleData.renderingHints;
|
||||
return NS_OK;
|
||||
PRUint32 result = 0;
|
||||
|
||||
aResult = result;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsRenderingContextOS2::DrawString( const char *aString,
|
||||
|
@ -1259,15 +1266,16 @@ nsresult nsRenderingContextOS2::DrawString( const char *aString,
|
|||
|
||||
GpiMove( mSurface->mPS, &ptl);
|
||||
|
||||
PRUint32 lLength = aLength;
|
||||
// GpiCharString has a max length of 512 chars at a time...
|
||||
while( aLength)
|
||||
while( lLength)
|
||||
{
|
||||
ULONG thislen = min( aLength, 512);
|
||||
ULONG thislen = min( lLength, 512);
|
||||
GpiCharStringPos( mSurface->mPS, nsnull,
|
||||
aSpacing == nsnull ? 0 : CHS_VECTOR,
|
||||
thislen, (PCH)aString,
|
||||
aSpacing == nsnull ? nsnull : (PLONG) dx0);
|
||||
aLength -= thislen;
|
||||
lLength -= thislen;
|
||||
aString += thislen;
|
||||
dx0 += thislen;
|
||||
}
|
||||
|
@ -1280,9 +1288,11 @@ nsresult nsRenderingContextOS2::DrawString( const PRUnichar *aString, PRUint32 a
|
|||
PRInt32 aFontID,
|
||||
const nscoord* aSpacing)
|
||||
{
|
||||
// XXX unicode hack XXX
|
||||
return DrawString( gModuleData.ConvertFromUcs( aString, aLength),
|
||||
aLength, aX, aY, aSpacing);
|
||||
char buf[1024];
|
||||
|
||||
int newLength = WideCharToMultiByte( ((nsFontMetricsOS2*)mFontMetrics)->mCodePage, aString, aLength, buf, sizeof(buf));
|
||||
|
||||
return DrawString( buf, newLength, aX, aY, aSpacing);
|
||||
}
|
||||
|
||||
nsresult nsRenderingContextOS2::DrawString( const nsString& aString,
|
||||
|
@ -1341,17 +1351,18 @@ NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const char* aString,
|
|||
nscoord &aWidth)
|
||||
{
|
||||
PRUint32 sum = 0;
|
||||
PRUint32 lLength = aLength;
|
||||
|
||||
SetupFontAndColor(); // select font
|
||||
|
||||
POINTL ptls[ 4];
|
||||
|
||||
while( aLength) // max data to gpi function is 512 chars.
|
||||
while( lLength) // max data to gpi function is 512 chars.
|
||||
{
|
||||
ULONG thislen = min( aLength, 512);
|
||||
ULONG thislen = min( lLength, 512);
|
||||
GpiQueryTextBox( mSurface->mPS, thislen, (PCH) aString, 4, ptls);
|
||||
sum += ptls[ TXTBOX_TOPRIGHT].x;
|
||||
aLength -= thislen;
|
||||
lLength -= thislen;
|
||||
aString += thislen;
|
||||
}
|
||||
|
||||
|
@ -1365,9 +1376,12 @@ NS_IMETHODIMP nsRenderingContextOS2::GetWidth( const PRUnichar *aString,
|
|||
nscoord &aWidth,
|
||||
PRInt32 *aFontID)
|
||||
{
|
||||
// XXX unicode hack XXX
|
||||
return GetWidth( gModuleData.ConvertFromUcs( aString, aLength),
|
||||
aLength, aWidth);
|
||||
nsresult temp;
|
||||
char buf[1024];
|
||||
|
||||
int newLength = WideCharToMultiByte( ((nsFontMetricsOS2*)mFontMetrics)->mCodePage, aString, aLength, buf, sizeof(buf));
|
||||
temp = GetWidth( buf, newLength, aWidth);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// Image drawing: just proxy on to the image object, so no worries yet.
|
||||
|
|
Загрузка…
Ссылка в новой задаче