layout/base/nsCSSRenderingBorders.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:cindent:ts=2:et:sw=2:
     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 NS_CSS_RENDERING_BORDERS_H
     8 #define NS_CSS_RENDERING_BORDERS_H
    10 #include "nsColor.h"
    12 class gfxContext;
    13 class gfxPattern;
    14 struct gfxRGBA;
    16 namespace mozilla {
    17 namespace gfx {
    18 class GradientStops;
    19 }
    20 }
    22 // define this to enable a bunch of debug dump info
    23 #undef DEBUG_NEW_BORDERS
    25 //thickness of dashed line relative to dotted line
    26 #define DOT_LENGTH  1           //square
    27 #define DASH_LENGTH 3           //3 times longer than dot
    29 //some shorthand for side bits
    30 #define SIDE_BIT_TOP (1 << NS_SIDE_TOP)
    31 #define SIDE_BIT_RIGHT (1 << NS_SIDE_RIGHT)
    32 #define SIDE_BIT_BOTTOM (1 << NS_SIDE_BOTTOM)
    33 #define SIDE_BIT_LEFT (1 << NS_SIDE_LEFT)
    34 #define SIDE_BITS_ALL (SIDE_BIT_TOP|SIDE_BIT_RIGHT|SIDE_BIT_BOTTOM|SIDE_BIT_LEFT)
    36 #define C_TL NS_CORNER_TOP_LEFT
    37 #define C_TR NS_CORNER_TOP_RIGHT
    38 #define C_BR NS_CORNER_BOTTOM_RIGHT
    39 #define C_BL NS_CORNER_BOTTOM_LEFT
    41 /*
    42  * Helper class that handles border rendering.
    43  *
    44  * appUnitsPerPixel -- current value of AUPP
    45  * destContext -- the gfxContext to which the border should be rendered
    46  * outsideRect -- the rectangle on the outer edge of the border
    47  *
    48  * For any parameter where an array of side values is passed in,
    49  * they are in top, right, bottom, left order.
    50  *
    51  * borderStyles -- one border style enum per side
    52  * borderWidths -- one border width per side
    53  * borderRadii -- a gfxCornerSizes struct describing the w/h for each rounded corner.
    54  *    If the corner doesn't have a border radius, 0,0 should be given for it.
    55  * borderColors -- one nscolor per side
    56  * compositeColors -- a pointer to an array of composite color structs, or
    57  *    nullptr if none.
    58  *
    59  * skipSides -- a bit mask specifying which sides, if any, to skip
    60  * backgroundColor -- the background color of the element.
    61  *    Used in calculating colors for 2-tone borders, such as inset and outset
    62  * gapRect - a rectangle that should be clipped out to leave a gap in a border,
    63  *    or nullptr if none.
    64  */
    66 typedef enum {
    67   BorderColorStyleNone,
    68   BorderColorStyleSolid,
    69   BorderColorStyleLight,
    70   BorderColorStyleDark
    71 } BorderColorStyle;
    73 struct nsCSSBorderRenderer {
    74   nsCSSBorderRenderer(int32_t aAppUnitsPerPixel,
    75                       gfxContext* aDestContext,
    76                       gfxRect& aOuterRect,
    77                       const uint8_t* aBorderStyles,
    78                       const gfxFloat* aBorderWidths,
    79                       gfxCornerSizes& aBorderRadii,
    80                       const nscolor* aBorderColors,
    81                       nsBorderColors* const* aCompositeColors,
    82                       int aSkipSides,
    83                       nscolor aBackgroundColor);
    85   gfxCornerSizes mBorderCornerDimensions;
    87   // destination context
    88   gfxContext* mContext;
    90   // the rectangle of the outside and the inside of the border
    91   gfxRect mOuterRect;
    92   gfxRect mInnerRect;
    94   // the style and size of the border
    95   const uint8_t* mBorderStyles;
    96   const gfxFloat* mBorderWidths;
    97   uint8_t* mSanitizedStyles;
    98   gfxFloat* mSanitizedWidths;
    99   gfxCornerSizes mBorderRadii;
   101   // colors
   102   const nscolor* mBorderColors;
   103   nsBorderColors* const* mCompositeColors;
   105   // core app units per pixel
   106   int32_t mAUPP;
   108   // misc -- which sides to skip, the background color
   109   int mSkipSides;
   110   nscolor mBackgroundColor;
   112   // calculated values
   113   bool mOneUnitBorder;
   114   bool mNoBorderRadius;
   115   bool mAvoidStroke;
   117   // For all the sides in the bitmask, would they be rendered
   118   // in an identical color and style?
   119   bool AreBorderSideFinalStylesSame(uint8_t aSides);
   121   // For the given style, is the given corner a solid color?
   122   bool IsSolidCornerStyle(uint8_t aStyle, mozilla::css::Corner aCorner);
   124   // For the given solid corner, what color style should be used?
   125   BorderColorStyle BorderColorStyleForSolidCorner(uint8_t aStyle, mozilla::css::Corner aCorner);
   127   //
   128   // Path generation functions
   129   //
   131   // add the path for drawing the given corner to the context
   132   void DoCornerSubPath(mozilla::css::Corner aCorner);
   133   // add the path for drawing the given side without any adjacent corners to the context
   134   void DoSideClipWithoutCornersSubPath(mozilla::css::Side aSide);
   136   // Create a clip path for the wedge that this side of
   137   // the border should take up.  This is only called
   138   // when we're drawing separate border sides, so we know
   139   // that ADD compositing is taking place.
   140   //
   141   // This code needs to make sure that the individual pieces
   142   // don't ever (mathematically) overlap; the pixel overlap
   143   // is taken care of by the ADD compositing.
   144   void DoSideClipSubPath(mozilla::css::Side aSide);
   146   // Given a set of sides to fill and a color, do so in the fastest way.
   147   //
   148   // Stroke tends to be faster for smaller borders because it doesn't go
   149   // through the tessellator, which has initialization overhead.  If
   150   // we're rendering all sides, we can use stroke at any thickness; we
   151   // also do TL/BR pairs at 1px thickness using stroke.
   152   //
   153   // If we can't stroke, then if it's a TL/BR pair, we use the specific
   154   // TL/BR paths.  Otherwise, we do the full path and fill.
   155   //
   156   // Calling code is expected to only set up a clip as necessary; no
   157   // clip is needed if we can render the entire border in 1 or 2 passes.
   158   void FillSolidBorder(const gfxRect& aOuterRect,
   159                        const gfxRect& aInnerRect,
   160                        const gfxCornerSizes& aBorderRadii,
   161                        const gfxFloat *aBorderSizes,
   162                        int aSides,
   163                        const gfxRGBA& aColor);
   165   //
   166   // core rendering
   167   //
   169   // draw the border for the given sides, using the style of the first side
   170   // present in the bitmask
   171   void DrawBorderSides (int aSides);
   173   // function used by the above to handle -moz-border-colors
   174   void DrawBorderSidesCompositeColors(int aSides, const nsBorderColors *compositeColors);
   176   // draw the given dashed side
   177   void DrawDashedSide (mozilla::css::Side aSide);
   179   // Setup the stroke style for a given side
   180   void SetupStrokeStyle(mozilla::css::Side aSize);
   182   // Analyze if all border sides have the same width.
   183   bool AllBordersSameWidth();
   185   // Analyze if all borders are 'solid' this also considers hidden or 'none'
   186   // borders because they can be considered 'solid' borders of 0 width and
   187   // with no color effect.
   188   bool AllBordersSolid(bool *aHasCompositeColors);
   190   // Create a gradient pattern that will handle the color transition for a
   191   // corner.
   192   already_AddRefed<gfxPattern> CreateCornerGradient(mozilla::css::Corner aCorner,
   193                                                     const gfxRGBA &aFirstColor,
   194                                                     const gfxRGBA &aSecondColor);
   196   // Azure variant of CreateCornerGradient.
   197   mozilla::TemporaryRef<mozilla::gfx::GradientStops>
   198   CreateCornerGradient(mozilla::css::Corner aCorner, const gfxRGBA &aFirstColor,
   199                        const gfxRGBA &aSecondColor, mozilla::gfx::DrawTarget *aDT,
   200                        mozilla::gfx::Point &aPoint1, mozilla::gfx::Point &aPoint2);
   202   // Draw a solid color border that is uniformly the same width.
   203   void DrawSingleWidthSolidBorder();
   205   // Draw any border which is solid on all sides and does not use
   206   // CompositeColors.
   207   void DrawNoCompositeColorSolidBorder();
   208   // Draw any border which is solid on all sides and does not use
   209   // CompositeColors. Using Azure.
   210   void DrawNoCompositeColorSolidBorderAzure();
   212   // Draw a solid border that has no border radius (i.e. is rectangular) and
   213   // uses CompositeColors.
   214   void DrawRectangularCompositeColors();
   216   // draw the entire border
   217   void DrawBorders ();
   219   // utility function used for background painting as well as borders
   220   static void ComputeInnerRadii(const gfxCornerSizes& aRadii,
   221                                 const gfxFloat *aBorderSizes,
   222                                 gfxCornerSizes *aInnerRadiiRet);
   224   // Given aRadii as the border radii for a rectangle, compute the
   225   // appropriate radii for another rectangle *outside* that rectangle
   226   // by increasing the radii, except keeping sharp corners sharp.
   227   // Used for spread box-shadows
   228   static void ComputeOuterRadii(const gfxCornerSizes& aRadii,
   229                                 const gfxFloat *aBorderSizes,
   230                                 gfxCornerSizes *aOuterRadiiRet);
   231 };
   233 namespace mozilla {
   235 #ifdef DEBUG_NEW_BORDERS
   236 #include <stdarg.h>
   238 static inline void S(const gfxPoint& p) {
   239   fprintf (stderr, "[%f,%f]", p.x, p.y);
   240 }
   242 static inline void S(const gfxSize& s) {
   243   fprintf (stderr, "[%f %f]", s.width, s.height);
   244 }
   246 static inline void S(const gfxRect& r) {
   247   fprintf (stderr, "[%f %f %f %f]", r.pos.x, r.pos.y, r.size.width, r.size.height);
   248 }
   250 static inline void S(const gfxFloat f) {
   251   fprintf (stderr, "%f", f);
   252 }
   254 static inline void S(const char *s) {
   255   fprintf (stderr, "%s", s);
   256 }
   258 static inline void SN(const char *s = nullptr) {
   259   if (s)
   260     fprintf (stderr, "%s", s);
   261   fprintf (stderr, "\n");
   262   fflush (stderr);
   263 }
   265 static inline void SF(const char *fmt, ...) {
   266   va_list vl;
   267   va_start(vl, fmt);
   268   vfprintf (stderr, fmt, vl);
   269   va_end(vl);
   270 }
   272 static inline void SX(gfxContext *ctx) {
   273   gfxPoint p = ctx->CurrentPoint();
   274   fprintf (stderr, "p: %f %f\n", p.x, p.y);
   275   return;
   276   ctx->MoveTo(p + gfxPoint(-2, -2)); ctx->LineTo(p + gfxPoint(2, 2));
   277   ctx->MoveTo(p + gfxPoint(-2, 2)); ctx->LineTo(p + gfxPoint(2, -2));
   278   ctx->MoveTo(p);
   279 }
   282 #else
   283 static inline void S(const gfxPoint& p) {}
   284 static inline void S(const gfxSize& s) {}
   285 static inline void S(const gfxRect& r) {}
   286 static inline void S(const gfxFloat f) {}
   287 static inline void S(const char *s) {}
   288 static inline void SN(const char *s = nullptr) {}
   289 static inline void SF(const char *fmt, ...) {}
   290 static inline void SX(gfxContext *ctx) {}
   291 #endif
   293 }
   295 #endif /* NS_CSS_RENDERING_BORDERS_H */

mercurial