Bug 473576 - font-family text attribute should expose actual font used, r=tbsaunde, f=karl

This commit is contained in:
Alexander Surkov 2012-02-29 09:25:06 +09:00
parent 77c048b6f8
commit 9581a345b4
5 changed files with 167 additions and 20 deletions

View File

@ -74,7 +74,6 @@ const char* const kCopyValue = nsnull;
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{
// CSS name CSS value Attribute name Attribute value
{ "font-family", kAnyValue, &nsGkAtoms::font_family, kCopyValue },
{ "font-style", kAnyValue, &nsGkAtoms::font_style, kCopyValue },
{ "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" },
{ "text-decoration", "underline", &nsGkAtoms::textUnderlineStyle, "solid" },
@ -157,24 +156,20 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr));
// "font-family" text attribute
nsCSSTextAttr fontFamilyTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontFamilyTextAttr));
// "font-style" text attribute
nsCSSTextAttr fontStyleTextAttr(1, hyperTextElm, offsetElm);
nsCSSTextAttr fontStyleTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr));
// "text-line-through-style" text attribute
nsCSSTextAttr lineThroughTextAttr(2, hyperTextElm, offsetElm);
nsCSSTextAttr lineThroughTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr));
// "text-underline-style" text attribute
nsCSSTextAttr underlineTextAttr(3, hyperTextElm, offsetElm);
nsCSSTextAttr underlineTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr));
// "text-position" text attribute
nsCSSTextAttr posTextAttr(4, hyperTextElm, offsetElm);
nsCSSTextAttr posTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr));
// "background-color" text attribute
@ -185,6 +180,10 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
ColorTextAttr colorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
// "font-family" text attribute
FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontFamilyTextAttr));
// "font-size" text attribute
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontSizeTextAttr));
@ -458,6 +457,50 @@ ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
}
////////////////////////////////////////////////////////////////////////////////
// FontFamilyTextAttr
////////////////////////////////////////////////////////////////////////////////
FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nsAutoString>(aFrame == nsnull)
{
mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
if (aFrame)
mIsDefined = GetFontFamily(aFrame, mNativeValue);
}
bool
FontFamilyTextAttr::GetValueFor(nsIContent* aElm, nsAutoString* aValue)
{
nsIFrame* frame = aElm->GetPrimaryFrame();
if (!frame)
return false;
return GetFontFamily(frame, *aValue);
}
void
FontFamilyTextAttr::Format(const nsAutoString& aValue,
nsAString& aFormattedValue)
{
aFormattedValue = aValue;
}
bool
FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
{
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
gfxFont* font = fontGroup->GetFontAt(0);
gfxFontEntry* fontEntry = font->GetFontEntry();
aFamily = fontEntry->FamilyName();
return true;
}
////////////////////////////////////////////////////////////////////////////////
// nsFontSizeTextAttr
////////////////////////////////////////////////////////////////////////////////
@ -482,7 +525,7 @@ nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
nsIFrame *frame = aContent->GetPrimaryFrame();
if (!frame)
return false;
*aValue = GetFontSize(frame);
return true;
}
@ -494,7 +537,7 @@ nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
//
// Note: according to IA2, "The conversion doesn't have to be exact.
// The intent is to give the user a feel for the size of the text."
//
//
// ATK does not specify a unit and will likely follow IA2 here.
//
// XXX todo: consider sharing this code with layout module? (bug 474621)

View File

@ -100,7 +100,6 @@ public:
PRInt32 *aEndHTOffset = nsnull);
protected:
/**
* Calculates range (start and end offsets) of text where the text attributes
* are stretched. New offsets may be smaller if one of text attributes changes
@ -326,6 +325,30 @@ protected:
};
/**
* Class is used for the work with "font-family" text attribute in
* nsTextAttrsMgr class.
*/
class FontFamilyTextAttr : public nsTextAttr<nsAutoString>
{
public:
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::font_family; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nsAutoString* aValue);
virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
private:
bool GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily);
};
/**
* Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
* class.

View File

@ -208,6 +208,39 @@ const kBoldFontWeight =
const kInputFontSize = WIN ?
"10pt" : (MAC ? "8pt" : function() { return true; });
const kAbsentFontFamily =
function(aFontFamily) { return aFontFamily != "sans-serif"; }
const kInputFontFamily =
function(aFontFamily) { return aFontFamily != "sans-serif"; }
const kMonospaceFontFamily =
function(aFontFamily) { return aFontFamily != "monospace"; }
const kSansSerifFontFamily =
function(aFontFamily) { return aFontFamily != "sans-serif"; }
const kSerifFontFamily =
function(aFontFamily) { return aFontFamily != "serif"; }
const kCursiveFontFamily = WIN ? "Comic Sans MS" :
(LINUX ? "DejaVu Serif" : "MacFont");
/**
* Return used font from the given computed style.
*/
function fontFamily(aComputedStyle)
{
var name = aComputedStyle.fontFamily;
switch (name) {
case "monospace":
return kMonospaceFontFamily;
case "sans-serif":
return kSansSerifFontFamily;
case "serif":
return kSerifFontFamily;
default:
return name;
}
}
/**
* Build an object of default text attributes expected for the given accessible.
*
@ -216,7 +249,7 @@ const kInputFontSize = WIN ?
* @param aFontWeight [in, optional] kBoldFontWeight or kNormalFontWeight,
* default value is kNormalFontWeight
*/
function buildDefaultTextAttrs(aID, aFontSize, aFontWeight)
function buildDefaultTextAttrs(aID, aFontSize, aFontWeight, aFontFamily)
{
var elm = getNode(aID);
var computedStyle = document.defaultView.getComputedStyle(elm, "");
@ -229,7 +262,7 @@ function buildDefaultTextAttrs(aID, aFontSize, aFontWeight)
"background-color": bgColor,
"font-weight": aFontWeight ? aFontWeight : kNormalFontWeight,
"color": computedStyle.color,
"font-family": computedStyle.fontFamily,
"font-family": aFontFamily ? aFontFamily : fontFamily(computedStyle),
"text-position": computedStyle.verticalAlign
};

View File

@ -263,7 +263,7 @@
// Walk from span with font-style to the one with font-family.
tempElem = tempElem.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = { "font-family": gComputedStyle.fontFamily };
attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 70, attrs, defAttrs, 69, 83);
attrs = {};
@ -281,6 +281,7 @@
attrs = {};
testTextAttrs(ID, 123, attrs, defAttrs, 122, 130);
//////////////////////////////////////////////////////////////////////////
// area10, different single style spans in non-styled paragraph
ID = "area10";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
@ -316,7 +317,7 @@
// Walk from span with font-style to the one with font-family.
tempElem = tempElem.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-family": gComputedStyle.fontFamily};
attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 71, attrs, defAttrs, 70, 84);
attrs = {};
@ -334,6 +335,7 @@
attrs = {};
testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
//////////////////////////////////////////////////////////////////////////
// area11, "font-weight" tests
ID = "area11";
defAttrs = buildDefaultTextAttrs(ID, "12pt", kBoldFontWeight);
@ -373,7 +375,8 @@
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
ID = "area14";
defAttrs = buildDefaultTextAttrs(ID, kInputFontSize);
defAttrs = buildDefaultTextAttrs(ID, kInputFontSize,
kNormalFontWeight, kInputFontFamily);
attrs = { };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
@ -404,6 +407,36 @@
// p
testTextAttrs(ID, 23, { }, { }, 23, 24);
//////////////////////////////////////////////////////////////////////////
// area16, "font-family" tests
ID = "area16";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
testDefaultTextAttrs(ID, defAttrs);
attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 4);
attrs = { };
testTextAttrs(ID, 4, attrs, defAttrs, 4, 9);
attrs = { "font-family": kSerifFontFamily };
testTextAttrs(ID, 9, attrs, defAttrs, 9, 13);
attrs = { };
testTextAttrs(ID, 13, attrs, defAttrs, 13, 18);
attrs = { "font-family": kAbsentFontFamily };
testTextAttrs(ID, 18, attrs, defAttrs, 18, 22);
attrs = { };
testTextAttrs(ID, 22, attrs, defAttrs, 22, 27);
attrs = { "font-family": kCursiveFontFamily };
testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);
attrs = { };
testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
SimpleTest.finish();
}
@ -417,6 +450,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
title="Implement text attributes">
Mozilla Bug 345759
</a><br>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
title="font-family text attribute should expose actual font used">
Mozilla Bug 473576
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -469,7 +507,7 @@
<span style="font-size: 120%">bigger</span> smaller
<span style="background-color: blue;">background blue</span> normal
<span style="font-style: italic;">Different styling</span> normal
<span style="font-family: tahoma;">Different font</span> normal
<span style="font-family: monospace;">Different font</span> normal
<span style="text-decoration: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal
</p>
@ -478,7 +516,7 @@
<span style="font-size: 120%">bigger</span> smaller
<span style="background-color: blue;">background blue</span> normal
<span style="font-style: italic;">Different styling</span> normal
<span style="font-family: tahoma;">Different font</span> normal
<span style="font-family: monospace;">Different font</span> normal
<span style="text-decoration: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal
</p>
@ -500,5 +538,13 @@
<!-- *plain*plain**bold*bold*-->
<div id="area15"><p>embed</p>plain<p>embed</p>plain<p>embed</p><img src="../moz.png" alt="image"/><b>bold</b><p>embed</p><b>bold</b><p>embed</p></div>
<p id="area16" style="font-family: sans-serif;">
<span style="font-family: monospace;">text</span>text
<span style="font-family: serif;">text</span>text
<span style="font-family: BodoniThatDoesntExist;">text</span>text
<span style="font-family: Comic Sans MS, cursive;">text</span>text
<span style="font-family: sans-serif, fantasy;">text</span>text
</p>
</body>
</html>

View File

@ -49,7 +49,9 @@
this.finalCheck = function spelledTextInvoker_finalCheck()
{
var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize);
var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize,
kNormalFontWeight,
kInputFontFamily);
testDefaultTextAttrs(aID, defAttrs);
var attrs = { };