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[] = static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{ {
// CSS name CSS value Attribute name Attribute value // CSS name CSS value Attribute name Attribute value
{ "font-family", kAnyValue, &nsGkAtoms::font_family, kCopyValue },
{ "font-style", kAnyValue, &nsGkAtoms::font_style, kCopyValue }, { "font-style", kAnyValue, &nsGkAtoms::font_style, kCopyValue },
{ "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" }, { "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" },
{ "text-decoration", "underline", &nsGkAtoms::textUnderlineStyle, "solid" }, { "text-decoration", "underline", &nsGkAtoms::textUnderlineStyle, "solid" },
@ -157,24 +156,20 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode); nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr)); 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 // "font-style" text attribute
nsCSSTextAttr fontStyleTextAttr(1, hyperTextElm, offsetElm); nsCSSTextAttr fontStyleTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr)); textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr));
// "text-line-through-style" text attribute // "text-line-through-style" text attribute
nsCSSTextAttr lineThroughTextAttr(2, hyperTextElm, offsetElm); nsCSSTextAttr lineThroughTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr)); textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr));
// "text-underline-style" text attribute // "text-underline-style" text attribute
nsCSSTextAttr underlineTextAttr(3, hyperTextElm, offsetElm); nsCSSTextAttr underlineTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr)); textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr));
// "text-position" text attribute // "text-position" text attribute
nsCSSTextAttr posTextAttr(4, hyperTextElm, offsetElm); nsCSSTextAttr posTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr)); textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr));
// "background-color" text attribute // "background-color" text attribute
@ -185,6 +180,10 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
ColorTextAttr colorTextAttr(rootFrame, frame); ColorTextAttr colorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr)); textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
// "font-family" text attribute
FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontFamilyTextAttr));
// "font-size" text attribute // "font-size" text attribute
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame); nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontSizeTextAttr)); 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 // nsFontSizeTextAttr
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -100,7 +100,6 @@ public:
PRInt32 *aEndHTOffset = nsnull); PRInt32 *aEndHTOffset = nsnull);
protected: protected:
/** /**
* Calculates range (start and end offsets) of text where the text attributes * 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 * 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 is used for the work with "font-size" text attribute in nsTextAttrsMgr
* class. * class.

View File

@ -208,6 +208,39 @@ const kBoldFontWeight =
const kInputFontSize = WIN ? const kInputFontSize = WIN ?
"10pt" : (MAC ? "8pt" : function() { return true; }); "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. * 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, * @param aFontWeight [in, optional] kBoldFontWeight or kNormalFontWeight,
* default value is kNormalFontWeight * default value is kNormalFontWeight
*/ */
function buildDefaultTextAttrs(aID, aFontSize, aFontWeight) function buildDefaultTextAttrs(aID, aFontSize, aFontWeight, aFontFamily)
{ {
var elm = getNode(aID); var elm = getNode(aID);
var computedStyle = document.defaultView.getComputedStyle(elm, ""); var computedStyle = document.defaultView.getComputedStyle(elm, "");
@ -229,7 +262,7 @@ function buildDefaultTextAttrs(aID, aFontSize, aFontWeight)
"background-color": bgColor, "background-color": bgColor,
"font-weight": aFontWeight ? aFontWeight : kNormalFontWeight, "font-weight": aFontWeight ? aFontWeight : kNormalFontWeight,
"color": computedStyle.color, "color": computedStyle.color,
"font-family": computedStyle.fontFamily, "font-family": aFontFamily ? aFontFamily : fontFamily(computedStyle),
"text-position": computedStyle.verticalAlign "text-position": computedStyle.verticalAlign
}; };

View File

@ -263,7 +263,7 @@
// Walk from span with font-style to the one with font-family. // Walk from span with font-style to the one with font-family.
tempElem = tempElem.nextSibling.nextSibling; tempElem = tempElem.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, ""); gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = { "font-family": gComputedStyle.fontFamily }; attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 70, attrs, defAttrs, 69, 83); testTextAttrs(ID, 70, attrs, defAttrs, 69, 83);
attrs = {}; attrs = {};
@ -281,6 +281,7 @@
attrs = {}; attrs = {};
testTextAttrs(ID, 123, attrs, defAttrs, 122, 130); testTextAttrs(ID, 123, attrs, defAttrs, 122, 130);
//////////////////////////////////////////////////////////////////////////
// area10, different single style spans in non-styled paragraph // area10, different single style spans in non-styled paragraph
ID = "area10"; ID = "area10";
defAttrs = buildDefaultTextAttrs(ID, "12pt"); defAttrs = buildDefaultTextAttrs(ID, "12pt");
@ -316,7 +317,7 @@
// Walk from span with font-style to the one with font-family. // Walk from span with font-style to the one with font-family.
tempElem = tempElem.nextSibling.nextSibling; tempElem = tempElem.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, ""); gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-family": gComputedStyle.fontFamily}; attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 71, attrs, defAttrs, 70, 84); testTextAttrs(ID, 71, attrs, defAttrs, 70, 84);
attrs = {}; attrs = {};
@ -334,6 +335,7 @@
attrs = {}; attrs = {};
testTextAttrs(ID, 124, attrs, defAttrs, 123, 131); testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
//////////////////////////////////////////////////////////////////////////
// area11, "font-weight" tests // area11, "font-weight" tests
ID = "area11"; ID = "area11";
defAttrs = buildDefaultTextAttrs(ID, "12pt", kBoldFontWeight); defAttrs = buildDefaultTextAttrs(ID, "12pt", kBoldFontWeight);
@ -373,7 +375,8 @@
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0); testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
ID = "area14"; ID = "area14";
defAttrs = buildDefaultTextAttrs(ID, kInputFontSize); defAttrs = buildDefaultTextAttrs(ID, kInputFontSize,
kNormalFontWeight, kInputFontFamily);
attrs = { }; attrs = { };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0); testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
@ -404,6 +407,36 @@
// p // p
testTextAttrs(ID, 23, { }, { }, 23, 24); 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(); SimpleTest.finish();
} }
@ -417,6 +450,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
title="Implement text attributes"> title="Implement text attributes">
Mozilla Bug 345759 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> </a>
<p id="display"></p> <p id="display"></p>
<div id="content" style="display: none"></div> <div id="content" style="display: none"></div>
@ -469,7 +507,7 @@
<span style="font-size: 120%">bigger</span> smaller <span style="font-size: 120%">bigger</span> smaller
<span style="background-color: blue;">background blue</span> normal <span style="background-color: blue;">background blue</span> normal
<span style="font-style: italic;">Different styling</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: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal <span style="text-decoration: line-through;">strikethrough</span> normal
</p> </p>
@ -478,7 +516,7 @@
<span style="font-size: 120%">bigger</span> smaller <span style="font-size: 120%">bigger</span> smaller
<span style="background-color: blue;">background blue</span> normal <span style="background-color: blue;">background blue</span> normal
<span style="font-style: italic;">Different styling</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: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal <span style="text-decoration: line-through;">strikethrough</span> normal
</p> </p>
@ -500,5 +538,13 @@
<!-- *plain*plain**bold*bold*--> <!-- *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> <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> </body>
</html> </html>

View File

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