Bug 1362394 - Favicons in bookmarks treeviews don't use high quality scaling. r=tnikkel draft
authorMarco Bonardo <mbonardo@mozilla.com>
Sat, 06 May 2017 14:04:38 +0200
changeset 580414 9b359b9cce617c089e66f778b728fbd1d20b3911
parent 580382 2fa6931995b23f1f39752385b6689dc6b8d94c1b
child 629272 9097791af3e34aa00937651eb86be2dbd237c472
push id59541
push usermak77@bonardo.net
push dateThu, 18 May 2017 13:58:57 +0000
reviewerstnikkel
bugs1362394
milestone55.0a1
Bug 1362394 - Favicons in bookmarks treeviews don't use high quality scaling. r=tnikkel MozReview-Commit-ID: 4NLhHtGybyv
layout/xul/tree/nsTreeBodyFrame.cpp
layout/xul/tree/nsTreeBodyFrame.h
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -2804,21 +2804,22 @@ public:
     }
 
     nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
   }
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx) override
   {
+    MOZ_ASSERT(aBuilder);
     DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
                                                       mDisableSubpixelAA);
 
     DrawResult result = static_cast<nsTreeBodyFrame*>(mFrame)
-      ->PaintTreeBody(*aCtx, mVisibleRect, ToReferenceFrame());
+      ->PaintTreeBody(*aCtx, mVisibleRect, ToReferenceFrame(), aBuilder);
 
     nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
   }
 
   NS_DISPLAY_DECL_NAME("XULTreeBody", TYPE_XUL_TREE_BODY)
 
   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override
   {
@@ -2898,17 +2899,18 @@ nsTreeBodyFrame::BuildDisplayList(nsDisp
 #endif
 
   aLists.Content()->AppendNewToTop(new (aBuilder)
     nsDisplayTreeBody(aBuilder, this));
 }
 
 DrawResult
 nsTreeBodyFrame::PaintTreeBody(nsRenderingContext& aRenderingContext,
-                               const nsRect& aDirtyRect, nsPoint aPt)
+                               const nsRect& aDirtyRect, nsPoint aPt,
+                               nsDisplayListBuilder* aBuilder)
 {
   // Update our available height and our page count.
   CalcInnerBox();
 
   DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
   gfxContext* gfx = aRenderingContext.ThebesContext();
 
   gfx->Save();
@@ -2953,18 +2955,18 @@ nsTreeBodyFrame::PaintTreeBody(nsRenderi
     }
   }
   // Loop through our on-screen rows.
   for (int32_t i = mTopRowIndex; i < mRowCount && i <= mTopRowIndex+mPageLength; i++) {
     nsRect rowRect(mInnerBox.x, mInnerBox.y+mRowHeight*(i-mTopRowIndex), mInnerBox.width, mRowHeight);
     nsRect dirtyRect;
     if (dirtyRect.IntersectRect(aDirtyRect, rowRect + aPt) &&
         rowRect.y < (mInnerBox.y+mInnerBox.height)) {
-      result &=
-        PaintRow(i, rowRect + aPt, PresContext(), aRenderingContext, aDirtyRect, aPt);
+      result &= PaintRow(i, rowRect + aPt, PresContext(), aRenderingContext,
+                         aDirtyRect, aPt, aBuilder);
     }
   }
 
   if (mSlots && mSlots->mDropAllowed && (mSlots->mDropOrient == nsITreeView::DROP_BEFORE ||
       mSlots->mDropOrient == nsITreeView::DROP_AFTER)) {
     nscoord yPos = mInnerBox.y + mRowHeight * (mSlots->mDropRow - mTopRowIndex) - mRowHeight / 2;
     nsRect feedbackRect(mInnerBox.x, yPos, mInnerBox.width, mRowHeight);
     if (mSlots->mDropOrient == nsITreeView::DROP_AFTER)
@@ -3011,22 +3013,23 @@ nsTreeBodyFrame::PaintColumn(nsTreeColum
   colContext->StyleMargin()->GetMargin(colMargin);
   colRect.Deflate(colMargin);
 
   return PaintBackgroundLayer(colContext, aPresContext, aRenderingContext,
                               colRect, aDirtyRect);
 }
 
 DrawResult
-nsTreeBodyFrame::PaintRow(int32_t              aRowIndex,
-                          const nsRect&        aRowRect,
-                          nsPresContext*       aPresContext,
-                          nsRenderingContext& aRenderingContext,
-                          const nsRect&        aDirtyRect,
-                          nsPoint              aPt)
+nsTreeBodyFrame::PaintRow(int32_t               aRowIndex,
+                          const nsRect&         aRowRect,
+                          nsPresContext*        aPresContext,
+                          nsRenderingContext&   aRenderingContext,
+                          const nsRect&         aDirtyRect,
+                          nsPoint               aPt,
+                          nsDisplayListBuilder* aBuilder)
 {
   // We have been given a rect for our row.  We treat this row like a full-blown
   // frame, meaning that it can have borders, margins, padding, and a background.
   
   // Without a view, we have no data. Check for this up front.
   if (!mView) {
     return DrawResult::SUCCESS;
   }
@@ -3101,17 +3104,18 @@ nsTreeBodyFrame::PaintRow(int32_t       
 
       if (OffsetForHorzScroll(cellRect, false)) {
         cellRect.x += aPt.x;
         nsRect dirtyRect;
         nsRect checkRect(cellRect.x, originalRowRect.y,
                          cellRect.width, originalRowRect.height);
         if (dirtyRect.IntersectRect(aDirtyRect, checkRect)) {
           result &= PaintCell(aRowIndex, primaryCol, cellRect, aPresContext,
-                              aRenderingContext, aDirtyRect, primaryX, aPt);
+                              aRenderingContext, aDirtyRect, primaryX, aPt,
+                              aBuilder);
         }
       }
 
       // Paint the left side of the separator.
       nscoord currX;
       nsTreeColumn* previousCol = primaryCol->GetPrevious();
       if (previousCol) {
         nsRect prevColRect;
@@ -3167,17 +3171,18 @@ nsTreeBodyFrame::PaintRow(int32_t       
         if (currCol->IsPrimary())
           checkRect = nsRect(cellRect.x, originalRowRect.y,
                              cellRect.width, originalRowRect.height);
 
         nsRect dirtyRect;
         nscoord dummy;
         if (dirtyRect.IntersectRect(aDirtyRect, checkRect))
           result &= PaintCell(aRowIndex, currCol, cellRect, aPresContext,
-                              aRenderingContext, aDirtyRect, dummy, aPt);
+                              aRenderingContext, aDirtyRect, dummy, aPt,
+                              aBuilder);
       }
     }
   }
   // If we've changed the font smoothing background color for this row, restore
   // the color to the original one.
   if (originalColor != ctx->GetFontSmoothingBackgroundColor()) {
     ctx->SetFontSmoothingBackgroundColor(originalColor);
   }
@@ -3238,24 +3243,25 @@ nsTreeBodyFrame::PaintSeparator(int32_t 
                                    aRenderingContext, separatorRect,
                                    aDirtyRect);
   }
 
   return result;
 }
 
 DrawResult
-nsTreeBodyFrame::PaintCell(int32_t              aRowIndex,
-                           nsTreeColumn*        aColumn,
-                           const nsRect&        aCellRect,
-                           nsPresContext*       aPresContext,
-                           nsRenderingContext& aRenderingContext,
-                           const nsRect&        aDirtyRect,
-                           nscoord&             aCurrX,
-                           nsPoint              aPt)
+nsTreeBodyFrame::PaintCell(int32_t               aRowIndex,
+                           nsTreeColumn*         aColumn,
+                           const nsRect&         aCellRect,
+                           nsPresContext*        aPresContext,
+                           nsRenderingContext&   aRenderingContext,
+                           const nsRect&         aDirtyRect,
+                           nscoord&              aCurrX,
+                           nsPoint               aPt,
+                           nsDisplayListBuilder* aBuilder)
 {
   NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed");
 
   // Now obtain the properties for our cell.
   // XXX Automatically fill in the following props: open, closed, container, leaf, selected, focused, and the col ID.
   PrefillPropertyArray(aRowIndex, aColumn);
   nsAutoString properties;
   mView->GetCellProperties(aRowIndex, aColumn, properties);
@@ -3399,17 +3405,17 @@ nsTreeBodyFrame::PaintCell(int32_t      
   }
   
   // Now paint the icon for our cell.
   nsRect iconRect(currX, cellRect.y, remainingWidth, cellRect.height);
   nsRect dirtyRect;
   if (dirtyRect.IntersectRect(aDirtyRect, iconRect)) {
     result &= PaintImage(aRowIndex, aColumn, iconRect, aPresContext,
                          aRenderingContext, aDirtyRect, remainingWidth,
-                         currX);
+                         currX, aBuilder);
   }
 
   // Now paint our element, but only if we aren't a cycler column.
   // XXX until we have the ability to load images, allow the view to 
   // insert text into cycler columns...
   if (!aColumn->IsCycler()) {
     nsRect elementRect(currX, cellRect.y, remainingWidth, cellRect.height);
     nsRect dirtyRect;
@@ -3427,17 +3433,17 @@ nsTreeBodyFrame::PaintCell(int32_t      
         case nsITreeColumn::TYPE_PROGRESSMETER:
           int32_t state;
           mView->GetProgressMode(aRowIndex, aColumn, &state);
           switch (state) {
             case nsITreeView::PROGRESS_NORMAL:
             case nsITreeView::PROGRESS_UNDETERMINED:
               result &= PaintProgressMeter(aRowIndex, aColumn, elementRect,
                                            aPresContext, aRenderingContext,
-                                           aDirtyRect);
+                                           aDirtyRect, aBuilder);
               break;
             case nsITreeView::PROGRESS_NONE:
             default:
               result &= PaintText(aRowIndex, aColumn, elementRect, aPresContext,
                                   aRenderingContext, aDirtyRect, currX);
               break;
           }
           break;
@@ -3547,24 +3553,25 @@ nsTreeBodyFrame::PaintTwisty(int32_t    
       }
     }
   }
 
   return result;
 }
 
 DrawResult
-nsTreeBodyFrame::PaintImage(int32_t              aRowIndex,
-                            nsTreeColumn*        aColumn,
-                            const nsRect&        aImageRect,
-                            nsPresContext*       aPresContext,
-                            nsRenderingContext& aRenderingContext,
-                            const nsRect&        aDirtyRect,
-                            nscoord&             aRemainingWidth,
-                            nscoord&             aCurrX)
+nsTreeBodyFrame::PaintImage(int32_t               aRowIndex,
+                            nsTreeColumn*         aColumn,
+                            const nsRect&         aImageRect,
+                            nsPresContext*        aPresContext,
+                            nsRenderingContext&   aRenderingContext,
+                            const nsRect&         aDirtyRect,
+                            nscoord&              aRemainingWidth,
+                            nscoord&              aCurrX,
+                            nsDisplayListBuilder* aBuilder)
 {
   NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed");
 
   bool isRTL = StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
   nscoord rightEdge = aCurrX + aRemainingWidth;
   // Resolve style for the image.
   nsStyleContext* imageContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreeimage);
 
@@ -3701,21 +3708,22 @@ nsTreeBodyFrame::PaintImage(int32_t     
       }
     }
 
     gfxContext* ctx = aRenderingContext.ThebesContext();
     if (opacity != 1.0f) {
       ctx->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity);
     }
 
+    uint32_t drawFlags = aBuilder && aBuilder->IsPaintingToWindow() ?
+      imgIContainer::FLAG_HIGH_QUALITY_SCALING : imgIContainer::FLAG_NONE;
     result &=
       nsLayoutUtils::DrawImage(*ctx, aPresContext, image,
         nsLayoutUtils::GetSamplingFilterForFrame(this),
-        wholeImageDest, destRect, destRect.TopLeft(), aDirtyRect,
-        imgIContainer::FLAG_NONE);
+        wholeImageDest, destRect, destRect.TopLeft(), aDirtyRect, drawFlags);
 
     if (opacity != 1.0f) {
       ctx->PopGroupAndBlend();
     }
   }
 
   // Update the aRemainingWidth and aCurrX values.
   imageRect.Inflate(imageMargin);
@@ -3935,22 +3943,23 @@ nsTreeBodyFrame::PaintCheckbox(int32_t  
         image, SamplingFilter::POINT, pt, &aDirtyRect,
         imgIContainer::FLAG_NONE, &imageSize);
   }
 
   return result;
 }
 
 DrawResult
-nsTreeBodyFrame::PaintProgressMeter(int32_t              aRowIndex,
-                                    nsTreeColumn*        aColumn,
-                                    const nsRect&        aProgressMeterRect,
-                                    nsPresContext*      aPresContext,
-                                    nsRenderingContext& aRenderingContext,
-                                    const nsRect&        aDirtyRect)
+nsTreeBodyFrame::PaintProgressMeter(int32_t               aRowIndex,
+                                    nsTreeColumn*         aColumn,
+                                    const nsRect&         aProgressMeterRect,
+                                    nsPresContext*        aPresContext,
+                                    nsRenderingContext&   aRenderingContext,
+                                    const nsRect&         aDirtyRect,
+                                    nsDisplayListBuilder* aBuilder)
 {
   NS_PRECONDITION(aColumn && aColumn->GetFrame(), "invalid column passed");
 
   // Resolve style for the progress meter.  It contains all the info we need
   // to lay ourselves out and to paint.
   nsStyleContext* meterContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreeprogressmeter);
 
   // Obtain the margins for the progress meter and then deflate our rect by that 
@@ -3992,22 +4001,24 @@ nsTreeBodyFrame::PaintProgressMeter(int3
     nsCOMPtr<imgIContainer> image;
     GetImage(aRowIndex, aColumn, true, meterContext, useImageRegion, getter_AddRefs(image));
     if (image) {
       int32_t width, height;
       image->GetWidth(&width);
       image->GetHeight(&height);
       nsSize size(width*nsDeviceContext::AppUnitsPerCSSPixel(),
                   height*nsDeviceContext::AppUnitsPerCSSPixel());
+      uint32_t drawFlags = aBuilder && aBuilder->IsPaintingToWindow() ?
+        imgIContainer::FLAG_HIGH_QUALITY_SCALING : imgIContainer::FLAG_NONE;
       result &=
         nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
           aPresContext, image,
           nsLayoutUtils::GetSamplingFilterForFrame(this),
           nsRect(meterRect.TopLeft(), size), meterRect, meterRect.TopLeft(),
-          aDirtyRect, imgIContainer::FLAG_NONE);
+          aDirtyRect, drawFlags);
     } else {
       DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
       int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
       Rect rect =
         NSRectToSnappedRect(meterRect, appUnitsPerDevPixel, *drawTarget);
       ColorPattern color(ToDeviceColor(meterContext->StyleColor()->mColor));
       drawTarget->FillRect(rect, color);
     }
@@ -4020,22 +4031,24 @@ nsTreeBodyFrame::PaintProgressMeter(int3
     nsCOMPtr<imgIContainer> image;
     GetImage(aRowIndex, aColumn, true, meterContext, useImageRegion, getter_AddRefs(image));
     if (image) {
       int32_t width, height;
       image->GetWidth(&width);
       image->GetHeight(&height);
       nsSize size(width*nsDeviceContext::AppUnitsPerCSSPixel(),
                   height*nsDeviceContext::AppUnitsPerCSSPixel());
+      uint32_t drawFlags = aBuilder && aBuilder->IsPaintingToWindow() ?
+        imgIContainer::FLAG_HIGH_QUALITY_SCALING : imgIContainer::FLAG_NONE;
       result &=
         nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
           aPresContext, image,
           nsLayoutUtils::GetSamplingFilterForFrame(this),
           nsRect(meterRect.TopLeft(), size), meterRect, meterRect.TopLeft(),
-          aDirtyRect, imgIContainer::FLAG_NONE);
+          aDirtyRect, drawFlags);
     }
   }
 
   return result;
 }
 
 
 DrawResult
--- a/layout/xul/tree/nsTreeBodyFrame.h
+++ b/layout/xul/tree/nsTreeBodyFrame.h
@@ -191,17 +191,18 @@ public:
     nsCOMPtr<nsIContent> mVScrollbarContent;
     nsScrollbarFrame*    mHScrollbar;
     nsCOMPtr<nsIContent> mHScrollbarContent;
     nsIFrame*            mColumnsFrame;
     nsIScrollableFrame*  mColumnsScrollFrame;
   };
 
   DrawResult PaintTreeBody(nsRenderingContext& aRenderingContext,
-                           const nsRect& aDirtyRect, nsPoint aPt);
+                           const nsRect& aDirtyRect, nsPoint aPt,
+                           nsDisplayListBuilder* aBuilder);
 
   nsITreeBoxObject* GetTreeBoxObject() const { return mTreeBoxObject; }
 
   // Get the base element, <tree> or <select>
   nsIContent* GetBaseElement();
 
   bool GetVerticalOverflow() const { return mVerticalOverflow; }
   bool GetHorizontalOverflow() const {return mHorizontalOverflow; }
@@ -212,59 +213,62 @@ protected:
   // This method paints a specific column background of the tree.
   DrawResult PaintColumn(nsTreeColumn*        aColumn,
                          const nsRect&        aColumnRect,
                          nsPresContext*       aPresContext,
                          nsRenderingContext&  aRenderingContext,
                          const nsRect&        aDirtyRect);
 
   // This method paints a single row in the tree.
-  DrawResult PaintRow(int32_t              aRowIndex,
-                      const nsRect&        aRowRect,
-                      nsPresContext*       aPresContext,
-                      nsRenderingContext&  aRenderingContext,
-                      const nsRect&        aDirtyRect,
-                      nsPoint              aPt);
+  DrawResult PaintRow(int32_t               aRowIndex,
+                      const nsRect&         aRowRect,
+                      nsPresContext*        aPresContext,
+                      nsRenderingContext&   aRenderingContext,
+                      const nsRect&         aDirtyRect,
+                      nsPoint               aPt,
+                      nsDisplayListBuilder* aBuilder);
 
   // This method paints a single separator in the tree.
   DrawResult PaintSeparator(int32_t              aRowIndex,
                             const nsRect&        aSeparatorRect,
                             nsPresContext*       aPresContext,
                             nsRenderingContext&  aRenderingContext,
                             const nsRect&        aDirtyRect);
 
   // This method paints a specific cell in a given row of the tree.
-  DrawResult PaintCell(int32_t              aRowIndex, 
-                       nsTreeColumn*        aColumn,
-                       const nsRect&        aCellRect,
-                       nsPresContext*       aPresContext,
-                       nsRenderingContext&  aRenderingContext,
-                       const nsRect&        aDirtyRect,
-                       nscoord&             aCurrX,
-                       nsPoint              aPt);
+  DrawResult PaintCell(int32_t               aRowIndex,
+                       nsTreeColumn*         aColumn,
+                       const nsRect&         aCellRect,
+                       nsPresContext*        aPresContext,
+                       nsRenderingContext&   aRenderingContext,
+                       const nsRect&         aDirtyRect,
+                       nscoord&              aCurrX,
+                       nsPoint               aPt,
+                       nsDisplayListBuilder* aBuilder);
 
   // This method paints the twisty inside a cell in the primary column of an tree.
   DrawResult PaintTwisty(int32_t              aRowIndex,
                          nsTreeColumn*        aColumn,
                          const nsRect&        aTwistyRect,
                          nsPresContext*       aPresContext,
                          nsRenderingContext&  aRenderingContext,
                          const nsRect&        aDirtyRect,
                          nscoord&             aRemainingWidth,
                          nscoord&             aCurrX);
 
   // This method paints the image inside the cell of an tree.
-  DrawResult PaintImage(int32_t              aRowIndex,
-                        nsTreeColumn*        aColumn,
-                        const nsRect&        aImageRect,
-                        nsPresContext*       aPresContext,
-                        nsRenderingContext&  aRenderingContext,
-                        const nsRect&        aDirtyRect,
-                        nscoord&             aRemainingWidth,
-                        nscoord&             aCurrX);
+  DrawResult PaintImage(int32_t               aRowIndex,
+                        nsTreeColumn*         aColumn,
+                        const nsRect&         aImageRect,
+                        nsPresContext*        aPresContext,
+                        nsRenderingContext&   aRenderingContext,
+                        const nsRect&         aDirtyRect,
+                        nscoord&              aRemainingWidth,
+                        nscoord&              aCurrX,
+                        nsDisplayListBuilder* aBuilder);
 
   // This method paints the text string inside a particular cell of the tree.
   DrawResult PaintText(int32_t             aRowIndex,
                        nsTreeColumn*       aColumn,
                        const nsRect&       aTextRect,
                        nsPresContext*      aPresContext,
                        nsRenderingContext& aRenderingContext,
                        const nsRect&       aDirtyRect,
@@ -274,22 +278,23 @@ protected:
   DrawResult PaintCheckbox(int32_t              aRowIndex, 
                            nsTreeColumn*        aColumn,
                            const nsRect&        aCheckboxRect,
                            nsPresContext*       aPresContext,
                            nsRenderingContext&  aRenderingContext,
                            const nsRect&        aDirtyRect);
 
   // This method paints the progress meter inside a particular cell of the tree.
-  DrawResult PaintProgressMeter(int32_t              aRowIndex, 
-                                nsTreeColumn*        aColumn,
-                                const nsRect&        aProgressMeterRect,
-                                nsPresContext*       aPresContext,
-                                nsRenderingContext&  aRenderingContext,
-                                const nsRect&        aDirtyRect);
+  DrawResult PaintProgressMeter(int32_t               aRowIndex,
+                                nsTreeColumn*         aColumn,
+                                const nsRect&         aProgressMeterRect,
+                                nsPresContext*        aPresContext,
+                                nsRenderingContext&   aRenderingContext,
+                                const nsRect&         aDirtyRect,
+                                nsDisplayListBuilder* aBuilder);
 
   // This method paints a drop feedback of the tree.
   DrawResult PaintDropFeedback(const nsRect&        aDropFeedbackRect, 
                                nsPresContext*       aPresContext,
                                nsRenderingContext&  aRenderingContext,
                                const nsRect&        aDirtyRect,
                                nsPoint              aPt);