LCOV - app.info - layout/generic/nsCanvasFrame.cpp

LCOV - code coverage report
| Current view: | directory - layout/generic - nsCanvasFrame.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 216 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 29 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           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.org 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                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : /* rendering object that goes directly inside the document's scrollbars */
          39                 :
          40                 : #include "nsCanvasFrame.h"
          41                 : #include "nsIServiceManager.h"
          42                 : #include "nsHTMLParts.h"
          43                 : #include "nsContainerFrame.h"
          44                 : #include "nsCSSRendering.h"
          45                 : #include "nsPresContext.h"
          46                 : #include "nsStyleContext.h"
          47                 : #include "nsRenderingContext.h"
          48                 : #include "nsGUIEvent.h"
          49                 : #include "nsStyleConsts.h"
          50                 : #include "nsGkAtoms.h"
          51                 : #include "nsEventStateManager.h"
          52                 : #include "nsIPresShell.h"
          53                 : #include "nsIScrollPositionListener.h"
          54                 : #include "nsDisplayList.h"
          55                 : #include "nsCSSFrameConstructor.h"
          56                 : #include "nsFrameManager.h"
          57                 :
          58                 : // for focus
          59                 : #include "nsIScrollableFrame.h"
          60                 : #include "nsIDocShell.h"
          61                 :
          62                 : #ifdef DEBUG_rods
          63                 : //#define DEBUG_CANVAS_FOCUS
          64                 : #endif
          65                 :
          66                 :
          67                 : nsIFrame*
          68               0 : NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
          69                 : {
          70               0 :   return new (aPresShell) nsCanvasFrame(aContext);
          71                 : }
          72                 :
          73               0 : NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
          74                 :
          75               0 : NS_QUERYFRAME_HEAD(nsCanvasFrame)
          76               0 :   NS_QUERYFRAME_ENTRY(nsCanvasFrame)
          77               0 : NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
          78                 :
          79                 : void
          80               0 : nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
          81                 : {
          82               0 :   DestroyAbsoluteFrames(aDestructRoot);
          83                 :   nsIScrollableFrame* sf =
          84               0 :     PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
          85               0 :   if (sf) {
          86               0 :     sf->RemoveScrollPositionListener(this);
          87                 :   }
          88                 :
          89               0 :   nsContainerFrame::DestroyFrom(aDestructRoot);
          90               0 : }
          91                 :
          92                 : void
          93               0 : nsCanvasFrame::ScrollPositionWillChange(nscoord aX, nscoord aY)
          94                 : {
          95               0 :   if (mDoPaintFocus) {
          96               0 :     mDoPaintFocus = false;
          97               0 :     PresContext()->FrameManager()->GetRootFrame()->InvalidateFrameSubtree();
          98                 :   }
          99               0 : }
         100                 :
         101                 : NS_IMETHODIMP
         102               0 : nsCanvasFrame::SetHasFocus(bool aHasFocus)
         103                 : {
         104               0 :   if (mDoPaintFocus != aHasFocus) {
         105               0 :     mDoPaintFocus = aHasFocus;
         106               0 :     PresContext()->FrameManager()->GetRootFrame()->InvalidateFrameSubtree();
         107                 :
         108               0 :     if (!mAddedScrollPositionListener) {
         109                 :       nsIScrollableFrame* sf =
         110               0 :         PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
         111               0 :       if (sf) {
         112               0 :         sf->AddScrollPositionListener(this);
         113               0 :         mAddedScrollPositionListener = true;
         114                 :       }
         115                 :     }
         116                 :   }
         117               0 :   return NS_OK;
         118                 : }
         119                 :
         120                 : NS_IMETHODIMP
         121               0 : nsCanvasFrame::SetInitialChildList(ChildListID     aListID,
         122                 :                                    nsFrameList&    aChildList)
         123                 : {
         124               0 :   NS_ASSERTION(aListID != kPrincipalList ||
         125                 :                aChildList.IsEmpty() || aChildList.OnlyChild(),
         126                 :                "Primary child list can have at most one frame in it");
         127               0 :   return nsContainerFrame::SetInitialChildList(aListID, aChildList);
         128                 : }
         129                 :
         130                 : NS_IMETHODIMP
         131               0 : nsCanvasFrame::AppendFrames(ChildListID     aListID,
         132                 :                             nsFrameList&    aFrameList)
         133                 : {
         134               0 :   NS_ASSERTION(aListID == kPrincipalList ||
         135                 :                aListID == kAbsoluteList, "unexpected child list ID");
         136               0 :   NS_PRECONDITION(aListID != kAbsoluteList ||
         137                 :                   mFrames.IsEmpty(), "already have a child frame");
         138               0 :   if (aListID != kPrincipalList) {
         139                 :     // We only support the Principal and Absolute child lists.
         140               0 :     return NS_ERROR_INVALID_ARG;
         141                 :   }
         142                 :
         143               0 :   if (!mFrames.IsEmpty()) {
         144                 :     // We only allow a single principal child frame.
         145               0 :     return NS_ERROR_INVALID_ARG;
         146                 :   }
         147                 :
         148                 :   // Insert the new frames
         149               0 :   NS_ASSERTION(aFrameList.FirstChild() == aFrameList.LastChild(),
         150                 :                "Only one principal child frame allowed");
         151                 : #ifdef NS_DEBUG
         152               0 :   nsFrame::VerifyDirtyBitSet(aFrameList);
         153                 : #endif
         154               0 :   mFrames.AppendFrames(nsnull, aFrameList);
         155                 :
         156               0 :   PresContext()->PresShell()->
         157                 :     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
         158               0 :                      NS_FRAME_HAS_DIRTY_CHILDREN);
         159                 :
         160               0 :   return NS_OK;
         161                 : }
         162                 :
         163                 : NS_IMETHODIMP
         164               0 : nsCanvasFrame::InsertFrames(ChildListID     aListID,
         165                 :                             nsIFrame*       aPrevFrame,
         166                 :                             nsFrameList&    aFrameList)
         167                 : {
         168                 :   // Because we only support a single child frame inserting is the same
         169                 :   // as appending
         170               0 :   NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
         171               0 :   if (aPrevFrame)
         172               0 :     return NS_ERROR_UNEXPECTED;
         173                 :
         174               0 :   return AppendFrames(aListID, aFrameList);
         175                 : }
         176                 :
         177                 : NS_IMETHODIMP
         178               0 : nsCanvasFrame::RemoveFrame(ChildListID     aListID,
         179                 :                            nsIFrame*       aOldFrame)
         180                 : {
         181               0 :   NS_ASSERTION(aListID == kPrincipalList ||
         182                 :                aListID == kAbsoluteList, "unexpected child list ID");
         183               0 :   if (aListID != kPrincipalList || aListID != kAbsoluteList) {
         184                 :     // We only support the Principal and Absolute child lists.
         185               0 :     return NS_ERROR_INVALID_ARG;
         186                 :   }
         187                 :
         188               0 :   if (aOldFrame != mFrames.FirstChild())
         189               0 :     return NS_ERROR_FAILURE;
         190                 :
         191                 :   // It's our one and only child frame
         192                 :   // Damage the area occupied by the deleted frame
         193                 :   // The child of the canvas probably can't have an outline, but why bother
         194                 :   // thinking about that?
         195               0 :   Invalidate(aOldFrame->GetVisualOverflowRect() + aOldFrame->GetPosition());
         196                 :
         197                 :   // Remove the frame and destroy it
         198               0 :   mFrames.DestroyFrame(aOldFrame);
         199                 :
         200               0 :   PresContext()->PresShell()->
         201                 :     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
         202               0 :                      NS_FRAME_HAS_DIRTY_CHILDREN);
         203               0 :   return NS_OK;
         204                 : }
         205                 :
         206               0 : nsRect nsCanvasFrame::CanvasArea() const
         207                 : {
         208                 :   // Not clear which overflow rect we want here, but it probably doesn't
         209                 :   // matter.
         210               0 :   nsRect result(GetVisualOverflowRect());
         211                 :
         212               0 :   nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
         213               0 :   if (scrollableFrame) {
         214               0 :     nsRect portRect = scrollableFrame->GetScrollPortRect();
         215               0 :     result.UnionRect(result, nsRect(nsPoint(0, 0), portRect.Size()));
         216                 :   }
         217                 :   return result;
         218                 : }
         219                 :
         220                 : void
         221               0 : nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
         222                 :                                  nsRenderingContext* aCtx)
         223                 : {
         224               0 :   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
         225               0 :   nsPoint offset = ToReferenceFrame();
         226               0 :   nsRect bgClipRect = frame->CanvasArea() + offset;
         227                 :
         228               0 :   if (NS_GET_A(mExtraBackgroundColor) > 0) {
         229               0 :     aCtx->SetColor(mExtraBackgroundColor);
         230               0 :     aCtx->FillRect(bgClipRect);
         231                 :   }
         232                 :
         233                 :   nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
         234                 :                                   mVisibleRect,
         235               0 :                                   nsRect(offset, mFrame->GetSize()),
         236                 :                                   aBuilder->GetBackgroundPaintFlags(),
         237               0 :                                   &bgClipRect);
         238               0 : }
         239                 :
         240                 : /**
         241                 :  * A display item to paint the focus ring for the document.
         242                 :  *
         243                 :  * The only reason this can't use nsDisplayGeneric is overriding GetBounds.
         244                 :  */
         245                 : class nsDisplayCanvasFocus : public nsDisplayItem {
         246                 : public:
         247               0 :   nsDisplayCanvasFocus(nsDisplayListBuilder* aBuilder, nsCanvasFrame *aFrame)
         248               0 :     : nsDisplayItem(aBuilder, aFrame)
         249                 :   {
         250               0 :     MOZ_COUNT_CTOR(nsDisplayCanvasFocus);
         251               0 :   }
         252               0 :   virtual ~nsDisplayCanvasFocus() {
         253               0 :     MOZ_COUNT_DTOR(nsDisplayCanvasFocus);
         254               0 :   }
         255                 :
         256               0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
         257                 :   {
         258                 :     // This is an overestimate, but that's not a problem.
         259               0 :     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
         260               0 :     return frame->CanvasArea() + ToReferenceFrame();
         261                 :   }
         262                 :
         263               0 :   virtual void Paint(nsDisplayListBuilder* aBuilder,
         264                 :                      nsRenderingContext* aCtx)
         265                 :   {
         266               0 :     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
         267               0 :     frame->PaintFocus(*aCtx, ToReferenceFrame());
         268               0 :   }
         269                 :
         270               0 :   NS_DISPLAY_DECL_NAME("CanvasFocus", TYPE_CANVAS_FOCUS)
         271                 : };
         272                 :
         273                 : NS_IMETHODIMP
         274               0 : nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
         275                 :                                 const nsRect&           aDirtyRect,
         276                 :                                 const nsDisplayListSet& aLists)
         277                 : {
         278                 :   nsresult rv;
         279                 :
         280               0 :   if (GetPrevInFlow()) {
         281               0 :     DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
         282                 :   }
         283                 :
         284                 :   // Force a background to be shown. We may have a background propagated to us,
         285                 :   // in which case GetStyleBackground wouldn't have the right background
         286                 :   // and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
         287                 :   // a background.
         288                 :   // We don't have any border or outline, and our background draws over
         289                 :   // the overflow area, so just add nsDisplayCanvasBackground instead of
         290                 :   // calling DisplayBorderBackgroundOutline.
         291               0 :   if (IsVisibleForPainting(aBuilder)) {
         292                 :     rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
         293               0 :            nsDisplayCanvasBackground(aBuilder, this));
         294               0 :     NS_ENSURE_SUCCESS(rv, rv);
         295                 :   }
         296                 :
         297                 :   nsIFrame* kid;
         298               0 :   for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
         299                 :     // Put our child into its own pseudo-stack.
         300               0 :     rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
         301               0 :     NS_ENSURE_SUCCESS(rv, rv);
         302                 :   }
         303                 :
         304                 : #ifdef DEBUG_CANVAS_FOCUS
         305                 :   nsCOMPtr<nsIContent> focusContent;
         306                 :   aPresContext->EventStateManager()->
         307                 :     GetFocusedContent(getter_AddRefs(focusContent));
         308                 :
         309                 :   bool hasFocus = false;
         310                 :   nsCOMPtr<nsISupports> container;
         311                 :   aPresContext->GetContainer(getter_AddRefs(container));
         312                 :   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
         313                 :   if (docShell) {
         314                 :     docShell->GetHasFocus(&hasFocus);
         315                 :     printf("%p - nsCanvasFrame::Paint R:%d,%d,%d,%d  DR: %d,%d,%d,%d\n", this,
         316                 :             mRect.x, mRect.y, mRect.width, mRect.height,
         317                 :             aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
         318                 :   }
         319                 :   printf("%p - Focus: %s   c: %p  DoPaint:%s\n", docShell.get(), hasFocus?"Y":"N",
         320                 :          focusContent.get(), mDoPaintFocus?"Y":"N");
         321                 : #endif
         322                 :
         323               0 :   if (!mDoPaintFocus)
         324               0 :     return NS_OK;
         325                 :   // Only paint the focus if we're visible
         326               0 :   if (!GetStyleVisibility()->IsVisible())
         327               0 :     return NS_OK;
         328                 :
         329                 :   return aLists.Outlines()->AppendNewToTop(new (aBuilder)
         330               0 :       nsDisplayCanvasFocus(aBuilder, this));
         331                 : }
         332                 :
         333                 : void
         334               0 : nsCanvasFrame::PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt)
         335                 : {
         336               0 :   nsRect focusRect(aPt, GetSize());
         337                 :
         338               0 :   nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
         339               0 :   if (scrollableFrame) {
         340               0 :     nsRect portRect = scrollableFrame->GetScrollPortRect();
         341               0 :     focusRect.width = portRect.width;
         342               0 :     focusRect.height = portRect.height;
         343               0 :     focusRect.MoveBy(scrollableFrame->GetScrollPosition());
         344                 :   }
         345                 :
         346                 :  // XXX use the root frame foreground color, but should we find BODY frame
         347                 :  // for HTML documents?
         348               0 :   nsIFrame* root = mFrames.FirstChild();
         349                 :   const nsStyleColor* color =
         350               0 :     root ? root->GetStyleContext()->GetStyleColor() :
         351               0 :            mStyleContext->GetStyleColor();
         352               0 :   if (!color) {
         353               0 :     NS_ERROR("current color cannot be found");
         354                 :     return;
         355                 :   }
         356                 :
         357                 :   nsCSSRendering::PaintFocus(PresContext(), aRenderingContext,
         358               0 :                              focusRect, color->mColor);
         359                 : }
         360                 :
         361                 : /* virtual */ nscoord
         362               0 : nsCanvasFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
         363                 : {
         364                 :   nscoord result;
         365               0 :   DISPLAY_MIN_WIDTH(this, result);
         366               0 :   if (mFrames.IsEmpty())
         367               0 :     result = 0;
         368                 :   else
         369               0 :     result = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
         370               0 :   return result;
         371                 : }
         372                 :
         373                 : /* virtual */ nscoord
         374               0 : nsCanvasFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
         375                 : {
         376                 :   nscoord result;
         377               0 :   DISPLAY_PREF_WIDTH(this, result);
         378               0 :   if (mFrames.IsEmpty())
         379               0 :     result = 0;
         380                 :   else
         381               0 :     result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
         382               0 :   return result;
         383                 : }
         384                 :
         385                 : NS_IMETHODIMP
         386               0 : nsCanvasFrame::Reflow(nsPresContext*           aPresContext,
         387                 :                     nsHTMLReflowMetrics&     aDesiredSize,
         388                 :                     const nsHTMLReflowState& aReflowState,
         389                 :                     nsReflowStatus&          aStatus)
         390                 : {
         391               0 :   DO_GLOBAL_REFLOW_COUNT("nsCanvasFrame");
         392               0 :   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
         393               0 :   NS_FRAME_TRACE_REFLOW_IN("nsCanvasFrame::Reflow");
         394                 :
         395                 :   // Initialize OUT parameter
         396               0 :   aStatus = NS_FRAME_COMPLETE;
         397                 :
         398                 :   nsCanvasFrame* prevCanvasFrame = static_cast<nsCanvasFrame*>
         399               0 :                                                (GetPrevInFlow());
         400               0 :   if (prevCanvasFrame) {
         401               0 :     nsAutoPtr<nsFrameList> overflow(prevCanvasFrame->StealOverflowFrames());
         402               0 :     if (overflow) {
         403               0 :       NS_ASSERTION(overflow->OnlyChild(),
         404                 :                    "must have doc root as canvas frame's only child");
         405               0 :       nsContainerFrame::ReparentFrameViewList(aPresContext, *overflow,
         406               0 :                                               prevCanvasFrame, this);
         407                 :       // Prepend overflow to the our child list. There may already be
         408                 :       // children placeholders for fixed-pos elements, which don't get
         409                 :       // reflowed but must not be lost until the canvas frame is destroyed.
         410               0 :       mFrames.InsertFrames(this, nsnull, *overflow);
         411                 :     }
         412                 :   }
         413                 :
         414                 :   // Set our size up front, since some parts of reflow depend on it
         415                 :   // being already set.  Note that the computed height may be
         416                 :   // unconstrained; that's ok.  Consumers should watch out for that.
         417               0 :   SetSize(nsSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight()));
         418                 :
         419                 :   // Reflow our one and only normal child frame. It's either the root
         420                 :   // element's frame or a placeholder for that frame, if the root element
         421                 :   // is abs-pos or fixed-pos. We may have additional children which
         422                 :   // are placeholders for continuations of fixed-pos content, but those
         423                 :   // don't need to be reflowed. The normal child is always comes before
         424                 :   // the fixed-pos placeholders, because we insert it at the start
         425                 :   // of the child list, above.
         426               0 :   nsHTMLReflowMetrics kidDesiredSize;
         427               0 :   if (mFrames.IsEmpty()) {
         428                 :     // We have no child frame, so return an empty size
         429               0 :     aDesiredSize.width = aDesiredSize.height = 0;
         430                 :   } else {
         431               0 :     nsIFrame* kidFrame = mFrames.FirstChild();
         432               0 :     nsRect oldKidRect = kidFrame->GetRect();
         433               0 :     bool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
         434                 :
         435                 :     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
         436                 :                                      nsSize(aReflowState.availableWidth,
         437               0 :                                             aReflowState.availableHeight));
         438                 :
         439               0 :     if (aReflowState.mFlags.mVResize &&
         440               0 :         (kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
         441                 :       // Tell our kid it's being vertically resized too.  Bit of a
         442                 :       // hack for framesets.
         443               0 :       kidReflowState.mFlags.mVResize = true;
         444                 :     }
         445                 :
         446                 :     nsPoint kidPt(kidReflowState.mComputedMargin.left,
         447               0 :                   kidReflowState.mComputedMargin.top);
         448                 :     // Apply CSS relative positioning
         449               0 :     const nsStyleDisplay* styleDisp = kidFrame->GetStyleDisplay();
         450               0 :     if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
         451                 :       kidPt += nsPoint(kidReflowState.mComputedOffsets.left,
         452               0 :                        kidReflowState.mComputedOffsets.top);
         453                 :     }
         454                 :
         455                 :     // Reflow the frame
         456                 :     ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
         457               0 :                 kidPt.x, kidPt.y, 0, aStatus);
         458                 :
         459                 :     // Complete the reflow and position and size the child frame
         460                 :     FinishReflowChild(kidFrame, aPresContext, &kidReflowState, kidDesiredSize,
         461               0 :                       kidPt.x, kidPt.y, 0);
         462                 :
         463               0 :     if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
         464               0 :       nsIFrame* nextFrame = kidFrame->GetNextInFlow();
         465               0 :       NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
         466                 :         "If it's incomplete and has no nif yet, it must flag a nif reflow.");
         467               0 :       if (!nextFrame) {
         468                 :         nsresult rv = aPresContext->PresShell()->FrameConstructor()->
         469               0 :           CreateContinuingFrame(aPresContext, kidFrame, this, &nextFrame);
         470               0 :         NS_ENSURE_SUCCESS(rv, rv);
         471               0 :         SetOverflowFrames(aPresContext, nsFrameList(nextFrame, nextFrame));
         472                 :         // Root overflow containers will be normal children of
         473                 :         // the canvas frame, but that's ok because there
         474                 :         // aren't any other frames we need to isolate them from
         475                 :         // during reflow.
         476                 :       }
         477               0 :       if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
         478               0 :         nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
         479                 :       }
         480                 :     }
         481                 :
         482                 :     // If the child frame was just inserted, then we're responsible for making sure
         483                 :     // it repaints
         484               0 :     if (kidDirty) {
         485                 :       // But we have a new child, which will affect our background, so
         486                 :       // invalidate our whole rect.
         487                 :       // Note: Even though we request to be sized to our child's size, our
         488                 :       // scroll frame ensures that we are always the size of the viewport.
         489                 :       // Also note: GetPosition() on a CanvasFrame is always going to return
         490                 :       // (0, 0). We only want to invalidate GetRect() since Get*OverflowRect()
         491                 :       // could also include overflow to our top and left (out of the viewport)
         492                 :       // which doesn't need to be painted.
         493               0 :       nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
         494               0 :       viewport->Invalidate(nsRect(nsPoint(0, 0), viewport->GetSize()));
         495                 :     } else {
         496               0 :       nsRect newKidRect = kidFrame->GetRect();
         497               0 :       if (newKidRect.TopLeft() == oldKidRect.TopLeft()) {
         498               0 :         InvalidateRectDifference(oldKidRect, kidFrame->GetRect());
         499                 :       } else {
         500               0 :         Invalidate(oldKidRect);
         501               0 :         Invalidate(newKidRect);
         502                 :       }
         503                 :     }
         504                 :
         505                 :     // Return our desired size. Normally it's what we're told, but
         506                 :     // sometimes we can be given an unconstrained height (when a window
         507                 :     // is sizing-to-content), and we should compute our desired height.
         508               0 :     aDesiredSize.width = aReflowState.ComputedWidth();
         509               0 :     if (aReflowState.ComputedHeight() == NS_UNCONSTRAINEDSIZE) {
         510               0 :       aDesiredSize.height = kidFrame->GetRect().height +
         511               0 :         kidReflowState.mComputedMargin.TopBottom();
         512                 :     } else {
         513               0 :       aDesiredSize.height = aReflowState.ComputedHeight();
         514                 :     }
         515                 :
         516               0 :     aDesiredSize.SetOverflowAreasToDesiredBounds();
         517                 :     aDesiredSize.mOverflowAreas.UnionWith(
         518               0 :       kidDesiredSize.mOverflowAreas + kidPt);
         519                 :
         520                 :     // Handle invalidating fixed-attachment backgrounds propagated to the
         521                 :     // canvas when the canvas size (and therefore the background positioning
         522                 :     // area's size) changes.  Such backgrounds are not invalidated in the
         523                 :     // normal manner because the size of the original frame for that background
         524                 :     // may not have changed.
         525                 :     //
         526                 :     // This isn't the right fix for this issue, taken more generally.  In
         527                 :     // particular, this doesn't handle fixed-attachment backgrounds that are *not*
         528                 :     // propagated.  If a layer with the characteristics tested for below exists
         529                 :     // in a non-propagated background, we should invalidate the "corresponding"
         530                 :     // frame (which subsumes this special case if defined broadly).  For now,
         531                 :     // however, this addresses the most common case.  Given that this behavior has
         532                 :     // long been broken (non-zero percent background-size may be a new instance,
         533                 :     // but non-zero percent background-position is longstanding), we defer a
         534                 :     // fully correct fix until later.
         535               0 :     if (nsSize(aDesiredSize.width, aDesiredSize.height) != GetSize()) {
         536                 :       nsIFrame* rootElementFrame =
         537               0 :         aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
         538                 :       nsStyleContext* bgSC =
         539               0 :         nsCSSRendering::FindCanvasBackground(this, rootElementFrame);
         540               0 :       const nsStyleBackground* bg = bgSC->GetStyleBackground();
         541               0 :       if (!bg->IsTransparent()) {
         542               0 :         NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
         543               0 :           const nsStyleBackground::Layer& layer = bg->mLayers[i];
         544               0 :           if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
         545               0 :               layer.RenderingMightDependOnFrameSize()) {
         546               0 :             Invalidate(nsRect(nsPoint(0, 0), GetSize()));
         547               0 :             break;
         548                 :           }
         549                 :         }
         550                 :       }
         551                 :     }
         552                 :   }
         553                 :
         554               0 :   if (prevCanvasFrame) {
         555                 :     ReflowOverflowContainerChildren(aPresContext, aReflowState,
         556                 :                                     aDesiredSize.mOverflowAreas, 0,
         557               0 :                                     aStatus);
         558                 :   }
         559                 :
         560               0 :   FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
         561                 :
         562               0 :   NS_FRAME_TRACE_REFLOW_OUT("nsCanvasFrame::Reflow", aStatus);
         563               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
         564               0 :   return NS_OK;
         565                 : }
         566                 :
         567                 : PRIntn
         568               0 : nsCanvasFrame::GetSkipSides() const
         569                 : {
         570               0 :   return 0;
         571                 : }
         572                 :
         573                 : nsIAtom*
         574               0 : nsCanvasFrame::GetType() const
         575                 : {
         576               0 :   return nsGkAtoms::canvasFrame;
         577                 : }
         578                 :
         579                 : NS_IMETHODIMP
         580               0 : nsCanvasFrame::GetContentForEvent(nsEvent* aEvent,
         581                 :                                   nsIContent** aContent)
         582                 : {
         583               0 :   NS_ENSURE_ARG_POINTER(aContent);
         584                 :   nsresult rv = nsFrame::GetContentForEvent(aEvent,
         585               0 :                                             aContent);
         586               0 :   if (NS_FAILED(rv) || !*aContent) {
         587               0 :     nsIFrame* kid = mFrames.FirstChild();
         588               0 :     if (kid) {
         589                 :       rv = kid->GetContentForEvent(aEvent,
         590               0 :                                    aContent);
         591                 :     }
         592                 :   }
         593                 :
         594               0 :   return rv;
         595                 : }
         596                 :
         597                 : #ifdef DEBUG
         598                 : NS_IMETHODIMP
         599               0 : nsCanvasFrame::GetFrameName(nsAString& aResult) const
         600                 : {
         601               0 :   return MakeFrameName(NS_LITERAL_STRING("Canvas"), aResult);
         602                 : }
         603                 : #endif

Generated by: LCOV version 1.7