Bug 473570 - Restrict font-weight text attribute to allowed values, r=marcoz, davidb, mozbugz, sr=roc

This commit is contained in:
Alexander Surkov 2009-03-04 14:46:29 +08:00
Родитель 209b129774
Коммит 80275f20c6
4 изменённых файлов: 202 добавлений и 25 удалений

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

@ -41,6 +41,10 @@
#include "nsAccessNode.h"
#include "nsHyperTextAccessibleWrap.h"
#include "gfxFont.h"
#include "gfxUserFontSet.h"
#include "nsIThebesFontMetrics.h"
////////////////////////////////////////////////////////////////////////////////
// Constants and structures
@ -67,7 +71,6 @@ static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{ "color", kAnyValue, &nsAccessibilityAtoms::color, kCopyValue },
{ "font-family", kAnyValue, &nsAccessibilityAtoms::fontFamily, kCopyValue },
{ "font-style", kAnyValue, &nsAccessibilityAtoms::fontStyle, kCopyValue },
{ "font-weight", kAnyValue, &nsAccessibilityAtoms::fontWeight, kCopyValue },
{ "text-decoration", "line-through", &nsAccessibilityAtoms::textLineThroughStyle, "solid" },
{ "text-decoration", "underline", &nsAccessibilityAtoms::textUnderlineStyle, "solid" },
{ "vertical-align", kAnyValue, &nsAccessibilityAtoms::textPosition, kCopyValue }
@ -131,20 +134,16 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsCSSTextAttr fontStyleTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr));
// "font-weight" text attribute
nsCSSTextAttr fontWeightTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontWeightTextAttr));
// "text-line-through-style" text attribute
nsCSSTextAttr lineThroughTextAttr(4, hyperTextElm, offsetElm);
nsCSSTextAttr lineThroughTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr));
// "text-underline-style" text attribute
nsCSSTextAttr underlineTextAttr(5, hyperTextElm, offsetElm);
nsCSSTextAttr underlineTextAttr(4, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr));
// "text-position" text attribute
nsCSSTextAttr posTextAttr(6, hyperTextElm, offsetElm);
nsCSSTextAttr posTextAttr(5, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr));
// "background-color" text attribute
@ -155,6 +154,10 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontSizeTextAttr));
// "font-weight" text attribute
nsFontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontWeightTextAttr));
// Expose text attributes if applicable.
if (aAttributes) {
PRUint32 len = textAttrArray.Length();
@ -603,3 +606,83 @@ nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
return styleFont->mSize;
}
////////////////////////////////////////////////////////////////////////////////
// nsFontWeightTextAttr
nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
nsIFrame *aFrame) :
nsTextAttr<PRInt32>(aFrame == nsnull)
{
mRootNativeValue = GetFontWeight(aRootFrame);
mIsRootDefined = PR_TRUE;
if (aFrame) {
mNativeValue = GetFontWeight(aFrame);
mIsDefined = PR_TRUE;
}
}
PRBool
nsFontWeightTextAttr::GetValueFor(nsIDOMElement *aElm, PRInt32 *aValue)
{
nsIFrame *frame = nsCoreUtils::GetFrameFor(aElm);
if (!frame)
return PR_FALSE;
*aValue = GetFontWeight(frame);
return PR_TRUE;
}
void
nsFontWeightTextAttr::Format(const PRInt32& aValue, nsAString& aFormattedValue)
{
nsAutoString value;
value.AppendInt(aValue);
aFormattedValue = value;
}
PRInt32
nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
{
// nsFont::width isn't suitable here because it's necessary to expose real
// value of font weight (used font might not have some font weight values).
nsStyleFont* styleFont =
(nsStyleFont*)(aFrame->GetStyleDataExternal(eStyleStruct_Font));
gfxUserFontSet *fs = aFrame->PresContext()->GetUserFontSet();
nsCOMPtr<nsIFontMetrics> fm;
aFrame->PresContext()->DeviceContext()->
GetMetricsFor(styleFont->mFont, aFrame->GetStyleVisibility()->mLangGroup,
fs, *getter_AddRefs(fm));
nsCOMPtr<nsIThebesFontMetrics> tfm = do_QueryInterface(fm);
gfxFontGroup *fontGroup = tfm->GetThebesFontGroup();
gfxFont *font = fontGroup->GetFontAt(0);
// When there doesn't exist a bold font in the family and so the rendering of
// a non-bold font face is changed so that the user sees what looks like a
// bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
// needed on Mac, but it is "safe" to use on all platforms. (For non-Mac
// platforms it always return false.)
if (font->IsSyntheticBold())
return 700;
#ifdef MOZ_PANGO
// On Linux, font->GetStyle()->weight will give the absolute weight requested
// of the font face. The Linux code uses the gfxFontEntry constructor which
// doesn't initialize the weight field.
return font->GetStyle()->weight;
#else
// On Windows, font->GetStyle()->weight will give the same weight as
// fontEntry->Weight(), the weight of the first font in the font group, which
// may not be the weight of the font face used to render the characters.
// On Mac, font->GetStyle()->weight will just give the same number as
// getComputedStyle(). fontEntry->Weight() will give the weight of the font
// face used.
gfxFontEntry *fontEntry = font->GetFontEntry();
return fontEntry->Weight();
#endif
}

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

@ -368,4 +368,34 @@ private:
nsIDeviceContext *mDC;
};
/**
* Class is used for the work with "font-weight" text attribute in
* nsTextAttrsMgr class.
*/
class nsFontWeightTextAttr : public nsTextAttr<PRInt32>
{
public:
nsFontWeightTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
// nsITextAttr
virtual nsIAtom *GetName() { return nsAccessibilityAtoms::fontWeight; }
protected:
// nsTextAttr
virtual PRBool GetValueFor(nsIDOMElement *aElm, PRInt32 *aValue);
virtual void Format(const PRInt32& aValue, nsAString& aFormattedValue);
private:
/**
* Return font weight for the given frame.
*
* @param aFrame [in] the given frame to query font weight
* @return font weight
*/
PRInt32 GetFontWeight(nsIFrame *aFrame);
};
#endif

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

@ -180,8 +180,13 @@ function compareAttrs(aErrorMsg, aAttrs, aExpectedAttrs, aSkipUnexpectedAttrs)
ok(false, "Unexpected attribute '" + prop.key + "' having '" +
prop.value + "'" + aErrorMsg);
} else {
is(prop.value, aExpectedAttrs[prop.key],
"Attribute '" + prop.key + " 'has wrong value" + aErrorMsg);
var msg = "Attribute '" + prop.key + " 'has wrong value" + aErrorMsg;
var expectedValue = aExpectedAttrs[prop.key];
if (typeof expectedValue == "function")
ok(expectedValue(prop.value), msg);
else
is(prop.value, expectedValue, msg);
}
}

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

@ -23,6 +23,16 @@
var gComputedStyle = null;
function equalsToNormal(aWeight)
{
return aWeight <= 400;
}
function equalsToBold(aWeight)
{
return aWeight > 400;
}
var gTextAttrChangedEventHandler = {
handleEvent: function gTextAttrChangedEventHandler_handleEvent(aEvent)
{
@ -54,7 +64,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": (MAC) ? "8pt" : "10pt",
"background-color": gComputedStyle.backgroundColor,
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -92,7 +102,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "10pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -105,7 +115,7 @@
tempElem = tempElem.firstChild.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-weight": gComputedStyle.fontWeight};
attrs = { "font-weight": equalsToBold };
testTextAttrs(ID, 7, attrs, defAttrs, 7, 11);
attrs = {};
@ -120,7 +130,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "14pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -133,18 +143,18 @@
tempElem = tempElem.firstChild.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-weight": gComputedStyle.fontWeight};
attrs = { "font-weight": equalsToBold };
testTextAttrs(ID, 7, attrs, defAttrs, 7, 12);
tempElem = tempElem.firstChild.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-style": gComputedStyle.fontStyle,
"font-weight": gComputedStyle.fontWeight};
"font-weight": equalsToBold };
testTextAttrs(ID, 13, attrs, defAttrs, 12, 19);
tempElem = tempElem.parentNode;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-weight": "401"};
attrs = { "font-weight": equalsToBold };
testTextAttrs(ID, 20, attrs, defAttrs, 19, 23);
attrs = {};
@ -159,7 +169,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": gComputedStyle.backgroundColor,
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -197,7 +207,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -229,7 +239,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -262,7 +272,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -314,7 +324,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -352,7 +362,7 @@
tempElem = tempElem.firstChild.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-weight": gComputedStyle.fontWeight,
attrs = {"font-weight": equalsToBold,
"color": gComputedStyle.color};
testTextAttrs(ID, 57, attrs, defAttrs, 57, 61);
@ -370,7 +380,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "10pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -434,7 +444,7 @@
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": gComputedStyle.fontWeight,
"font-weight": equalsToNormal,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
@ -490,6 +500,44 @@
attrs = {};
testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
// area11, "font-weight" tests
ID = "area11";
tempElem = document.getElementById(ID);
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
defAttrs = {
"font-style": gComputedStyle.fontStyle,
"font-size": "12pt",
"background-color": "rgb(255, 255, 255)",
"font-weight": equalsToBold,
"color": gComputedStyle.color,
"font-family": gComputedStyle.fontFamily,
"text-position": gComputedStyle.verticalAlign
};
testDefaultTextAttrs(ID, defAttrs);
attrs = { };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 13);
attrs = { "font-weight": equalsToNormal };
testTextAttrs(ID, 13, attrs, defAttrs, 13, 20);
attrs = { };
testTextAttrs(ID, 20, attrs, defAttrs, 20, 27);
attrs = { "font-weight": equalsToNormal };
testTextAttrs(ID, 27, attrs, defAttrs, 27, 33);
attrs = { };
testTextAttrs(ID, 33, attrs, defAttrs, 33, 51);
attrs = { "font-weight": equalsToNormal };
testTextAttrs(ID, 51, attrs, defAttrs, 51, 57);
attrs = { };
testTextAttrs(ID, 57, attrs, defAttrs, 57, 97);
//////////////////////////////////////////////////////////////////////////
// test spelling text attributes
testSpellTextAttrs(); // Will call SimpleTest.finish();
@ -571,5 +619,16 @@
<span style="text-decoration: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal
</p>
<p id="area11" style="font-weight: bolder;">
<span style="font-weight: bolder;">bolder</span>bolder
<span style="font-weight: lighter;">lighter</span>bolder
<span style="font-weight: normal;">normal</span>bolder
<b>bold</b>bolder
<span style="font-weight: 400;">normal</span>bolder
<span style="font-weight: 700;">bold</span>bolder
<span style="font-weight: bold;">bold</span>bolder
<span style="font-weight: 900;">bold</span>bolder
</p>
</body>
</html>