LCOV - app.info - layout/xul/base/src/nsTextBoxFrame.cpp

LCOV - code coverage report
| Current view: | directory - layout/xul/base/src - nsTextBoxFrame.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 475 | 0 | 0.0 %
| Date: | 2012-06-02 | Functions: | 47 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Mozilla Communicator client code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Eric Vaughan, Netscape Communications
          24                 :  *   Peter Annema <disttsc@bart.nl>
          25                 :  *   Dean Tessman <dean_tessman@hotmail.com>
          26                 :  *   Masayuki Nakano <masayuki@d-toybox.com>
          27                 :  *
          28                 :  * Alternatively, the contents of this file may be used under the terms of
          29                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          30                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          32                 :  * of those above. If you wish to allow use of your version of this file only
          33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          34                 :  * use your version of this file under the terms of the MPL, indicate your
          35                 :  * decision by deleting the provisions above and replace them with the notice
          36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          37                 :  * the provisions above, a recipient may use your version of this file under
          38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          39                 :  *
          40                 :  * ***** END LICENSE BLOCK ***** */
          41                 :
          42                 : #include "nsTextBoxFrame.h"
          43                 :
          44                 : #include "nsReadableUtils.h"
          45                 : #include "nsCOMPtr.h"
          46                 : #include "nsGkAtoms.h"
          47                 : #include "nsPresContext.h"
          48                 : #include "nsRenderingContext.h"
          49                 : #include "nsStyleContext.h"
          50                 : #include "nsIContent.h"
          51                 : #include "nsINameSpaceManager.h"
          52                 : #include "nsBoxLayoutState.h"
          53                 : #include "nsMenuBarListener.h"
          54                 : #include "nsXPIDLString.h"
          55                 : #include "nsIServiceManager.h"
          56                 : #include "nsIDocument.h"
          57                 : #include "nsIDOMDocument.h"
          58                 : #include "nsIDOMElement.h"
          59                 : #include "nsIDOMXULLabelElement.h"
          60                 : #include "nsEventStateManager.h"
          61                 : #include "nsITheme.h"
          62                 : #include "nsUnicharUtils.h"
          63                 : #include "nsContentUtils.h"
          64                 : #include "nsDisplayList.h"
          65                 : #include "nsCSSRendering.h"
          66                 : #include "nsIReflowCallback.h"
          67                 : #include "nsBoxFrame.h"
          68                 : #include "mozilla/Preferences.h"
          69                 : #include "nsLayoutUtils.h"
          70                 :
          71                 : #ifdef IBMBIDI
          72                 : #include "nsBidiUtils.h"
          73                 : #include "nsBidiPresUtils.h"
          74                 : #endif // IBMBIDI
          75                 :
          76                 : using namespace mozilla;
          77                 :
          78                 : class nsAccessKeyInfo
          79                 : {
          80                 : public:
          81                 :     PRInt32 mAccesskeyIndex;
          82                 :     nscoord mBeforeWidth, mAccessWidth, mAccessUnderlineSize, mAccessOffset;
          83                 : };
          84                 :
          85                 :
          86                 : bool nsTextBoxFrame::gAlwaysAppendAccessKey          = false;
          87                 : bool nsTextBoxFrame::gAccessKeyPrefInitialized       = false;
          88                 : bool nsTextBoxFrame::gInsertSeparatorBeforeAccessKey = false;
          89                 : bool nsTextBoxFrame::gInsertSeparatorPrefInitialized = false;
          90                 :
          91                 : nsIFrame*
          92               0 : NS_NewTextBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
          93                 : {
          94               0 :     return new (aPresShell) nsTextBoxFrame (aPresShell, aContext);
          95                 : }
          96                 :
          97               0 : NS_IMPL_FRAMEARENA_HELPERS(nsTextBoxFrame)
          98                 :
          99                 :
         100                 : NS_IMETHODIMP
         101               0 : nsTextBoxFrame::AttributeChanged(PRInt32         aNameSpaceID,
         102                 :                                  nsIAtom*        aAttribute,
         103                 :                                  PRInt32         aModType)
         104                 : {
         105                 :     bool aResize;
         106                 :     bool aRedraw;
         107                 :
         108               0 :     UpdateAttributes(aAttribute, aResize, aRedraw);
         109                 :
         110               0 :     if (aResize) {
         111               0 :         PresContext()->PresShell()->
         112                 :             FrameNeedsReflow(this, nsIPresShell::eStyleChange,
         113               0 :                              NS_FRAME_IS_DIRTY);
         114               0 :     } else if (aRedraw) {
         115               0 :         nsBoxLayoutState state(PresContext());
         116               0 :         Redraw(state);
         117                 :     }
         118                 :
         119                 :     // If the accesskey changed, register for the new value
         120                 :     // The old value has been unregistered in nsXULElement::SetAttr
         121               0 :     if (aAttribute == nsGkAtoms::accesskey || aAttribute == nsGkAtoms::control)
         122               0 :         RegUnregAccessKey(true);
         123                 :
         124               0 :     return NS_OK;
         125                 : }
         126                 :
         127               0 : nsTextBoxFrame::nsTextBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext):
         128                 :   nsLeafBoxFrame(aShell, aContext), mAccessKeyInfo(nsnull), mCropType(CropRight),
         129               0 :   mNeedsReflowCallback(false)
         130                 : {
         131               0 :     MarkIntrinsicWidthsDirty();
         132               0 : }
         133                 :
         134               0 : nsTextBoxFrame::~nsTextBoxFrame()
         135                 : {
         136               0 :     delete mAccessKeyInfo;
         137               0 : }
         138                 :
         139                 :
         140                 : NS_IMETHODIMP
         141               0 : nsTextBoxFrame::Init(nsIContent*      aContent,
         142                 :                      nsIFrame*        aParent,
         143                 :                      nsIFrame*        aPrevInFlow)
         144                 : {
         145               0 :     nsTextBoxFrameSuper::Init(aContent, aParent, aPrevInFlow);
         146                 :
         147                 :     bool aResize;
         148                 :     bool aRedraw;
         149               0 :     UpdateAttributes(nsnull, aResize, aRedraw); /* update all */
         150                 :
         151                 :     // register access key
         152               0 :     RegUnregAccessKey(true);
         153                 :
         154               0 :     return NS_OK;
         155                 : }
         156                 :
         157                 : void
         158               0 : nsTextBoxFrame::DestroyFrom(nsIFrame* aDestructRoot)
         159                 : {
         160                 :     // unregister access key
         161               0 :     RegUnregAccessKey(false);
         162               0 :     nsTextBoxFrameSuper::DestroyFrom(aDestructRoot);
         163               0 : }
         164                 :
         165                 : bool
         166               0 : nsTextBoxFrame::AlwaysAppendAccessKey()
         167                 : {
         168               0 :   if (!gAccessKeyPrefInitialized)
         169                 :   {
         170               0 :     gAccessKeyPrefInitialized = true;
         171                 :
         172               0 :     const char* prefName = "intl.menuitems.alwaysappendaccesskeys";
         173               0 :     nsAdoptingString val = Preferences::GetLocalizedString(prefName);
         174               0 :     gAlwaysAppendAccessKey = val.Equals(NS_LITERAL_STRING("true"));
         175                 :   }
         176               0 :   return gAlwaysAppendAccessKey;
         177                 : }
         178                 :
         179                 : bool
         180               0 : nsTextBoxFrame::InsertSeparatorBeforeAccessKey()
         181                 : {
         182               0 :   if (!gInsertSeparatorPrefInitialized)
         183                 :   {
         184               0 :     gInsertSeparatorPrefInitialized = true;
         185                 :
         186               0 :     const char* prefName = "intl.menuitems.insertseparatorbeforeaccesskeys";
         187               0 :     nsAdoptingString val = Preferences::GetLocalizedString(prefName);
         188               0 :     gInsertSeparatorBeforeAccessKey = val.EqualsLiteral("true");
         189                 :   }
         190               0 :   return gInsertSeparatorBeforeAccessKey;
         191                 : }
         192                 :
         193                 : class nsAsyncAccesskeyUpdate : public nsIReflowCallback
         194               0 : {
         195                 : public:
         196               0 :     nsAsyncAccesskeyUpdate(nsIFrame* aFrame) : mWeakFrame(aFrame)
         197                 :     {
         198               0 :     }
         199                 :
         200               0 :     virtual bool ReflowFinished()
         201                 :     {
         202               0 :         bool shouldFlush = false;
         203                 :         nsTextBoxFrame* frame =
         204               0 :             static_cast<nsTextBoxFrame*>(mWeakFrame.GetFrame());
         205               0 :         if (frame) {
         206               0 :             shouldFlush = frame->UpdateAccesskey(mWeakFrame);
         207                 :         }
         208               0 :         delete this;
         209               0 :         return shouldFlush;
         210                 :     }
         211                 :
         212               0 :     virtual void ReflowCallbackCanceled()
         213                 :     {
         214               0 :         delete this;
         215               0 :     }
         216                 :
         217                 :     nsWeakFrame mWeakFrame;
         218                 : };
         219                 :
         220                 : bool
         221               0 : nsTextBoxFrame::UpdateAccesskey(nsWeakFrame& aWeakThis)
         222                 : {
         223               0 :     nsAutoString accesskey;
         224               0 :     nsCOMPtr<nsIDOMXULLabelElement> labelElement = do_QueryInterface(mContent);
         225               0 :     NS_ENSURE_TRUE(aWeakThis.IsAlive(), false);
         226               0 :     if (labelElement) {
         227                 :         // Accesskey may be stored on control.
         228                 :         // Because this method is called by the reflow callback, current context
         229                 :         // may not be the right one. Pushing the context of mContent so that
         230                 :         // if nsIDOMXULLabelElement is implemented in XBL, we don't get a
         231                 :         // security exception.
         232               0 :         nsCxPusher cx;
         233               0 :         if (cx.Push(mContent)) {
         234               0 :           labelElement->GetAccessKey(accesskey);
         235               0 :           NS_ENSURE_TRUE(aWeakThis.IsAlive(), false);
         236                 :         }
         237                 :     }
         238                 :     else {
         239               0 :         mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accesskey);
         240                 :     }
         241                 :
         242               0 :     if (!accesskey.Equals(mAccessKey)) {
         243                 :         // Need to get clean mTitle.
         244               0 :         mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, mTitle);
         245               0 :         mAccessKey = accesskey;
         246               0 :         UpdateAccessTitle();
         247               0 :         PresContext()->PresShell()->
         248                 :             FrameNeedsReflow(this, nsIPresShell::eStyleChange,
         249               0 :                              NS_FRAME_IS_DIRTY);
         250               0 :         return true;
         251                 :     }
         252               0 :     return false;
         253                 : }
         254                 :
         255                 : void
         256               0 : nsTextBoxFrame::UpdateAttributes(nsIAtom*         aAttribute,
         257                 :                                  bool&          aResize,
         258                 :                                  bool&          aRedraw)
         259                 : {
         260               0 :     bool doUpdateTitle = false;
         261               0 :     aResize = false;
         262               0 :     aRedraw = false;
         263                 :
         264               0 :     if (aAttribute == nsnull || aAttribute == nsGkAtoms::crop) {
         265                 :         static nsIContent::AttrValuesArray strings[] =
         266                 :           {&nsGkAtoms::left, &nsGkAtoms::start, &nsGkAtoms::center,
         267                 :            &nsGkAtoms::right, &nsGkAtoms::end, nsnull};
         268                 :         CroppingStyle cropType;
         269               0 :         switch (mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::crop,
         270               0 :                                           strings, eCaseMatters)) {
         271                 :           case 0:
         272                 :           case 1:
         273               0 :             cropType = CropLeft;
         274               0 :             break;
         275                 :           case 2:
         276               0 :             cropType = CropCenter;
         277               0 :             break;
         278                 :           case 3:
         279                 :           case 4:
         280               0 :             cropType = CropRight;
         281               0 :             break;
         282                 :           default:
         283               0 :             cropType = CropNone;
         284               0 :             break;
         285                 :         }
         286                 :
         287               0 :         if (cropType != mCropType) {
         288               0 :             aResize = true;
         289               0 :             mCropType = cropType;
         290                 :         }
         291                 :     }
         292                 :
         293               0 :     if (aAttribute == nsnull || aAttribute == nsGkAtoms::value) {
         294               0 :         mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, mTitle);
         295               0 :         doUpdateTitle = true;
         296                 :     }
         297                 :
         298               0 :     if (aAttribute == nsnull || aAttribute == nsGkAtoms::accesskey) {
         299               0 :         mNeedsReflowCallback = true;
         300                 :         // Ensure that layout is refreshed and reflow callback called.
         301               0 :         aResize = true;
         302                 :     }
         303                 :
         304               0 :     if (doUpdateTitle) {
         305               0 :         UpdateAccessTitle();
         306               0 :         aResize = true;
         307                 :     }
         308                 :
         309               0 : }
         310                 :
         311                 : class nsDisplayXULTextBox : public nsDisplayItem {
         312                 : public:
         313               0 :   nsDisplayXULTextBox(nsDisplayListBuilder* aBuilder,
         314                 :                       nsTextBoxFrame* aFrame) :
         315                 :     nsDisplayItem(aBuilder, aFrame),
         316               0 :     mDisableSubpixelAA(false)
         317                 :   {
         318               0 :     MOZ_COUNT_CTOR(nsDisplayXULTextBox);
         319               0 :   }
         320                 : #ifdef NS_BUILD_REFCNT_LOGGING
         321               0 :   virtual ~nsDisplayXULTextBox() {
         322               0 :     MOZ_COUNT_DTOR(nsDisplayXULTextBox);
         323               0 :   }
         324                 : #endif
         325                 :
         326                 :   virtual void Paint(nsDisplayListBuilder* aBuilder,
         327                 :                      nsRenderingContext* aCtx);
         328                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
         329               0 :   NS_DISPLAY_DECL_NAME("XULTextBox", TYPE_XUL_TEXT_BOX)
         330                 :
         331                 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
         332                 :
         333               0 :   virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; }
         334                 :
         335                 :   void PaintTextToContext(nsRenderingContext* aCtx,
         336                 :                           nsPoint aOffset,
         337                 :                           const nscolor* aColor);
         338                 :
         339                 :   bool mDisableSubpixelAA;
         340                 : };
         341                 :
         342                 : static void
         343               0 : PaintTextShadowCallback(nsRenderingContext* aCtx,
         344                 :                         nsPoint aShadowOffset,
         345                 :                         const nscolor& aShadowColor,
         346                 :                         void* aData)
         347                 : {
         348                 :   reinterpret_cast<nsDisplayXULTextBox*>(aData)->
         349               0 :            PaintTextToContext(aCtx, aShadowOffset, &aShadowColor);
         350               0 : }
         351                 :
         352                 : void
         353               0 : nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
         354                 :                            nsRenderingContext* aCtx)
         355                 : {
         356                 :   gfxContextAutoDisableSubpixelAntialiasing disable(aCtx->ThebesContext(),
         357               0 :                                                     mDisableSubpixelAA);
         358                 :
         359                 :   // Paint the text shadow before doing any foreground stuff
         360                 :   nsRect drawRect = static_cast<nsTextBoxFrame*>(mFrame)->mTextDrawRect +
         361               0 :                     ToReferenceFrame();
         362                 :   nsLayoutUtils::PaintTextShadow(mFrame, aCtx,
         363                 :                                  drawRect, mVisibleRect,
         364               0 :                                  mFrame->GetStyleColor()->mColor,
         365                 :                                  PaintTextShadowCallback,
         366               0 :                                  (void*)this);
         367                 :
         368               0 :   PaintTextToContext(aCtx, nsPoint(0, 0), nsnull);
         369               0 : }
         370                 :
         371                 : void
         372               0 : nsDisplayXULTextBox::PaintTextToContext(nsRenderingContext* aCtx,
         373                 :                                         nsPoint aOffset,
         374                 :                                         const nscolor* aColor)
         375                 : {
         376                 :   static_cast<nsTextBoxFrame*>(mFrame)->
         377               0 :     PaintTitle(*aCtx, mVisibleRect, ToReferenceFrame() + aOffset, aColor);
         378               0 : }
         379                 :
         380                 : nsRect
         381               0 : nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder) {
         382               0 :   return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
         383                 : }
         384                 :
         385                 : nsRect
         386               0 : nsDisplayXULTextBox::GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
         387                 : {
         388               0 :   return static_cast<nsTextBoxFrame*>(mFrame)->GetComponentAlphaBounds() +
         389               0 :       ToReferenceFrame();
         390                 : }
         391                 :
         392                 : NS_IMETHODIMP
         393               0 : nsTextBoxFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
         394                 :                                  const nsRect&           aDirtyRect,
         395                 :                                  const nsDisplayListSet& aLists)
         396                 : {
         397               0 :     if (!IsVisibleForPainting(aBuilder))
         398               0 :       return NS_OK;
         399                 :
         400               0 :     nsresult rv = nsLeafBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
         401               0 :     NS_ENSURE_SUCCESS(rv, rv);
         402                 :
         403                 :     return aLists.Content()->AppendNewToTop(new (aBuilder)
         404               0 :         nsDisplayXULTextBox(aBuilder, this));
         405                 : }
         406                 :
         407                 : void
         408               0 : nsTextBoxFrame::PaintTitle(nsRenderingContext& aRenderingContext,
         409                 :                            const nsRect&        aDirtyRect,
         410                 :                            nsPoint              aPt,
         411                 :                            const nscolor*       aOverrideColor)
         412                 : {
         413               0 :     if (mTitle.IsEmpty())
         414               0 :         return;
         415                 :
         416               0 :     DrawText(aRenderingContext, aDirtyRect, mTextDrawRect + aPt, aOverrideColor);
         417                 : }
         418                 :
         419                 : void
         420               0 : nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext,
         421                 :                          const nsRect&       aDirtyRect,
         422                 :                          const nsRect&       aTextRect,
         423                 :                          const nscolor*      aOverrideColor)
         424                 : {
         425               0 :     nsPresContext* presContext = PresContext();
         426                 :
         427                 :     // paint the title
         428                 :     nscolor overColor;
         429                 :     nscolor underColor;
         430                 :     nscolor strikeColor;
         431                 :     PRUint8 overStyle;
         432                 :     PRUint8 underStyle;
         433                 :     PRUint8 strikeStyle;
         434                 :
         435                 :     // Begin with no decorations
         436               0 :     PRUint8 decorations = NS_STYLE_TEXT_DECORATION_LINE_NONE;
         437                 :     // A mask of all possible decorations.
         438               0 :     PRUint8 decorMask = NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK;
         439                 :
         440               0 :     nsIFrame* f = this;
         441               0 :     do {  // find decoration colors
         442               0 :       nsStyleContext* context = f->GetStyleContext();
         443               0 :       if (!context->HasTextDecorationLines()) {
         444               0 :         break;
         445                 :       }
         446               0 :       const nsStyleTextReset* styleText = context->GetStyleTextReset();
         447                 :
         448               0 :       if (decorMask & styleText->mTextDecorationLine) {  // a decoration defined here
         449                 :         nscolor color;
         450               0 :         if (aOverrideColor) {
         451               0 :           color = *aOverrideColor;
         452                 :         } else {
         453                 :           bool isForeground;
         454               0 :           styleText->GetDecorationColor(color, isForeground);
         455               0 :           if (isForeground) {
         456               0 :             color = nsLayoutUtils::GetColor(f, eCSSProperty_color);
         457                 :           }
         458                 :         }
         459               0 :         PRUint8 style = styleText->GetDecorationStyle();
         460                 :
         461               0 :         if (NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE & decorMask &
         462                 :               styleText->mTextDecorationLine) {
         463               0 :           underColor = color;
         464               0 :           underStyle = style;
         465               0 :           decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
         466               0 :           decorations |= NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
         467                 :         }
         468               0 :         if (NS_STYLE_TEXT_DECORATION_LINE_OVERLINE & decorMask &
         469                 :               styleText->mTextDecorationLine) {
         470               0 :           overColor = color;
         471               0 :           overStyle = style;
         472               0 :           decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
         473               0 :           decorations |= NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
         474                 :         }
         475               0 :         if (NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH & decorMask &
         476                 :               styleText->mTextDecorationLine) {
         477               0 :           strikeColor = color;
         478               0 :           strikeStyle = style;
         479               0 :           decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
         480               0 :           decorations |= NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
         481                 :         }
         482                 :       }
         483                 :     } while (0 != decorMask &&
         484                 :              (f = nsLayoutUtils::GetParentOrPlaceholderFor(
         485               0 :                                    presContext->FrameManager(), f)));
         486                 :
         487               0 :     nsRefPtr<nsFontMetrics> fontMet;
         488               0 :     nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet));
         489                 :
         490                 :     nscoord offset;
         491                 :     nscoord size;
         492               0 :     nscoord ascent = fontMet->MaxAscent();
         493                 :
         494                 :     nscoord baseline =
         495               0 :       presContext->RoundAppUnitsToNearestDevPixels(aTextRect.y + ascent);
         496               0 :     nsRefPtr<gfxContext> ctx = aRenderingContext.ThebesContext();
         497                 :     gfxPoint pt(presContext->AppUnitsToGfxUnits(aTextRect.x),
         498               0 :                 presContext->AppUnitsToGfxUnits(aTextRect.y));
         499               0 :     gfxFloat width = presContext->AppUnitsToGfxUnits(aTextRect.width);
         500               0 :     gfxFloat ascentPixel = presContext->AppUnitsToGfxUnits(ascent);
         501               0 :     gfxRect dirtyRect(presContext->AppUnitsToGfxUnits(aDirtyRect));
         502                 :
         503                 :     // Underlines are drawn before overlines, and both before the text
         504                 :     // itself, per http://www.w3.org/TR/CSS21/zindex.html point 7.2.1.4.1.1.
         505                 :     // (We don't apply this rule to the access-key underline because we only
         506                 :     // find out where that is as a side effect of drawing the text, in the
         507                 :     // general case -- see below.)
         508               0 :     if (decorations & (NS_FONT_DECORATION_OVERLINE |
         509                 :                        NS_FONT_DECORATION_UNDERLINE)) {
         510               0 :       fontMet->GetUnderline(offset, size);
         511               0 :       gfxFloat offsetPixel = presContext->AppUnitsToGfxUnits(offset);
         512               0 :       gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size);
         513               0 :       if ((decorations & NS_FONT_DECORATION_UNDERLINE) &&
         514                 :           underStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
         515                 :         nsCSSRendering::PaintDecorationLine(ctx, dirtyRect, underColor,
         516                 :                           pt, gfxSize(width, sizePixel),
         517                 :                           ascentPixel, offsetPixel,
         518               0 :                           NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, underStyle);
         519                 :       }
         520               0 :       if ((decorations & NS_FONT_DECORATION_OVERLINE) &&
         521                 :           overStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
         522                 :         nsCSSRendering::PaintDecorationLine(ctx, dirtyRect, overColor,
         523                 :                           pt, gfxSize(width, sizePixel),
         524                 :                           ascentPixel, ascentPixel,
         525               0 :                           NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, overStyle);
         526                 :       }
         527                 :     }
         528                 :
         529                 :     nsRefPtr<nsRenderingContext> refContext =
         530               0 :         PresContext()->PresShell()->GetReferenceRenderingContext();
         531                 :
         532               0 :     aRenderingContext.SetFont(fontMet);
         533               0 :     refContext->SetFont(fontMet);
         534                 :
         535               0 :     CalculateUnderline(*refContext);
         536                 :
         537               0 :     aRenderingContext.SetColor(aOverrideColor ? *aOverrideColor : GetStyleColor()->mColor);
         538                 :
         539                 : #ifdef IBMBIDI
         540               0 :     nsresult rv = NS_ERROR_FAILURE;
         541                 :
         542               0 :     if (mState & NS_FRAME_IS_BIDI) {
         543               0 :       presContext->SetBidiEnabled();
         544               0 :       const nsStyleVisibility* vis = GetStyleVisibility();
         545               0 :       nsBidiDirection direction = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? NSBIDI_RTL : NSBIDI_LTR;
         546               0 :       if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
         547                 :           // We let the RenderText function calculate the mnemonic's
         548                 :           // underline position for us.
         549                 :           nsBidiPositionResolve posResolve;
         550               0 :           posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex;
         551               0 :           rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
         552                 :                                            presContext, aRenderingContext,
         553               0 :                                            *refContext,
         554                 :                                            aTextRect.x, baseline,
         555                 :                                            &posResolve,
         556               0 :                                            1);
         557               0 :           mAccessKeyInfo->mBeforeWidth = posResolve.visualLeftTwips;
         558               0 :           mAccessKeyInfo->mAccessWidth = posResolve.visualWidth;
         559                 :       }
         560                 :       else
         561                 :       {
         562               0 :           rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
         563                 :                                            presContext, aRenderingContext,
         564               0 :                                            *refContext,
         565               0 :                                            aTextRect.x, baseline);
         566                 :       }
         567                 :     }
         568               0 :     if (NS_FAILED(rv) )
         569                 : #endif // IBMBIDI
         570                 :     {
         571               0 :        aRenderingContext.SetTextRunRTL(false);
         572                 :
         573               0 :        if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
         574                 :            // In the simple (non-BiDi) case, we calculate the mnemonic's
         575                 :            // underline position by getting the text metric.
         576                 :            // XXX are attribute values always two byte?
         577               0 :            if (mAccessKeyInfo->mAccesskeyIndex > 0)
         578                 :                mAccessKeyInfo->mBeforeWidth =
         579                 :                    refContext->GetWidth(mCroppedTitle.get(),
         580               0 :                                         mAccessKeyInfo->mAccesskeyIndex);
         581                 :            else
         582               0 :                mAccessKeyInfo->mBeforeWidth = 0;
         583                 :        }
         584                 :
         585                 :        fontMet->DrawString(mCroppedTitle.get(), mCroppedTitle.Length(),
         586                 :                            aTextRect.x, baseline, &aRenderingContext,
         587               0 :                            refContext.get());
         588                 :     }
         589                 :
         590               0 :     if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
         591                 :         aRenderingContext.FillRect(aTextRect.x + mAccessKeyInfo->mBeforeWidth,
         592                 :                                    aTextRect.y + mAccessKeyInfo->mAccessOffset,
         593                 :                                    mAccessKeyInfo->mAccessWidth,
         594               0 :                                    mAccessKeyInfo->mAccessUnderlineSize);
         595                 :     }
         596                 :
         597                 :     // Strikeout is drawn on top of the text, per
         598                 :     // http://www.w3.org/TR/CSS21/zindex.html point 7.2.1.4.1.1.
         599               0 :     if ((decorations & NS_FONT_DECORATION_LINE_THROUGH) &&
         600                 :         strikeStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
         601               0 :       fontMet->GetStrikeout(offset, size);
         602               0 :       gfxFloat offsetPixel = presContext->AppUnitsToGfxUnits(offset);
         603               0 :       gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size);
         604                 :       nsCSSRendering::PaintDecorationLine(ctx, dirtyRect, strikeColor,
         605                 :                         pt, gfxSize(width, sizePixel), ascentPixel, offsetPixel,
         606                 :                         NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
         607               0 :                         strikeStyle);
         608                 :     }
         609               0 : }
         610                 :
         611                 : void
         612               0 : nsTextBoxFrame::CalculateUnderline(nsRenderingContext& aRenderingContext)
         613                 : {
         614               0 :     if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
         615                 :          // Calculate all fields of mAccessKeyInfo which
         616                 :          // are the same for both BiDi and non-BiDi frames.
         617               0 :          const PRUnichar *titleString = mCroppedTitle.get();
         618               0 :          aRenderingContext.SetTextRunRTL(false);
         619                 :          mAccessKeyInfo->mAccessWidth =
         620                 :              aRenderingContext.GetWidth(titleString[mAccessKeyInfo->
         621               0 :                                                     mAccesskeyIndex]);
         622                 :
         623                 :          nscoord offset, baseline;
         624               0 :          nsFontMetrics* metrics = aRenderingContext.FontMetrics();
         625               0 :          metrics->GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize);
         626               0 :          baseline = metrics->MaxAscent();
         627               0 :          mAccessKeyInfo->mAccessOffset = baseline - offset;
         628                 :     }
         629               0 : }
         630                 :
         631                 : nscoord
         632               0 : nsTextBoxFrame::CalculateTitleForWidth(nsPresContext*      aPresContext,
         633                 :                                        nsRenderingContext& aRenderingContext,
         634                 :                                        nscoord              aWidth)
         635                 : {
         636               0 :     if (mTitle.IsEmpty())
         637               0 :         return 0;
         638                 :
         639               0 :     nsRefPtr<nsFontMetrics> fm;
         640               0 :     nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
         641               0 :     aRenderingContext.SetFont(fm);
         642                 :
         643                 :     // see if the text will completely fit in the width given
         644                 :     nscoord titleWidth = nsLayoutUtils::GetStringWidth(this, &aRenderingContext,
         645               0 :                                                        mTitle.get(), mTitle.Length());
         646                 :
         647               0 :     if (titleWidth <= aWidth) {
         648               0 :         mCroppedTitle = mTitle;
         649                 : #ifdef IBMBIDI
         650               0 :         if (HasRTLChars(mTitle)) {
         651               0 :             mState |= NS_FRAME_IS_BIDI;
         652                 :         }
         653                 : #endif // IBMBIDI
         654               0 :         return titleWidth;  // fits, done.
         655                 :     }
         656                 :
         657               0 :     const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis();
         658                 :     // start with an ellipsis
         659               0 :     mCroppedTitle.Assign(kEllipsis);
         660                 :
         661                 :     // see if the width is even smaller than the ellipsis
         662                 :     // if so, clear the text (XXX set as many '.' as we can?).
         663               0 :     aRenderingContext.SetTextRunRTL(false);
         664               0 :     titleWidth = aRenderingContext.GetWidth(kEllipsis);
         665                 :
         666               0 :     if (titleWidth > aWidth) {
         667               0 :         mCroppedTitle.SetLength(0);
         668               0 :         return 0;
         669                 :     }
         670                 :
         671                 :     // if the ellipsis fits perfectly, no use in trying to insert
         672               0 :     if (titleWidth == aWidth)
         673               0 :         return titleWidth;
         674                 :
         675               0 :     aWidth -= titleWidth;
         676                 :
         677                 :     // XXX: This whole block should probably take surrogates into account
         678                 :     // XXX and clusters!
         679                 :     // ok crop things
         680               0 :     switch (mCropType)
         681                 :     {
         682                 :         case CropNone:
         683                 :         case CropRight:
         684                 :         {
         685                 :             nscoord cwidth;
         686               0 :             nscoord twidth = 0;
         687               0 :             int length = mTitle.Length();
         688                 :             int i;
         689               0 :             for (i = 0; i < length; ++i) {
         690               0 :                 PRUnichar ch = mTitle.CharAt(i);
         691                 :                 // still in LTR mode
         692               0 :                 cwidth = aRenderingContext.GetWidth(ch);
         693               0 :                 if (twidth + cwidth > aWidth)
         694               0 :                     break;
         695                 :
         696               0 :                 twidth += cwidth;
         697                 : #ifdef IBMBIDI
         698               0 :                 if (UCS2_CHAR_IS_BIDI(ch) ) {
         699               0 :                   mState |= NS_FRAME_IS_BIDI;
         700                 :                 }
         701                 : #endif // IBMBIDI
         702                 :             }
         703                 :
         704               0 :             if (i == 0)
         705               0 :                 return titleWidth;
         706                 :
         707                 :             // insert what character we can in.
         708               0 :             nsAutoString title( mTitle );
         709               0 :             title.Truncate(i);
         710               0 :             mCroppedTitle.Insert(title, 0);
         711                 :         }
         712               0 :         break;
         713                 :
         714                 :         case CropLeft:
         715                 :         {
         716                 :             nscoord cwidth;
         717               0 :             nscoord twidth = 0;
         718               0 :             int length = mTitle.Length();
         719                 :             int i;
         720               0 :             for (i=length-1; i >= 0; --i) {
         721               0 :                 PRUnichar ch = mTitle.CharAt(i);
         722               0 :                 cwidth = aRenderingContext.GetWidth(ch);
         723               0 :                 if (twidth + cwidth > aWidth)
         724               0 :                     break;
         725                 :
         726               0 :                 twidth += cwidth;
         727                 : #ifdef IBMBIDI
         728               0 :                 if (UCS2_CHAR_IS_BIDI(ch) ) {
         729               0 :                   mState |= NS_FRAME_IS_BIDI;
         730                 :                 }
         731                 : #endif // IBMBIDI
         732                 :             }
         733                 :
         734               0 :             if (i == length-1)
         735               0 :                 return titleWidth;
         736                 :
         737               0 :             nsAutoString copy;
         738               0 :             mTitle.Right(copy, length-1-i);
         739               0 :             mCroppedTitle += copy;
         740                 :         }
         741               0 :         break;
         742                 :
         743                 :         case CropCenter:
         744                 :         {
         745                 :             nscoord stringWidth =
         746                 :                 nsLayoutUtils::GetStringWidth(this, &aRenderingContext,
         747               0 :                                               mTitle.get(), mTitle.Length());
         748               0 :             if (stringWidth <= aWidth) {
         749                 :                 // the entire string will fit in the maximum width
         750               0 :                 mCroppedTitle.Insert(mTitle, 0);
         751               0 :                 break;
         752                 :             }
         753                 :
         754                 :             // determine how much of the string will fit in the max width
         755               0 :             nscoord charWidth = 0;
         756               0 :             nscoord totalWidth = 0;
         757                 :             PRUnichar ch;
         758                 :             int leftPos, rightPos;
         759               0 :             nsAutoString leftString, rightString;
         760                 :
         761               0 :             rightPos = mTitle.Length() - 1;
         762               0 :             aRenderingContext.SetTextRunRTL(false);
         763               0 :             for (leftPos = 0; leftPos <= rightPos;) {
         764                 :                 // look at the next character on the left end
         765               0 :                 ch = mTitle.CharAt(leftPos);
         766               0 :                 charWidth = aRenderingContext.GetWidth(ch);
         767               0 :                 totalWidth += charWidth;
         768               0 :                 if (totalWidth > aWidth)
         769                 :                     // greater than the allowable width
         770               0 :                     break;
         771               0 :                 leftString.Insert(ch, leftString.Length());
         772                 :
         773                 : #ifdef IBMBIDI
         774               0 :                 if (UCS2_CHAR_IS_BIDI(ch))
         775               0 :                     mState |= NS_FRAME_IS_BIDI;
         776                 : #endif
         777                 :
         778                 :                 // look at the next character on the right end
         779               0 :                 if (rightPos > leftPos) {
         780                 :                     // haven't looked at this character yet
         781               0 :                     ch = mTitle.CharAt(rightPos);
         782               0 :                     charWidth = aRenderingContext.GetWidth(ch);
         783               0 :                     totalWidth += charWidth;
         784               0 :                     if (totalWidth > aWidth)
         785                 :                         // greater than the allowable width
         786               0 :                         break;
         787               0 :                     rightString.Insert(ch, 0);
         788                 :
         789                 : #ifdef IBMBIDI
         790               0 :                     if (UCS2_CHAR_IS_BIDI(ch))
         791               0 :                         mState |= NS_FRAME_IS_BIDI;
         792                 : #endif
         793                 :                 }
         794                 :
         795                 :                 // look at the next two characters
         796               0 :                 leftPos++;
         797               0 :                 rightPos--;
         798                 :             }
         799                 :
         800               0 :             mCroppedTitle = leftString + kEllipsis + rightString;
         801                 :         }
         802               0 :         break;
         803                 :     }
         804                 :
         805                 :     return nsLayoutUtils::GetStringWidth(this, &aRenderingContext,
         806               0 :                                          mCroppedTitle.get(), mCroppedTitle.Length());
         807                 : }
         808                 :
         809                 : #define OLD_ELLIPSIS NS_LITERAL_STRING("...")
         810                 :
         811                 : // the following block is to append the accesskey to mTitle if there is an accesskey
         812                 : // but the mTitle doesn't have the character
         813                 : void
         814               0 : nsTextBoxFrame::UpdateAccessTitle()
         815                 : {
         816                 :     /*
         817                 :      * Note that if you change appending access key label spec,
         818                 :      * you need to maintain same logic in following methods. See bug 324159.
         819                 :      * toolkit/content/commonDialog.js (setLabelForNode)
         820                 :      * toolkit/content/widgets/text.xml (formatAccessKey)
         821                 :      */
         822                 :     PRInt32 menuAccessKey;
         823               0 :     nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
         824               0 :     if (!menuAccessKey || mAccessKey.IsEmpty())
         825               0 :         return;
         826                 :
         827               0 :     if (!AlwaysAppendAccessKey() &&
         828               0 :         FindInReadable(mAccessKey, mTitle, nsCaseInsensitiveStringComparator()))
         829               0 :         return;
         830                 :
         831               0 :     nsAutoString accessKeyLabel;
         832               0 :     accessKeyLabel += '(';
         833               0 :     accessKeyLabel += mAccessKey;
         834               0 :     ToUpperCase(accessKeyLabel);
         835               0 :     accessKeyLabel += ')';
         836                 :
         837               0 :     if (mTitle.IsEmpty()) {
         838               0 :         mTitle = accessKeyLabel;
         839                 :         return;
         840                 :     }
         841                 :
         842               0 :     const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis();
         843               0 :     PRUint32 offset = mTitle.Length();
         844               0 :     if (StringEndsWith(mTitle, kEllipsis)) {
         845               0 :         offset -= kEllipsis.Length();
         846               0 :     } else if (StringEndsWith(mTitle, OLD_ELLIPSIS)) {
         847                 :         // Try to check with our old ellipsis (for old addons)
         848               0 :         offset -= OLD_ELLIPSIS.Length();
         849                 :     } else {
         850                 :         // Try to check with
         851                 :         // our default ellipsis (for non-localized addons) or ':'
         852               0 :         const PRUnichar kLastChar = mTitle.Last();
         853               0 :         if (kLastChar == PRUnichar(0x2026) || kLastChar == PRUnichar(':'))
         854               0 :             offset--;
         855                 :     }
         856                 :
         857               0 :     if (InsertSeparatorBeforeAccessKey() &&
         858               0 :         offset > 0 && !NS_IS_SPACE(mTitle[offset - 1])) {
         859               0 :         mTitle.Insert(' ', offset);
         860               0 :         offset++;
         861                 :     }
         862                 :
         863               0 :     mTitle.Insert(accessKeyLabel, offset);
         864                 : }
         865                 :
         866                 : void
         867               0 : nsTextBoxFrame::UpdateAccessIndex()
         868                 : {
         869                 :     PRInt32 menuAccessKey;
         870               0 :     nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
         871               0 :     if (menuAccessKey) {
         872               0 :         if (mAccessKey.IsEmpty()) {
         873               0 :             if (mAccessKeyInfo) {
         874               0 :                 delete mAccessKeyInfo;
         875               0 :                 mAccessKeyInfo = nsnull;
         876                 :             }
         877                 :         } else {
         878               0 :             if (!mAccessKeyInfo) {
         879               0 :                 mAccessKeyInfo = new nsAccessKeyInfo();
         880               0 :                 if (!mAccessKeyInfo)
         881               0 :                     return;
         882                 :             }
         883                 :
         884               0 :             nsAString::const_iterator start, end;
         885                 :
         886               0 :             mCroppedTitle.BeginReading(start);
         887               0 :             mCroppedTitle.EndReading(end);
         888                 :
         889                 :             // remember the beginning of the string
         890               0 :             nsAString::const_iterator originalStart = start;
         891                 :
         892                 :             bool found;
         893               0 :             if (!AlwaysAppendAccessKey()) {
         894                 :                 // not appending access key - do case-sensitive search
         895                 :                 // first
         896               0 :                 found = FindInReadable(mAccessKey, start, end);
         897               0 :                 if (!found) {
         898                 :                     // didn't find it - perform a case-insensitive search
         899               0 :                     start = originalStart;
         900                 :                     found = FindInReadable(mAccessKey, start, end,
         901               0 :                                            nsCaseInsensitiveStringComparator());
         902                 :                 }
         903                 :             } else {
         904                 :                 found = RFindInReadable(mAccessKey, start, end,
         905               0 :                                         nsCaseInsensitiveStringComparator());
         906                 :             }
         907                 :
         908               0 :             if (found)
         909               0 :                 mAccessKeyInfo->mAccesskeyIndex = Distance(originalStart, start);
         910                 :             else
         911               0 :                 mAccessKeyInfo->mAccesskeyIndex = kNotFound;
         912                 :         }
         913                 :     }
         914                 : }
         915                 :
         916                 : NS_IMETHODIMP
         917               0 : nsTextBoxFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState)
         918                 : {
         919               0 :     if (mNeedsReflowCallback) {
         920               0 :         nsIReflowCallback* cb = new nsAsyncAccesskeyUpdate(this);
         921               0 :         if (cb) {
         922               0 :             PresContext()->PresShell()->PostReflowCallback(cb);
         923                 :         }
         924               0 :         mNeedsReflowCallback = false;
         925                 :     }
         926                 :
         927               0 :     nsresult rv = nsLeafBoxFrame::DoLayout(aBoxLayoutState);
         928                 :
         929               0 :     CalcDrawRect(*aBoxLayoutState.GetRenderingContext());
         930                 :
         931               0 :     const nsStyleText* textStyle = GetStyleText();
         932               0 :     if (textStyle->mTextShadow) {
         933               0 :       nsRect bounds(nsPoint(0, 0), GetSize());
         934               0 :       nsOverflowAreas overflow(bounds, bounds);
         935                 :       // Our scrollable overflow is our bounds; our visual overflow may
         936                 :       // extend beyond that.
         937               0 :       nsPoint origin(0,0);
         938               0 :       nsRect &vis = overflow.VisualOverflow();
         939               0 :       vis.UnionRect(vis, nsLayoutUtils::GetTextShadowRectsUnion(mTextDrawRect, this));
         940               0 :       FinishAndStoreOverflow(overflow, GetSize());
         941                 :     }
         942                 :
         943               0 :     return rv;
         944                 : }
         945                 :
         946                 : nsRect
         947               0 : nsTextBoxFrame::GetComponentAlphaBounds()
         948                 : {
         949                 :   return nsLayoutUtils::GetTextShadowRectsUnion(mTextDrawRect, this,
         950               0 :                                                 nsLayoutUtils::EXCLUDE_BLUR_SHADOWS);
         951                 : }
         952                 :
         953                 : bool
         954               0 : nsTextBoxFrame::ComputesOwnOverflowArea()
         955                 : {
         956               0 :     return true;
         957                 : }
         958                 :
         959                 : /* virtual */ void
         960               0 : nsTextBoxFrame::MarkIntrinsicWidthsDirty()
         961                 : {
         962               0 :     mNeedsRecalc = true;
         963               0 :     nsTextBoxFrameSuper::MarkIntrinsicWidthsDirty();
         964               0 : }
         965                 :
         966                 : void
         967               0 : nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext,
         968                 :                             nsRenderingContext& aRenderingContext,
         969                 :                             const nsString& aString,
         970                 :                             nsSize& aSize, nscoord& aAscent)
         971                 : {
         972               0 :     nsRefPtr<nsFontMetrics> fontMet;
         973               0 :     nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet));
         974               0 :     aSize.height = fontMet->MaxHeight();
         975               0 :     aRenderingContext.SetFont(fontMet);
         976                 :     aSize.width =
         977                 :       nsLayoutUtils::GetStringWidth(this, &aRenderingContext,
         978               0 :                                     aString.get(), aString.Length());
         979               0 :     aAscent = fontMet->MaxAscent();
         980               0 : }
         981                 :
         982                 : void
         983               0 : nsTextBoxFrame::CalcTextSize(nsBoxLayoutState& aBoxLayoutState)
         984                 : {
         985               0 :     if (mNeedsRecalc)
         986                 :     {
         987               0 :         nsSize size;
         988               0 :         nsPresContext* presContext = aBoxLayoutState.PresContext();
         989               0 :         nsRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext();
         990               0 :         if (rendContext) {
         991                 :             GetTextSize(presContext, *rendContext,
         992               0 :                         mTitle, size, mAscent);
         993               0 :             mTextSize = size;
         994               0 :             mNeedsRecalc = false;
         995                 :         }
         996                 :     }
         997               0 : }
         998                 :
         999                 : void
        1000               0 : nsTextBoxFrame::CalcDrawRect(nsRenderingContext &aRenderingContext)
        1001                 : {
        1002               0 :     nsRect textRect(nsPoint(0, 0), GetSize());
        1003               0 :     nsMargin borderPadding;
        1004               0 :     GetBorderAndPadding(borderPadding);
        1005               0 :     textRect.Deflate(borderPadding);
        1006                 :
        1007                 :     // determine (cropped) title and underline position
        1008               0 :     nsPresContext* presContext = PresContext();
        1009                 :     // determine (cropped) title which fits in aRect.width and its width
        1010                 :     nscoord titleWidth =
        1011               0 :         CalculateTitleForWidth(presContext, aRenderingContext, textRect.width);
        1012                 :     // determine if and at which position to put the underline
        1013               0 :     UpdateAccessIndex();
        1014                 :
        1015                 :     // make the rect as small as our (cropped) text.
        1016               0 :     nscoord outerWidth = textRect.width;
        1017               0 :     textRect.width = titleWidth;
        1018                 :
        1019                 :     // Align our text within the overall rect by checking our text-align property.
        1020               0 :     const nsStyleVisibility* vis = GetStyleVisibility();
        1021               0 :     const nsStyleText* textStyle = GetStyleText();
        1022                 :
        1023               0 :     if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_CENTER)
        1024               0 :       textRect.x += (outerWidth - textRect.width)/2;
        1025               0 :     else if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_RIGHT ||
        1026                 :              (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_DEFAULT &&
        1027                 :               vis->mDirection == NS_STYLE_DIRECTION_RTL) ||
        1028                 :              (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_END &&
        1029                 :               vis->mDirection == NS_STYLE_DIRECTION_LTR)) {
        1030               0 :       textRect.x += (outerWidth - textRect.width);
        1031                 :     }
        1032                 :
        1033               0 :     mTextDrawRect = textRect;
        1034               0 : }
        1035                 :
        1036                 : /**
        1037                 :  * Ok return our dimensions
        1038                 :  */
        1039                 : nsSize
        1040               0 : nsTextBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState)
        1041                 : {
        1042               0 :     CalcTextSize(aBoxLayoutState);
        1043                 :
        1044               0 :     nsSize size = mTextSize;
        1045               0 :     DISPLAY_PREF_SIZE(this, size);
        1046                 :
        1047               0 :     AddBorderAndPadding(size);
        1048                 :     bool widthSet, heightSet;
        1049               0 :     nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
        1050                 :
        1051                 :     return size;
        1052                 : }
        1053                 :
        1054                 : /**
        1055                 :  * Ok return our dimensions
        1056                 :  */
        1057                 : nsSize
        1058               0 : nsTextBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState)
        1059                 : {
        1060               0 :     CalcTextSize(aBoxLayoutState);
        1061                 :
        1062               0 :     nsSize size = mTextSize;
        1063               0 :     DISPLAY_MIN_SIZE(this, size);
        1064                 :
        1065                 :     // if there is cropping our min width becomes our border and padding
        1066               0 :     if (mCropType != CropNone)
        1067               0 :         size.width = 0;
        1068                 :
        1069               0 :     AddBorderAndPadding(size);
        1070                 :     bool widthSet, heightSet;
        1071               0 :     nsIBox::AddCSSMinSize(aBoxLayoutState, this, size, widthSet, heightSet);
        1072                 :
        1073                 :     return size;
        1074                 : }
        1075                 :
        1076                 : nscoord
        1077               0 : nsTextBoxFrame::GetBoxAscent(nsBoxLayoutState& aBoxLayoutState)
        1078                 : {
        1079               0 :     CalcTextSize(aBoxLayoutState);
        1080                 :
        1081               0 :     nscoord ascent = mAscent;
        1082                 :
        1083               0 :     nsMargin m(0,0,0,0);
        1084               0 :     GetBorderAndPadding(m);
        1085               0 :     ascent += m.top;
        1086                 :
        1087               0 :     return ascent;
        1088                 : }
        1089                 :
        1090                 : #ifdef DEBUG
        1091                 : NS_IMETHODIMP
        1092               0 : nsTextBoxFrame::GetFrameName(nsAString& aResult) const
        1093                 : {
        1094               0 :     MakeFrameName(NS_LITERAL_STRING("TextBox"), aResult);
        1095               0 :     aResult += NS_LITERAL_STRING("[value=") + mTitle + NS_LITERAL_STRING("]");
        1096               0 :     return NS_OK;
        1097                 : }
        1098                 : #endif
        1099                 :
        1100                 : // If you make changes to this function, check its counterparts
        1101                 : // in nsBoxFrame and nsXULLabelFrame
        1102                 : nsresult
        1103               0 : nsTextBoxFrame::RegUnregAccessKey(bool aDoReg)
        1104                 : {
        1105                 :     // if we have no content, we can't do anything
        1106               0 :     if (!mContent)
        1107               0 :         return NS_ERROR_FAILURE;
        1108                 :
        1109                 :     // check if we have a |control| attribute
        1110                 :     // do this check first because few elements have control attributes, and we
        1111                 :     // can weed out most of the elements quickly.
        1112                 :
        1113                 :     // XXXjag a side-effect is that we filter out anonymous <label>s
        1114                 :     // in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
        1115                 :     // |accesskey| and would otherwise register themselves, overwriting
        1116                 :     // the content we really meant to be registered.
        1117               0 :     if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::control))
        1118               0 :         return NS_OK;
        1119                 :
        1120                 :     // see if we even have an access key
        1121               0 :     nsAutoString accessKey;
        1122               0 :     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accessKey);
        1123                 :
        1124               0 :     if (accessKey.IsEmpty())
        1125               0 :         return NS_OK;
        1126                 :
        1127                 :     // With a valid PresContext we can get the ESM
        1128                 :     // and (un)register the access key
        1129               0 :     nsEventStateManager *esm = PresContext()->EventStateManager();
        1130                 :
        1131               0 :     PRUint32 key = accessKey.First();
        1132               0 :     if (aDoReg)
        1133               0 :         esm->RegisterAccessKey(mContent, key);
        1134                 :     else
        1135               0 :         esm->UnregisterAccessKey(mContent, key);
        1136                 :
        1137               0 :     return NS_OK;
        1138                 : }

Generated by: LCOV version 1.7