From 9581a345b4190420d0ceedbf9493e8743f5c4154 Mon Sep 17 00:00:00 2001
From: Alexander Surkov
Date: Wed, 29 Feb 2012 09:25:06 +0900
Subject: [PATCH] Bug 473576 - font-family text attribute should expose actual
font used, r=tbsaunde, f=karl
---
accessible/src/base/nsTextAttrs.cpp | 65 +++++++++++++++----
accessible/src/base/nsTextAttrs.h | 25 ++++++-
accessible/tests/mochitest/attributes.js | 37 ++++++++++-
.../tests/mochitest/attributes/test_text.html | 56 ++++++++++++++--
.../mochitest/events/test_textattrchange.html | 4 +-
5 files changed, 167 insertions(+), 20 deletions(-)
diff --git a/accessible/src/base/nsTextAttrs.cpp b/accessible/src/base/nsTextAttrs.cpp
index 6d2243b18bc..c300deca139 100644
--- a/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/nsTextAttrs.cpp
@@ -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(&langTextAttr));
- // "font-family" text attribute
- nsCSSTextAttr fontFamilyTextAttr(0, hyperTextElm, offsetElm);
- textAttrArray.AppendElement(static_cast(&fontFamilyTextAttr));
-
// "font-style" text attribute
- nsCSSTextAttr fontStyleTextAttr(1, hyperTextElm, offsetElm);
+ nsCSSTextAttr fontStyleTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast(&fontStyleTextAttr));
// "text-line-through-style" text attribute
- nsCSSTextAttr lineThroughTextAttr(2, hyperTextElm, offsetElm);
+ nsCSSTextAttr lineThroughTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast(&lineThroughTextAttr));
// "text-underline-style" text attribute
- nsCSSTextAttr underlineTextAttr(3, hyperTextElm, offsetElm);
+ nsCSSTextAttr underlineTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast(&underlineTextAttr));
// "text-position" text attribute
- nsCSSTextAttr posTextAttr(4, hyperTextElm, offsetElm);
+ nsCSSTextAttr posTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast(&posTextAttr));
// "background-color" text attribute
@@ -185,6 +180,10 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
ColorTextAttr colorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast(&colorTextAttr));
+ // "font-family" text attribute
+ FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
+ textAttrArray.AppendElement(static_cast(&fontFamilyTextAttr));
+
// "font-size" text attribute
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast(&fontSizeTextAttr));
@@ -458,6 +457,50 @@ ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
}
+////////////////////////////////////////////////////////////////////////////////
+// FontFamilyTextAttr
+////////////////////////////////////////////////////////////////////////////////
+
+FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+ nsTextAttr(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 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)
diff --git a/accessible/src/base/nsTextAttrs.h b/accessible/src/base/nsTextAttrs.h
index 9e527a3c75f..8872574deb6 100644
--- a/accessible/src/base/nsTextAttrs.h
+++ b/accessible/src/base/nsTextAttrs.h
@@ -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
+{
+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.
diff --git a/accessible/tests/mochitest/attributes.js b/accessible/tests/mochitest/attributes.js
index 6ce363d9c99..45a7ac1f8b4 100644
--- a/accessible/tests/mochitest/attributes.js
+++ b/accessible/tests/mochitest/attributes.js
@@ -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
};
diff --git a/accessible/tests/mochitest/attributes/test_text.html b/accessible/tests/mochitest/attributes/test_text.html
index 3e7430bb0d1..fc4c92f7a59 100644
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -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
+
+
+ Mozilla Bug 473576
@@ -469,7 +507,7 @@
bigger smaller
background blue normal
Different styling normal
- Different font normal
+ Different font normal
underlined normal
strikethrough normal
@@ -478,7 +516,7 @@
bigger smaller
background blue normal
Different styling normal
- Different font normal
+ Different font normal
underlined normal
strikethrough normal
@@ -500,5 +538,13 @@
embed
plain
embed
plain
embed
boldembed
boldembed
+
+
+ texttext
+ texttext
+ texttext
+ texttext
+ texttext
+