accessible/src/base/TextAttrs.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "TextAttrs.h"
     8 #include "Accessible-inl.h"
     9 #include "nsAccUtils.h"
    10 #include "nsCoreUtils.h"
    11 #include "StyleInfo.h"
    13 #include "gfxFont.h"
    14 #include "nsFontMetrics.h"
    15 #include "nsLayoutUtils.h"
    16 #include "HyperTextAccessible.h"
    17 #include "mozilla/AppUnits.h"
    18 #include "mozilla/gfx/2D.h"
    20 using namespace mozilla;
    21 using namespace mozilla::a11y;
    23 ////////////////////////////////////////////////////////////////////////////////
    24 // TextAttrsMgr
    25 ////////////////////////////////////////////////////////////////////////////////
    27 void
    28 TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes,
    29                             int32_t* aStartHTOffset,
    30                             int32_t* aEndHTOffset)
    31 {
    32   // 1. Hyper text accessible must be specified always.
    33   // 2. Offset accessible and result hyper text offsets must be specified in
    34   // the case of text attributes.
    35   // 3. Offset accessible and result hyper text offsets must not be specified
    36   // but include default text attributes flag and attributes list must be
    37   // specified in the case of default text attributes.
    38   NS_PRECONDITION(mHyperTextAcc &&
    39                   ((mOffsetAcc && mOffsetAccIdx != -1 &&
    40                     aStartHTOffset && aEndHTOffset) ||
    41                   (!mOffsetAcc && mOffsetAccIdx == -1 &&
    42                     !aStartHTOffset && !aEndHTOffset &&
    43                    mIncludeDefAttrs && aAttributes)),
    44                   "Wrong usage of TextAttrsMgr!");
    46   // Embedded objects are combined into own range with empty attributes set.
    47   if (mOffsetAcc && nsAccUtils::IsEmbeddedObject(mOffsetAcc)) {
    48     for (int32_t childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
    49       Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
    50       if (!nsAccUtils::IsEmbeddedObject(currAcc))
    51         break;
    53       (*aStartHTOffset)--;
    54     }
    56     uint32_t childCount = mHyperTextAcc->ChildCount();
    57     for (uint32_t childIdx = mOffsetAccIdx + 1; childIdx < childCount;
    58          childIdx++) {
    59       Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
    60       if (!nsAccUtils::IsEmbeddedObject(currAcc))
    61         break;
    63       (*aEndHTOffset)++;
    64     }
    66     return;
    67   }
    69   // Get the content and frame of the accessible. In the case of document
    70   // accessible it's role content and root frame.
    71   nsIContent *hyperTextElm = mHyperTextAcc->GetContent();
    72   nsIFrame *rootFrame = mHyperTextAcc->GetFrame();
    73   NS_ASSERTION(rootFrame, "No frame for accessible!");
    74   if (!rootFrame)
    75     return;
    77   nsIContent *offsetNode = nullptr, *offsetElm = nullptr;
    78   nsIFrame *frame = nullptr;
    79   if (mOffsetAcc) {
    80     offsetNode = mOffsetAcc->GetContent();
    81     offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
    82     NS_ASSERTION(offsetElm, "No element for offset accessible!");
    83     if (!offsetElm)
    84       return;
    85     frame = offsetElm->GetPrimaryFrame();
    86   }
    88   // "language" text attribute
    89   LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
    91   // "aria-invalid" text attribute
    92   InvalidTextAttr invalidTextAttr(hyperTextElm, offsetNode);
    94   // "background-color" text attribute
    95   BGColorTextAttr bgColorTextAttr(rootFrame, frame);
    97   // "color" text attribute
    98   ColorTextAttr colorTextAttr(rootFrame, frame);
   100   // "font-family" text attribute
   101   FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
   103   // "font-size" text attribute
   104   FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
   106   // "font-style" text attribute
   107   FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);
   109   // "font-weight" text attribute
   110   FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
   112   // "auto-generated" text attribute
   113   AutoGeneratedTextAttr autoGenTextAttr(mHyperTextAcc, mOffsetAcc);
   115   // "text-underline(line-through)-style(color)" text attributes
   116   TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
   118   // "text-position" text attribute
   119   TextPosTextAttr textPosTextAttr(rootFrame, frame);
   121   TextAttr* attrArray[] =
   122   {
   123     &langTextAttr,
   124     &invalidTextAttr,
   125     &bgColorTextAttr,
   126     &colorTextAttr,
   127     &fontFamilyTextAttr,
   128     &fontSizeTextAttr,
   129     &fontStyleTextAttr,
   130     &fontWeightTextAttr,
   131     &autoGenTextAttr,
   132     &textDecorTextAttr,
   133     &textPosTextAttr
   134   };
   136   // Expose text attributes if applicable.
   137   if (aAttributes) {
   138     for (uint32_t idx = 0; idx < ArrayLength(attrArray); idx++)
   139       attrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
   140   }
   142   // Expose text attributes range where they are applied if applicable.
   143   if (mOffsetAcc)
   144     GetRange(attrArray, ArrayLength(attrArray), aStartHTOffset, aEndHTOffset);
   145 }
   147 void
   148 TextAttrsMgr::GetRange(TextAttr* aAttrArray[], uint32_t aAttrArrayLen,
   149                        int32_t* aStartHTOffset, int32_t* aEndHTOffset)
   150 {
   151   // Navigate backward from anchor accessible to find start offset.
   152   for (int32_t childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
   153     Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
   155     // Stop on embedded accessible since embedded accessibles are combined into
   156     // own range.
   157     if (nsAccUtils::IsEmbeddedObject(currAcc))
   158       break;
   160     bool offsetFound = false;
   161     for (uint32_t attrIdx = 0; attrIdx < aAttrArrayLen; attrIdx++) {
   162       TextAttr* textAttr = aAttrArray[attrIdx];
   163       if (!textAttr->Equal(currAcc)) {
   164         offsetFound = true;
   165         break;
   166       }
   167     }
   169     if (offsetFound)
   170       break;
   172     *(aStartHTOffset) -= nsAccUtils::TextLength(currAcc);
   173   }
   175   // Navigate forward from anchor accessible to find end offset.
   176   uint32_t childLen = mHyperTextAcc->ChildCount();
   177   for (uint32_t childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
   178     Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
   179     if (nsAccUtils::IsEmbeddedObject(currAcc))
   180       break;
   182     bool offsetFound = false;
   183     for (uint32_t attrIdx = 0; attrIdx < aAttrArrayLen; attrIdx++) {
   184       TextAttr* textAttr = aAttrArray[attrIdx];
   186       // Alter the end offset when text attribute changes its value and stop
   187       // the search.
   188       if (!textAttr->Equal(currAcc)) {
   189         offsetFound = true;
   190         break;
   191       }
   192     }
   194     if (offsetFound)
   195       break;
   197     (*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
   198   }
   199 }
   202 ////////////////////////////////////////////////////////////////////////////////
   203 // LangTextAttr
   204 ////////////////////////////////////////////////////////////////////////////////
   206 TextAttrsMgr::LangTextAttr::
   207   LangTextAttr(HyperTextAccessible* aRoot,
   208                nsIContent* aRootElm, nsIContent* aElm) :
   209   TTextAttr<nsString>(!aElm), mRootContent(aRootElm)
   210 {
   211   aRoot->Language(mRootNativeValue);
   212   mIsRootDefined =  !mRootNativeValue.IsEmpty();
   214   if (aElm) {
   215     nsCoreUtils::GetLanguageFor(aElm, mRootContent, mNativeValue);
   216     mIsDefined = !mNativeValue.IsEmpty();
   217   }
   218 }
   220 TextAttrsMgr::LangTextAttr::
   221   ~LangTextAttr() {}
   223 bool
   224 TextAttrsMgr::LangTextAttr::
   225   GetValueFor(Accessible* aAccessible, nsString* aValue)
   226 {
   227   nsCoreUtils::GetLanguageFor(aAccessible->GetContent(), mRootContent, *aValue);
   228   return !aValue->IsEmpty();
   229 }
   231 void
   232 TextAttrsMgr::LangTextAttr::
   233   ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
   234 {
   235   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::language, aValue);
   236 }
   238 ////////////////////////////////////////////////////////////////////////////////
   239 // InvalidTextAttr
   240 ////////////////////////////////////////////////////////////////////////////////
   242 TextAttrsMgr::InvalidTextAttr::
   243   InvalidTextAttr(nsIContent* aRootElm, nsIContent* aElm) :
   244   TTextAttr<uint32_t>(!aElm), mRootElm(aRootElm)
   245 {
   246   mIsRootDefined = GetValue(mRootElm, &mRootNativeValue);
   247   if (aElm)
   248     mIsDefined = GetValue(aElm, &mNativeValue);
   249 }
   251 bool
   252 TextAttrsMgr::InvalidTextAttr::
   253   GetValueFor(Accessible* aAccessible, uint32_t* aValue)
   254 {
   255   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   256   return elm ? GetValue(elm, aValue) : false;
   257 }
   259 void
   260 TextAttrsMgr::InvalidTextAttr::
   261   ExposeValue(nsIPersistentProperties* aAttributes, const uint32_t& aValue)
   262 {
   263   switch (aValue) {
   264     case eFalse:
   265       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
   266                              NS_LITERAL_STRING("false"));
   267       break;
   269     case eGrammar:
   270       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
   271                              NS_LITERAL_STRING("grammar"));
   272       break;
   274     case eSpelling:
   275       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
   276                              NS_LITERAL_STRING("spelling"));
   277       break;
   279     case eTrue:
   280       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
   281                              NS_LITERAL_STRING("true"));
   282       break;
   283   }
   284 }
   286 bool
   287 TextAttrsMgr::InvalidTextAttr::
   288   GetValue(nsIContent* aElm, uint32_t* aValue)
   289 {
   290   nsIContent* elm = aElm;
   291   do {
   292     if (nsAccUtils::HasDefinedARIAToken(elm, nsGkAtoms::aria_invalid)) {
   293       static nsIContent::AttrValuesArray tokens[] =
   294         { &nsGkAtoms::_false, &nsGkAtoms::grammar, &nsGkAtoms::spelling,
   295           nullptr };
   297       int32_t idx = elm->FindAttrValueIn(kNameSpaceID_None,
   298                                          nsGkAtoms::aria_invalid, tokens,
   299                                          eCaseMatters);
   300       switch (idx) {
   301         case 0:
   302           *aValue = eFalse;
   303           return true;
   304         case 1:
   305           *aValue = eGrammar;
   306           return true;
   307         case 2:
   308           *aValue = eSpelling;
   309           return true;
   310         default:
   311           *aValue = eTrue;
   312           return true;
   313       }
   314     }
   315   } while ((elm = elm->GetParent()) && elm != mRootElm);
   317   return false;
   318 }
   321 ////////////////////////////////////////////////////////////////////////////////
   322 // BGColorTextAttr
   323 ////////////////////////////////////////////////////////////////////////////////
   325 TextAttrsMgr::BGColorTextAttr::
   326   BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   327   TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame)
   328 {
   329   mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
   330   if (aFrame)
   331     mIsDefined = GetColor(aFrame, &mNativeValue);
   332 }
   334 bool
   335 TextAttrsMgr::BGColorTextAttr::
   336   GetValueFor(Accessible* aAccessible, nscolor* aValue)
   337 {
   338   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   339   nsIFrame* frame = elm->GetPrimaryFrame();
   340   return frame ? GetColor(frame, aValue) : false;
   341 }
   343 void
   344 TextAttrsMgr::BGColorTextAttr::
   345   ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
   346 {
   347   nsAutoString formattedValue;
   348   StyleInfo::FormatColor(aValue, formattedValue);
   349   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::backgroundColor,
   350                          formattedValue);
   351 }
   353 bool
   354 TextAttrsMgr::BGColorTextAttr::
   355   GetColor(nsIFrame* aFrame, nscolor* aColor)
   356 {
   357   const nsStyleBackground* styleBackground = aFrame->StyleBackground();
   359   if (NS_GET_A(styleBackground->mBackgroundColor) > 0) {
   360     *aColor = styleBackground->mBackgroundColor;
   361     return true;
   362   }
   364   nsIFrame *parentFrame = aFrame->GetParent();
   365   if (!parentFrame) {
   366     *aColor = aFrame->PresContext()->DefaultBackgroundColor();
   367     return true;
   368   }
   370   // Each frame of parents chain for the initially passed 'aFrame' has
   371   // transparent background color. So background color isn't changed from
   372   // 'mRootFrame' to initially passed 'aFrame'.
   373   if (parentFrame == mRootFrame)
   374     return false;
   376   return GetColor(parentFrame, aColor);
   377 }
   380 ////////////////////////////////////////////////////////////////////////////////
   381 // ColorTextAttr
   382 ////////////////////////////////////////////////////////////////////////////////
   384 TextAttrsMgr::ColorTextAttr::
   385   ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   386   TTextAttr<nscolor>(!aFrame)
   387 {
   388   mRootNativeValue = aRootFrame->StyleColor()->mColor;
   389   mIsRootDefined = true;
   391   if (aFrame) {
   392     mNativeValue = aFrame->StyleColor()->mColor;
   393     mIsDefined = true;
   394   }
   395 }
   397 bool
   398 TextAttrsMgr::ColorTextAttr::
   399   GetValueFor(Accessible* aAccessible, nscolor* aValue)
   400 {
   401   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   402   nsIFrame* frame = elm->GetPrimaryFrame();
   403   if (frame) {
   404     *aValue = frame->StyleColor()->mColor;
   405     return true;
   406   }
   408   return false;
   409 }
   411 void
   412 TextAttrsMgr::ColorTextAttr::
   413   ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
   414 {
   415   nsAutoString formattedValue;
   416   StyleInfo::FormatColor(aValue, formattedValue);
   417   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::color, formattedValue);
   418 }
   421 ////////////////////////////////////////////////////////////////////////////////
   422 // FontFamilyTextAttr
   423 ////////////////////////////////////////////////////////////////////////////////
   425 TextAttrsMgr::FontFamilyTextAttr::
   426   FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   427   TTextAttr<nsString>(!aFrame)
   428 {
   429   mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
   431   if (aFrame)
   432     mIsDefined = GetFontFamily(aFrame, mNativeValue);
   433 }
   435 bool
   436 TextAttrsMgr::FontFamilyTextAttr::
   437   GetValueFor(Accessible* aAccessible, nsString* aValue)
   438 {
   439   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   440   nsIFrame* frame = elm->GetPrimaryFrame();
   441   return frame ? GetFontFamily(frame, *aValue) : false;
   442 }
   444 void
   445 TextAttrsMgr::FontFamilyTextAttr::
   446   ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
   447 {
   448   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
   449 }
   451 bool
   452 TextAttrsMgr::FontFamilyTextAttr::
   453   GetFontFamily(nsIFrame* aFrame, nsString& aFamily)
   454 {
   455   nsRefPtr<nsFontMetrics> fm;
   456   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
   458   gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
   459   gfxFont* font = fontGroup->GetFontAt(0);
   460   gfxFontEntry* fontEntry = font->GetFontEntry();
   461   aFamily = fontEntry->FamilyName();
   462   return true;
   463 }
   466 ////////////////////////////////////////////////////////////////////////////////
   467 // FontSizeTextAttr
   468 ////////////////////////////////////////////////////////////////////////////////
   470 TextAttrsMgr::FontSizeTextAttr::
   471   FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   472   TTextAttr<nscoord>(!aFrame)
   473 {
   474   mDC = aRootFrame->PresContext()->DeviceContext();
   476   mRootNativeValue = aRootFrame->StyleFont()->mSize;
   477   mIsRootDefined = true;
   479   if (aFrame) {
   480     mNativeValue = aFrame->StyleFont()->mSize;
   481     mIsDefined = true;
   482   }
   483 }
   485 bool
   486 TextAttrsMgr::FontSizeTextAttr::
   487   GetValueFor(Accessible* aAccessible, nscoord* aValue)
   488 {
   489   nsIContent* content = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   490   nsIFrame* frame = content->GetPrimaryFrame();
   491   if (frame) {
   492     *aValue = frame->StyleFont()->mSize;
   493     return true;
   494   }
   496   return false;
   497 }
   499 void
   500 TextAttrsMgr::FontSizeTextAttr::
   501   ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
   502 {
   503   // Convert from nscoord to pt.
   504   //
   505   // Note: according to IA2, "The conversion doesn't have to be exact.
   506   // The intent is to give the user a feel for the size of the text."
   507   //
   508   // ATK does not specify a unit and will likely follow IA2 here.
   509   //
   510   // XXX todo: consider sharing this code with layout module? (bug 474621)
   511   float px =
   512     NSAppUnitsToFloatPixels(aValue, mozilla::AppUnitsPerCSSPixel());
   513   // Each pt is 4/3 of a CSS pixel.
   514   int pts = NS_lround(px*3/4);
   516   nsAutoString value;
   517   value.AppendInt(pts);
   518   value.Append(NS_LITERAL_STRING("pt"));
   520   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_size, value);
   521 }
   524 ////////////////////////////////////////////////////////////////////////////////
   525 // FontStyleTextAttr
   526 ////////////////////////////////////////////////////////////////////////////////
   528 TextAttrsMgr::FontStyleTextAttr::
   529   FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   530   TTextAttr<nscoord>(!aFrame)
   531 {
   532   mRootNativeValue = aRootFrame->StyleFont()->mFont.style;
   533   mIsRootDefined = true;
   535   if (aFrame) {
   536     mNativeValue = aFrame->StyleFont()->mFont.style;
   537     mIsDefined = true;
   538   }
   539 }
   541 bool
   542 TextAttrsMgr::FontStyleTextAttr::
   543   GetValueFor(Accessible* aAccessible, nscoord* aValue)
   544 {
   545   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   546   nsIFrame* frame = elm->GetPrimaryFrame();
   547   if (frame) {
   548     *aValue = frame->StyleFont()->mFont.style;
   549     return true;
   550   }
   552   return false;
   553 }
   555 void
   556 TextAttrsMgr::FontStyleTextAttr::
   557   ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
   558 {
   559   nsAutoString formattedValue;
   560   StyleInfo::FormatFontStyle(aValue, formattedValue);
   562   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_style, formattedValue);
   563 }
   566 ////////////////////////////////////////////////////////////////////////////////
   567 // FontWeightTextAttr
   568 ////////////////////////////////////////////////////////////////////////////////
   570 TextAttrsMgr::FontWeightTextAttr::
   571   FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   572   TTextAttr<int32_t>(!aFrame)
   573 {
   574   mRootNativeValue = GetFontWeight(aRootFrame);
   575   mIsRootDefined = true;
   577   if (aFrame) {
   578     mNativeValue = GetFontWeight(aFrame);
   579     mIsDefined = true;
   580   }
   581 }
   583 bool
   584 TextAttrsMgr::FontWeightTextAttr::
   585   GetValueFor(Accessible* aAccessible, int32_t* aValue)
   586 {
   587   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   588   nsIFrame* frame = elm->GetPrimaryFrame();
   589   if (frame) {
   590     *aValue = GetFontWeight(frame);
   591     return true;
   592   }
   594   return false;
   595 }
   597 void
   598 TextAttrsMgr::FontWeightTextAttr::
   599   ExposeValue(nsIPersistentProperties* aAttributes, const int32_t& aValue)
   600 {
   601   nsAutoString formattedValue;
   602   formattedValue.AppendInt(aValue);
   604   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::fontWeight, formattedValue);
   605 }
   607 int32_t
   608 TextAttrsMgr::FontWeightTextAttr::
   609   GetFontWeight(nsIFrame* aFrame)
   610 {
   611   // nsFont::width isn't suitable here because it's necessary to expose real
   612   // value of font weight (used font might not have some font weight values).
   613   nsRefPtr<nsFontMetrics> fm;
   614   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
   616   gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
   617   gfxFont *font = fontGroup->GetFontAt(0);
   619   // When there doesn't exist a bold font in the family and so the rendering of
   620   // a non-bold font face is changed so that the user sees what looks like a
   621   // bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
   622   // needed on Mac, but it is "safe" to use on all platforms.  (For non-Mac
   623   // platforms it always return false.)
   624   if (font->IsSyntheticBold())
   625     return 700;
   627 #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
   628   // On Linux, font->GetStyle()->weight will give the absolute weight requested
   629   // of the font face. The Linux code uses the gfxFontEntry constructor which
   630   // doesn't initialize the weight field.
   631   return font->GetStyle()->weight;
   632 #else
   633   // On Windows, font->GetStyle()->weight will give the same weight as
   634   // fontEntry->Weight(), the weight of the first font in the font group, which
   635   // may not be the weight of the font face used to render the characters.
   636   // On Mac, font->GetStyle()->weight will just give the same number as
   637   // getComputedStyle(). fontEntry->Weight() will give the weight of the font
   638   // face used.
   639   gfxFontEntry *fontEntry = font->GetFontEntry();
   640   return fontEntry->Weight();
   641 #endif
   642 }
   644 ////////////////////////////////////////////////////////////////////////////////
   645 // AutoGeneratedTextAttr
   646 ////////////////////////////////////////////////////////////////////////////////
   647 TextAttrsMgr::AutoGeneratedTextAttr::
   648   AutoGeneratedTextAttr(HyperTextAccessible* aHyperTextAcc,
   649                         Accessible* aAccessible) :
   650   TTextAttr<bool>(!aAccessible)
   651 {
   652   mRootNativeValue = false;
   653   mIsRootDefined = false;
   655   if (aAccessible)
   656     mIsDefined = mNativeValue = (aAccessible->NativeRole() == roles::STATICTEXT);
   657 }
   659 bool
   660 TextAttrsMgr::AutoGeneratedTextAttr::
   661   GetValueFor(Accessible* aAccessible, bool* aValue)
   662 {
   663   return *aValue = (aAccessible->NativeRole() == roles::STATICTEXT);
   664 }
   666 void
   667 TextAttrsMgr::AutoGeneratedTextAttr::
   668   ExposeValue(nsIPersistentProperties* aAttributes, const bool& aValue)
   669 {
   670   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::auto_generated,
   671                          aValue ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"));
   672 }
   675 ////////////////////////////////////////////////////////////////////////////////
   676 // TextDecorTextAttr
   677 ////////////////////////////////////////////////////////////////////////////////
   679 TextAttrsMgr::TextDecorValue::
   680   TextDecorValue(nsIFrame* aFrame)
   681 {
   682   const nsStyleTextReset* textReset = aFrame->StyleTextReset();
   683   mStyle = textReset->GetDecorationStyle();
   685   bool isForegroundColor = false;
   686   textReset->GetDecorationColor(mColor, isForegroundColor);
   687   if (isForegroundColor)
   688     mColor = aFrame->StyleColor()->mColor;
   690   mLine = textReset->mTextDecorationLine &
   691     (NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE |
   692      NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
   693 }
   695 TextAttrsMgr::TextDecorTextAttr::
   696   TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   697   TTextAttr<TextDecorValue>(!aFrame)
   698 {
   699   mRootNativeValue = TextDecorValue(aRootFrame);
   700   mIsRootDefined = mRootNativeValue.IsDefined();
   702   if (aFrame) {
   703     mNativeValue = TextDecorValue(aFrame);
   704     mIsDefined = mNativeValue.IsDefined();
   705   }
   706 }
   708 bool
   709 TextAttrsMgr::TextDecorTextAttr::
   710   GetValueFor(Accessible* aAccessible, TextDecorValue* aValue)
   711 {
   712   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   713   nsIFrame* frame = elm->GetPrimaryFrame();
   714   if (frame) {
   715     *aValue = TextDecorValue(frame);
   716     return aValue->IsDefined();
   717   }
   719   return false;
   720 }
   722 void
   723 TextAttrsMgr::TextDecorTextAttr::
   724   ExposeValue(nsIPersistentProperties* aAttributes, const TextDecorValue& aValue)
   725 {
   726   if (aValue.IsUnderline()) {
   727     nsAutoString formattedStyle;
   728     StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
   729     nsAccUtils::SetAccAttr(aAttributes,
   730                            nsGkAtoms::textUnderlineStyle,
   731                            formattedStyle);
   733     nsAutoString formattedColor;
   734     StyleInfo::FormatColor(aValue.Color(), formattedColor);
   735     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textUnderlineColor,
   736                            formattedColor);
   737     return;
   738   }
   740   if (aValue.IsLineThrough()) {
   741     nsAutoString formattedStyle;
   742     StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
   743     nsAccUtils::SetAccAttr(aAttributes,
   744                            nsGkAtoms::textLineThroughStyle,
   745                            formattedStyle);
   747     nsAutoString formattedColor;
   748     StyleInfo::FormatColor(aValue.Color(), formattedColor);
   749     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textLineThroughColor,
   750                            formattedColor);
   751   }
   752 }
   754 ////////////////////////////////////////////////////////////////////////////////
   755 // TextPosTextAttr
   756 ////////////////////////////////////////////////////////////////////////////////
   758 TextAttrsMgr::TextPosTextAttr::
   759   TextPosTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
   760   TTextAttr<TextPosValue>(!aFrame)
   761 {
   762   mRootNativeValue = GetTextPosValue(aRootFrame);
   763   mIsRootDefined = mRootNativeValue != eTextPosNone;
   765   if (aFrame) {
   766     mNativeValue = GetTextPosValue(aFrame);
   767     mIsDefined = mNativeValue != eTextPosNone;
   768   }
   769 }
   771 bool
   772 TextAttrsMgr::TextPosTextAttr::
   773   GetValueFor(Accessible* aAccessible, TextPosValue* aValue)
   774 {
   775   nsIContent* elm = nsCoreUtils::GetDOMElementFor(aAccessible->GetContent());
   776   nsIFrame* frame = elm->GetPrimaryFrame();
   777   if (frame) {
   778     *aValue = GetTextPosValue(frame);
   779     return *aValue != eTextPosNone;
   780   }
   782   return false;
   783 }
   785 void
   786 TextAttrsMgr::TextPosTextAttr::
   787   ExposeValue(nsIPersistentProperties* aAttributes, const TextPosValue& aValue)
   788 {
   789   switch (aValue) {
   790     case eTextPosBaseline:
   791       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
   792                              NS_LITERAL_STRING("baseline"));
   793       break;
   795     case eTextPosSub:
   796       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
   797                              NS_LITERAL_STRING("sub"));
   798       break;
   800     case eTextPosSuper:
   801       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
   802                              NS_LITERAL_STRING("super"));
   803       break;
   805     case eTextPosNone:
   806       break;
   807   }
   808 }
   810 TextAttrsMgr::TextPosValue
   811 TextAttrsMgr::TextPosTextAttr::
   812   GetTextPosValue(nsIFrame* aFrame) const
   813 {
   814   const nsStyleCoord& styleCoord = aFrame->StyleTextReset()->mVerticalAlign;
   815   switch (styleCoord.GetUnit()) {
   816     case eStyleUnit_Enumerated:
   817       switch (styleCoord.GetIntValue()) {
   818         case NS_STYLE_VERTICAL_ALIGN_BASELINE:
   819           return eTextPosBaseline;
   820         case NS_STYLE_VERTICAL_ALIGN_SUB:
   821           return eTextPosSub;
   822         case NS_STYLE_VERTICAL_ALIGN_SUPER:
   823           return eTextPosSuper;
   825         // No good guess for these:
   826         //   NS_STYLE_VERTICAL_ALIGN_TOP
   827         //   NS_STYLE_VERTICAL_ALIGN_TEXT_TOP
   828         //   NS_STYLE_VERTICAL_ALIGN_MIDDLE
   829         //   NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM
   830         //   NS_STYLE_VERTICAL_ALIGN_BOTTOM
   831         //   NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE
   832         // Do not expose value of text-position attribute.
   834         default:
   835           break;
   836       }
   837       return eTextPosNone;
   839     case eStyleUnit_Percent:
   840     {
   841       float percentValue = styleCoord.GetPercentValue();
   842       return percentValue > 0 ?
   843         eTextPosSuper :
   844         (percentValue < 0 ? eTextPosSub : eTextPosBaseline);
   845     }
   847     case eStyleUnit_Coord:
   848     {
   849        nscoord coordValue = styleCoord.GetCoordValue();
   850        return coordValue > 0 ?
   851          eTextPosSuper :
   852          (coordValue < 0 ? eTextPosSub : eTextPosBaseline);
   853     }
   855     case eStyleUnit_Null:
   856     case eStyleUnit_Normal:
   857     case eStyleUnit_Auto:
   858     case eStyleUnit_None:
   859     case eStyleUnit_Factor:
   860     case eStyleUnit_Degree:
   861     case eStyleUnit_Grad:
   862     case eStyleUnit_Radian:
   863     case eStyleUnit_Turn:
   864     case eStyleUnit_FlexFraction:
   865     case eStyleUnit_Integer:
   866     case eStyleUnit_Calc:
   867       break;
   868   }
   870   const nsIContent* content = aFrame->GetContent();
   871   if (content && content->IsHTML()) {
   872     const nsIAtom* tagName = content->Tag();
   873     if (tagName == nsGkAtoms::sup) 
   874       return eTextPosSuper;
   875     if (tagName == nsGkAtoms::sub) 
   876       return eTextPosSub;
   877   }
   879   return eTextPosNone;
   880 }

mercurial