зеркало из https://github.com/mozilla/gecko-dev.git
changed nsFont to contain face lists in name
This commit is contained in:
Родитель
79c1b74a7a
Коммит
4c0e289be4
|
@ -432,7 +432,7 @@ nsresult nsDeviceContextMac :: LoadIconImage(PRInt32 aId, nsIImage*& aImage)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextMac :: CheckFontExistence(const char * aFontName)
|
||||
nsresult nsDeviceContextMac :: CheckFontExistence(const nsString& aFontName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
virtual PRUint32 ConvertPixel(nscolor aColor);
|
||||
|
||||
NS_IMETHOD LoadIconImage(PRInt32 aId, nsIImage*& aImage);
|
||||
NS_IMETHOD CheckFontExistence(const char * aFontName);
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFontName);
|
||||
NS_IMETHOD CreateILColorSpace(IL_ColorSpace*& aColorSpace);
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
|
||||
|
|
|
@ -346,10 +346,10 @@ nsDrawingSurface nsDeviceContextUnix :: GetDrawingSurface()
|
|||
|
||||
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextUnix :: CheckFontExistence(const char * aFontName)
|
||||
NS_IMETHODIMP nsDeviceContextUnix :: CheckFontExistence(const nsString& aFontName)
|
||||
{
|
||||
char **fnames = nsnull;
|
||||
PRInt32 namelen = strlen(aFontName) + 1;
|
||||
PRInt32 namelen = aFontName.Length() + 1;
|
||||
char *wildstring = (char *)PR_Malloc(namelen + 200);
|
||||
PRInt32 dpi = NSToIntRound(GetTwipsToDevUnits() * 1440);
|
||||
Display *dpy = XtDisplay((Widget)GetNativeWidget());
|
||||
|
@ -365,9 +365,11 @@ NS_IMETHODIMP nsDeviceContextUnix :: CheckFontExistence(const char * aFontName)
|
|||
else
|
||||
dpi = 100;
|
||||
|
||||
char* fontName = aFontName.ToNewCString();
|
||||
PR_snprintf(wildstring, namelen + 200,
|
||||
"*-%s-*-*-normal--*-*-%d-%d-*-*-*",
|
||||
aFontName, dpi, dpi);
|
||||
fontName, dpi, dpi);
|
||||
delete [] fontName;
|
||||
|
||||
fnames = ::XListFontsWithInfo(dpy, wildstring, 1, &numnames, &fonts);
|
||||
|
||||
|
|
|
@ -58,8 +58,13 @@ nsresult nsFontMetricsUnix :: Init(const nsFont& aFont, nsIDeviceContext* aCX)
|
|||
{
|
||||
NS_ASSERTION(!(nsnull == aCX), "attempt to init fontmetrics with null device context");
|
||||
|
||||
nsAutoString firstFace;
|
||||
if (NS_OK != aCX->FirstExistingFont(aFont, firstFace)) {
|
||||
aFont.GetFirstFamily(firstFace);
|
||||
}
|
||||
|
||||
char **fnames = nsnull;
|
||||
PRInt32 namelen = aFont.name.Length() + 1;
|
||||
PRInt32 namelen = firstFace.Length() + 1;
|
||||
char *wildstring = (char *)PR_Malloc((namelen << 1) + 200);
|
||||
int numnames = 0;
|
||||
char altitalicization = 0;
|
||||
|
@ -74,7 +79,7 @@ nsresult nsFontMetricsUnix :: Init(const nsFont& aFont, nsIDeviceContext* aCX)
|
|||
mContext = aCX;
|
||||
mFontHandle = nsnull;
|
||||
|
||||
aFont.name.ToCString(wildstring, namelen);
|
||||
firstFace.ToCString(wildstring, namelen);
|
||||
|
||||
if (abs(dpi - 75) < abs(dpi - 100))
|
||||
dpi = 75;
|
||||
|
@ -116,11 +121,12 @@ nsresult nsFontMetricsUnix :: Init(const nsFont& aFont, nsIDeviceContext* aCX)
|
|||
fnames = ::XListFontsWithInfo(dpy, &wildstring[namelen + 1], 200, &numnames, &fonts);
|
||||
}
|
||||
|
||||
|
||||
if (numnames <= 0)
|
||||
{
|
||||
//we were not able to match the font name at all...
|
||||
|
||||
const char *newname = MapFamilyToFont(aFont.name);
|
||||
const char *newname = firstFace.ToNewCString();
|
||||
|
||||
PR_snprintf(&wildstring[namelen + 1], namelen + 200,
|
||||
"*-%s-%s-%c-normal--*-*-%d-%d-*-*-*",
|
||||
|
@ -141,6 +147,8 @@ nsresult nsFontMetricsUnix :: Init(const nsFont& aFont, nsIDeviceContext* aCX)
|
|||
|
||||
fnames = ::XListFontsWithInfo(dpy, &wildstring[namelen + 1], 200, &numnames, &fonts);
|
||||
}
|
||||
|
||||
delete [] newname;
|
||||
}
|
||||
|
||||
if (numnames > 0)
|
||||
|
@ -355,43 +363,30 @@ nsFontHandle nsFontMetricsUnix :: GetFontHandle()
|
|||
}
|
||||
|
||||
|
||||
// XXX this function is a hack; the only logical font names we should
|
||||
// support are the one used by css.
|
||||
const char* nsFontMetricsUnix::MapFamilyToFont(const nsString& aLogicalFontName)
|
||||
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsIDeviceContext* aDC,
|
||||
nsString& aFontFace)
|
||||
{
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Times Roman")) {
|
||||
return "times";
|
||||
// the CSS generic names (conversions from Nav for now)
|
||||
// XXX this need to check availability with the dc
|
||||
PRBool aliased;
|
||||
if (aGenericFamily.EqualsIgnoreCase("serif")) {
|
||||
aDC->GetLocalFontName("times", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Times New Roman")) {
|
||||
return "times";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("sans-serif")) {
|
||||
aDC->GetLocalFontName("helvetica", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Unicode")) {
|
||||
return "Bitstream Cyberbit";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("cursive")) {
|
||||
aDC->GetLocalFontName("script", aFontFace, aliased); // XXX ???
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Courier New")) {
|
||||
return "courier";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("fantasy")) {
|
||||
aDC->GetLocalFontName("helvetica", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Arial")) {
|
||||
return "helvetica";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("monospace")) {
|
||||
aDC->GetLocalFontName("fixed", aFontFace, aliased);
|
||||
}
|
||||
|
||||
// the CSS generic names
|
||||
if (aLogicalFontName.EqualsIgnoreCase("serif")) {
|
||||
return "times";
|
||||
else {
|
||||
aFontFace.Truncate();
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("sans-serif")) {
|
||||
return "helvetica";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("cursive")) {
|
||||
// return "XXX";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("fantasy")) {
|
||||
// return "XXX";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("monospace")) {
|
||||
return "fixed";
|
||||
}
|
||||
return "helvetica";/* XXX for now */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ public:
|
|||
|
||||
protected:
|
||||
void RealizeFont();
|
||||
static const char* MapFamilyToFont(const nsString& aLogicalFontName);
|
||||
|
||||
protected:
|
||||
void QueryFont();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsIFontCache.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsImageNet.h"
|
||||
|
@ -45,8 +46,16 @@ DeviceContextImpl :: DeviceContextImpl()
|
|||
for (PRInt32 i = 0; i < NS_NUMBER_OF_ICONS; i++) {
|
||||
mIcons[i] = nsnull;
|
||||
}
|
||||
mFontAliasTable = nsnull;
|
||||
}
|
||||
|
||||
static PRBool DeleteValue(nsHashKey* aKey, void* aValue)
|
||||
{
|
||||
delete ((nsString*)aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
DeviceContextImpl :: ~DeviceContextImpl()
|
||||
{
|
||||
NS_IF_RELEASE(mFontCache);
|
||||
|
@ -62,6 +71,11 @@ DeviceContextImpl :: ~DeviceContextImpl()
|
|||
for (PRInt32 i = 0; i < NS_NUMBER_OF_ICONS; i++) {
|
||||
NS_IF_RELEASE(mIcons[i]);
|
||||
}
|
||||
|
||||
if (nsnull != mFontAliasTable) {
|
||||
mFontAliasTable->Enumerate(DeleteValue);
|
||||
delete mFontAliasTable;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult DeviceContextImpl :: Init(nsNativeWidget aWidget)
|
||||
|
@ -319,6 +333,161 @@ NS_IMETHODIMP DeviceContextImpl::LoadIconImage(PRInt32 aId, nsIImage*& aImage)
|
|||
return result;
|
||||
}
|
||||
|
||||
struct FontEnumData {
|
||||
FontEnumData(nsIDeviceContext* aDC, nsString& aFaceName)
|
||||
: mDC(aDC), mFaceName(aFaceName)
|
||||
{}
|
||||
nsIDeviceContext* mDC;
|
||||
nsString& mFaceName;
|
||||
};
|
||||
|
||||
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
{
|
||||
FontEnumData* data = (FontEnumData*)aData;
|
||||
// XXX for now, all generic fonts are presumed to exist
|
||||
// we may want to actually check if there's an installed conversion
|
||||
if (aGeneric) {
|
||||
data->mFaceName = aFamily;
|
||||
return PR_FALSE; // found one, stop.
|
||||
}
|
||||
else {
|
||||
nsAutoString local;
|
||||
PRBool aliased;
|
||||
data->mDC->GetLocalFontName(aFamily, local, aliased);
|
||||
if (aliased || (NS_OK == data->mDC->CheckFontExistence(local))) {
|
||||
data->mFaceName = local;
|
||||
return PR_FALSE; // found one, stop.
|
||||
}
|
||||
}
|
||||
return PR_TRUE; // didn't exist, continue looking
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DeviceContextImpl::FirstExistingFont(const nsFont& aFont, nsString& aFaceName)
|
||||
{
|
||||
if (aFont.EnumerateFamilies(FontEnumCallback, &FontEnumData(this, aFaceName))) {
|
||||
return NS_ERROR_FAILURE; // ran out
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class StringKey: public nsHashKey
|
||||
{
|
||||
public:
|
||||
StringKey(const nsString& aString)
|
||||
: mString(aString)
|
||||
{}
|
||||
|
||||
virtual PRUint32 HashValue(void) const;
|
||||
virtual PRBool Equals(const nsHashKey *aKey) const;
|
||||
virtual nsHashKey *Clone(void) const;
|
||||
|
||||
nsAutoString mString;
|
||||
};
|
||||
|
||||
PRUint32 StringKey::HashValue(void) const
|
||||
{
|
||||
PRUint32 hash = 0;
|
||||
PRUnichar* string = mString;
|
||||
PRUnichar ch;
|
||||
while ((ch = *string++) != 0) {
|
||||
// FYI: hash = hash*37 + ch
|
||||
ch = nsCRT::ToUpper(ch);
|
||||
hash = ((hash << 5) + (hash << 2) + hash) + ch;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
PRBool StringKey::Equals(const nsHashKey *aKey) const
|
||||
{
|
||||
return mString.EqualsIgnoreCase(((StringKey*)aKey)->mString);
|
||||
}
|
||||
|
||||
nsHashKey* StringKey::Clone(void) const
|
||||
{
|
||||
return new StringKey(mString);
|
||||
}
|
||||
|
||||
|
||||
nsresult DeviceContextImpl::CreateFontAliasTable()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (nsnull == mFontAliasTable) {
|
||||
mFontAliasTable = new nsHashtable();
|
||||
if (nsnull != mFontAliasTable) {
|
||||
AliasFont("Times", "Times New Roman", "Times Roman");
|
||||
AliasFont("Times Roman", "Times New Roman", "Times");
|
||||
AliasFont("Times New Roman", "Times Roman", "Times");
|
||||
AliasFont("Arial", "Helvetica", "");
|
||||
AliasFont("Helvetica", "Arial", "");
|
||||
AliasFont("Courier", "Courier New", "");
|
||||
AliasFont("Courier New", "Courier", "");
|
||||
AliasFont("Unicode", "Bitstream Cyberbit", ""); // XXX ????
|
||||
}
|
||||
else {
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult DeviceContextImpl::AliasFont(const nsString& aFont,
|
||||
const nsString& aAlias, const nsString& aAltAlias)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (nsnull != mFontAliasTable) {
|
||||
if (NS_OK != CheckFontExistence(aFont)) {
|
||||
if (NS_OK == CheckFontExistence(aAlias)) {
|
||||
nsString* entry = aAlias.ToNewString();
|
||||
if (nsnull != entry) {
|
||||
mFontAliasTable->Put(&StringKey(aFont), entry);
|
||||
}
|
||||
else {
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else if ((aAltAlias.Length() > 0) && (NS_OK == CheckFontExistence(aAltAlias))) {
|
||||
nsString* entry = aAltAlias.ToNewString();
|
||||
if (nsnull != entry) {
|
||||
mFontAliasTable->Put(&StringKey(aFont), entry);
|
||||
}
|
||||
else {
|
||||
result = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = NS_ERROR_FAILURE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DeviceContextImpl::GetLocalFontName(const nsString& aFaceName, nsString& aLocalName,
|
||||
PRBool& aAliased)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (nsnull == mFontAliasTable) {
|
||||
result = CreateFontAliasTable();
|
||||
}
|
||||
|
||||
if (nsnull != mFontAliasTable) {
|
||||
const nsString* alias = (const nsString*)mFontAliasTable->Get(&StringKey(aFaceName));
|
||||
if (nsnull != alias) {
|
||||
aLocalName = *alias;
|
||||
aAliased = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
aLocalName = aFaceName;
|
||||
aAliased = PR_FALSE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP DeviceContextImpl::CreateILColorSpace(IL_ColorSpace*& aColorSpace)
|
||||
{
|
||||
IL_RGBBits colorRGBBits;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libimg.h"
|
||||
|
||||
class nsIImageRequest;
|
||||
class nsHashtable;
|
||||
|
||||
class DeviceContextImpl : public nsIDeviceContext
|
||||
{
|
||||
|
@ -62,6 +63,11 @@ public:
|
|||
|
||||
NS_IMETHOD LoadIconImage(PRInt32 aId, nsIImage*& aImage);
|
||||
|
||||
NS_IMETHOD FirstExistingFont(const nsFont& aFont, nsString& aFaceName);
|
||||
|
||||
NS_IMETHOD GetLocalFontName(const nsString& aFaceName, nsString& aLocalName,
|
||||
PRBool& aAliased);
|
||||
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
|
||||
NS_IMETHOD CreateILColorSpace(IL_ColorSpace*& aColorSpace);
|
||||
|
@ -72,6 +78,9 @@ protected:
|
|||
nsresult CreateFontCache();
|
||||
void SetGammaTable(PRUint8 * aTable, float aCurrentGamma, float aNewGamma);
|
||||
nsresult CreateIconILGroupContext();
|
||||
virtual nsresult CreateFontAliasTable();
|
||||
nsresult AliasFont(const nsString& aFont,
|
||||
const nsString& aAlias, const nsString& aAltAlias);
|
||||
|
||||
float mTwipsToPixels;
|
||||
float mPixelsToTwips;
|
||||
|
@ -84,6 +93,7 @@ protected:
|
|||
nsNativeWidget mWidget;
|
||||
IL_GroupContext* mIconImageGroup;
|
||||
nsIImageRequest* mIcons[NS_NUMBER_OF_ICONS];
|
||||
nsHashtable* mFontAliasTable;
|
||||
};
|
||||
|
||||
#endif /* nsDeviceContext_h___ */
|
||||
|
|
|
@ -78,3 +78,93 @@ nsFont& nsFont::operator=(const nsFont& aOther)
|
|||
size = aOther.size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
static PRBool IsGenericFontFamily(const nsString& aFamily)
|
||||
{
|
||||
return PRBool(aFamily.EqualsIgnoreCase("serif") ||
|
||||
aFamily.EqualsIgnoreCase("sans-serif") ||
|
||||
aFamily.EqualsIgnoreCase("cursive") ||
|
||||
aFamily.EqualsIgnoreCase("fantasy") ||
|
||||
aFamily.EqualsIgnoreCase("monospace"));
|
||||
}
|
||||
|
||||
const PRUnichar kNullCh = PRUnichar('\0');
|
||||
const PRUnichar kSingleQuote = PRUnichar('\'');
|
||||
const PRUnichar kDoubleQuote = PRUnichar('\"');
|
||||
const PRUnichar kComma = PRUnichar(',');
|
||||
|
||||
PRBool nsFont::EnumerateFamilies(nsFontFamilyEnumFunc aFunc, void* aData) const
|
||||
{
|
||||
PRBool running = PR_TRUE;
|
||||
|
||||
nsAutoString familyList(name); // copy to work buffer
|
||||
nsAutoString familyStr;
|
||||
|
||||
familyList.Append(kNullCh); // put an extra null at the end
|
||||
|
||||
PRUnichar* start = (PRUnichar*)familyList;
|
||||
PRUnichar* end = start;
|
||||
|
||||
while (running && (kNullCh != *start)) {
|
||||
PRBool quoted = PR_FALSE;
|
||||
PRBool generic = PR_FALSE;
|
||||
|
||||
while ((kNullCh != *start) && nsString::IsSpace(*start)) { // skip leading space
|
||||
start++;
|
||||
}
|
||||
|
||||
if ((kSingleQuote == *start) || (kDoubleQuote == *start)) { // quoted string
|
||||
PRUnichar quote = *start++;
|
||||
|
||||
end = start;
|
||||
while (kNullCh != *end) {
|
||||
if (quote == *end) { // found closing quote
|
||||
*end++ = kNullCh; // end string here
|
||||
while ((kNullCh != *end) && (kComma != *end)) { // keep going until comma
|
||||
end++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
end++;
|
||||
}
|
||||
}
|
||||
else { // non-quoted string or ended
|
||||
end = start;
|
||||
|
||||
while ((kNullCh != *end) && (kComma != *end)) { // look for comma
|
||||
end++;
|
||||
}
|
||||
*end = kNullCh; // end string here
|
||||
}
|
||||
|
||||
familyStr = start;
|
||||
|
||||
if (PR_FALSE == quoted) {
|
||||
familyStr.CompressWhitespace(PR_FALSE, PR_TRUE);
|
||||
if (0 < familyStr.Length()) {
|
||||
generic = IsGenericFontFamily(familyStr);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < familyStr.Length()) {
|
||||
running = (*aFunc)(familyStr, generic, aData);
|
||||
}
|
||||
|
||||
start = ++end;
|
||||
}
|
||||
|
||||
return running;
|
||||
}
|
||||
|
||||
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
{
|
||||
*((nsString*)aData) = aFamily;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsFont::GetFirstFamily(nsString& aFamily) const
|
||||
{
|
||||
EnumerateFamilies(FontEnumCallback, &aFamily);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
// XXX we need a method to enumerate all of the possible fonts on the
|
||||
// system across family, weight, style, size, etc. But not here!
|
||||
|
||||
// Enumerator callback function. Return PR_FALSE to stop
|
||||
typedef PRBool (*nsFontFamilyEnumFunc)(const nsString& aFamily, PRBool aGeneric, void *aData);
|
||||
|
||||
// Font structure.
|
||||
struct NS_GFX nsFont {
|
||||
// The family name of the font
|
||||
|
@ -67,6 +70,13 @@ struct NS_GFX nsFont {
|
|||
PRBool Equals(const nsFont& aOther) const ;
|
||||
|
||||
nsFont& operator=(const nsFont& aOther);
|
||||
|
||||
// Utility method to interpret name string
|
||||
// enumerates all families specified by this font only
|
||||
// returns PR_TRUE if completed, PF_FALSE if stopped
|
||||
// enclosing quotes will be removed, and whitespace compressed (as needed)
|
||||
PRBool EnumerateFamilies(nsFontFamilyEnumFunc aFunc, void* aData) const;
|
||||
void GetFirstFamily(nsString& aFamily) const;
|
||||
};
|
||||
|
||||
#define NS_FONT_STYLE_NORMAL 0
|
||||
|
|
|
@ -117,7 +117,11 @@ public:
|
|||
* @param aFontName character string of font face name
|
||||
* @return NS_OK if font is available, else font is unavailable
|
||||
*/
|
||||
NS_IMETHOD CheckFontExistence(const char * aFontName) = 0;
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFaceName) = 0;
|
||||
NS_IMETHOD FirstExistingFont(const nsFont& aFont, nsString& aFaceName) = 0;
|
||||
|
||||
NS_IMETHOD GetLocalFontName(const nsString& aFaceName, nsString& aLocalName,
|
||||
PRBool& aAliased) = 0;
|
||||
|
||||
/**
|
||||
* Return the bit depth of the device.
|
||||
|
|
|
@ -84,13 +84,15 @@ int CALLBACK fontcallback(ENUMLOGFONT FAR *lpelf, NEWTEXTMETRIC FAR *lpntm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextWin :: CheckFontExistence(const char * aFontName)
|
||||
NS_IMETHODIMP nsDeviceContextWin :: CheckFontExistence(const nsString& aFontName)
|
||||
{
|
||||
HWND hwnd = (HWND)GetNativeWidget();
|
||||
HDC hdc = ::GetDC(hwnd);
|
||||
PRBool isthere = PR_FALSE;
|
||||
|
||||
::EnumFontFamilies(hdc, aFontName, (FONTENUMPROC)fontcallback, (LPARAM)&isthere);
|
||||
char fontName[LF_FACESIZE];
|
||||
aFontName.ToCString(fontName, LF_FACESIZE);
|
||||
::EnumFontFamilies(hdc, fontName, (FONTENUMPROC)fontcallback, (LPARAM)&isthere);
|
||||
|
||||
::ReleaseDC(hwnd, hdc);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
//in the device context for re-use.
|
||||
virtual nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext);
|
||||
|
||||
NS_IMETHOD CheckFontExistence(const char * aFontName);
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFontName);
|
||||
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
|
||||
|
|
|
@ -95,46 +95,61 @@ nsresult nsFontMetricsWin :: Init(const nsFont& aFont, nsIDeviceContext *aContex
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX this function is a hack; the only logical font names we should
|
||||
// support are the one used by css.
|
||||
const char* nsFontMetricsWin::MapFamilyToFont(const nsString& aLogicalFontName)
|
||||
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsIDeviceContext* aDC,
|
||||
nsString& aFontFace)
|
||||
{
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Times Roman")) {
|
||||
return "Times New Roman";
|
||||
// the CSS generic names (conversions from Nav for now)
|
||||
// XXX this need to check availability with the dc
|
||||
PRBool aliased;
|
||||
if (aGenericFamily.EqualsIgnoreCase("serif")) {
|
||||
aDC->GetLocalFontName("Times New Roman", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Times")) {
|
||||
return "Times New Roman";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("sans-serif")) {
|
||||
aDC->GetLocalFontName("Arial", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Unicode")) {
|
||||
return "Bitstream Cyberbit";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("cursive")) {
|
||||
aDC->GetLocalFontName("Script", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Courier")) {
|
||||
return "Courier New";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("fantasy")) {
|
||||
aDC->GetLocalFontName("Arial", aFontFace, aliased);
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("Courier New")) {
|
||||
return "Courier New";
|
||||
else if (aGenericFamily.EqualsIgnoreCase("monospace")) {
|
||||
aDC->GetLocalFontName("Courier New", aFontFace, aliased);
|
||||
}
|
||||
else {
|
||||
aFontFace.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
// the CSS generic names
|
||||
if (aLogicalFontName.EqualsIgnoreCase("serif")) {
|
||||
return "Times New Roman";
|
||||
struct FontEnumData {
|
||||
FontEnumData(nsIDeviceContext* aContext, TCHAR* aFaceName)
|
||||
{
|
||||
mContext = aContext;
|
||||
mFaceName = aFaceName;
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("sans-serif")) {
|
||||
return "Arial";
|
||||
nsIDeviceContext* mContext;
|
||||
TCHAR* mFaceName;
|
||||
};
|
||||
|
||||
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
{
|
||||
FontEnumData* data = (FontEnumData*)aData;
|
||||
if (aGeneric) {
|
||||
nsAutoString realFace;
|
||||
MapGenericFamilyToFont(aFamily, data->mContext, realFace);
|
||||
realFace.ToCString(data->mFaceName, LF_FACESIZE);
|
||||
return PR_FALSE; // stop
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("cursive")) {
|
||||
// return "XXX";
|
||||
else {
|
||||
nsAutoString realFace;
|
||||
PRBool aliased;
|
||||
data->mContext->GetLocalFontName(aFamily, realFace, aliased);
|
||||
if (aliased || (NS_OK == data->mContext->CheckFontExistence(realFace))) {
|
||||
realFace.ToCString(data->mFaceName, LF_FACESIZE);
|
||||
return PR_FALSE; // stop
|
||||
}
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("fantasy")) {
|
||||
// return "XXX";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("monospace")) {
|
||||
return "Courier New";
|
||||
}
|
||||
if (aLogicalFontName.EqualsIgnoreCase("desdemona")) {
|
||||
return "Desdemona";
|
||||
}
|
||||
return "Arial";/* XXX for now */
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsFontMetricsWin::RealizeFont(nsIDeviceContext *aContext)
|
||||
|
@ -166,9 +181,9 @@ void nsFontMetricsWin::RealizeFont(nsIDeviceContext *aContext)
|
|||
// round font size off to floor point size to be windows compatible
|
||||
// logFont.lfHeight = - NSToIntRound(rounded * app2dev); // this is proper (windows) rounding
|
||||
logFont.lfHeight = - LONG(rounded * app2dev); // this floor rounding is to make ours compatible with Nav 4.0
|
||||
strncpy(logFont.lfFaceName,
|
||||
MapFamilyToFont(mFont->name),
|
||||
LF_FACESIZE);
|
||||
|
||||
logFont.lfFaceName[0] = '\0';
|
||||
mFont->EnumerateFamilies(FontEnumCallback, &FontEnumData(aContext, logFont.lfFaceName));
|
||||
|
||||
// Create font handle from font spec
|
||||
mFontHandle = ::CreateFontIndirect(&logFont);
|
||||
|
|
|
@ -61,7 +61,6 @@ public:
|
|||
|
||||
protected:
|
||||
void RealizeFont(nsIDeviceContext *aContext);
|
||||
static const char* MapFamilyToFont(const nsString& aLogicalFontName);
|
||||
|
||||
nsFont *mFont;
|
||||
nscoord mCharWidths[256];
|
||||
|
|
|
@ -432,7 +432,7 @@ nsresult nsDeviceContextMac :: LoadIconImage(PRInt32 aId, nsIImage*& aImage)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult nsDeviceContextMac :: CheckFontExistence(const char * aFontName)
|
||||
nsresult nsDeviceContextMac :: CheckFontExistence(const nsString& aFontName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
virtual PRUint32 ConvertPixel(nscolor aColor);
|
||||
|
||||
NS_IMETHOD LoadIconImage(PRInt32 aId, nsIImage*& aImage);
|
||||
NS_IMETHOD CheckFontExistence(const char * aFontName);
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFontName);
|
||||
NS_IMETHOD CreateILColorSpace(IL_ColorSpace*& aColorSpace);
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче