layout/generic/TextOverflow.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef TextOverflow_h_
     8 #define TextOverflow_h_
    10 #include "nsDisplayList.h"
    11 #include "nsTHashtable.h"
    12 #include "mozilla/Likely.h"
    13 #include <algorithm>
    15 class nsIScrollableFrame;
    16 class gfxTextRun;
    17 class nsLineBox;
    19 namespace mozilla {
    20 namespace css {
    22 /**
    23  * A class for rendering CSS3 text-overflow.
    24  * Usage:
    25  *  1. allocate an object using WillProcessLines
    26  *  2. then call ProcessLine for each line you are building display lists for
    27  */
    28 class TextOverflow {
    29  public:
    30   /**
    31    * Allocate an object for text-overflow processing.
    32    * @return nullptr if no processing is necessary.  The caller owns the object.
    33    */
    34   static TextOverflow* WillProcessLines(nsDisplayListBuilder*   aBuilder,
    35                                         nsIFrame*               aBlockFrame);
    36   /**
    37    * Analyze the display lists for text overflow and what kind of item is at
    38    * the content edges.  Add display items for text-overflow markers as needed
    39    * and remove or clip items that would overlap a marker.
    40    */
    41   void ProcessLine(const nsDisplayListSet& aLists, nsLineBox* aLine);
    43   /**
    44    * Get the resulting text-overflow markers (the list may be empty).
    45    * @return a DisplayList containing any text-overflow markers.
    46    */
    47   nsDisplayList& GetMarkers() { return mMarkerList; }
    49   /**
    50    * @return true if aBlockFrame needs analysis for text overflow.
    51    */
    52   static bool CanHaveTextOverflow(nsDisplayListBuilder* aBuilder,
    53                                   nsIFrame*             aBlockFrame);
    55   typedef nsTHashtable<nsPtrHashKey<nsIFrame> > FrameHashtable;
    57  protected:
    58   TextOverflow() {}
    59   void Init(nsDisplayListBuilder*   aBuilder,
    60             nsIFrame*               aBlockFrame);
    62   struct AlignmentEdges {
    63     AlignmentEdges() : mAssigned(false) {}
    64     void Accumulate(const nsRect& aRect) {
    65       if (MOZ_LIKELY(mAssigned)) {
    66         x = std::min(x, aRect.X());
    67         xmost = std::max(xmost, aRect.XMost());
    68       } else {
    69         x = aRect.X();
    70         xmost = aRect.XMost();
    71         mAssigned = true;
    72       }
    73     }
    74     nscoord Width() { return xmost - x; }
    75     nscoord x;
    76     nscoord xmost;
    77     bool mAssigned;
    78   };
    80   struct InnerClipEdges {
    81     InnerClipEdges() : mAssignedLeft(false), mAssignedRight(false) {}
    82     void AccumulateLeft(const nsRect& aRect) {
    83       if (MOZ_LIKELY(mAssignedLeft)) {
    84         mLeft = std::max(mLeft, aRect.X());
    85       } else {
    86         mLeft = aRect.X();
    87         mAssignedLeft = true;
    88       }
    89     }
    90     void AccumulateRight(const nsRect& aRect) {
    91       if (MOZ_LIKELY(mAssignedRight)) {
    92         mRight = std::min(mRight, aRect.XMost());
    93       } else {
    94         mRight = aRect.XMost();
    95         mAssignedRight = true;
    96       }
    97     }
    98     nscoord mLeft;
    99     nscoord mRight;
   100     bool mAssignedLeft;
   101     bool mAssignedRight;
   102   };
   104   /**
   105    * Examines frames on the line to determine whether we should draw a left
   106    * and/or right marker, and if so, which frames should be completely hidden
   107    * and the bounds of what will be displayed between the markers.
   108    * @param aLine the line we're processing
   109    * @param aFramesToHide frames that should have their display items removed
   110    * @param aAlignmentEdges the outermost edges of all text and atomic
   111    *   inline-level frames that are inside the area between the markers
   112    */
   113   void ExamineLineFrames(nsLineBox*      aLine,
   114                          FrameHashtable* aFramesToHide,
   115                          AlignmentEdges* aAlignmentEdges);
   117   /**
   118    * LineHasOverflowingText calls this to analyze edges, both the block's
   119    * content edges and the hypothetical marker edges aligned at the block edges.
   120    * @param aFrame the descendant frame of mBlock that we're analyzing
   121    * @param aContentArea the block's content area
   122    * @param aInsideMarkersArea the rectangle between the markers
   123    * @param aFramesToHide frames that should have their display items removed
   124    * @param aAlignmentEdges the outermost edges of all text and atomic
   125    *   inline-level frames that are inside the area between the markers
   126    * @param aFoundVisibleTextOrAtomic is set to true if a text or atomic
   127    *   inline-level frame is visible between the marker edges
   128    * @param aClippedMarkerEdges the innermost edges of all text and atomic
   129    *   inline-level frames that are clipped by the current marker width
   130    */
   131   void ExamineFrameSubtree(nsIFrame*       aFrame,
   132                            const nsRect&   aContentArea,
   133                            const nsRect&   aInsideMarkersArea,
   134                            FrameHashtable* aFramesToHide,
   135                            AlignmentEdges* aAlignmentEdges,
   136                            bool*           aFoundVisibleTextOrAtomic,
   137                            InnerClipEdges* aClippedMarkerEdges);
   139   /**
   140    * ExamineFrameSubtree calls this to analyze a frame against the hypothetical
   141    * marker edges (aInsideMarkersArea) for text frames and atomic inline-level
   142    * elements.  A text frame adds its extent inside aInsideMarkersArea where
   143    * grapheme clusters are fully visible.  An atomic adds its border box if
   144    * it's fully inside aInsideMarkersArea, otherwise the frame is added to
   145    * aFramesToHide.
   146    * @param aFrame the descendant frame of mBlock that we're analyzing
   147    * @param aFrameType aFrame's frame type
   148    * @param aInsideMarkersArea the rectangle between the markers
   149    * @param aFramesToHide frames that should have their display items removed
   150    * @param aAlignmentEdges the outermost edges of all text and atomic
   151    *   inline-level frames that are inside the area between the markers
   152    *                       inside aInsideMarkersArea
   153    * @param aFoundVisibleTextOrAtomic is set to true if a text or atomic
   154    *   inline-level frame is visible between the marker edges
   155    * @param aClippedMarkerEdges the innermost edges of all text and atomic
   156    *   inline-level frames that are clipped by the current marker width
   157    */
   158   void AnalyzeMarkerEdges(nsIFrame*       aFrame,
   159                           const nsIAtom*  aFrameType,
   160                           const nsRect&   aInsideMarkersArea,
   161                           FrameHashtable* aFramesToHide,
   162                           AlignmentEdges* aAlignmentEdges,
   163                           bool*           aFoundVisibleTextOrAtomic,
   164                           InnerClipEdges* aClippedMarkerEdges);
   166   /**
   167    * Clip or remove items given the final marker edges. ("clip" here just means
   168    * assigning mLeftEdge/mRightEdge for any nsCharClipDisplayItem that needs it,
   169    * see nsDisplayList.h for a description of that item).
   170    * @param aFramesToHide remove display items for these frames
   171    * @param aInsideMarkersArea is the area inside the markers
   172    */
   173   void PruneDisplayListContents(nsDisplayList*        aList,
   174                                 const FrameHashtable& aFramesToHide,
   175                                 const nsRect&         aInsideMarkersArea);
   177   /**
   178    * ProcessLine calls this to create display items for the markers and insert
   179    * them into mMarkerList.
   180    * @param aLine the line we're processing
   181    * @param aCreateLeft if true, create a marker on the left side
   182    * @param aCreateRight if true, create a marker on the right side
   183    * @param aInsideMarkersArea is the area inside the markers
   184    */
   185   void CreateMarkers(const nsLineBox* aLine,
   186                      bool             aCreateLeft,
   187                      bool             aCreateRight,
   188                      const nsRect&    aInsideMarkersArea);
   190   nsRect                 mContentArea;
   191   nsDisplayListBuilder*  mBuilder;
   192   nsIFrame*              mBlock;
   193   nsIScrollableFrame*    mScrollableFrame;
   194   nsDisplayList          mMarkerList;
   195   bool                   mBlockIsRTL;
   196   bool                   mCanHaveHorizontalScrollbar;
   197   bool                   mAdjustForPixelSnapping;
   199   class Marker {
   200   public:
   201     void Init(const nsStyleTextOverflowSide& aStyle) {
   202       mInitialized = false;
   203       mWidth = 0;
   204       mStyle = &aStyle;
   205     }
   207     /**
   208      * Setup the marker string and calculate its size, if not done already.
   209      */
   210     void SetupString(nsIFrame* aFrame);
   212     bool IsNeeded() const {
   213       return mHasOverflow;
   214     }
   215     void Reset() {
   216       mHasOverflow = false;
   217     }
   219     // The current width of the marker, the range is [0 .. mIntrinsicWidth].
   220     nscoord                        mWidth;
   221     // The intrinsic width of the marker.
   222     nscoord                        mIntrinsicWidth;
   223     // The style for this side.
   224     const nsStyleTextOverflowSide* mStyle;
   225     // True if there is visible overflowing inline content on this side.
   226     bool                           mHasOverflow;
   227     // True if mMarkerString and mWidth have been setup from style.
   228     bool                           mInitialized;
   229     // True if the style is text-overflow:clip on this side and the marker
   230     // won't cause the line to become empty.
   231     bool                           mActive;
   232   };
   234   Marker mLeft;  // the horizontal left marker
   235   Marker mRight; // the horizontal right marker
   236 };
   238 } // namespace css
   239 } // namespace mozilla
   241 #endif /* !defined(TextOverflow_h_) */

mercurial