When there are fonts with multiple foundry names, pick the best font based upon widget, height & available size.

Thanks to Brian Stell <bstell@netscape.com> & Roland Mainz <Roland.Mainz@informatik.med.uni-giessen.de> for the patch.
Bug #94327 r=katakai sr=kin
This commit is contained in:
seawood%netscape.com 2001-12-03 04:18:26 +00:00
Родитель 581f35a9c1
Коммит bf97a88f70
2 изменённых файлов: 439 добавлений и 245 удалений

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

@ -232,7 +232,8 @@ static nsIUnicodeEncoder* gUserDefinedConverter = nsnull;
static nsHashtable* gAliases = nsnull;
static nsHashtable* gCharSetMaps = nsnull;
static nsHashtable* gFamilies = nsnull;
static nsHashtable* gNodes = nsnull;
static nsHashtable* gFFRENodes = nsnull;
static nsHashtable* gAFRENodes = nsnull;
// gCachedFFRESearches holds the "already looked up"
// FFRE (Foundry Family Registry Encoding) font searches
static nsHashtable* gCachedFFRESearches = nsnull;
@ -764,10 +765,15 @@ FreeGlobals(void)
delete gCachedFFRESearches;
gCachedFFRESearches = nsnull;
}
if (gNodes) {
gNodes->Reset(FreeNode, nsnull);
delete gNodes;
gNodes = nsnull;
if (gFFRENodes) {
gFFRENodes->Reset(FreeNode, nsnull);
delete gFFRENodes;
gFFRENodes = nsnull;
}
if (gAFRENodes) {
gAFRENodes->Reset(FreeNode, nsnull);
delete gAFRENodes;
gAFRENodes = nsnull;
}
NS_IF_RELEASE(gPref);
if (gSpecialCharSets) {
@ -920,8 +926,13 @@ InitGlobals(void)
SIZE_FONT_PRINTF(("gBitmapUndersize = %g", gBitmapUndersize));
}
gNodes = new nsHashtable();
if (!gNodes) {
gFFRENodes = new nsHashtable();
if (!gFFRENodes) {
FreeGlobals();
return NS_ERROR_OUT_OF_MEMORY;
}
gAFRENodes = new nsHashtable();
if (!gAFRENodes) {
FreeGlobals();
return NS_ERROR_OUT_OF_MEMORY;
}
@ -2730,7 +2741,11 @@ nsFontMetricsGTK::PickASizeAndLoad(nsFontStretch* aStretch,
// if we do not have the correct size
// check if we can use a scaled font
if ((mPixelSize != bitmap_size) && (aStretch->mScalable)) {
// (when the size of a hand tuned font is close to the desired size
// favor it over outline scaled font)
if (( (bitmap_size < mPixelSize-(mPixelSize/10))
|| (bitmap_size > mPixelSize+(mPixelSize/10)))
&& (aStretch->mScalable)) {
// if we have an outline font then use that
// if it is allowed to be closer than the bitmap
if (aStretch->mOutlineScaled) {
@ -3281,8 +3296,133 @@ SetFontLangGroupInfo(nsFontCharSetMap* aCharSetMap)
}
}
static nsFontStyle*
NodeGetStyle(nsFontNode* aNode, int aStyleIndex)
{
nsFontStyle* style = aNode->mStyles[aStyleIndex];
if (!style) {
style = new nsFontStyle;
if (!style) {
return nsnull;
}
aNode->mStyles[aStyleIndex] = style;
}
return style;
}
static nsFontWeight*
NodeGetWeight(nsFontStyle* aStyle, int aWeightIndex)
{
nsFontWeight* weight = aStyle->mWeights[aWeightIndex];
if (!weight) {
weight = new nsFontWeight;
if (!weight) {
return nsnull;
}
aStyle->mWeights[aWeightIndex] = weight;
}
return weight;
}
static nsFontStretch*
NodeGetStretch(nsFontWeight* aWeight, int aStretchIndex)
{
nsFontStretch* stretch = aWeight->mStretches[aStretchIndex];
if (!stretch) {
stretch = new nsFontStretch;
if (!stretch) {
return nsnull;
}
aWeight->mStretches[aStretchIndex] = stretch;
}
return stretch;
}
static PRBool
NodeAddScalable(nsFontStretch* aStretch, PRBool aOutlineScaled,
const char *aDashFoundry, const char *aFamily,
const char *aWeight, const char * aSlant,
const char *aWidth, const char *aStyle,
const char *aSpacing, const char *aCharSet)
{
// if we have both an outline scaled font and a bitmap
// scaled font pick the outline scaled font
if ((aStretch->mScalable) && (!aStretch->mOutlineScaled)
&& (aOutlineScaled)) {
PR_smprintf_free(aStretch->mScalable);
aStretch->mScalable = nsnull;
}
if (!aStretch->mScalable) {
aStretch->mOutlineScaled = aOutlineScaled;
if (aOutlineScaled) {
aStretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-0-0-%s-*-%s",
aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle,
aSpacing, aCharSet);
if (!aStretch->mScalable)
return PR_FALSE;
}
else {
aStretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-*-*-%s-*-%s",
aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle,
aSpacing, aCharSet);
if (!aStretch->mScalable)
return PR_FALSE;
}
}
return PR_TRUE;
}
static PRBool
NodeAddSize(nsFontStretch* aStretch, int aSize, const char *aName,
nsFontCharSetInfo* aCharSetInfo)
{
PRBool haveSize = PR_FALSE;
if (aStretch->mSizesCount) {
nsFontGTK** end = &aStretch->mSizes[aStretch->mSizesCount];
nsFontGTK** s;
for (s = aStretch->mSizes; s < end; s++) {
if ((*s)->mSize == aSize) {
haveSize = PR_TRUE;
break;
}
}
}
if (!haveSize) {
if (aStretch->mSizesCount == aStretch->mSizesAlloc) {
int newSize = 2 * (aStretch->mSizesAlloc ? aStretch->mSizesAlloc : 1);
nsFontGTK** newSizes = new nsFontGTK*[newSize];
if (!newSizes)
return PR_FALSE;
for (int j = aStretch->mSizesAlloc - 1; j >= 0; j--) {
newSizes[j] = aStretch->mSizes[j];
}
aStretch->mSizesAlloc = newSize;
delete [] aStretch->mSizes;
aStretch->mSizes = newSizes;
}
char* copy = PR_smprintf("%s", aName);
if (!copy) {
return PR_FALSE;
}
nsFontGTK* size = new nsFontGTKNormal();
if (!size) {
return PR_FALSE;
}
aStretch->mSizes[aStretch->mSizesCount++] = size;
size->mName = copy;
// size->mFont is initialized in the constructor
size->mSize = aSize;
size->mBaselineAdjust = 0;
size->mCCMap = nsnull;
size->mCharSetInfo = aCharSetInfo;
}
return PR_TRUE;
}
static void
GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
GetFontNames(const char* aPattern, PRBool aAnyFoundry, nsFontNodeArray* aNodes)
{
#ifdef NS_FONT_DEBUG_CALL_TRACE
if (gDebug & NS_FONT_DEBUG_CALL_TRACE) {
@ -3291,6 +3431,14 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
#endif
nsCAutoString previousNodeName;
nsHashtable* node_hash;
if (aAnyFoundry) {
NS_ASSERTION(aPattern[1] == '*', "invalid 'anyFoundry' pattern");
node_hash = gAFRENodes;
}
else {
node_hash = gFFRENodes;
}
/*
* We do not use XListFontsWithInfo here, because it is very expensive.
@ -3400,6 +3548,18 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
FIND_FIELD(averageWidth);
if (averageWidth[0] == '0') {
scalable = 1;
/* Workaround for bug 103159 ("sorting fonts by foundry names cause font
* size of css ignored in some cases").
* Hardcoded font ban until bug 104075 ("need X font banning") has been
* implemented. See http://bugzilla.mozilla.org/show_bug.cgi?id=94327#c34
* for additional comments...
*/
#ifndef ENABLE_X_FONT_BANNING
// skip 'mysterious' and 'spurious' cases like
// -adobe-times-medium-r-normal--17-120-100-100-p-0-iso8859-9
if (pixelSize[0] != '0' || pointSize[0] != 0 )
continue;
#endif /* ENABLE_X_FONT_BANNING */
}
char* charSetName = p; // CHARSET_REGISTRY & CHARSET_ENCODING
if (!*charSetName) {
@ -3431,22 +3591,27 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
SetCharsetLangGroup(charSetInfo);
SetFontLangGroupInfo(charSetMap);
nsCAutoString nodeName(foundry);
nsCAutoString nodeName;
if (aAnyFoundry)
nodeName.Assign('*');
else
nodeName.Assign(foundry);
nodeName.Append('-');
nodeName.Append(familyName);
nodeName.Append('-');
nodeName.Append(charSetName);
nsCStringKey key(nodeName);
nsFontNode* node = (nsFontNode*) gNodes->Get(&key);
nsFontNode* node = (nsFontNode*) node_hash->Get(&key);
if (!node) {
node = new nsFontNode;
if (!node) {
continue;
}
gNodes->Put(&key, node);
node_hash->Put(&key, node);
node->mName = nodeName;
node->mCharSetInfo = charSetInfo;
}
int found = 0;
if (nodeName == previousNodeName) {
found = 1;
@ -3473,14 +3638,9 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
styleIndex = NS_FONT_STYLE_NORMAL;
break;
}
nsFontStyle* style = node->mStyles[styleIndex];
if (!style) {
style = new nsFontStyle;
if (!style) {
continue;
}
node->mStyles[styleIndex] = style;
}
nsFontStyle* style = NodeGetStyle(node, styleIndex);
if (!style)
continue;
nsCStringKey weightKey(weightName);
int weightNumber = NS_PTR_TO_INT32(gWeights->Get(&weightKey));
@ -3491,14 +3651,9 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
weightNumber = NS_FONT_WEIGHT_NORMAL;
}
int weightIndex = WEIGHT_INDEX(weightNumber);
nsFontWeight* weight = style->mWeights[weightIndex];
if (!weight) {
weight = new nsFontWeight;
if (!weight) {
continue;
}
style->mWeights[weightIndex] = weight;
}
nsFontWeight* weight = NodeGetWeight(style, weightIndex);
if (!weight)
continue;
nsCStringKey setWidthKey(setWidth);
int stretchIndex = NS_PTR_TO_INT32(gStretches->Get(&setWidthKey));
@ -3509,68 +3664,16 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
stretchIndex = 5;
}
stretchIndex--;
nsFontStretch* stretch = weight->mStretches[stretchIndex];
if (!stretch) {
stretch = new nsFontStretch;
if (!stretch) {
continue;
}
weight->mStretches[stretchIndex] = stretch;
}
if (scalable) {
// if we have both an outline scaled font and a bitmap
// scaled font pick the outline scaled font
if ((stretch->mScalable) && (!stretch->mOutlineScaled)
&& (outline_scaled)) {
PR_smprintf_free(stretch->mScalable);
stretch->mScalable = nsnull;
}
if (!stretch->mScalable) {
stretch->mOutlineScaled = outline_scaled;
if (outline_scaled) {
stretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-0-0-%s-*-%s",
name, familyName, weightName, slant, setWidth, addStyle,
spacing, charSetName);
}
else {
stretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-*-*-%s-*-%s",
name, familyName, weightName, slant, setWidth, addStyle,
spacing, charSetName);
}
}
nsFontStretch* stretch = NodeGetStretch(weight, stretchIndex);
if (!stretch)
continue;
if (scalable) {
if (!NodeAddScalable(stretch, outline_scaled, name, familyName,
weightName, slant, setWidth, addStyle, spacing, charSetName))
continue;
}
int pixels = atoi(pixelSize);
if (stretch->mSizesCount) {
nsFontGTK** end = &stretch->mSizes[stretch->mSizesCount];
nsFontGTK** s;
for (s = stretch->mSizes; s < end; s++) {
if ((*s)->mSize == pixels) {
break;
}
}
if (s != end) {
continue;
}
}
if (stretch->mSizesCount == stretch->mSizesAlloc) {
int newSize = 2 * (stretch->mSizesAlloc ? stretch->mSizesAlloc : 1);
nsFontGTK** newPointer = new nsFontGTK*[newSize];
if (newPointer) {
for (int j = stretch->mSizesAlloc - 1; j >= 0; j--) {
newPointer[j] = stretch->mSizes[j];
}
stretch->mSizesAlloc = newSize;
delete [] stretch->mSizes;
stretch->mSizes = newPointer;
}
else {
continue;
}
}
p = name;
while (p < charSetName) {
if (!*p) {
@ -3578,21 +3681,10 @@ GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
}
p++;
}
char* copy = PR_smprintf("%s", name);
if (!copy) {
int pixels = atoi(pixelSize);
if (!NodeAddSize(stretch, pixels, name, charSetInfo))
continue;
}
nsFontGTK* size = new nsFontGTKNormal();
if (!size) {
continue;
}
stretch->mSizes[stretch->mSizesCount++] = size;
size->mName = copy;
// size->mFont is initialized in the constructor
size->mSize = pixels;
size->mBaselineAdjust = 0;
size->mCCMap = nsnull;
size->mCharSetInfo = charSetInfo;
}
XFreeFontNames(list);
@ -3611,7 +3703,9 @@ GetAllFontNames(void)
if (!gGlobalList) {
return NS_ERROR_OUT_OF_MEMORY;
}
GetFontNames("-*", gGlobalList);
/* Using "-*" instead of the full-qualified "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
* because it's faster and "smarter" - see bug 34242 for details. */
GetFontNames("-*", PR_FALSE, gGlobalList);
}
return NS_OK;
@ -3628,7 +3722,7 @@ FindFamily(nsCString* aName)
char pattern[256];
PR_snprintf(pattern, sizeof(pattern), "-*-%s-*-*-*-*-*-*-*-*-*-*-*-*",
aName->get());
GetFontNames(pattern, &family->mNodes);
GetFontNames(pattern, PR_TRUE, &family->mNodes);
gFamilies->Put(&key, family);
}
}
@ -3707,7 +3801,9 @@ nsFontMetricsGTK::TryNodes(nsAWritableCString &aFFREName, PRUnichar aChar)
{
FIND_FONT_PRINTF((" TryNodes aFFREName = %s",
PromiseFlatCString(aFFREName).get()));
nsCStringKey key(PromiseFlatCString(aFFREName).get());
const char *FFREName = PromiseFlatCString(aFFREName).get();
nsCStringKey key(FFREName);
PRBool anyFoundry = (FFREName[0] == '*');
nsFontNodeArray* nodes = (nsFontNodeArray*) gCachedFFRESearches->Get(&key);
if (!nodes) {
nsCAutoString pattern;
@ -3715,7 +3811,7 @@ nsFontMetricsGTK::TryNodes(nsAWritableCString &aFFREName, PRUnichar aChar)
nodes = new nsFontNodeArray;
if (!nodes)
return nsnull;
GetFontNames(pattern.get(), nodes);
GetFontNames(pattern.get(), anyFoundry, nodes);
gCachedFFRESearches->Put(&key, nodes);
}
int i, cnt = nodes->Count();
@ -3739,17 +3835,16 @@ nsFontMetricsGTK::TryNode(nsCString* aName, PRUnichar aChar)
nsFontGTK* font;
nsCStringKey key(*aName);
nsFontNode* node = (nsFontNode*) gNodes->Get(&key);
nsFontNode* node = (nsFontNode*) gFFRENodes->Get(&key);
if (!node) {
nsCAutoString pattern;
FFREToXLFDPattern(*aName, pattern);
nsFontNodeArray nodes;
GetFontNames(pattern.get(), &nodes);
// no need to call gNodes->Put() since GetFontNames already did
GetFontNames(pattern.get(), PR_FALSE, &nodes);
// no need to call gFFRENodes->Put() since GetFontNames already did
if (nodes.Count() > 0) {
// XXX This assertion may be spurious; you can have more than
// -*-courier-iso8859-1 font, for example, from different
// foundries.
// This assertion is not spurious; when searching for an FFRE
// like -*-courier-iso8859-1 TryNodes should be called not TryNode
NS_ASSERTION((nodes.Count() == 1), "unexpected number of nodes");
node = nodes.GetElement(0);
}
@ -3759,7 +3854,7 @@ nsFontMetricsGTK::TryNode(nsCString* aName, PRUnichar aChar)
if (!node) {
return nsnull;
}
gNodes->Put(&key, node);
gFFRENodes->Put(&key, node);
node->mDummy = 1;
}
}
@ -4288,10 +4383,10 @@ nsFontMetricsGTK::FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCStr
}
// look for a font with this charset (registry-encoding) & char
//
nsCAutoString ffreName("");
nsCAutoString ffreName;
if(aName) {
// if aName was specified so call TryNode() not TryNodes()
ffreName.Append(*aName);
ffreName.Assign(*aName);
FFRESubstituteCharset(ffreName, charSetMap->mName);
FIND_FONT_PRINTF((" %s ffre = %s", charSetMap->mName, ffreName.get()));
if(aName->First() == '*') {
@ -4303,7 +4398,7 @@ nsFontMetricsGTK::FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCStr
NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char");
} else {
// no name was specified so call TryNodes() for this charset
ffreName.Append("*-*-*-*");
ffreName.Assign("*-*-*-*");
FFRESubstituteCharset(ffreName, charSetMap->mName);
FIND_FONT_PRINTF((" %s ffre = %s", charSetMap->mName, ffreName.get()));
font = TryNodes(ffreName, aChar);

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

@ -60,6 +60,7 @@
#include "nsAWritableString.h"
#include "nsXPIDLString.h"
#include <stdlib.h>
#include <errno.h>
#include <X11/Xatom.h>
#ifdef USE_XPRINT
#include <X11/extensions/Print.h>
@ -208,7 +209,8 @@ static nsIUnicodeEncoder* gUserDefinedConverter = nsnull;
static nsHashtable* gAliases = nsnull;
static nsHashtable* gCharSetMaps = nsnull;
static nsHashtable* gFamilies = nsnull;
static nsHashtable* gNodes = nsnull;
static nsHashtable* gFFRENodes = nsnull;
static nsHashtable* gAFRENodes = nsnull;
/* gCachedFFRESearches holds the "already looked up"
FFRE (Foundry Family Registry Encoding) font searches */
static nsHashtable* gCachedFFRESearches = nsnull;
@ -725,10 +727,16 @@ nsFontMetricsXlib::FreeGlobals(void)
gCachedFFRESearches = nsnull;
}
if (gNodes) {
gNodes->Reset(FreeNode, nsnull);
delete gNodes;
gNodes = nsnull;
if (gFFRENodes) {
gFFRENodes->Reset(FreeNode, nsnull);
delete gFFRENodes;
gFFRENodes = nsnull;
}
if (gAFRENodes) {
gAFRENodes->Reset(FreeNode, nsnull);
delete gAFRENodes;
gAFRENodes = nsnull;
}
NS_IF_RELEASE(gPref);
@ -833,8 +841,14 @@ nsFontMetricsXlib::InitGlobals(nsIDeviceContext *aDevice)
if (percent)
gBitmapUndersize = percent / 100.0;
gNodes = new nsHashtable();
if (!gNodes) {
gFFRENodes = new nsHashtable();
if (!gFFRENodes) {
FreeGlobals();
return NS_ERROR_OUT_OF_MEMORY;
}
gAFRENodes = new nsHashtable();
if (!gAFRENodes) {
FreeGlobals();
return NS_ERROR_OUT_OF_MEMORY;
}
@ -2602,7 +2616,11 @@ nsFontMetricsXlib::PickASizeAndLoad(nsFontStretchXlib* aStretch,
#endif /* !ABS */
// if we do not have the correct size
// check if we can use a scaled font
if ((mPixelSize != bitmap_size) && (aStretch->mScalable)) {
// (when the size of a hand tuned font is close to the desired size
// favor it over outline scaled font)
if (( (bitmap_size < mPixelSize-(mPixelSize/10))
|| (bitmap_size > mPixelSize+(mPixelSize/10)))
&& (aStretch->mScalable)) {
// if we have an outline font then use that
// if it is allowed to be closer than the bitmap
if (aStretch->mOutlineScaled) {
@ -2627,7 +2645,7 @@ nsFontMetricsXlib::PickASizeAndLoad(nsFontStretchXlib* aStretch,
NS_ASSERTION((bitmap_size < NOT_FOUND_FONT_SIZE) || use_scaled_font, "did not find font size");
if (use_scaled_font) {
if (use_scaled_font && aStretch->mScalable) {
PRInt32 i;
PRInt32 n = aStretch->mScaledFonts.Count();
nsFontXlib *p = nsnull;
@ -3073,11 +3091,154 @@ SetFontLangGroupInfo(nsFontCharSetMapXlib* aCharSetMap)
}
}
static void
GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
static nsFontStyleXlib*
NodeGetStyle(nsFontNodeXlib* aNode, int aStyleIndex)
{
nsFontStyleXlib* style = aNode->mStyles[aStyleIndex];
if (!style) {
style = new nsFontStyleXlib;
if (!style) {
return nsnull;
}
aNode->mStyles[aStyleIndex] = style;
}
return style;
}
static nsFontWeightXlib*
NodeGetWeight(nsFontStyleXlib* aStyle, int aWeightIndex)
{
nsFontWeightXlib* weight = aStyle->mWeights[aWeightIndex];
if (!weight) {
weight = new nsFontWeightXlib;
if (!weight) {
return nsnull;
}
aStyle->mWeights[aWeightIndex] = weight;
}
return weight;
}
static nsFontStretchXlib*
NodeGetStretch(nsFontWeightXlib* aWeight, int aStretchIndex)
{
nsFontStretchXlib* stretch = aWeight->mStretches[aStretchIndex];
if (!stretch) {
stretch = new nsFontStretchXlib;
if (!stretch) {
return nsnull;
}
aWeight->mStretches[aStretchIndex] = stretch;
}
return stretch;
}
static PRBool
NodeAddScalable(nsFontStretchXlib* aStretch, PRBool aOutlineScaled,
const char *aDashFoundry, const char *aFamily,
const char *aWeight, const char *aSlant,
const char *aWidth, const char *aStyle,
const char *aSpacing, const char *aCharSet)
{
#ifdef USE_XPRINT
/* gisburn: disabled for Xprint - this kills printer buildin fonts
* Xprint printer-buildin fonts look like bitmap scaled fonts but are
* (scaleable) printer-buildin fonts in reality.
*/
if (nsFontMetricsXlib::mPrinterMode)
return PR_TRUE;
#endif /* USE_XPRINT */
// if we have both an outline scaled font and a bitmap
// scaled font pick the outline scaled font
if ((aStretch->mScalable) && (!aStretch->mOutlineScaled)
&& (aOutlineScaled)) {
PR_smprintf_free(aStretch->mScalable);
aStretch->mScalable = nsnull;
}
if (!aStretch->mScalable) {
aStretch->mOutlineScaled = aOutlineScaled;
if (aOutlineScaled) {
aStretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-0-0-%s-*-%s",
aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle,
aSpacing, aCharSet);
if (!aStretch->mScalable)
return PR_FALSE;
}
else {
aStretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-*-*-%s-*-%s",
aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle,
aSpacing, aCharSet);
if (!aStretch->mScalable)
return PR_FALSE;
}
}
return PR_TRUE;
}
static PRBool
NodeAddSize(nsFontStretchXlib* aStretch, int aSize, const char *aName,
nsFontCharSetXlibInfo* aCharSetInfo)
{
PRBool haveSize = PR_FALSE;
if (aStretch->mSizesCount) {
nsFontXlib** end = &aStretch->mSizes[aStretch->mSizesCount];
nsFontXlib** s;
for (s = aStretch->mSizes; s < end; s++) {
if ((*s)->mSize == aSize) {
haveSize = PR_TRUE;
break;
}
}
}
if (!haveSize) {
if (aStretch->mSizesCount == aStretch->mSizesAlloc) {
int newSize = 2 * (aStretch->mSizesAlloc ? aStretch->mSizesAlloc : 1);
nsFontXlib** newSizes = new nsFontXlib*[newSize];
if (!newSizes)
return PR_FALSE;
for (int j = aStretch->mSizesAlloc - 1; j >= 0; j--) {
newSizes[j] = aStretch->mSizes[j];
}
aStretch->mSizesAlloc = newSize;
delete [] aStretch->mSizes;
aStretch->mSizes = newSizes;
}
char* copy = PR_smprintf("%s", aName);
if (!copy) {
return PR_FALSE;
}
nsFontXlib* size = new nsFontXlibNormal();
if (!size) {
return PR_FALSE;
}
aStretch->mSizes[aStretch->mSizesCount++] = size;
size->mName = copy;
// size->mFont is initialized in the constructor
size->mSize = aSize;
size->mBaselineAdjust = 0;
size->mCCMap = nsnull;
size->mCharSetInfo = aCharSetInfo;
}
return PR_TRUE;
}
static void
GetFontNames(const char* aPattern, PRBool aAnyFoundry, nsFontNodeArrayXlib * aNodes)
{
nsCAutoString previousNodeName;
Display *dpy = xxlib_rgb_get_display(gXlibRgbHandle);
nsCAutoString previousNodeName;
nsHashtable *node_hash;
if (aAnyFoundry) {
NS_ASSERTION(aPattern[1] == '*', "invalid 'anyFoundry' pattern");
node_hash = gAFRENodes;
}
else {
node_hash = gFFRENodes;
}
#ifdef USE_XPRINT
#ifdef DEBUG
@ -3193,6 +3354,24 @@ GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
FIND_FIELD(averageWidth);
if (averageWidth[0] == '0') {
scalable = 1;
/* Workaround for bug 103159 ("sorting fonts by foundry names cause font
* size of css ignored in some cases").
* Hardcoded font ban until bug 104075 ("need X font banning") has been
* implemented. See http://bugzilla.mozilla.org/show_bug.cgi?id=94327#c34
* for additional comments...
*/
#ifndef ENABLE_X_FONT_BANNING
#ifdef USE_XPRINT
/* The following check kills Xprint printer-buildin fonts... ;-( */
if (!nsFontMetricsXlib::mPrinterMode)
#endif /* USE_XPRINT */
{
// skip 'mysterious' and 'spurious' cases like
// -adobe-times-medium-r-normal--17-120-100-100-p-0-iso8859-9
if (pixelSize[0] != '0' || pointSize[0] != 0 )
continue;
}
#endif /* ENABLE_X_FONT_BANNING */
}
char* charSetName = p; // CHARSET_REGISTRY & CHARSET_ENCODING
if (!*charSetName) {
@ -3225,20 +3404,24 @@ GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
SetCharsetLangGroup(charSetInfo);
SetFontLangGroupInfo(charSetMap);
nsCAutoString nodeName(foundry);
nsCAutoString nodeName;
if (aAnyFoundry)
nodeName.Assign('*');
else
nodeName.Assign(foundry);
nodeName.Append('-');
nodeName.Append(familyName);
nodeName.Append('-');
nodeName.Append(charSetName);
nsCStringKey key(nodeName);
nsFontNodeXlib* node = (nsFontNodeXlib*) gNodes->Get(&key);
nsFontNodeXlib* node = (nsFontNodeXlib*) node_hash->Get(&key);
if (!node) {
node = new nsFontNodeXlib;
if (!node)
continue;
gNodes->Put(&key, node);
node_hash->Put(&key, node);
node->mName = nodeName;
node->mCharSetInfo = charSetInfo;
}
@ -3269,14 +3452,9 @@ GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
styleIndex = NS_FONT_STYLE_NORMAL;
break;
}
nsFontStyleXlib* style = node->mStyles[styleIndex];
if (!style) {
style = new nsFontStyleXlib;
if (!style) {
continue;
}
node->mStyles[styleIndex] = style;
}
nsFontStyleXlib* style = NodeGetStyle(node, styleIndex);
if (!style)
continue;
nsCStringKey weightKey(weightName);
int weightNumber = NS_PTR_TO_INT32(gWeights->Get(&weightKey));
@ -3286,14 +3464,9 @@ GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
weightNumber = NS_FONT_WEIGHT_NORMAL;
}
int weightIndex = WEIGHT_INDEX(weightNumber);
nsFontWeightXlib* weight = style->mWeights[weightIndex];
if (!weight) {
weight = new nsFontWeightXlib;
if (!weight) {
continue;
}
style->mWeights[weightIndex] = weight;
}
nsFontWeightXlib *weight = NodeGetWeight(style, weightIndex);
if (!weight)
continue;
nsCStringKey setWidthKey(setWidth);
int stretchIndex = NS_PTR_TO_INT32(gStretches->Get(&setWidthKey));
@ -3303,78 +3476,16 @@ GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
stretchIndex = 5;
}
stretchIndex--;
nsFontStretchXlib* stretch = weight->mStretches[stretchIndex];
if (!stretch) {
stretch = new nsFontStretchXlib;
if (!stretch) {
continue;
}
weight->mStretches[stretchIndex] = stretch;
}
if (scalable) {
/* gisburn: disabled for Xprint - this kills printer buildin fonts
* Xprint printer-buildin fonts look like bitmap scaled fonts but are
* (scaleable) printer-buildin fonts in reality.
*/
#ifdef USE_XPRINT
if(!nsFontMetricsXlib::mPrinterMode)
#endif /* USE_XPRINT */
{
// if we have both an outline scaled font and a bitmap
// scaled font pick the outline scaled font
if ((stretch->mScalable) && (!stretch->mOutlineScaled)
&& (outline_scaled)) {
PR_smprintf_free(stretch->mScalable);
stretch->mScalable = nsnull;
}
}
if (!stretch->mScalable) {
stretch->mOutlineScaled = outline_scaled;
if (outline_scaled) {
stretch->mScalable = PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-0-0-%s-*-%s",
name, familyName, weightName, slant, setWidth, addStyle, spacing, charSetName);
}
else {
stretch->mScalable =
PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-*-*-%s-*-%s",
name, familyName, weightName, slant, setWidth, addStyle,
spacing, charSetName);
}
}
nsFontStretchXlib* stretch = NodeGetStretch(weight, stretchIndex);
if (!stretch)
continue;
}
int pixels = atoi(pixelSize);
NS_ASSERTION((pixels > 0), "unexpected pixel size");
if (stretch->mSizesCount) {
nsFontXlib** end = &stretch->mSizes[stretch->mSizesCount];
nsFontXlib** s;
for (s = stretch->mSizes; s < end; s++) {
if ((*s)->mSize == pixels) {
break;
}
}
if (s != end) {
if (scalable) {
if (!NodeAddScalable(stretch, outline_scaled, name, familyName,
weightName, slant, setWidth, addStyle, spacing, charSetName))
continue;
}
}
if (stretch->mSizesCount == stretch->mSizesAlloc) {
int newSize = 2 * (stretch->mSizesAlloc ? stretch->mSizesAlloc : 1);
nsFontXlib** newPointer = new nsFontXlib*[newSize];
if (newPointer) {
for (int j = stretch->mSizesAlloc - 1; j >= 0; j--) {
newPointer[j] = stretch->mSizes[j];
}
stretch->mSizesAlloc = newSize;
delete [] stretch->mSizes;
stretch->mSizes = newPointer;
}
else {
continue;
}
}
p = name;
while (p < charSetName) {
if (!*p) {
@ -3383,23 +3494,10 @@ GetFontNames(const char* aPattern, nsFontNodeArrayXlib* aNodes)
p++;
}
char* copy = PR_smprintf("%s", name);
if (!copy) {
continue;
}
nsFontXlib* size = new nsFontXlibNormal();
if (!size)
continue;
stretch->mSizes[stretch->mSizesCount++] = size;
size->mName = copy;
size->mFont = nsnull;
size->mSize = pixels;
size->mBaselineAdjust = 0;
size->mCCMap = nsnull;
size->mCharSetInfo = charSetInfo;
int pixels = atoi(pixelSize);
NS_ASSERTION(!((pixels == 0) && (errno == EINVAL)), "unexpected pixel size");
if (!NodeAddSize(stretch, pixels, name, charSetInfo))
continue;
}
XFreeFontNames(list);
@ -3420,7 +3518,7 @@ GetAllFontNames(void)
}
/* Using "-*" instead of the full-qualified "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
* because it's faster and "smarter" - see bug 34242 for details. */
GetFontNames("-*", gGlobalList);
GetFontNames("-*", PR_FALSE, gGlobalList);
}
return NS_OK;
@ -3437,7 +3535,7 @@ FindFamily(nsCString* aName)
char pattern[256];
PR_snprintf(pattern, sizeof(pattern), "-*-%s-*-*-*-*-*-*-*-*-*-*-*-*",
aName->get());
GetFontNames(pattern, &family->mNodes);
GetFontNames(pattern, PR_TRUE, &family->mNodes);
gFamilies->Put(&key, family);
}
}
@ -3504,7 +3602,9 @@ FFRESubstituteEncoding(nsAWritableCString &aFFREName, const char *aReplacementEn
nsFontXlib*
nsFontMetricsXlib::TryNodes(nsAWritableCString &aFFREName, PRUnichar aChar)
{
nsCStringKey key(PromiseFlatCString(aFFREName).get());
const char *FFREName = PromiseFlatCString(aFFREName).get();
nsCStringKey key(FFREName);
PRBool anyFoundry = (FFREName[0] == '*');
nsFontNodeArrayXlib* nodes = (nsFontNodeArrayXlib*) gCachedFFRESearches->Get(&key);
if (!nodes) {
nsCAutoString pattern;
@ -3512,7 +3612,7 @@ nsFontMetricsXlib::TryNodes(nsAWritableCString &aFFREName, PRUnichar aChar)
nodes = new nsFontNodeArrayXlib;
if (!nodes)
return nsnull;
GetFontNames(pattern.get(), nodes);
GetFontNames(pattern.get(), anyFoundry, nodes);
gCachedFFRESearches->Put(&key, nodes);
}
int i, cnt = nodes->Count();
@ -3533,17 +3633,16 @@ nsFontMetricsXlib::TryNode(nsCString* aName, PRUnichar aChar)
nsFontXlib* font;
nsCStringKey key(*aName);
nsFontNodeXlib* node = (nsFontNodeXlib*) gNodes->Get(&key);
nsFontNodeXlib* node = (nsFontNodeXlib*) gFFRENodes->Get(&key);
if (!node) {
nsCAutoString pattern;
FFREToXLFDPattern(*aName, pattern);
nsFontNodeArrayXlib nodes;
GetFontNames(pattern.get(), &nodes);
// no need to call gNodes->Put() since GetFontNames already did
GetFontNames(pattern.get(), PR_FALSE, &nodes);
// no need to call gFFRENodes->Put() since GetFontNames already did
if (nodes.Count() > 0) {
// XXX This assertion may be spurious; you can have more than
// -*-courier-iso8859-1 font, for example, from different
// foundries.
// This assertion is not spurious; when searching for an FFRE
// like -*-courier-iso8859-1 TryNodes should be called not TryNode
NS_ASSERTION((nodes.Count() == 1), "unexpected number of nodes");
node = nodes.GetElement(0);
}
@ -3553,7 +3652,7 @@ nsFontMetricsXlib::TryNode(nsCString* aName, PRUnichar aChar)
if (!node) {
return nsnull;
}
gNodes->Put(&key, node);
gFFRENodes->Put(&key, node);
node->mDummy = 1;
}
}
@ -4025,10 +4124,10 @@ nsFontMetricsXlib::FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCSt
// look for a font with this charset (registry-encoding) & char
//
nsCAutoString ffreName("");
nsCAutoString ffreName;
if (aName) {
// if aName was specified so call TryNode() not TryNodes()
ffreName.Append(*aName);
ffreName.Assign(*aName);
FFRESubstituteCharset(ffreName, charSetMap->mName);
if(aName->First() == '*') {
// called from TryFamily()
@ -4039,7 +4138,7 @@ nsFontMetricsXlib::FindLangGroupFont(nsIAtom* aLangGroup, PRUnichar aChar, nsCSt
NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char");
} else {
// no name was specified so call TryNodes() for this charset
ffreName.Append("*-*-*-*");
ffreName.Assign("*-*-*-*");
FFRESubstituteCharset(ffreName, charSetMap->mName);
font = TryNodes(ffreName, aChar);
NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char");