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

imagebold

embed

bold

embed

+ +

+ texttext + texttext + texttext + texttext + texttext +

diff --git a/accessible/tests/mochitest/events/test_textattrchange.html b/accessible/tests/mochitest/events/test_textattrchange.html index 4a9b28fe8f6..3a3fead13c0 100644 --- a/accessible/tests/mochitest/events/test_textattrchange.html +++ b/accessible/tests/mochitest/events/test_textattrchange.html @@ -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 = { };