File: nsCSSRenderingBorders.h

package info (click to toggle)
wine-gecko-2.24 2.24%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 740,092 kB
  • ctags: 688,789
  • sloc: cpp: 3,160,639; ansic: 1,619,153; python: 164,084; java: 128,022; asm: 114,527; xml: 69,863; sh: 55,281; makefile: 49,648; perl: 20,454; objc: 2,344; yacc: 2,066; pascal: 995; lex: 982; exp: 449; php: 244; lisp: 228; awk: 211; sed: 61; csh: 21; ada: 16; ruby: 3
file content (287 lines) | stat: -rw-r--r-- 9,988 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:cindent:ts=2:et:sw=2:
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef NS_CSS_RENDERING_BORDERS_H
#define NS_CSS_RENDERING_BORDERS_H

#include "nsColor.h"
#include "nsStyleStruct.h"

#include "gfxContext.h"
#include "mozilla/gfx/2D.h"

// define this to enable a bunch of debug dump info
#undef DEBUG_NEW_BORDERS

//thickness of dashed line relative to dotted line
#define DOT_LENGTH  1           //square
#define DASH_LENGTH 3           //3 times longer than dot

//some shorthand for side bits
#define SIDE_BIT_TOP (1 << NS_SIDE_TOP)
#define SIDE_BIT_RIGHT (1 << NS_SIDE_RIGHT)
#define SIDE_BIT_BOTTOM (1 << NS_SIDE_BOTTOM)
#define SIDE_BIT_LEFT (1 << NS_SIDE_LEFT)
#define SIDE_BITS_ALL (SIDE_BIT_TOP|SIDE_BIT_RIGHT|SIDE_BIT_BOTTOM|SIDE_BIT_LEFT)

#define C_TL NS_CORNER_TOP_LEFT
#define C_TR NS_CORNER_TOP_RIGHT
#define C_BR NS_CORNER_BOTTOM_RIGHT
#define C_BL NS_CORNER_BOTTOM_LEFT

/*
 * Helper class that handles border rendering.
 *
 * appUnitsPerPixel -- current value of AUPP
 * destContext -- the gfxContext to which the border should be rendered
 * outsideRect -- the rectangle on the outer edge of the border
 *
 * For any parameter where an array of side values is passed in,
 * they are in top, right, bottom, left order.
 *
 * borderStyles -- one border style enum per side
 * borderWidths -- one border width per side
 * borderRadii -- a gfxCornerSizes struct describing the w/h for each rounded corner.
 *    If the corner doesn't have a border radius, 0,0 should be given for it.
 * borderColors -- one nscolor per side
 * compositeColors -- a pointer to an array of composite color structs, or NULL if none
 *
 * skipSides -- a bit mask specifying which sides, if any, to skip
 * backgroundColor -- the background color of the element.
 *    Used in calculating colors for 2-tone borders, such as inset and outset
 * gapRect - a rectangle that should be clipped out to leave a gap in a border,
 *    or nullptr if none.
 */

typedef enum {
  BorderColorStyleNone,
  BorderColorStyleSolid,
  BorderColorStyleLight,
  BorderColorStyleDark
} BorderColorStyle;

struct nsCSSBorderRenderer {
  nsCSSBorderRenderer(int32_t aAppUnitsPerPixel,
                      gfxContext* aDestContext,
                      gfxRect& aOuterRect,
                      const uint8_t* aBorderStyles,
                      const gfxFloat* aBorderWidths,
                      gfxCornerSizes& aBorderRadii,
                      const nscolor* aBorderColors,
                      nsBorderColors* const* aCompositeColors,
                      int aSkipSides,
                      nscolor aBackgroundColor);

  static void Init();
  static void Shutdown();

  gfxCornerSizes mBorderCornerDimensions;

  // destination context
  gfxContext* mContext;

  // the rectangle of the outside and the inside of the border
  gfxRect mOuterRect;
  gfxRect mInnerRect;

  // the style and size of the border
  const uint8_t* mBorderStyles;
  const gfxFloat* mBorderWidths;
  uint8_t* mSanitizedStyles;
  gfxFloat* mSanitizedWidths;
  gfxCornerSizes mBorderRadii;

  // colors
  const nscolor* mBorderColors;
  nsBorderColors* const* mCompositeColors;

  // core app units per pixel
  int32_t mAUPP;

  // misc -- which sides to skip, the background color
  int mSkipSides;
  nscolor mBackgroundColor;

  // calculated values
  bool mOneUnitBorder;
  bool mNoBorderRadius;
  bool mAvoidStroke;

  // For all the sides in the bitmask, would they be rendered
  // in an identical color and style?
  bool AreBorderSideFinalStylesSame(uint8_t aSides);

  // For the given style, is the given corner a solid color?
  bool IsSolidCornerStyle(uint8_t aStyle, mozilla::css::Corner aCorner);

  // For the given solid corner, what color style should be used?
  BorderColorStyle BorderColorStyleForSolidCorner(uint8_t aStyle, mozilla::css::Corner aCorner);

  //
  // Path generation functions
  //

  // add the path for drawing the given corner to the context
  void DoCornerSubPath(mozilla::css::Corner aCorner);
  // add the path for drawing the given side without any adjacent corners to the context
  void DoSideClipWithoutCornersSubPath(mozilla::css::Side aSide);

  // Create a clip path for the wedge that this side of
  // the border should take up.  This is only called
  // when we're drawing separate border sides, so we know
  // that ADD compositing is taking place.
  //
  // This code needs to make sure that the individual pieces
  // don't ever (mathematically) overlap; the pixel overlap
  // is taken care of by the ADD compositing.
  void DoSideClipSubPath(mozilla::css::Side aSide);

  // Given a set of sides to fill and a color, do so in the fastest way.
  //
  // Stroke tends to be faster for smaller borders because it doesn't go
  // through the tessellator, which has initialization overhead.  If
  // we're rendering all sides, we can use stroke at any thickness; we
  // also do TL/BR pairs at 1px thickness using stroke.
  //
  // If we can't stroke, then if it's a TL/BR pair, we use the specific
  // TL/BR paths.  Otherwise, we do the full path and fill.
  //
  // Calling code is expected to only set up a clip as necessary; no
  // clip is needed if we can render the entire border in 1 or 2 passes.
  void FillSolidBorder(const gfxRect& aOuterRect,
                       const gfxRect& aInnerRect,
                       const gfxCornerSizes& aBorderRadii,
                       const gfxFloat *aBorderSizes,
                       int aSides,
                       const gfxRGBA& aColor);

  //
  // core rendering
  //

  // draw the border for the given sides, using the style of the first side
  // present in the bitmask
  void DrawBorderSides (int aSides);

  // function used by the above to handle -moz-border-colors
  void DrawBorderSidesCompositeColors(int aSides, const nsBorderColors *compositeColors);

  // draw the given dashed side
  void DrawDashedSide (mozilla::css::Side aSide);
  
  // Setup the stroke style for a given side
  void SetupStrokeStyle(mozilla::css::Side aSize);

  // Analyze if all border sides have the same width.
  bool AllBordersSameWidth();

  // Analyze if all borders are 'solid' this also considers hidden or 'none'
  // borders because they can be considered 'solid' borders of 0 width and
  // with no color effect.
  bool AllBordersSolid(bool *aHasCompositeColors);

  // Create a gradient pattern that will handle the color transition for a
  // corner.
  already_AddRefed<gfxPattern> CreateCornerGradient(mozilla::css::Corner aCorner,
                                                    const gfxRGBA &aFirstColor,
                                                    const gfxRGBA &aSecondColor);

  // Azure variant of CreateCornerGradient.
  mozilla::TemporaryRef<mozilla::gfx::GradientStops>
  CreateCornerGradient(mozilla::css::Corner aCorner, const gfxRGBA &aFirstColor,
                       const gfxRGBA &aSecondColor, mozilla::gfx::DrawTarget *aDT,
                       mozilla::gfx::Point &aPoint1, mozilla::gfx::Point &aPoint2);

  // Draw a solid color border that is uniformly the same width.
  void DrawSingleWidthSolidBorder();

  // Draw any border which is solid on all sides and does not use
  // CompositeColors.
  void DrawNoCompositeColorSolidBorder();
  // Draw any border which is solid on all sides and does not use
  // CompositeColors. Using Azure.
  void DrawNoCompositeColorSolidBorderAzure();

  // Draw a solid border that has no border radius (i.e. is rectangular) and
  // uses CompositeColors.
  void DrawRectangularCompositeColors();

  // draw the entire border
  void DrawBorders ();

  // utility function used for background painting as well as borders
  static void ComputeInnerRadii(const gfxCornerSizes& aRadii,
                                const gfxFloat *aBorderSizes,
                                gfxCornerSizes *aInnerRadiiRet);

  // Given aRadii as the border radii for a rectangle, compute the
  // appropriate radii for another rectangle *outside* that rectangle
  // by increasing the radii, except keeping sharp corners sharp.
  // Used for spread box-shadows
  static void ComputeOuterRadii(const gfxCornerSizes& aRadii,
                                const gfxFloat *aBorderSizes,
                                gfxCornerSizes *aOuterRadiiRet);
};

#ifdef DEBUG_NEW_BORDERS
#include <stdarg.h>

static inline void S(const gfxPoint& p) {
  fprintf (stderr, "[%f,%f]", p.x, p.y);
}

static inline void S(const gfxSize& s) {
  fprintf (stderr, "[%f %f]", s.width, s.height);
}

static inline void S(const gfxRect& r) {
  fprintf (stderr, "[%f %f %f %f]", r.pos.x, r.pos.y, r.size.width, r.size.height);
}

static inline void S(const gfxFloat f) {
  fprintf (stderr, "%f", f);
}

static inline void S(const char *s) {
  fprintf (stderr, "%s", s);
}

static inline void SN(const char *s = nullptr) {
  if (s)
    fprintf (stderr, "%s", s);
  fprintf (stderr, "\n");
  fflush (stderr);
}

static inline void SF(const char *fmt, ...) {
  va_list vl;
  va_start(vl, fmt);
  vfprintf (stderr, fmt, vl);
  va_end(vl);
}

static inline void SX(gfxContext *ctx) {
  gfxPoint p = ctx->CurrentPoint();
  fprintf (stderr, "p: %f %f\n", p.x, p.y);
  return;
  ctx->MoveTo(p + gfxPoint(-2, -2)); ctx->LineTo(p + gfxPoint(2, 2));
  ctx->MoveTo(p + gfxPoint(-2, 2)); ctx->LineTo(p + gfxPoint(2, -2));
  ctx->MoveTo(p);
}


#else
static inline void S(const gfxPoint& p) {}
static inline void S(const gfxSize& s) {}
static inline void S(const gfxRect& r) {}
static inline void S(const gfxFloat f) {}
static inline void S(const char *s) {}
static inline void SN(const char *s = nullptr) {}
static inline void SF(const char *fmt, ...) {}
static inline void SX(gfxContext *ctx) {}
#endif

#endif /* NS_CSS_RENDERING_BORDERS_H */