Back to index

lightning-sunbird  0.9+nobinonly
Static Public Member Functions | Static Protected Member Functions
nsCSSRendering Class Reference

#include <nsCSSRendering.h>

List of all members.

Static Public Member Functions

static void PaintBorder (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aDirtyRect, const nsRect &aBorderArea, const nsStyleBorder &aBorderStyle, nsStyleContext *aStyleContext, PRIntn aSkipSides, nsRect *aGap=0, nscoord aHardBorderSize=0, PRBool aShouldIgnoreRounded=PR_FALSE)
 Render the border for an element using css rendering rules for borders.
static void PaintOutline (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aDirtyRect, const nsRect &aBorderArea, const nsStyleBorder &aBorderStyle, const nsStyleOutline &aOutlineStyle, nsStyleContext *aStyleContext, PRIntn aSkipSides, nsRect *aGap=0)
 Render the outline for an element using css rendering rules for borders.
static void PaintBorderEdges (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aDirtyRect, const nsRect &aBorderArea, nsBorderEdges *aBorderEdges, nsStyleContext *aStyleContext, PRIntn aSkipSides, nsRect *aGap=0)
 Just like PaintBorder, but takes as input a list of border segments rather than a single border style.
static PRBool FindBackground (nsPresContext *aPresContext, nsIFrame *aForFrame, const nsStyleBackground **aBackground, PRBool *aIsCanvas)
 Fill in an nsStyleBackground to be used to paint the background for an element.
static const nsStyleBackgroundFindNonTransparentBackground (nsStyleContext *aContext, PRBool aStartAtParent=PR_FALSE)
 Find a non-transparent background, for various table-related and HR-related backwards-compatibility hacks.
static void PaintBackground (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aDirtyRect, const nsRect &aBorderArea, const nsStyleBorder &aBorder, const nsStylePadding &aPadding, PRBool aUsePrintSettings, nsRect *aBGClipRect=nsnull)
 Render the background for an element using css rendering rules for backgrounds.
static void PaintBackgroundWithSC (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aDirtyRect, const nsRect &aBorderArea, const nsStyleBackground &aColor, const nsStyleBorder &aBorder, const nsStylePadding &aPadding, PRBool aUsePrintSettings=PR_FALSE, nsRect *aBGClipRect=nsnull)
 Same as |PaintBackground|, except using the provided style context (which short-circuits the code that ensures that the root element's background is drawn on the canvas.
static void DidPaint ()
 Called by the presShell when painting is finished, so we can clear our inline background data cache.
static void DrawDashedSides (PRIntn startSide, nsIRenderingContext &aContext, const nsRect &aDirtyRect, const PRUint8 borderStyles[], const nscolor borderColors[], const nsRect &borderOutside, const nsRect &borderInside, PRIntn aSkipSides, nsRect *aGap)
 Draw a dotted/dashed sides of a box.
static void DrawDashedSides (PRIntn startSide, nsIRenderingContext &aContext, const nsRect &aDirtyRect, const nsStyleColor *aColorStyle, const nsStyleBorder *aBorderStyle, const nsStyleOutline *aOutlineStyle, PRBool aDoOutline, const nsRect &borderOutside, const nsRect &borderInside, PRIntn aSkipSides, nsRect *aGap)
 
See documentation in nsCSSRendering.h 10/22/99 dwc
static void DrawDashedSegments (nsIRenderingContext &aContext, const nsRect &aBounds, nsBorderEdges *aBorderEdges, PRIntn aSkipSides, nsRect *aGap)
 draw the dashed segements of a segmented border
static void DrawTableBorderSegment (nsIRenderingContext &aContext, PRUint8 aBorderStyle, nscolor aBorderColor, const nsStyleBackground *aBGColor, const nsRect &aBorderRect, float aPixelsToTwips, PRUint8 aStartBevelSide=0, nscoord aStartBevelOffset=0, PRUint8 aEndBevelSide=0, nscoord aEndBevelOffset=0)
static nscolor TransformColor (nscolor aMapColor, PRBool aNoBackGround)
 transform a color to a color that will show up on a printer if needed aMapColor - color to evaluate aIsPrinter - Is this a printing device return - the transformed color

Static Protected Member Functions

static void PaintRoundedBorder (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aDirtyRect, const nsRect &aBorderArea, const nsStyleBorder *aBorderStyle, const nsStyleOutline *aOutlineStyle, nsStyleContext *aStyleContext, PRIntn aSkipSides, PRInt16 aBorderRadius[4], nsRect *aGap=0, PRBool aIsOutline=PR_FALSE)
 Render the border for an element using css rendering rules for borders.
static void RenderSide (nsFloatPoint aPoints[], nsIRenderingContext &aRenderingContext, const nsStyleBorder *aBorderStyle, const nsStyleOutline *aOutlineStyle, nsStyleContext *aStyleContext, PRUint8 aSide, nsMargin &aBorThick, nscoord aTwipsPerPixel, PRBool aIsOutline=PR_FALSE)
 
See documentation in nsCSSRendering.h 3/26/99 dwc
static void PaintBackgroundColor (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aBgClipArea, const nsStyleBackground &aColor, const nsStyleBorder &aBorder, const nsStylePadding &aPadding, PRBool aCanPaintNonWhite)
static void PaintRoundedBackground (nsPresContext *aPresContext, nsIRenderingContext &aRenderingContext, nsIFrame *aForFrame, const nsRect &aBorderArea, const nsStyleBackground &aColor, const nsStyleBorder &aBorder, PRInt16 aTheRadius[4], PRBool aCanPaintNonWhite)
 
See documentation in nsCSSRendering.h 3/26/99 dwc
static nscolor MakeBevelColor (PRIntn whichSide, PRUint8 style, nscolor aBackgroundColor, nscolor aBorderColor, PRBool aSpecialCase)
 Make a bevel color.
static PRIntn MakeSide (nsPoint aPoints[], nsIRenderingContext &aContext, PRIntn whichSide, const nsRect &outside, const nsRect &inside, PRIntn aSkipSides, PRIntn borderPart, float borderFrac, nscoord twipsPerPixel)
static void DrawSide (nsIRenderingContext &aContext, PRIntn whichSide, const PRUint8 borderStyle, const nscolor borderColor, const nscolor aBackgroundColor, const nsRect &borderOutside, const nsRect &borderInside, PRIntn aSkipSides, nscoord twipsPerPixel, nsRect *aGap=0)
static void DrawCompositeSide (nsIRenderingContext &aContext, PRIntn aWhichSide, nsBorderColors *aCompositeColors, const nsRect &aOuterRect, const nsRect &aInnerRect, PRInt16 *aBorderRadii, nscoord aTwipsPerPixel, nsRect *aGap)
static void DrawLine (nsIRenderingContext &aContext, nscoord aX1, nscoord aY1, nscoord aX2, nscoord aY2, nsRect *aGap)
static void FillPolygon (nsIRenderingContext &aContext, const nsPoint aPoints[], PRInt32 aNumPoints, nsRect *aGap)

Detailed Description

Definition at line 45 of file nsCSSRendering.h.


Member Function Documentation

Called by the presShell when painting is finished, so we can clear our inline background data cache.

Definition at line 2719 of file nsCSSRendering.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::DrawCompositeSide ( nsIRenderingContext aContext,
PRIntn  aWhichSide,
nsBorderColors aCompositeColors,
const nsRect aOuterRect,
const nsRect aInnerRect,
PRInt16 aBorderRadii,
nscoord  aTwipsPerPixel,
nsRect aGap 
) [static, protected]

Definition at line 1856 of file nsCSSRendering.cpp.

{
  // Loop over each color and at each iteration shrink the length of the
  // lines that we draw.
  nsRect currOuterRect(aOuterRect);

  // XXXdwh This border radius code is rather hacky and will only work for
  // small radii, but it will be sufficient to get a major performance
  // improvement in themes with small curvature (like Modern).
  // Still, this code should be rewritten if/when someone chooses to pick
  // up the -moz-border-radius gauntlet.
  // Alternatively we could add support for a -moz-border-diagonal property, which is
  // what this code actually draws (instead of a curve).

  // determine the the number of pixels we need to draw for this side
  // and the start and end radii
  nscoord shrinkage, startRadius, endRadius;
  if (aWhichSide == NS_SIDE_TOP) {
    shrinkage = aInnerRect.y - aOuterRect.y;
    startRadius = aBorderRadii[0];
    endRadius = aBorderRadii[1];
  } else if (aWhichSide == NS_SIDE_BOTTOM) {
    shrinkage = (aOuterRect.height+aOuterRect.y) - (aInnerRect.height+aInnerRect.y);
    startRadius = aBorderRadii[3];
    endRadius = aBorderRadii[2];
  } else if (aWhichSide == NS_SIDE_RIGHT) {
    shrinkage = (aOuterRect.width+aOuterRect.x) - (aInnerRect.width+aInnerRect.x);
    startRadius = aBorderRadii[1];
    endRadius = aBorderRadii[2];
  } else {
    NS_ASSERTION(aWhichSide == NS_SIDE_LEFT, "incorrect aWhichSide");
    shrinkage = aInnerRect.x - aOuterRect.x;
    startRadius = aBorderRadii[0];
    endRadius = aBorderRadii[3];
  }

  while (shrinkage > 0) {
    nscoord xshrink = 0;
    nscoord yshrink = 0;
    nscoord widthshrink = 0;
    nscoord heightshrink = 0;

    if (startRadius || endRadius) {
      if (aWhichSide == NS_SIDE_TOP || aWhichSide == NS_SIDE_BOTTOM) {
        xshrink = startRadius;
        widthshrink = startRadius + endRadius;
      }
      else if (aWhichSide == NS_SIDE_LEFT || aWhichSide == NS_SIDE_RIGHT) {
        yshrink = startRadius-1;
        heightshrink = yshrink + endRadius;
      }
    }

    // subtract any rounded pixels from the outer rect
    nsRect newOuterRect(currOuterRect);
    newOuterRect.x += xshrink;
    newOuterRect.y += yshrink;
    newOuterRect.width -= widthshrink;
    newOuterRect.height -= heightshrink;

    nsRect borderInside(currOuterRect);
    
    // try to subtract one pixel from each side of the outer rect, but only if 
    // that side has any extra space left to shrink
    if (aInnerRect.x > borderInside.x) { // shrink left
      borderInside.x += twipsPerPixel;
      borderInside.width -= twipsPerPixel;
    }
    if (borderInside.x+borderInside.width > aInnerRect.x+aInnerRect.width) // shrink right
      borderInside.width -= twipsPerPixel;
    
    if (aInnerRect.y > borderInside.y) { // shrink top
      borderInside.y += twipsPerPixel;
      borderInside.height -= twipsPerPixel;
    }
    if (borderInside.y+borderInside.height > aInnerRect.y+aInnerRect.height) // shrink bottom
      borderInside.height -= twipsPerPixel;

    if (!aCompositeColors->mTransparent) {
      nsPoint theSide[MAX_POLY_POINTS];
      PRInt32 np = MakeSide(theSide, aRenderingContext, aWhichSide, newOuterRect, borderInside, 0,
                            BORDER_FULL, 1.0f, twipsPerPixel);
      NS_ASSERTION(np == 2, "Composite border should always be single pixel!");
      aRenderingContext.SetColor(aCompositeColors->mColor);
      DrawLine(aRenderingContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    
      if (aWhichSide == NS_SIDE_TOP) {
        if (startRadius) {
          // Connecting line between top/left
          nscoord distance = (startRadius+twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder) 
            distance += twipsPerPixel - remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+startRadius,
                   currOuterRect.y, 
                   currOuterRect.x+startRadius-distance,
                   currOuterRect.y+distance,
                   aGap);
        }
        if (endRadius) {
          // Connecting line between top/right
          nscoord distance = (endRadius+twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder) 
            distance += twipsPerPixel - remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+currOuterRect.width-endRadius-twipsPerPixel,
                   currOuterRect.y, 
                   currOuterRect.x+currOuterRect.width-endRadius-twipsPerPixel+distance,
                   currOuterRect.y+distance,
                   aGap);
        }
      }
      else if (aWhichSide == NS_SIDE_BOTTOM) {
        if (startRadius) {
          // Connecting line between bottom/left
          nscoord distance = (startRadius+twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder) 
            distance += twipsPerPixel - remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+startRadius, 
                   currOuterRect.y+currOuterRect.height-twipsPerPixel,
                   currOuterRect.x+startRadius-distance, 
                   currOuterRect.y+currOuterRect.height-twipsPerPixel-distance,
                   aGap);
        }
        if (endRadius) {
          // Connecting line between bottom/right
          nscoord distance = (endRadius+twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder) 
            distance += twipsPerPixel - remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+currOuterRect.width-endRadius-twipsPerPixel, 
                   currOuterRect.y+currOuterRect.height-twipsPerPixel, 
                   currOuterRect.x+currOuterRect.width-endRadius-twipsPerPixel+distance, 
                   currOuterRect.y+currOuterRect.height-twipsPerPixel-distance,
                   aGap);
        }
      }
      else if (aWhichSide == NS_SIDE_LEFT) {
        if (startRadius) {
          // Connecting line between left/top
          nscoord distance = (startRadius-twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder)
            distance -= remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+distance,
                   currOuterRect.y+startRadius-distance, 
                   currOuterRect.x,
                   currOuterRect.y+startRadius,
                   aGap);
        }
        if (endRadius) {
          // Connecting line between left/bottom
          nscoord distance = (endRadius-twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder)
            distance -= remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+distance,
                   currOuterRect.y+currOuterRect.height-twipsPerPixel-endRadius+distance,
                   currOuterRect.x,
                   currOuterRect.y+currOuterRect.height-twipsPerPixel-endRadius,
                   aGap);
        }
      }
      else if (aWhichSide == NS_SIDE_RIGHT) {
       if (startRadius) {
          // Connecting line between right/top
          nscoord distance = (startRadius-twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder)
            distance -= remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+currOuterRect.width-twipsPerPixel-distance,
                   currOuterRect.y+startRadius-distance, 
                   currOuterRect.x+currOuterRect.width-twipsPerPixel,
                   currOuterRect.y+startRadius,
                   aGap);
        }
        if (endRadius) {
          // Connecting line between right/bottom
          nscoord distance = (endRadius-twipsPerPixel)/2;
          nscoord remainder = distance%twipsPerPixel;
          if (remainder)
            distance -= remainder;
          DrawLine(aRenderingContext,
                   currOuterRect.x+currOuterRect.width-twipsPerPixel-distance, 
                   currOuterRect.y+currOuterRect.height-twipsPerPixel-endRadius+distance,
                   currOuterRect.x+currOuterRect.width-twipsPerPixel, 
                   currOuterRect.y+currOuterRect.height-twipsPerPixel-endRadius,
                   aGap);
        }
      }
    }
    
    if (aCompositeColors->mNext)
      aCompositeColors = aCompositeColors->mNext;

    currOuterRect = borderInside;
    shrinkage -= twipsPerPixel;
    
    startRadius -= twipsPerPixel;
    if (startRadius < 0) startRadius = 0;
    endRadius -= twipsPerPixel;
    if (endRadius < 0) endRadius = 0;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::DrawDashedSegments ( nsIRenderingContext aContext,
const nsRect aBounds,
nsBorderEdges aBorderEdges,
PRIntn  aSkipSides,
nsRect aGap 
) [static]

draw the dashed segements of a segmented border

Definition at line 1119 of file nsCSSRendering.cpp.

{
PRIntn dashLength;
nsRect dashRect, currRect;

PRBool  bSolid = PR_TRUE;
float   over = 0.0f;
PRBool  skippedSide = PR_FALSE;
PRIntn  whichSide=0;


  // do this just to set up initial condition for loop
  // "segment" is the current portion of the edge we are computing
  nsBorderEdge * segment =  (nsBorderEdge *)(aBorderEdges->mEdges[whichSide].ElementAt(0));
  PRUint8 style = segment->mStyle;  
  for ( ; whichSide < 4; whichSide++) 
  {
    if ((1<<whichSide) & aSkipSides) {
      // Skipped side
      skippedSide = PR_TRUE;
      continue;
    }
    nscoord x=0;  nscoord y=0;
    PRInt32 i;
    PRInt32 segmentCount = aBorderEdges->mEdges[whichSide].Count();
    nsBorderEdges * neighborBorderEdges=nsnull;
    PRIntn neighborEdgeCount=0; // keeps track of which inside neighbor is shared with an outside segment
    for (i=0; i<segmentCount; i++)
    {
      bSolid=PR_TRUE;
      over = 0.0f;
      segment =  (nsBorderEdge *)(aBorderEdges->mEdges[whichSide].ElementAt(i));
      style = segment->mStyle;

      // XXX units for dash & dot?
      if (style == NS_STYLE_BORDER_STYLE_DASHED) {
        dashLength = DASH_LENGTH;
      } else {
        dashLength = DOT_LENGTH;
      }

      aContext.SetColor(segment->mColor);  
      switch (whichSide) {
      case NS_SIDE_LEFT:
      { // draw left segment i
        nsBorderEdge * topEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(0));
        if (0==y)
        { // y is the offset to the top of this segment.  0 means its the topmost left segment
          y = aBorderEdges->mMaxBorderWidth.top - topEdge->mWidth;
          if (PR_TRUE==aBorderEdges->mOutsideEdge)
            y += topEdge->mWidth;
        }
        // the x offset is the x position offset by the max width of the left edge minus this segment's width
        x = aBounds.x + (aBorderEdges->mMaxBorderWidth.left - segment->mWidth);
        nscoord height = segment->mLength;
        // the space between borderOutside and borderInside inclusive is the segment.
        nsRect borderOutside(x, y, aBounds.width, height);
        y += segment->mLength;  // keep track of the y offset for the next segment
        if ((style == NS_STYLE_BORDER_STYLE_DASHED) ||
            (style == NS_STYLE_BORDER_STYLE_DOTTED))
        {
          nsRect borderInside(borderOutside);
          nsMargin outsideMargin(segment->mWidth, 0, 0, 0);
          borderInside.Deflate(outsideMargin);
          nscoord totalLength = segment->mLength; // the computed length of this segment
          // outside edges need info from their inside neighbor.  The following code keeps track
          // of which segment of the inside neighbor's shared edge we should use for this outside segment
          if (PR_TRUE==aBorderEdges->mOutsideEdge)
          {
            if (segment->mInsideNeighbor == neighborBorderEdges)
            {
              neighborEdgeCount++;
            }
            else 
            {
              neighborBorderEdges = segment->mInsideNeighbor;
              neighborEdgeCount=0;
            }
            nsBorderEdge * neighborLeft = (nsBorderEdge *)(segment->mInsideNeighbor->mEdges[NS_SIDE_LEFT].ElementAt(neighborEdgeCount));
            totalLength = neighborLeft->mLength;
          }
          dashRect.width = borderInside.x - borderOutside.x;
          dashRect.height = nscoord(dashRect.width * dashLength);
          dashRect.x = borderOutside.x;
          dashRect.y = borderOutside.y + (totalLength/2) - dashRect.height;
          if ((PR_TRUE==aBorderEdges->mOutsideEdge) && (0!=i))
            dashRect.y -= topEdge->mWidth;  // account for the topmost left edge corner with the leftmost top edge
          if (0)
          {
            printf("  L: totalLength = %d, borderOutside.y = %d, midpoint %d, dashRect.y = %d\n", 
            totalLength, borderOutside.y, borderOutside.y +(totalLength/2), dashRect.y); 
          }
          currRect = dashRect;

          // we draw the segment in 2 halves to get the inside and outside edges to line up on the
          // centerline of the shared edge.

          // draw the top half
          while (currRect.YMost() > borderInside.y) {
            //clip if necessary
            if (currRect.y < borderInside.y) {
              over = float(borderInside.y - dashRect.y) /
                float(dashRect.height);
              currRect.height = currRect.height - (borderInside.y - currRect.y);
              currRect.y = borderInside.y;
            }

            //draw if necessary
            if (0)
            {
              printf("DASHED LEFT: xywh in loop currRect = %d %d %d %d %s\n", 
                   currRect.x, currRect.y, currRect.width, currRect.height, bSolid?"TRUE":"FALSE");
            }
            if (bSolid) {
              aContext.FillRect(currRect);
            }

            //setup for next iteration
            if (over == 0.0f) {
              bSolid = PRBool(!bSolid);
            }
            dashRect.y = dashRect.y - currRect.height;
            currRect = dashRect;
          }

          // draw the bottom half
          dashRect.y = borderOutside.y + (totalLength/2) + dashRect.height;
          if ((PR_TRUE==aBorderEdges->mOutsideEdge) && (0!=i))
            dashRect.y -= topEdge->mWidth;
          currRect = dashRect;
          bSolid=PR_TRUE;
          over = 0.0f;
          while (currRect.YMost() < borderInside.YMost()) {
            //clip if necessary
            if (currRect.y < borderInside.y) {
              over = float(borderInside.y - dashRect.y) /
                float(dashRect.height);
              currRect.height = currRect.height - (borderInside.y - currRect.y);
              currRect.y = borderInside.y;
            }

            //draw if necessary
            if (0)
            {
              printf("DASHED LEFT: xywh in loop currRect = %d %d %d %d %s\n", 
                   currRect.x, currRect.y, currRect.width, currRect.height, bSolid?"TRUE":"FALSE");
            }
            if (bSolid) {
              aContext.FillRect(currRect);
            }

            //setup for next iteration
            if (over == 0.0f) {
              bSolid = PRBool(!bSolid);
            }
            dashRect.y = dashRect.y + currRect.height;
            currRect = dashRect;
          }
        }
      }
      break;

      case NS_SIDE_TOP:
      { // draw top segment i
        if (0==x)
        {
          nsBorderEdge * leftEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
          x = aBorderEdges->mMaxBorderWidth.left - leftEdge->mWidth;
        }
        y = aBounds.y;
        if (PR_TRUE==aBorderEdges->mOutsideEdge) // segments of the outside edge are bottom-aligned
          y += aBorderEdges->mMaxBorderWidth.top - segment->mWidth;
        nsRect borderOutside(x, y, segment->mLength, aBounds.height);
        x += segment->mLength;
        if ((style == NS_STYLE_BORDER_STYLE_DASHED) ||
            (style == NS_STYLE_BORDER_STYLE_DOTTED))
        {
          nsRect borderInside(borderOutside);
          nsBorderEdge * neighbor;
          // XXX Adding check to make sure segment->mInsideNeighbor is not null
          // so it will do the else part, at this point we are assuming this is an
          // ok thing to do (Bug 52130)
          if (PR_TRUE==aBorderEdges->mOutsideEdge && segment->mInsideNeighbor)
            neighbor = (nsBorderEdge *)(segment->mInsideNeighbor->mEdges[NS_SIDE_LEFT].ElementAt(0));
          else
            neighbor = (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
          nsMargin outsideMargin(neighbor->mWidth, segment->mWidth, 0, segment->mWidth);
          borderInside.Deflate(outsideMargin);
          nscoord firstRectWidth = 0;
          if (PR_TRUE==aBorderEdges->mOutsideEdge && 0==i)
          {
            firstRectWidth = borderInside.x - borderOutside.x;
            aContext.FillRect(borderOutside.x, borderOutside.y,
                              firstRectWidth,
                              borderInside.y - borderOutside.y);
          }

          dashRect.height = borderInside.y - borderOutside.y;
          dashRect.width = dashRect.height * dashLength;
          dashRect.x = borderOutside.x + firstRectWidth;
          dashRect.y = borderOutside.y;
          currRect = dashRect;

          while (currRect.x < borderInside.XMost()) {
            //clip if necessary
            if (currRect.XMost() > borderInside.XMost()) {
              over = float(dashRect.XMost() - borderInside.XMost()) /
                float(dashRect.width);
              currRect.width = currRect.width -
                (currRect.XMost() - borderInside.XMost());
            }

            //draw if necessary
            if (bSolid) {
              aContext.FillRect(currRect);
            }

            //setup for next iteration
            if (over == 0.0f) {
              bSolid = PRBool(!bSolid);
            }
            dashRect.x = dashRect.x + currRect.width;
            currRect = dashRect;
          }
        }
      }
      break;

      case NS_SIDE_RIGHT:
      { // draw right segment i
        nsBorderEdge * topEdge =  (nsBorderEdge *)
            (aBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aBorderEdges->mEdges[NS_SIDE_TOP].Count()-1));
        if (0==y)
        {
          y = aBorderEdges->mMaxBorderWidth.top - topEdge->mWidth;
          if (PR_TRUE==aBorderEdges->mOutsideEdge)
            y += topEdge->mWidth;
        }
        nscoord width;
        if (PR_TRUE==aBorderEdges->mOutsideEdge)
        {
          width = aBounds.width - aBorderEdges->mMaxBorderWidth.right;
          width += segment->mWidth;
        }
        else
        {
          width = aBounds.width;
        }
        nscoord height = segment->mLength;
        nsRect borderOutside(aBounds.x, y, width, height);
        y += segment->mLength;
        if ((style == NS_STYLE_BORDER_STYLE_DASHED) ||
            (style == NS_STYLE_BORDER_STYLE_DOTTED))
        {
          nsRect borderInside(borderOutside);
          nsMargin outsideMargin(segment->mWidth, 0, (segment->mWidth), 0);
          borderInside.Deflate(outsideMargin);
          nscoord totalLength = segment->mLength;
          if (PR_TRUE==aBorderEdges->mOutsideEdge)
          {
            if (segment->mInsideNeighbor == neighborBorderEdges)
            {
              neighborEdgeCount++;
            }
            else 
            {
              neighborBorderEdges = segment->mInsideNeighbor;
              neighborEdgeCount=0;
            }
            nsBorderEdge * neighborRight = (nsBorderEdge *)(segment->mInsideNeighbor->mEdges[NS_SIDE_RIGHT].ElementAt(neighborEdgeCount));
            totalLength = neighborRight->mLength;
          }
          dashRect.width = borderOutside.XMost() - borderInside.XMost();
          dashRect.height = nscoord(dashRect.width * dashLength);
          dashRect.x = borderInside.XMost();
          dashRect.y = borderOutside.y + (totalLength/2) - dashRect.height;
          if ((PR_TRUE==aBorderEdges->mOutsideEdge) && (0!=i))
            dashRect.y -= topEdge->mWidth;
          currRect = dashRect;

          // draw the top half
          while (currRect.YMost() > borderInside.y) {
            //clip if necessary
            if (currRect.y < borderInside.y) {
              over = float(borderInside.y - dashRect.y) /
                float(dashRect.height);
              currRect.height = currRect.height - (borderInside.y - currRect.y);
              currRect.y = borderInside.y;
            }

            //draw if necessary
            if (bSolid) {
              aContext.FillRect(currRect);
            }

            //setup for next iteration
            if (over == 0.0f) {
              bSolid = PRBool(!bSolid);
            }
            dashRect.y = dashRect.y - currRect.height;
            currRect = dashRect;
          }

          // draw the bottom half
          dashRect.y = borderOutside.y + (totalLength/2) + dashRect.height;
          if ((PR_TRUE==aBorderEdges->mOutsideEdge) && (0!=i))
            dashRect.y -= topEdge->mWidth;
          currRect = dashRect;
          bSolid=PR_TRUE;
          over = 0.0f;
          while (currRect.YMost() < borderInside.YMost()) {
            //clip if necessary
            if (currRect.y < borderInside.y) {
              over = float(borderInside.y - dashRect.y) /
                float(dashRect.height);
              currRect.height = currRect.height - (borderInside.y - currRect.y);
              currRect.y = borderInside.y;
            }

            //draw if necessary
            if (bSolid) {
              aContext.FillRect(currRect);
            }

            //setup for next iteration
            if (over == 0.0f) {
              bSolid = PRBool(!bSolid);
            }
            dashRect.y = dashRect.y + currRect.height;
            currRect = dashRect;
          }

        }
      }
      break;

      case NS_SIDE_BOTTOM:
      {  // draw bottom segment i
        if (0==x)
        {
          nsBorderEdge * leftEdge =  (nsBorderEdge *)
            (aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(aBorderEdges->mEdges[NS_SIDE_LEFT].Count()-1));
          x = aBorderEdges->mMaxBorderWidth.left - leftEdge->mWidth;
        }
        y = aBounds.y;
        if (PR_TRUE==aBorderEdges->mOutsideEdge) // segments of the outside edge are top-aligned
          y -= aBorderEdges->mMaxBorderWidth.bottom - segment->mWidth;
        nsRect borderOutside(x, y, segment->mLength, aBounds.height);
        x += segment->mLength;
        if ((style == NS_STYLE_BORDER_STYLE_DASHED) ||
            (style == NS_STYLE_BORDER_STYLE_DOTTED))
        {
          nsRect borderInside(borderOutside);
          nsBorderEdge * neighbor;
          if (PR_TRUE==aBorderEdges->mOutsideEdge)
            neighbor = (nsBorderEdge *)(segment->mInsideNeighbor->mEdges[NS_SIDE_LEFT].ElementAt(0));
          else
            neighbor = (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
          nsMargin outsideMargin(neighbor->mWidth, segment->mWidth, 0, segment->mWidth);
          borderInside.Deflate(outsideMargin);
          nscoord firstRectWidth = 0;
          if (PR_TRUE==aBorderEdges->mOutsideEdge  &&  0==i)
          {
            firstRectWidth = borderInside.x - borderOutside.x;
            aContext.FillRect(borderOutside.x, borderInside.YMost(),
                              firstRectWidth,
                              borderOutside.YMost() - borderInside.YMost());
          }

          dashRect.height = borderOutside.YMost() - borderInside.YMost();
          dashRect.width = nscoord(dashRect.height * dashLength);
          dashRect.x = borderOutside.x + firstRectWidth;
          dashRect.y = borderInside.YMost();
          currRect = dashRect;

          while (currRect.x < borderInside.XMost()) {
            //clip if necessary
            if (currRect.XMost() > borderInside.XMost()) {
              over = float(dashRect.XMost() - borderInside.XMost()) / 
                float(dashRect.width);
              currRect.width = currRect.width -
                (currRect.XMost() - borderInside.XMost());
            }

            //draw if necessary
            if (bSolid) {
              aContext.FillRect(currRect);
            }

            //setup for next iteration
            if (over == 0.0f) {
              bSolid = PRBool(!bSolid);
            }
            dashRect.x = dashRect.x + currRect.width;
            currRect = dashRect;
          }
        }
      }
      break;
      }
    }
    skippedSide = PR_FALSE;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::DrawDashedSides ( PRIntn  startSide,
nsIRenderingContext aContext,
const nsRect aDirtyRect,
const PRUint8  borderStyles[],
const nscolor  borderColors[],
const nsRect borderOutside,
const nsRect borderInside,
PRIntn  aSkipSides,
nsRect aGap 
) [static]

Draw a dotted/dashed sides of a box.

Definition at line 661 of file nsCSSRendering.cpp.

{
PRIntn  dashLength;
nsRect  dashRect, firstRect, currRect;
PRBool  bSolid = PR_TRUE;
float   over = 0.0f;
PRUint8 style = borderStyles[startSide];  
PRBool  skippedSide = PR_FALSE;

  for (PRIntn whichSide = startSide; whichSide < 4; whichSide++) {
    PRUint8 prevStyle = style;
    style = borderStyles[whichSide];  
    if ((1<<whichSide) & aSkipSides) {
      // Skipped side
      skippedSide = PR_TRUE;
      continue;
    }
    if ((style == NS_STYLE_BORDER_STYLE_DASHED) ||
        (style == NS_STYLE_BORDER_STYLE_DOTTED))
    {
      if ((style != prevStyle) || skippedSide) {
        //style discontinuity
        over = 0.0f;
        bSolid = PR_TRUE;
      }

      // XXX units for dash & dot?
      if (style == NS_STYLE_BORDER_STYLE_DASHED) {
        dashLength = DASH_LENGTH;
      } else {
        dashLength = DOT_LENGTH;
      }

      aContext.SetColor(borderColors[whichSide]);  
      switch (whichSide) {
      case NS_SIDE_LEFT:
        //XXX need to properly handle wrap around from last edge to first edge
        //(this is the first edge) MMP
        dashRect.width = borderInside.x - borderOutside.x;
        dashRect.height = nscoord(dashRect.width * dashLength);
        dashRect.x = borderOutside.x;
        dashRect.y = borderInside.YMost() - dashRect.height;

        if (over > 0.0f) {
          firstRect.x = dashRect.x;
          firstRect.width = dashRect.width;
          firstRect.height = nscoord(dashRect.height * over);
          firstRect.y = dashRect.y + (dashRect.height - firstRect.height);
          over = 0.0f;
          currRect = firstRect;
        } else {
          currRect = dashRect;
        }

        while (currRect.YMost() > borderInside.y) {
          //clip if necessary
          if (currRect.y < borderInside.y) {
            over = float(borderInside.y - dashRect.y) /
              float(dashRect.height);
            currRect.height = currRect.height - (borderInside.y - currRect.y);
            currRect.y = borderInside.y;
          }

          //draw if necessary
          if (bSolid) {
            aContext.FillRect(currRect);
          }

          //setup for next iteration
          if (over == 0.0f) {
            bSolid = PRBool(!bSolid);
          }
          dashRect.y = dashRect.y - currRect.height;
          currRect = dashRect;
        }
        break;

      case NS_SIDE_TOP:
        //if we are continuing a solid rect, fill in the corner first
        if (bSolid) {
          aContext.FillRect(borderOutside.x, borderOutside.y,
                            borderInside.x - borderOutside.x,
                            borderInside.y - borderOutside.y);
        }

        dashRect.height = borderInside.y - borderOutside.y;
        dashRect.width = dashRect.height * dashLength;
        dashRect.x = borderInside.x;
        dashRect.y = borderOutside.y;

        if (over > 0.0f) {
          firstRect.x = dashRect.x;
          firstRect.y = dashRect.y;
          firstRect.width = nscoord(dashRect.width * over);
          firstRect.height = dashRect.height;
          over = 0.0f;
          currRect = firstRect;
        } else {
          currRect = dashRect;
        }

        while (currRect.x < borderInside.XMost()) {
          //clip if necessary
          if (currRect.XMost() > borderInside.XMost()) {
            over = float(dashRect.XMost() - borderInside.XMost()) /
              float(dashRect.width);
            currRect.width = currRect.width -
              (currRect.XMost() - borderInside.XMost());
          }

          //draw if necessary
          if (bSolid) {
            aContext.FillRect(currRect);
          }

          //setup for next iteration
          if (over == 0.0f) {
            bSolid = PRBool(!bSolid);
          }
          dashRect.x = dashRect.x + currRect.width;
          currRect = dashRect;
        }
        break;

      case NS_SIDE_RIGHT:
        //if we are continuing a solid rect, fill in the corner first
        if (bSolid) {
          aContext.FillRect(borderInside.XMost(), borderOutside.y,
                            borderOutside.XMost() - borderInside.XMost(),
                            borderInside.y - borderOutside.y);
        }

        dashRect.width = borderOutside.XMost() - borderInside.XMost();
        dashRect.height = nscoord(dashRect.width * dashLength);
        dashRect.x = borderInside.XMost();
        dashRect.y = borderInside.y;

        if (over > 0.0f) {
          firstRect.x = dashRect.x;
          firstRect.y = dashRect.y;
          firstRect.width = dashRect.width;
          firstRect.height = nscoord(dashRect.height * over);
          over = 0.0f;
          currRect = firstRect;
        } else {
          currRect = dashRect;
        }

        while (currRect.y < borderInside.YMost()) {
          //clip if necessary
          if (currRect.YMost() > borderInside.YMost()) {
            over = float(dashRect.YMost() - borderInside.YMost()) /
              float(dashRect.height);
            currRect.height = currRect.height -
              (currRect.YMost() - borderInside.YMost());
          }

          //draw if necessary
          if (bSolid) {
            aContext.FillRect(currRect);
          }

          //setup for next iteration
          if (over == 0.0f) {
            bSolid = PRBool(!bSolid);
          }
          dashRect.y = dashRect.y + currRect.height;
          currRect = dashRect;
        }
        break;

      case NS_SIDE_BOTTOM:
        //if we are continuing a solid rect, fill in the corner first
        if (bSolid) {
          aContext.FillRect(borderInside.XMost(), borderInside.YMost(),
                            borderOutside.XMost() - borderInside.XMost(),
                            borderOutside.YMost() - borderInside.YMost());
        }

        dashRect.height = borderOutside.YMost() - borderInside.YMost();
        dashRect.width = nscoord(dashRect.height * dashLength);
        dashRect.x = borderInside.XMost() - dashRect.width;
        dashRect.y = borderInside.YMost();

        if (over > 0.0f) {
          firstRect.y = dashRect.y;
          firstRect.width = nscoord(dashRect.width * over);
          firstRect.height = dashRect.height;
          firstRect.x = dashRect.x + (dashRect.width - firstRect.width);
          over = 0.0f;
          currRect = firstRect;
        } else {
          currRect = dashRect;
        }

        while (currRect.XMost() > borderInside.x) {
          //clip if necessary
          if (currRect.x < borderInside.x) {
            over = float(borderInside.x - dashRect.x) / float(dashRect.width);
            currRect.width = currRect.width - (borderInside.x - currRect.x);
            currRect.x = borderInside.x;
          }

          //draw if necessary
          if (bSolid) {
            aContext.FillRect(currRect);
          }

          //setup for next iteration
          if (over == 0.0f) {
            bSolid = PRBool(!bSolid);
          }
          dashRect.x = dashRect.x - currRect.width;
          currRect = dashRect;
        }
        break;
      }
    }
    skippedSide = PR_FALSE;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::DrawDashedSides ( PRIntn  startSide,
nsIRenderingContext aContext,
const nsRect aDirtyRect,
const nsStyleColor aColorStyle,
const nsStyleBorder aBorderStyle,
const nsStyleOutline aOutlineStyle,
PRBool  aDoOutline,
const nsRect borderOutside,
const nsRect borderInside,
PRIntn  aSkipSides,
nsRect aGap 
) [static]


See documentation in nsCSSRendering.h 10/22/99 dwc

Definition at line 895 of file nsCSSRendering.cpp.

{

PRIntn  dashLength;
nsRect  dashRect, currRect;
nscoord temp, temp1, adjust;
PRBool  bSolid = PR_TRUE;
float   over = 0.0f;
PRBool  skippedSide = PR_FALSE;
const nscolor kBlackColor = NS_RGB(0,0,0);

  NS_ASSERTION((aDoOutline && aOutlineStyle) || (!aDoOutline && aBorderStyle), "null params not allowed");
  PRUint8 style = aDoOutline
                  ? aOutlineStyle->GetOutlineStyle()
                  : aBorderStyle->GetBorderStyle(startSide);  

  // find the x and y width
  nscoord xwidth = aDirtyRect.XMost();
  nscoord ywidth = aDirtyRect.YMost();

  for (PRIntn whichSide = startSide; whichSide < 4; whichSide++) {
    PRUint8 prevStyle = style;
    style = aDoOutline
              ? aOutlineStyle->GetOutlineStyle()
              : aBorderStyle->GetBorderStyle(whichSide);  
    if ((1<<whichSide) & aSkipSides) {
      // Skipped side
      skippedSide = PR_TRUE;
      continue;
    }
    if ((style == NS_STYLE_BORDER_STYLE_DASHED) ||
        (style == NS_STYLE_BORDER_STYLE_DOTTED))
    {
      if ((style != prevStyle) || skippedSide) {
        //style discontinuity
        over = 0.0f;
        bSolid = PR_TRUE;
      }

      if (style == NS_STYLE_BORDER_STYLE_DASHED) {
        dashLength = DASH_LENGTH;
      } else {
        dashLength = DOT_LENGTH;
      }

      nscolor sideColor(kBlackColor); // default to black in case color cannot be resolved
                                      // (because invert is not supported on cur platform)
      PRBool  isInvert=PR_FALSE;
      if (aDoOutline) {
        // see if the outline color is 'invert'
        if (aOutlineStyle->GetOutlineInvert()) { 
          isInvert = PR_TRUE;
        } else {
          aOutlineStyle->GetOutlineColor(sideColor);
        }
      } else {
        PRBool transparent; 
        PRBool foreground;
        aBorderStyle->GetBorderColor(whichSide, sideColor, transparent, foreground);
        if (foreground)
          sideColor = aColorStyle->mColor;
        if (transparent)
          continue; // side is transparent
      }
      aContext.SetColor(sideColor);  

      switch (whichSide) {
      case NS_SIDE_RIGHT:
      case NS_SIDE_LEFT:
        bSolid = PR_FALSE;
        
        // This is our dot or dash..
        if(whichSide==NS_SIDE_LEFT){ 
          dashRect.width = borderInside.x - borderOutside.x;
        } else {
          dashRect.width = borderOutside.XMost() - borderInside.XMost();
        }
        if( dashRect.width >0 ) {
          dashRect.height = dashRect.width * dashLength;
          dashRect.y = borderOutside.y;

          if(whichSide == NS_SIDE_RIGHT){
            dashRect.x = borderInside.XMost();
          } else {
            dashRect.x = borderOutside.x;
          }

          temp = borderOutside.YMost();
          temp1 = temp/dashRect.height;

          currRect = dashRect;

          if((temp1%2)==0){
            adjust = (dashRect.height-(temp%dashRect.height))/2; // adjust back
            // draw in the left and right
            FillOrInvertRect(aContext,  dashRect.x, borderOutside.y,dashRect.width, dashRect.height-adjust,isInvert);
            FillOrInvertRect(aContext,dashRect.x,(borderOutside.YMost()-(dashRect.height-adjust)),dashRect.width, dashRect.height-adjust,isInvert);
            currRect.y += (dashRect.height-adjust);
            temp = temp-= (dashRect.height-adjust);
          } else {
            adjust = (temp%dashRect.width)/2;                   // adjust a tad longer
            // draw in the left and right
            FillOrInvertRect(aContext, dashRect.x, borderOutside.y,dashRect.width, dashRect.height+adjust,isInvert);
            FillOrInvertRect(aContext, dashRect.x,(borderOutside.YMost()-(dashRect.height+adjust)),dashRect.width, dashRect.height+adjust,isInvert);
            currRect.y += (dashRect.height+adjust);
            temp = temp-= (dashRect.height+adjust);
          }
        
          if( temp > ywidth)
            temp = ywidth;

          // get the currRect's x into the view before we start
          if( currRect.y < aDirtyRect.y){
            temp1 = NSToCoordFloor((float)((aDirtyRect.y-currRect.y)/dashRect.height));
            currRect.y += temp1*dashRect.height;
            if((temp1%2)==1){
              bSolid = PR_TRUE;
            }
         }

          while(currRect.y<temp) {
            //draw if necessary
            if (bSolid) {
              FillOrInvertRect(aContext, currRect,isInvert);
            }

            bSolid = PRBool(!bSolid);
            currRect.y += dashRect.height;
          }
        }
        break;

      case NS_SIDE_BOTTOM:
      case NS_SIDE_TOP:
        bSolid = PR_FALSE;
        
        // This is our dot or dash..

        if(whichSide==NS_SIDE_TOP){ 
          dashRect.height = borderInside.y - borderOutside.y;
        } else {
          dashRect.height = borderOutside.YMost() - borderInside.YMost();
        }
        if( dashRect.height >0 ) {
          dashRect.width = dashRect.height * dashLength;
          dashRect.x = borderOutside.x;

          if(whichSide == NS_SIDE_BOTTOM){
            dashRect.y = borderInside.YMost();
          } else {
            dashRect.y = borderOutside.y;
          }

          temp = borderOutside.XMost();
          temp1 = temp/dashRect.width;

          currRect = dashRect;

          if((temp1%2)==0){
            adjust = (dashRect.width-(temp%dashRect.width))/2;     // even, adjust back
            // draw in the left and right
            FillOrInvertRect(aContext, borderOutside.x,dashRect.y,dashRect.width-adjust,dashRect.height,isInvert);
            FillOrInvertRect(aContext, (borderOutside.XMost()-(dashRect.width-adjust)),dashRect.y,dashRect.width-adjust,dashRect.height,isInvert);
            currRect.x += (dashRect.width-adjust);
            temp = temp-= (dashRect.width-adjust);
          } else {
            adjust = (temp%dashRect.width)/2;
            // draw in the left and right
            FillOrInvertRect(aContext, borderOutside.x,dashRect.y,dashRect.width+adjust,dashRect.height,isInvert);
            FillOrInvertRect(aContext, (borderOutside.XMost()-(dashRect.width+adjust)),dashRect.y,dashRect.width+adjust,dashRect.height,isInvert);
            currRect.x += (dashRect.width+adjust);
            temp = temp-= (dashRect.width+adjust);
          }
       

          if( temp > xwidth)
            temp = xwidth;

          // get the currRect's x into the view before we start
          if( currRect.x < aDirtyRect.x){
            temp1 = NSToCoordFloor((float)((aDirtyRect.x-currRect.x)/dashRect.width));
            currRect.x += temp1*dashRect.width;
            if((temp1%2)==1){
              bSolid = PR_TRUE;
            }
          }

          while(currRect.x<temp) {
            //draw if necessary
            if (bSolid) {
              FillOrInvertRect(aContext, currRect,isInvert);
            }

            bSolid = PRBool(!bSolid);
            currRect.x += dashRect.width;
          }
        }
      break;
      }
    }
    skippedSide = PR_FALSE;
  }
}

Here is the call graph for this function:

void nsCSSRendering::DrawLine ( nsIRenderingContext aContext,
nscoord  aX1,
nscoord  aY1,
nscoord  aX2,
nscoord  aY2,
nsRect aGap 
) [static, protected]

Definition at line 204 of file nsCSSRendering.cpp.

{
  if (nsnull == aGap) {
    aContext.DrawLine(aX1, aY1, aX2, aY2);
  } else {
    nscoord x1 = (aX1 < aX2) ? aX1 : aX2;
    nscoord x2 = (aX1 < aX2) ? aX2 : aX1;
    nsPoint gapUpperRight(aGap->x + aGap->width, aGap->y);
    nsPoint gapLowerRight(aGap->x + aGap->width, aGap->y + aGap->height);
    if ((aGap->y <= aY1) && (gapLowerRight.y >= aY2)) {
      if ((aGap->x > x1) && (aGap->x < x2)) {
        aContext.DrawLine(x1, aY1, aGap->x, aY1);
      } 
      if ((gapLowerRight.x > x1) && (gapLowerRight.x < x2)) {
        aContext.DrawLine(gapUpperRight.x, aY2, x2, aY2);
      } 
    } else {
      aContext.DrawLine(aX1, aY1, aX2, aY2);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::DrawSide ( nsIRenderingContext aContext,
PRIntn  whichSide,
const PRUint8  borderStyle,
const nscolor  borderColor,
const nscolor  aBackgroundColor,
const nsRect borderOutside,
const nsRect borderInside,
PRIntn  aSkipSides,
nscoord  twipsPerPixel,
nsRect aGap = 0 
) [static, protected]

Definition at line 522 of file nsCSSRendering.cpp.

{
  nsPoint theSide[MAX_POLY_POINTS];
  nscolor theColor = borderColor; 
  PRUint8 theStyle = borderStyle; 
  PRInt32 np;
  switch (theStyle) {
  case NS_STYLE_BORDER_STYLE_NONE:
  case NS_STYLE_BORDER_STYLE_HIDDEN:
    return;

  case NS_STYLE_BORDER_STYLE_DOTTED:    //handled a special case elsewhere
  case NS_STYLE_BORDER_STYLE_DASHED:    //handled a special case elsewhere
    break; // That was easy...

  case NS_STYLE_BORDER_STYLE_GROOVE:
  case NS_STYLE_BORDER_STYLE_RIDGE:
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside, aSkipSides,
                   BORDER_INSIDE, 0.5f, twipsPerPixel);
    aContext.SetColor ( MakeBevelColor (whichSide, 
                                        ((theStyle == NS_STYLE_BORDER_STYLE_RIDGE) ?
                                         NS_STYLE_BORDER_STYLE_GROOVE :
                                         NS_STYLE_BORDER_STYLE_RIDGE), 
                                         aBackgroundColor, theColor, 
                                         PR_TRUE));
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
    }
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside,aSkipSides,
                   BORDER_OUTSIDE, 0.5f, twipsPerPixel);
    aContext.SetColor ( MakeBevelColor (whichSide, theStyle, aBackgroundColor, 
                                        theColor, PR_TRUE));
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
    }
    break;

  case NS_STYLE_BORDER_STYLE_AUTO:
  case NS_STYLE_BORDER_STYLE_SOLID:
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside,aSkipSides,
                   BORDER_FULL, 1.0f, twipsPerPixel);
    aContext.SetColor (borderColor);  
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
    }
    break;

  case NS_STYLE_BORDER_STYLE_BG_SOLID:
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside, aSkipSides,
                   BORDER_FULL, 1.0f, twipsPerPixel);
    nscolor colors[2]; 
    NS_Get3DColors(colors, aBackgroundColor); 
    aContext.SetColor (colors[0]);
    if (2 == np) {
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      FillPolygon (aContext, theSide, np, aGap);
    }
    break;

  case NS_STYLE_BORDER_STYLE_DOUBLE:
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside,aSkipSides,
                   BORDER_INSIDE, 0.333333f, twipsPerPixel);
    aContext.SetColor (borderColor);
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
   }
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside,aSkipSides,
                   BORDER_OUTSIDE, 0.333333f, twipsPerPixel);
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
    }
    break;

  case NS_STYLE_BORDER_STYLE_BG_OUTSET:
  case NS_STYLE_BORDER_STYLE_BG_INSET:
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside,aSkipSides,
                   BORDER_FULL, 1.0f, twipsPerPixel);
    aContext.SetColor ( MakeBevelColor (whichSide, theStyle, aBackgroundColor,
                                        theColor, PR_FALSE));
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
    }
    break;
  case NS_STYLE_BORDER_STYLE_OUTSET:
  case NS_STYLE_BORDER_STYLE_INSET:
    np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside,aSkipSides,
                   BORDER_FULL, 1.0f, twipsPerPixel);
    aContext.SetColor ( MakeBevelColor (whichSide, theStyle, aBackgroundColor, 
                                        theColor, PR_TRUE));
    if (2 == np) {
      //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y);
      DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap);
    } else {
      //aContext.FillPolygon (theSide, np);
      FillPolygon (aContext, theSide, np, aGap);
    }
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::DrawTableBorderSegment ( nsIRenderingContext aContext,
PRUint8  aBorderStyle,
nscolor  aBorderColor,
const nsStyleBackground aBGColor,
const nsRect aBorderRect,
float  aPixelsToTwips,
PRUint8  aStartBevelSide = 0,
nscoord  aStartBevelOffset = 0,
PRUint8  aEndBevelSide = 0,
nscoord  aEndBevelOffset = 0 
) [static]

Definition at line 4210 of file nsCSSRendering.cpp.

{
  aContext.SetColor (aBorderColor); 

  PRBool horizontal = ((NS_SIDE_TOP == aStartBevelSide) || (NS_SIDE_BOTTOM == aStartBevelSide));
  nscoord twipsPerPixel = NSIntPixelsToTwips(1, aPixelsToTwips);
  PRBool ridgeGroove = NS_STYLE_BORDER_STYLE_RIDGE;

  if ((twipsPerPixel >= aBorder.width) || (twipsPerPixel >= aBorder.height) ||
      (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) || (NS_STYLE_BORDER_STYLE_DOTTED == aBorderStyle)) {
    // no beveling for 1 pixel border, dash or dot
    aStartBevelOffset = 0;
    aEndBevelOffset = 0;
  }

  switch (aBorderStyle) {
  case NS_STYLE_BORDER_STYLE_NONE:
  case NS_STYLE_BORDER_STYLE_HIDDEN:
    //NS_ASSERTION(PR_FALSE, "style of none or hidden");
    break;
  case NS_STYLE_BORDER_STYLE_DOTTED:
  case NS_STYLE_BORDER_STYLE_DASHED: 
    {
      nscoord dashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) ? DASH_LENGTH : DOT_LENGTH;
      // make the dash length proportional to the border thickness
      dashLength *= (horizontal) ? aBorder.height : aBorder.width;
      // make the min dash length for the ends 1/2 the dash length
      nscoord minDashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) 
                              ? RoundFloatToPixel(((float)dashLength) / 2.0f, twipsPerPixel) : dashLength;
      minDashLength = PR_MAX(minDashLength, twipsPerPixel);
      nscoord numDashSpaces = 0;
      nscoord startDashLength = minDashLength;
      nscoord endDashLength   = minDashLength;
      if (horizontal) {
        GetDashInfo(aBorder.width, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
        nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height);
        DrawSolidBorderSegment(aContext, rect, PR_TRUE);
        for (PRInt32 spaceX = 0; spaceX < numDashSpaces; spaceX++) {
          rect.x += rect.width + dashLength;
          rect.width = (spaceX == (numDashSpaces - 1)) ? endDashLength : dashLength;
          DrawSolidBorderSegment(aContext, rect, PR_TRUE);
        }
      }
      else {
        GetDashInfo(aBorder.height, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
        nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength);
        DrawSolidBorderSegment(aContext, rect, PR_FALSE);
        for (PRInt32 spaceY = 0; spaceY < numDashSpaces; spaceY++) {
          rect.y += rect.height + dashLength;
          rect.height = (spaceY == (numDashSpaces - 1)) ? endDashLength : dashLength;
          DrawSolidBorderSegment(aContext, rect, PR_FALSE);
        }
      }
    }
    break;                                  
  case NS_STYLE_BORDER_STYLE_GROOVE:
    ridgeGroove = NS_STYLE_BORDER_STYLE_GROOVE; // and fall through to ridge
  case NS_STYLE_BORDER_STYLE_RIDGE:
    if ((horizontal && (twipsPerPixel >= aBorder.height)) ||
        (!horizontal && (twipsPerPixel >= aBorder.width))) {
      // a one pixel border
      DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide, aStartBevelOffset,
                             aEndBevelSide, aEndBevelOffset);
    }
    else {
      nscoord startBevel = (aStartBevelOffset > 0) 
                            ? RoundFloatToPixel(0.5f * (float)aStartBevelOffset, twipsPerPixel, PR_TRUE) : 0;
      nscoord endBevel =   (aEndBevelOffset > 0) 
                            ? RoundFloatToPixel(0.5f * (float)aEndBevelOffset, twipsPerPixel, PR_TRUE) : 0;
      PRUint8 ridgeGrooveSide = (horizontal) ? NS_SIDE_TOP : NS_SIDE_LEFT;
      aContext.SetColor ( 
        MakeBevelColor (ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor, PR_TRUE));
      nsRect rect(aBorder);
      nscoord half;
      if (horizontal) { // top, bottom
        half = RoundFloatToPixel(0.5f * (float)aBorder.height, twipsPerPixel);
        rect.height = half;
        if (NS_SIDE_TOP == aStartBevelSide) {
          rect.x += startBevel;
          rect.width -= startBevel;
        }
        if (NS_SIDE_TOP == aEndBevelSide) {
          rect.width -= endBevel;
        }
        DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide, 
                               startBevel, aEndBevelSide, endBevel);
      }
      else { // left, right
        half = RoundFloatToPixel(0.5f * (float)aBorder.width, twipsPerPixel);
        rect.width = half;
        if (NS_SIDE_LEFT == aStartBevelSide) {
          rect.y += startBevel;
          rect.height -= startBevel;
        }
        if (NS_SIDE_LEFT == aEndBevelSide) {
          rect.height -= endBevel;
        }
        DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide, 
                               startBevel, aEndBevelSide, endBevel);
      }

      rect = aBorder;
      ridgeGrooveSide = (NS_SIDE_TOP == ridgeGrooveSide) ? NS_SIDE_BOTTOM : NS_SIDE_RIGHT;
      aContext.SetColor ( 
        MakeBevelColor (ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor, PR_TRUE));
      if (horizontal) {
        rect.y = rect.y + half;
        rect.height = aBorder.height - half;
        if (NS_SIDE_BOTTOM == aStartBevelSide) {
          rect.x += startBevel;
          rect.width -= startBevel;
        }
        if (NS_SIDE_BOTTOM == aEndBevelSide) {
          rect.width -= endBevel;
        }
        DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide, 
                               startBevel, aEndBevelSide, endBevel);
      }
      else {
        rect.x = rect.x + half;
        rect.width = aBorder.width - half;
        if (NS_SIDE_RIGHT == aStartBevelSide) {
          rect.y += aStartBevelOffset - startBevel;
          rect.height -= startBevel;
        }
        if (NS_SIDE_RIGHT == aEndBevelSide) {
          rect.height -= endBevel;
        }
        DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide, 
                               startBevel, aEndBevelSide, endBevel);
      }
    }
    break;
  case NS_STYLE_BORDER_STYLE_DOUBLE:
    if ((aBorder.width > 2) && (aBorder.height > 2)) {
      nscoord startBevel = (aStartBevelOffset > 0) 
                            ? RoundFloatToPixel(0.333333f * (float)aStartBevelOffset, twipsPerPixel) : 0;
      nscoord endBevel =   (aEndBevelOffset > 0) 
                            ? RoundFloatToPixel(0.333333f * (float)aEndBevelOffset, twipsPerPixel) : 0;
      if (horizontal) { // top, bottom
        nscoord thirdHeight = RoundFloatToPixel(0.333333f * (float)aBorder.height, twipsPerPixel);

        // draw the top line or rect
        nsRect topRect(aBorder.x, aBorder.y, aBorder.width, thirdHeight);
        if (NS_SIDE_TOP == aStartBevelSide) {
          topRect.x += aStartBevelOffset - startBevel;
          topRect.width -= aStartBevelOffset - startBevel;
        }
        if (NS_SIDE_TOP == aEndBevelSide) {
          topRect.width -= aEndBevelOffset - endBevel;
        }
        DrawSolidBorderSegment(aContext, topRect, twipsPerPixel, aStartBevelSide, 
                               startBevel, aEndBevelSide, endBevel);

        // draw the botom line or rect
        nscoord heightOffset = aBorder.height - thirdHeight; 
        nsRect bottomRect(aBorder.x, aBorder.y + heightOffset, aBorder.width, aBorder.height - heightOffset);
        if (NS_SIDE_BOTTOM == aStartBevelSide) {
          bottomRect.x += aStartBevelOffset - startBevel;
          bottomRect.width -= aStartBevelOffset - startBevel;
        }
        if (NS_SIDE_BOTTOM == aEndBevelSide) {
          bottomRect.width -= aEndBevelOffset - endBevel;
        }
        DrawSolidBorderSegment(aContext, bottomRect, twipsPerPixel, aStartBevelSide, 
                               startBevel, aEndBevelSide, endBevel);
      }
      else { // left, right
        nscoord thirdWidth = RoundFloatToPixel(0.333333f * (float)aBorder.width, twipsPerPixel);

        nsRect leftRect(aBorder.x, aBorder.y, thirdWidth, aBorder.height); 
        if (NS_SIDE_LEFT == aStartBevelSide) {
          leftRect.y += aStartBevelOffset - startBevel;
          leftRect.height -= aStartBevelOffset - startBevel;
        }
        if (NS_SIDE_LEFT == aEndBevelSide) {
          leftRect.height -= aEndBevelOffset - endBevel;
        }
        DrawSolidBorderSegment(aContext, leftRect, twipsPerPixel, aStartBevelSide,
                               startBevel, aEndBevelSide, endBevel);

        nscoord widthOffset = aBorder.width - thirdWidth; 
        nsRect rightRect(aBorder.x + widthOffset, aBorder.y, aBorder.width - widthOffset, aBorder.height);
        if (NS_SIDE_RIGHT == aStartBevelSide) {
          rightRect.y += aStartBevelOffset - startBevel;
          rightRect.height -= aStartBevelOffset - startBevel;
        }
        if (NS_SIDE_RIGHT == aEndBevelSide) {
          rightRect.height -= aEndBevelOffset - endBevel;
        }
        DrawSolidBorderSegment(aContext, rightRect, twipsPerPixel, aStartBevelSide,
                               startBevel, aEndBevelSide, endBevel);
      }
      break;
    }
    // else fall through to solid
  case NS_STYLE_BORDER_STYLE_BG_SOLID:
  case NS_STYLE_BORDER_STYLE_SOLID:
    DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide, 
                           aStartBevelOffset, aEndBevelSide, aEndBevelOffset);
    break;
  case NS_STYLE_BORDER_STYLE_BG_OUTSET:
  case NS_STYLE_BORDER_STYLE_BG_INSET:
  case NS_STYLE_BORDER_STYLE_OUTSET:
  case NS_STYLE_BORDER_STYLE_INSET:
    NS_ASSERTION(PR_FALSE, "inset, outset should have been converted to groove, ridge");
    break;
  case NS_STYLE_BORDER_STYLE_AUTO:
    NS_ASSERTION(PR_FALSE, "Unexpected 'auto' table border");
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::FillPolygon ( nsIRenderingContext aContext,
const nsPoint  aPoints[],
PRInt32  aNumPoints,
nsRect aGap 
) [static, protected]

Definition at line 230 of file nsCSSRendering.cpp.

{
#ifdef DEBUG
  nsPenMode penMode;
  if (NS_SUCCEEDED(aContext.GetPenMode(penMode)) &&
      penMode == nsPenMode_kInvert) {
    NS_WARNING( "Invert mode ignored in FillPolygon" );
  }
#endif

  if (nsnull == aGap) {
    aContext.FillPolygon(aPoints, aNumPoints);
  } else if (4 == aNumPoints) {
    nsPoint gapUpperRight(aGap->x + aGap->width, aGap->y);
    nsPoint gapLowerRight(aGap->x + aGap->width, aGap->y + aGap->height);

    // sort the 4 points by x
    nsPoint points[4];
    for (PRInt32 pX = 0; pX < 4; pX++) {
      points[pX] = aPoints[pX];
    }
    for (PRInt32 i = 0; i < 3; i++) {
      for (PRInt32 j = i+1; j < 4; j++) { 
        if (points[j].x < points[i].x) {
          nsPoint swap = points[i];
          points[i] = points[j];
          points[j] = swap;
        }
      }
    }

    nsPoint upperLeft  = (points[0].y <= points[1].y) ? points[0] : points[1];
    nsPoint lowerLeft  = (points[0].y <= points[1].y) ? points[1] : points[0];
    nsPoint upperRight = (points[2].y <= points[3].y) ? points[2] : points[3];
    nsPoint lowerRight = (points[2].y <= points[3].y) ? points[3] : points[2];


    if ((aGap->y <= upperLeft.y) && (gapLowerRight.y >= lowerRight.y)) {
      if ((aGap->x > upperLeft.x) && (aGap->x < upperRight.x)) {
        nsPoint leftRect[4];
        leftRect[0] = upperLeft;
        leftRect[1] = nsPoint(aGap->x, upperLeft.y);
        leftRect[2] = nsPoint(aGap->x, lowerLeft.y);
        leftRect[3] = lowerLeft;
        aContext.FillPolygon(leftRect, 4);
      } 
      if ((gapUpperRight.x > upperLeft.x) && (gapUpperRight.x < upperRight.x)) {
        nsPoint rightRect[4];
        rightRect[0] = nsPoint(gapUpperRight.x, upperRight.y);
        rightRect[1] = upperRight;
        rightRect[2] = lowerRight;
        rightRect[3] = nsPoint(gapLowerRight.x, lowerRight.y);
        aContext.FillPolygon(rightRect, 4);
      } 
    } else {
      aContext.FillPolygon(aPoints, aNumPoints);
    }      
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsCSSRendering::FindBackground ( nsPresContext aPresContext,
nsIFrame aForFrame,
const nsStyleBackground **  aBackground,
PRBool aIsCanvas 
) [static]

Fill in an nsStyleBackground to be used to paint the background for an element.

The nsStyleBackground should first be initialized using the pres context. This applies the rules for propagating backgrounds between BODY, the root element, and the canvas.

Definition at line 2706 of file nsCSSRendering.cpp.

{
  nsIFrame* canvasFrame = IsCanvasFrame(aPresContext, aForFrame);
  *aIsCanvas = canvasFrame != nsnull;
  return canvasFrame
      ? FindCanvasBackground(aPresContext, canvasFrame, aBackground)
      : FindElementBackground(aPresContext, aForFrame, aBackground);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Find a non-transparent background, for various table-related and HR-related backwards-compatibility hacks.

Be very hesitant if you're considering calling this function -- it's usually not what you want.

Definition at line 2510 of file nsCSSRendering.cpp.

{
  NS_ASSERTION(aContext, "Cannot find NonTransparentBackground in a null context" );
  
  const nsStyleBackground* result = nsnull;
  nsStyleContext* context = nsnull;
  if (aStartAtParent) {
    context = aContext->GetParent();
  }
  if (!context) {
    context = aContext;
  }
  
  while (context) {
    result = context->GetStyleBackground();
    if (0 == (result->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT))
      break;

    context = context->GetParent();
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nscolor nsCSSRendering::MakeBevelColor ( PRIntn  whichSide,
PRUint8  style,
nscolor  aBackgroundColor,
nscolor  aBorderColor,
PRBool  aSpecialCase 
) [static, protected]

Make a bevel color.

Definition at line 296 of file nsCSSRendering.cpp.

{

  nscolor colors[2];
  nscolor theColor;

  // Given a background color and a border color
  // calculate the color used for the shading
  if(aSpecialCase)
    NS_GetSpecial3DColors(colors, aBackgroundColor, aBorderColor);
  else
    NS_Get3DColors(colors, aBackgroundColor);
 
  if ((style == NS_STYLE_BORDER_STYLE_BG_OUTSET) ||
      (style == NS_STYLE_BORDER_STYLE_OUTSET) ||
      (style == NS_STYLE_BORDER_STYLE_RIDGE)) {
    // Flip colors for these three border styles
    switch (whichSide) {
    case NS_SIDE_BOTTOM: whichSide = NS_SIDE_TOP;    break;
    case NS_SIDE_RIGHT:  whichSide = NS_SIDE_LEFT;   break;
    case NS_SIDE_TOP:    whichSide = NS_SIDE_BOTTOM; break;
    case NS_SIDE_LEFT:   whichSide = NS_SIDE_RIGHT;  break;
    }
  }

  switch (whichSide) {
  case NS_SIDE_BOTTOM:
    theColor = colors[1];
    break;
  case NS_SIDE_RIGHT:
    theColor = colors[1];
    break;
  case NS_SIDE_TOP:
    theColor = colors[0];
    break;
  case NS_SIDE_LEFT:
  default:
    theColor = colors[0];
    break;
  }
  return theColor;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRIntn nsCSSRendering::MakeSide ( nsPoint  aPoints[],
nsIRenderingContext aContext,
PRIntn  whichSide,
const nsRect outside,
const nsRect inside,
PRIntn  aSkipSides,
PRIntn  borderPart,
float  borderFrac,
nscoord  twipsPerPixel 
) [static, protected]

Definition at line 355 of file nsCSSRendering.cpp.

{
  nscoord outsideEdge, insideEdge, outsideTL, insideTL, outsideBR, insideBR;

  // Initialize the following six nscoord's:
  // outsideEdge, insideEdge, outsideTL, insideTL, outsideBR, insideBR
  // so that outsideEdge is the x or y of the outside edge, etc., and
  // outsideTR is the y or x at the top or right end, etc., e.g.:
  //
  // outsideEdge ---  ----------------------------------------
  //                  \                                      /
  //                   \                                    /
  //                    \                                  /
  // insideEdge -------  ----------------------------------
  //                 |   |                                |   |
  //         outsideTL   insideTL                  insideBR   outsideBR       
  //
  // if we don't want the bevel, we'll get rid of it later by setting
  // outsideXX to insideXX

  switch (aWhichSide) {
  case NS_SIDE_TOP:
    // the TL points are the left end; the BR points are the right end
    outsideEdge = aOutside.y;
    insideEdge = aInside.y;
    outsideTL = aOutside.x;
    insideTL = aInside.x;
    insideBR = aInside.XMost();
    outsideBR = aOutside.XMost();
    break;

  case NS_SIDE_BOTTOM:
    // the TL points are the left end; the BR points are the right end
    outsideEdge = aOutside.YMost();
    insideEdge = aInside.YMost();
    outsideTL = aOutside.x;
    insideTL = aInside.x;
    insideBR = aInside.XMost();
    outsideBR = aOutside.XMost();
    break;

  case NS_SIDE_LEFT:
    // the TL points are the top end; the BR points are the bottom end
    outsideEdge = aOutside.x;
    insideEdge = aInside.x;
    outsideTL = aOutside.y;
    insideTL = aInside.y;
    insideBR = aInside.YMost();
    outsideBR = aOutside.YMost();
    break;

  default:
    NS_ASSERTION(aWhichSide == NS_SIDE_RIGHT, "aWhichSide is not a valid side");
    // the TL points are the top end; the BR points are the bottom end
    outsideEdge = aOutside.XMost();
    insideEdge = aInside.XMost();
    outsideTL = aOutside.y;
    insideTL = aInside.y;
    insideBR = aInside.YMost();
    outsideBR = aOutside.YMost();
    break;
  }

  // Don't draw the bevels if an adjacent side is skipped

  if ( (aWhichSide == NS_SIDE_TOP) || (aWhichSide == NS_SIDE_BOTTOM) ) {
    // a top or bottom side
    if ((1<<NS_SIDE_LEFT) & aSkipSides) {
      insideTL = outsideTL;
    }
    if ((1<<NS_SIDE_RIGHT) & aSkipSides) {
      insideBR = outsideBR;
    }
  } else {
    // a right or left side
    if ((1<<NS_SIDE_TOP) & aSkipSides) {
      insideTL = outsideTL;
    }
    if ((1<<NS_SIDE_BOTTOM) & aSkipSides) {
      insideBR = outsideBR;
    }
  }

  nscoord fullThickness;
  if (aWhichSide == NS_SIDE_TOP || aWhichSide == NS_SIDE_LEFT)
    fullThickness = insideEdge - outsideEdge;
  else
    fullThickness = outsideEdge - insideEdge;
  if (fullThickness != 0)
    fullThickness = NS_MAX(fullThickness, aTwipsPerPixel);

  nscoord thickness = fullThickness;
  if (aBorderFrac != 1.0f && fullThickness != 0) {
    thickness = aTwipsPerPixel *
      NS_MAX(NSToCoordRound(fullThickness * aBorderFrac / aTwipsPerPixel), 1);
    if ((aWhichSide == NS_SIDE_TOP) || (aWhichSide == NS_SIDE_LEFT)) {
      if (aBorderPart == BORDER_INSIDE)
        outsideEdge = insideEdge - thickness;
      else if (aBorderPart == BORDER_OUTSIDE)
        insideEdge = outsideEdge + thickness;
    } else {
      if (aBorderPart == BORDER_INSIDE)
        outsideEdge = insideEdge + thickness;
      else if (aBorderPart == BORDER_OUTSIDE)
        insideEdge = outsideEdge - thickness;
    }

    float actualFrac = (float)thickness / (float)fullThickness;
    if (aBorderPart == BORDER_INSIDE) {
      outsideTL = insideTL +
        ACTUAL_THICKNESS(outsideTL, insideTL, actualFrac, aTwipsPerPixel);
      outsideBR = insideBR +
        ACTUAL_THICKNESS(outsideBR, insideBR, actualFrac, aTwipsPerPixel);
    } else if (aBorderPart == BORDER_OUTSIDE) {
      insideTL = outsideTL -
        ACTUAL_THICKNESS(outsideTL, insideTL, actualFrac, aTwipsPerPixel);
      insideBR = outsideBR -
        ACTUAL_THICKNESS(outsideBR, insideBR, actualFrac, aTwipsPerPixel);
    }
  }

  // Base our thickness check on the segment being less than a pixel and 1/2
  aTwipsPerPixel += aTwipsPerPixel >> 2;

  // if returning a line, do it along inside edge for bottom or right borders
  // so that it's in the same place as it would be with polygons (why?)
  // XXX The previous version of the code shortened the right border too.
  if ( !((thickness >= aTwipsPerPixel) || (aBorderPart != BORDER_FULL)) &&
       ((aWhichSide == NS_SIDE_BOTTOM) || (aWhichSide == NS_SIDE_RIGHT))) {
    outsideEdge = insideEdge;
    }

  // return the appropriate line or trapezoid
  PRIntn np = 0;
  if ((aWhichSide == NS_SIDE_TOP) || (aWhichSide == NS_SIDE_BOTTOM)) {
    // top and bottom borders
    aPoints[np++].MoveTo(outsideTL,outsideEdge);
    aPoints[np++].MoveTo(outsideBR,outsideEdge);
    // XXX Making this condition only (thickness >= aTwipsPerPixel) will
    // improve double borders and some cases of groove/ridge,
    //  but will cause problems with table borders.  See last and third
    // from last tests in test4.htm
    // Doing it this way emulates the old behavior.  It might be worth
    // fixing.
    if ((thickness >= aTwipsPerPixel) || (aBorderPart != BORDER_FULL)) {
      aPoints[np++].MoveTo(insideBR,insideEdge);
      aPoints[np++].MoveTo(insideTL,insideEdge);
    }
  } else {
    // right and left borders
    // XXX Ditto above
    if ((thickness >= aTwipsPerPixel) || (aBorderPart != BORDER_FULL))  {
      aPoints[np++].MoveTo(insideEdge,insideBR);
      aPoints[np++].MoveTo(insideEdge,insideTL);
    }
    aPoints[np++].MoveTo(outsideEdge,outsideTL);
    aPoints[np++].MoveTo(outsideEdge,outsideBR);
  }
  return np;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintBackground ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aDirtyRect,
const nsRect aBorderArea,
const nsStyleBorder aBorder,
const nsStylePadding aPadding,
PRBool  aUsePrintSettings,
nsRect aBGClipRect = nsnull 
) [static]

Render the background for an element using css rendering rules for backgrounds.

Both aDirtyRect and aBorderArea are in the local coordinate space of aForFrame

Definition at line 2725 of file nsCSSRendering.cpp.

{
  NS_PRECONDITION(aForFrame,
                  "Frame is expected to be provided to PaintBackground");

  PRBool isCanvas;
  const nsStyleBackground *color;

  if (!FindBackground(aPresContext, aForFrame, &color, &isCanvas)) {
    // we don't want to bail out of moz-appearance is set on a root
    // node. If it has a parent content node, bail because it's not
    // a root, other wise keep going in order to let the theme stuff
    // draw the background. The canvas really should be drawing the
    // bg, but there's no way to hook that up via css.
    if (!aForFrame->GetStyleDisplay()->mAppearance) {
      return;
    }

    nsIContent* content = aForFrame->GetContent();
    if (!content || content->GetParent()) {
      return;
    }
        
    color = aForFrame->GetStyleBackground();
  }
  if (!isCanvas) {
    PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
                          aDirtyRect, aBorderArea, *color, aBorder,
                          aPadding, aUsePrintSettings, aBGClipRect);
    return;
  }

  if (!color)
    return;
  nsStyleBackground canvasColor(*color);

  nsIViewManager* vm = aPresContext->GetViewManager();

  if (canvasColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) {
    nsIView* rootView;
    vm->GetRootView(rootView);
    if (!rootView->GetParent()) {
      PRBool widgetIsTranslucent = PR_FALSE;

      if (rootView->HasWidget()) {
        rootView->GetWidget()->GetWindowTranslucency(widgetIsTranslucent);
      }
      
      if (!widgetIsTranslucent) {
        // Ensure that we always paint a color for the root (in case there's
        // no background at all or a partly transparent image).
        canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
        canvasColor.mBackgroundColor = aPresContext->DefaultBackgroundColor();
      }
    }
  }

  vm->SetDefaultBackgroundColor(canvasColor.mBackgroundColor);

  // Since nsHTMLContainerFrame::CreateViewForFrame might have created
  // the view before we knew about the child with the fixed background
  // attachment (root or BODY) or the stylesheet specifying that
  // attachment, set the BitBlt flag here as well.
  if (canvasColor.mBackgroundAttachment == NS_STYLE_BG_ATTACHMENT_FIXED) {
    nsIView *view = aForFrame->GetView();
    if (view)
      vm->SetViewBitBltEnabled(view, PR_FALSE);
  }

  PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
                        aDirtyRect, aBorderArea, canvasColor,
                        aBorder, aPadding, aUsePrintSettings, aBGClipRect);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintBackgroundColor ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aBgClipArea,
const nsStyleBackground aColor,
const nsStyleBorder aBorder,
const nsStylePadding aPadding,
PRBool  aCanPaintNonWhite 
) [static, protected]

Definition at line 3239 of file nsCSSRendering.cpp.

{
  if (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) {
    // nothing to paint
    return;
  }

  nsStyleCoord bordStyleRadius[4];
  PRInt16 borderRadii[4];
  nsRect bgClipArea(aBgClipArea);

  // get the radius for our border
  aBorder.mBorderRadius.GetTop(bordStyleRadius[NS_SIDE_TOP]);       // topleft
  aBorder.mBorderRadius.GetRight(bordStyleRadius[NS_SIDE_RIGHT]);   // topright
  aBorder.mBorderRadius.GetBottom(bordStyleRadius[NS_SIDE_BOTTOM]); // bottomright
  aBorder.mBorderRadius.GetLeft(bordStyleRadius[NS_SIDE_LEFT]);     // bottomleft

  PRUint8 side = 0;
  for (; side < 4; ++side) {
    borderRadii[side] = 0;
    switch (bordStyleRadius[side].GetUnit()) {
      case eStyleUnit_Percent:
        borderRadii[side] = nscoord(bordStyleRadius[side].GetPercentValue() * aBgClipArea.width);
        break;
      case eStyleUnit_Coord:
        borderRadii[side] = bordStyleRadius[side].GetCoordValue();
        break;
      default:
        break;
    }
  }

  // Rounded version of the border
  // XXXdwh Composite borders (with multiple colors per side) use their own border radius
  // algorithm now, since the current one doesn't work right for small radii.
  if (!aBorder.mBorderColors) {
    for (side = 0; side < 4; ++side) {
      if (borderRadii[side] > 0) {
        PaintRoundedBackground(aPresContext, aRenderingContext, aForFrame,
                               bgClipArea, aColor, aBorder, borderRadii,
                               aCanPaintNonWhite);
        return;
      }
    }
  }
  else if (aColor.mBackgroundClip == NS_STYLE_BG_CLIP_BORDER) {
    // XXX users of -moz-border-*-colors expect a transparent border-color
    // to show the parent's background-color instead of its background-color.
    // This seems wrong, but we handle that here by explictly clipping the
    // background to the padding area.
    bgClipArea.Deflate(aBorder.GetBorder());
  }

  nscolor color = aColor.mBackgroundColor;
  if (!aCanPaintNonWhite) {
    color = NS_RGB(255, 255, 255);
  }
  aRenderingContext.SetColor(color);
  aRenderingContext.FillRect(bgClipArea);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintBackgroundWithSC ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aDirtyRect,
const nsRect aBorderArea,
const nsStyleBackground aColor,
const nsStyleBorder aBorder,
const nsStylePadding aPadding,
PRBool  aUsePrintSettings = PR_FALSE,
nsRect aBGClipRect = nsnull 
) [static]

Same as |PaintBackground|, except using the provided style context (which short-circuits the code that ensures that the root element's background is drawn on the canvas.

Definition at line 2808 of file nsCSSRendering.cpp.

{
  NS_PRECONDITION(aForFrame,
                  "Frame is expected to be provided to PaintBackground");

  PRBool canDrawBackgroundImage = PR_TRUE;
  PRBool canDrawBackgroundColor = PR_TRUE;

  if (aUsePrintSettings) {
    canDrawBackgroundImage = aPresContext->GetBackgroundImageDraw();
    canDrawBackgroundColor = aPresContext->GetBackgroundColorDraw();
  }

  // Check to see if we have an appearance defined.  If so, we let the theme
  // renderer draw the background and bail out.
  const nsStyleDisplay* displayData = aForFrame->GetStyleDisplay();
  if (displayData->mAppearance) {
    nsITheme *theme = aPresContext->GetTheme();
    if (theme && theme->ThemeSupportsWidget(aPresContext, aForFrame, displayData->mAppearance)) {
      theme->DrawWidgetBackground(&aRenderingContext, aForFrame, 
                                  displayData->mAppearance, aBorderArea, aDirtyRect); 
      return;
    }
  }

  nsRect bgClipArea;
  if (aBGClipRect) {
    bgClipArea = *aBGClipRect;
  }
  else {
    // The background is rendered over the 'background-clip' area.
    bgClipArea = aBorderArea;
    if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
      NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING,
                   "unknown background-clip value");
      bgClipArea.Deflate(aBorder.GetBorder());
    }
  }

  // The actual dirty rect is the intersection of the 'background-clip'
  // area and the dirty rect we were given
  nsRect dirtyRect;
  if (!dirtyRect.IntersectRect(bgClipArea, aDirtyRect)) {
    // Nothing to paint
    return;
  }

  // if there is no background image or background images are turned off, try a color.
  if (!aColor.mBackgroundImage || !canDrawBackgroundImage) {
    PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea,
                         aColor, aBorder, aPadding, canDrawBackgroundColor);
    return;
  }

  // We have a background image

  // Lookup the image
  imgIRequest *req = aPresContext->LoadImage(aColor.mBackgroundImage,
                                             aForFrame);

  PRUint32 status = imgIRequest::STATUS_ERROR;
  if (req)
    req->GetImageStatus(&status);

  if (!req || !(status & imgIRequest::STATUS_FRAME_COMPLETE) || !(status & imgIRequest::STATUS_SIZE_AVAILABLE)) {
    PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea,
                         aColor, aBorder, aPadding, canDrawBackgroundColor);
    return;
  }

  nsCOMPtr<imgIContainer> image;
  req->GetImage(getter_AddRefs(image));

  nsSize imageSize;
  image->GetWidth(&imageSize.width);
  image->GetHeight(&imageSize.height);

  float p2t;
  p2t = aPresContext->ScaledPixelsToTwips();
  imageSize.width = NSIntPixelsToTwips(imageSize.width, p2t);
  imageSize.height = NSIntPixelsToTwips(imageSize.height, p2t);

  req = nsnull;

  nsRect bgOriginArea;

  nsIAtom* frameType = aForFrame->GetType();
  if (frameType == nsLayoutAtoms::inlineFrame) {
    switch (aColor.mBackgroundInlinePolicy) {
    case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
      bgOriginArea = aBorderArea;
      break;
    case NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX:
      bgOriginArea = gInlineBGData.GetBoundingRect(aForFrame);
      break;
    default:
      NS_ERROR("Unknown background-inline-policy value!  "
               "Please, teach me what to do.");
    case NS_STYLE_BG_INLINE_POLICY_CONTINUOUS:
      bgOriginArea = gInlineBGData.GetContinuousRect(aForFrame);
      break;
    }
  }
  else {
    bgOriginArea = aBorderArea;
  }

  // Background images are tiled over the 'background-clip' area
  // but the origin of the tiling is based on the 'background-origin' area
  if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_BORDER) {
    bgOriginArea.Deflate(aBorder.GetBorder());
    if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
      nsMargin padding;
      // XXX CalcPaddingFor is deprecated, but we need it for percentage padding
      aPadding.CalcPaddingFor(aForFrame, padding);
      bgOriginArea.Deflate(padding);
      NS_ASSERTION(aColor.mBackgroundOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                   "unknown background-origin value");
    }
  }

  // Based on the repeat setting, compute how many tiles we should
  // lay down for each axis. The value computed is the maximum based
  // on the dirty rect before accounting for the background-position.
  nscoord tileWidth = imageSize.width;
  nscoord tileHeight = imageSize.height;
  PRBool  needBackgroundColor = !(aColor.mBackgroundFlags &
                                  NS_STYLE_BG_COLOR_TRANSPARENT);
  PRIntn  repeat = aColor.mBackgroundRepeat;
  nscoord xDistance, yDistance;

  switch (repeat) {
    case NS_STYLE_BG_REPEAT_X:
      xDistance = dirtyRect.width;
      yDistance = tileHeight;
      break;
    case NS_STYLE_BG_REPEAT_Y:
      xDistance = tileWidth;
      yDistance = dirtyRect.height;
      break;
    case NS_STYLE_BG_REPEAT_XY:
      xDistance = dirtyRect.width;
      yDistance = dirtyRect.height;
      if (needBackgroundColor) {
        // If the image is completely opaque, we do not need to paint the
        // background color
        nsCOMPtr<gfxIImageFrame> gfxImgFrame;
        image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
        if (gfxImgFrame) {
          gfxImgFrame->GetNeedsBackground(&needBackgroundColor);

          /* check for tiling of a image where frame smaller than container */
          nsSize iSize;
          image->GetWidth(&iSize.width);
          image->GetHeight(&iSize.height);
          nsRect iframeRect;
          gfxImgFrame->GetRect(iframeRect);
          if (iSize.width != iframeRect.width ||
              iSize.height != iframeRect.height) {
            needBackgroundColor = PR_TRUE;
          }
        }
      }
      break;
    case NS_STYLE_BG_REPEAT_OFF:
    default:
      NS_ASSERTION(repeat == NS_STYLE_BG_REPEAT_OFF, "unknown background-repeat value");
      xDistance = tileWidth;
      yDistance = tileHeight;
      break;
  }

  // The background color is rendered over the 'background-clip' area
  if (needBackgroundColor) {
    PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea,
                         aColor, aBorder, aPadding, canDrawBackgroundColor);
  }

  if ((tileWidth == 0) || (tileHeight == 0) || dirtyRect.IsEmpty()) {
    // Nothing left to paint
    return;
  }

  // Compute the anchor point.
  //
  // When tiling, the anchor coordinate values will be negative offsets
  // from the background-origin area.

  nsPoint anchor;
  if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) {
    // If it's a fixed background attachment, then the image is placed 
    // relative to the viewport
    nsIView* viewportView = nsnull;
    nsRect viewportArea;

    nsIFrame* rootFrame =
      aPresContext->PresShell()->FrameManager()->GetRootFrame();
    NS_ASSERTION(rootFrame, "no root frame");

    if (aPresContext->IsPaginated()) {
      nsIFrame* page = nsLayoutUtils::GetPageFrame(aForFrame);
      NS_ASSERTION(page, "no page");
      rootFrame = page;
    }

    viewportView = rootFrame->GetView();
    NS_ASSERTION(viewportView, "no viewport view");
    viewportArea = viewportView->GetBounds();
    viewportArea.x = 0;
    viewportArea.y = 0;

    nsIScrollableFrame* scrollableFrame =
      GetRootScrollableFrame(aPresContext, rootFrame);

    if (scrollableFrame) {
      nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes();
      viewportArea.Deflate(scrollbars);
    }

    // Get the anchor point
    ComputeBackgroundAnchorPoint(aColor, viewportArea, viewportArea, tileWidth, tileHeight, anchor);

    // Convert the anchor point to aForFrame's coordinate space
    nsPoint offset(0, 0);
    nsIView* view = aForFrame->GetClosestView(&offset);
    anchor -= offset;
    NS_ASSERTION(view, "expected a view");
    anchor -= view->GetOffsetTo(viewportView);
  } else {
    if (frameType == nsLayoutAtoms::canvasFrame) {
      // If the frame is the canvas, the image is placed relative to
      // the root element's (first) frame (see bug 46446)
      nsRect firstRootElementFrameArea;
      nsIFrame* firstRootElementFrame = aForFrame->GetFirstChild(nsnull);
      NS_ASSERTION(firstRootElementFrame, "A canvas with a background "
        "image had no child frame, which is impossible according to CSS. "
        "Make sure there isn't a background image specified on the "
        "|:viewport| pseudo-element in |html.css|.");

      // temporary null check -- see bug 97226
      if (firstRootElementFrame) {
        firstRootElementFrameArea = firstRootElementFrame->GetRect();

        // Take the border out of the frame's rect
        const nsStyleBorder* borderStyle = firstRootElementFrame->GetStyleBorder();
        firstRootElementFrameArea.Deflate(borderStyle->GetBorder());

        // Get the anchor point
        ComputeBackgroundAnchorPoint(aColor, firstRootElementFrameArea, bgClipArea, tileWidth, tileHeight, anchor);
      } else {
        ComputeBackgroundAnchorPoint(aColor, bgOriginArea, bgClipArea, tileWidth, tileHeight, anchor);
      }
    } else {
      // Otherwise, it is the normal case, and the background is
      // simply placed relative to the frame's background-clip area
      ComputeBackgroundAnchorPoint(aColor, bgOriginArea, bgClipArea, tileWidth, tileHeight, anchor);
    }
  }


#if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX)
  // Setup clipping so that rendering doesn't leak out of the computed
  // dirty rect
  aRenderingContext.PushState();
  aRenderingContext.SetClipRect(dirtyRect, nsClipCombine_kIntersect);
#endif

  // Compute the x and y starting points and limits for tiling

  /* An Overview Of The Following Logic

          A........ . . . . . . . . . . . . . .
          :   +---:-------.-------.-------.----  /|\
          :   |   :       .       .       .       |  nh 
          :.......: . . . x . . . . . . . . . .  \|/   
          .   |   .       .       .       .        
          .   |   .       .  ###########  .        
          . . . . . . . . . .#. . . . .#. . . .     
          .   |   .       .  ###########  .      /|\
          .   |   .       .       .       .       |  h
          . . | . . . . . . . . . . . . . z . .  \|/
          .   |   .       .       .       .    
          |<-----nw------>|       |<--w-->|

       ---- = the background clip area edge. The painting is done within
              to this area.  If the background is positioned relative to the 
              viewport ('fixed') then this is the viewport edge.

       .... = the primary tile.

       . .  = the other tiles.

       #### = the dirtyRect. This is the minimum region we want to cover.

          A = The anchor point. This is the point at which the tile should
              start. Always negative or zero.

          x = x0 and y0 in the code. The point at which tiling must start
              so that the fewest tiles are laid out while completly
              covering the dirtyRect area.

          z = x1 and y1 in the code. The point at which tiling must end so
              that the fewest tiles are laid out while completly covering
              the dirtyRect area.

          w = the width of the tile (tileWidth).

          h = the height of the tile (tileHeight).

          n = the number of whole tiles that fit between 'A' and 'x'.
              (the vertical n and the horizontal n are different)


       Therefore, 

          x0 = bgClipArea.x + anchor.x + n * tileWidth;

       ...where n is an integer greater or equal to 0 fitting:

          n * tileWidth <= 
                      dirtyRect.x - (bgClipArea.x + anchor.x) <=
                                                             (n+1) * tileWidth

       ...i.e.,

          n <= (dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth < n + 1

       ...which, treating the division as an integer divide rounding down, gives:

          n = (dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth

       Substituting into the original expression for x0:

          x0 = bgClipArea.x + anchor.x +
               ((dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth) *
               tileWidth;

       From this x1 is determined,

          x1 = x0 + m * tileWidth;

       ...where m is an integer greater than 0 fitting:

          (m - 1) * tileWidth <
                            dirtyRect.x + dirtyRect.width - x0 <=
                                                               m * tileWidth

       ...i.e.,

          m - 1 < (dirtyRect.x + dirtyRect.width - x0) / tileWidth <= m

       ...which, treating the division as an integer divide, and making it
          round up, gives:

          m = (dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) / tileWidth

       Substituting into the original expression for x1:

          x1 = x0 + ((dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) /
                     tileWidth) * tileWidth

       The vertical case is analogous. If the background is fixed, then 
       bgClipArea.x and bgClipArea.y are set to zero when finding the parent
       viewport, above.

  */

  // first do the horizontal case
  nscoord x0, x1;
  // For scrolling attachment, the anchor is within the 'background-clip'
  // For fixed attachment, the anchor is within the bounds of the nearest
  // scrolling ancestor (or the viewport)
  x0 = (NS_STYLE_BG_ATTACHMENT_SCROLL == aColor.mBackgroundAttachment) ?
       bgClipArea.x : 0;
  if (repeat & NS_STYLE_BG_REPEAT_X) {
    // When tiling in the x direction, adjust the starting position of the
    // tile to account for dirtyRect.x. When tiling in x, the anchor.x value
    // will be a negative value used to adjust the starting coordinate.
    x0 += anchor.x + 
          ((dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth) * tileWidth;
    x1 = x0 + ((dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) / tileWidth) * tileWidth;
  }
  else {
    x0 += anchor.x;
    x1 = x0 + tileWidth;
  }

  // now do all that again with the vertical case
  nscoord y0, y1;
  // For scrolling attachment, the anchor is within the 'background-clip'
  // For fixed attachment, the anchor is within the bounds of the nearest
  // scrolling ancestor (or the viewport)
  y0 = (NS_STYLE_BG_ATTACHMENT_SCROLL == aColor.mBackgroundAttachment) ?
       bgClipArea.y : 0;
  if (repeat & NS_STYLE_BG_REPEAT_Y) {
    // When tiling in the y direction, adjust the starting position of the
    // tile to account for dirtyRect.y. When tiling in y, the anchor.y value
    // will be a negative value used to adjust the starting coordinate.
    y0 += anchor.y + 
          ((dirtyRect.y - (bgClipArea.y + anchor.y)) / tileHeight) * tileHeight;
    y1 = y0 + ((dirtyRect.y + dirtyRect.height - y0 + tileHeight - 1) / tileHeight) * tileHeight;
  }
  else {
    y0 += anchor.y;
    y1 = y0 + tileHeight;
  }

  // Take the intersection again to paint only the required area
  nsRect tileRect(x0, y0, (x1 - x0), (y1 - y0));
  nsRect drawRect;

  if (drawRect.IntersectRect(tileRect, dirtyRect))
    aRenderingContext.DrawTile(image, x0, y0, &drawRect);

#if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX)
  // Restore clipping
  aRenderingContext.PopState();
#endif

}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintBorder ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aDirtyRect,
const nsRect aBorderArea,
const nsStyleBorder aBorderStyle,
nsStyleContext aStyleContext,
PRIntn  aSkipSides,
nsRect aGap = 0,
nscoord  aHardBorderSize = 0,
PRBool  aShouldIgnoreRounded = PR_FALSE 
) [static]

Render the border for an element using css rendering rules for borders.

aSkipSides is a bitmask of the sides to skip when rendering. If 0 then no sides are skipped.

Both aDirtyRect and aBorderArea are in the local coordinate space of aForFrame

Definition at line 1633 of file nsCSSRendering.cpp.

{
  PRIntn              cnt;
  nsMargin            border;
  nsStyleCoord        bordStyleRadius[4];
  PRInt16             borderRadii[4],i;
  float               percent;
  nsCompatibility     compatMode = aPresContext->CompatibilityMode();
  PRBool              forceSolid;

  // Check to see if we have an appearance defined.  If so, we let the theme
  // renderer draw the border.  DO not get the data from aForFrame, since the passed in style context
  // may be different!  Always use |aStyleContext|!
  const nsStyleDisplay* displayData = aStyleContext->GetStyleDisplay();
  if (displayData->mAppearance) {
    nsITheme *theme = aPresContext->GetTheme();
    if (theme && theme->ThemeSupportsWidget(aPresContext, aForFrame, displayData->mAppearance))
      return; // Let the theme handle it.
  }
  // Get our style context's color struct.
  const nsStyleColor* ourColor = aStyleContext->GetStyleColor();

  // in NavQuirks mode we want to use the parent's context as a starting point 
  // for determining the background color
  const nsStyleBackground* bgColor = 
    nsCSSRendering::FindNonTransparentBackground(aStyleContext, 
                                            compatMode == eCompatibility_NavQuirks ? PR_TRUE : PR_FALSE); 

  // mozBGColor is used instead of bgColor when the display type is BG_INSET or BG_OUTSET
  // or BG_SOLID, and, in quirk mode, it is set to the BODY element's background color
  // instead of the nearest ancestor's background color.
  const nsStyleBackground* mozBGColor = bgColor;

  // now check if we are in Quirks mode and have a border style of BG_INSET or OUTSET
  // or BG_SOLID - if so we use the bgColor from the HTML element instead of the
  // nearest ancestor
  if (compatMode == eCompatibility_NavQuirks) {
    PRBool bNeedBodyBGColor = PR_FALSE;
    if (aStyleContext) {
      for (cnt=0; cnt<4;cnt++) {
        bNeedBodyBGColor = MOZ_BG_BORDER(aBorderStyle.GetBorderStyle(cnt));
        if (bNeedBodyBGColor) {
          break;
        }
      }
    }
    if (bNeedBodyBGColor) {
      GetBGColorForHTMLElement(aPresContext, mozBGColor);
    } 
  }

  if (aHardBorderSize > 0) {
    border.SizeTo(aHardBorderSize, aHardBorderSize, aHardBorderSize, aHardBorderSize);
  } else {
    aBorderStyle.CalcBorderFor(aForFrame, border);
  }
  if ((0 == border.left) && (0 == border.right) &&
      (0 == border.top) && (0 == border.bottom)) {
    // Empty border area
    return;
  }


  // get the radius for our border
  aBorderStyle.mBorderRadius.GetTop(bordStyleRadius[0]);      //topleft
  aBorderStyle.mBorderRadius.GetRight(bordStyleRadius[1]);    //topright
  aBorderStyle.mBorderRadius.GetBottom(bordStyleRadius[2]);   //bottomright
  aBorderStyle.mBorderRadius.GetLeft(bordStyleRadius[3]);     //bottomleft

  for(i=0;i<4;i++) {
    borderRadii[i] = 0;
    switch ( bordStyleRadius[i].GetUnit()) {
    case eStyleUnit_Percent:
      percent = bordStyleRadius[i].GetPercentValue();
      borderRadii[i] = (nscoord)(percent * aBorderArea.width);
      break;
    case eStyleUnit_Coord:
      borderRadii[i] = bordStyleRadius[i].GetCoordValue();
      break;
    default:
      break;
    }
  }

  // rounded version of the outline
  // check for any corner that is rounded
  for(i=0;i<4;i++){
    if(borderRadii[i] > 0 && !aBorderStyle.mBorderColors){
      PaintRoundedBorder(aPresContext,aRenderingContext,aForFrame,aDirtyRect,aBorderArea,&aBorderStyle,nsnull,aStyleContext,aSkipSides,borderRadii,aGap,PR_FALSE);
      return;
    }
  }

  // Turn off rendering for all of the zero sized sides
  if (0 == border.top) aSkipSides |= (1 << NS_SIDE_TOP);
  if (0 == border.right) aSkipSides |= (1 << NS_SIDE_RIGHT);
  if (0 == border.bottom) aSkipSides |= (1 << NS_SIDE_BOTTOM);
  if (0 == border.left) aSkipSides |= (1 << NS_SIDE_LEFT);

  // get the inside and outside parts of the border
  nsRect outerRect(aBorderArea);
  nsRect innerRect(outerRect);
  innerRect.Deflate(border);

  if (border.left + border.right > aBorderArea.width) {
    innerRect.x = outerRect.x;
    innerRect.width = outerRect.width;
  }
  if (border.top + border.bottom > aBorderArea.height) {
    innerRect.y = outerRect.y;
    innerRect.height = outerRect.height;
  }



  // If the dirty rect is completely inside the border area (e.g., only the
  // content is being painted), then we can skip out now
  if (innerRect.Contains(aDirtyRect)) {
    return;
  }
 
  //see if any sides are dotted or dashed
  for (cnt = 0; cnt < 4; cnt++) {
    if ((aBorderStyle.GetBorderStyle(cnt) == NS_STYLE_BORDER_STYLE_DOTTED) || 
        (aBorderStyle.GetBorderStyle(cnt) == NS_STYLE_BORDER_STYLE_DASHED))  {
      break;
    }
  }
  if (cnt < 4) {
    DrawDashedSides(cnt, aRenderingContext,aDirtyRect, ourColor, &aBorderStyle,nsnull, PR_FALSE,
                    outerRect, innerRect, aSkipSides, aGap);
  }

  // dont clip the borders for composite borders, they use the inner and 
  // outer rect to compute the diagonale to cross the border radius
  nsRect compositeInnerRect(innerRect);
  nsRect compositeOuterRect(outerRect);

  // Draw all the other sides
  if (!aDirtyRect.Contains(outerRect)) {
    // Border leaks out of the dirty rectangle - lets clip it but with care
    if (innerRect.y < aDirtyRect.y) {
      aSkipSides |= (1 << NS_SIDE_TOP);
      PRUint32 shortenBy =
        PR_MIN(innerRect.height, aDirtyRect.y - innerRect.y);
      innerRect.y += shortenBy;
      innerRect.height -= shortenBy;
      outerRect.y += shortenBy;
      outerRect.height -= shortenBy;
    }
    if (aDirtyRect.YMost() < innerRect.YMost()) {
      aSkipSides |= (1 << NS_SIDE_BOTTOM);
      PRUint32 shortenBy =
        PR_MIN(innerRect.height, innerRect.YMost() - aDirtyRect.YMost());
      innerRect.height -= shortenBy;
      outerRect.height -= shortenBy;
    }
    if (innerRect.x < aDirtyRect.x) {
      aSkipSides |= (1 << NS_SIDE_LEFT);
      PRUint32 shortenBy =
        PR_MIN(innerRect.width, aDirtyRect.x - innerRect.x);
      innerRect.x += shortenBy;
      innerRect.width -= shortenBy;
      outerRect.x += shortenBy;
      outerRect.width -= shortenBy;
    }
    if (aDirtyRect.XMost() < innerRect.XMost()) {
      aSkipSides |= (1 << NS_SIDE_RIGHT);
      PRUint32 shortenBy =
        PR_MIN(innerRect.width, innerRect.XMost() - aDirtyRect.XMost());
      innerRect.width -= shortenBy;
      outerRect.width -= shortenBy;
    }
  }
  /* Get our conversion values */
  nscoord twipsPerPixel = aPresContext->IntScaledPixelsToTwips(1);

  static PRUint8 sideOrder[] = { NS_SIDE_BOTTOM, NS_SIDE_LEFT, NS_SIDE_TOP, NS_SIDE_RIGHT };
  nscolor sideColor;
  nsBorderColors* compositeColors = nsnull;

  for (cnt = 0; cnt < 4; cnt++) {
    PRUint8 side = sideOrder[cnt];

    // If a side needs a double/groove/ridge border but will be less than two
    // pixels, force it to be solid (see bug 1781 and bug 310124).
    if (aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_DOUBLE ||
        aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_GROOVE ||
        aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_RIDGE) {
      nscoord widths[] = { border.top, border.right, border.bottom, border.left };
      forceSolid = (widths[side]/twipsPerPixel < 2);
    } else 
      forceSolid = PR_FALSE;

    if (0 == (aSkipSides & (1<<side))) {
      if (GetBorderColor(ourColor, aBorderStyle, side, sideColor, &compositeColors)) {
        if (compositeColors)
          DrawCompositeSide(aRenderingContext, side, compositeColors, compositeOuterRect, 
                            compositeInnerRect, borderRadii, twipsPerPixel, aGap);
        else
          DrawSide(aRenderingContext, side,
                   forceSolid ? NS_STYLE_BORDER_STYLE_SOLID : aBorderStyle.GetBorderStyle(side),
                   sideColor,
                   MOZ_BG_BORDER(aBorderStyle.GetBorderStyle(side)) ? 
                    mozBGColor->mBackgroundColor :
                    bgColor->mBackgroundColor,
                   outerRect,innerRect, aSkipSides,
                   twipsPerPixel, aGap);
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintBorderEdges ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aDirtyRect,
const nsRect aBorderArea,
nsBorderEdges aBorderEdges,
nsStyleContext aStyleContext,
PRIntn  aSkipSides,
nsRect aGap = 0 
) [static]

Just like PaintBorder, but takes as input a list of border segments rather than a single border style.

Useful for any object that needs to draw a border where an edge is not necessarily homogenous. Render the border for an element using css rendering rules for borders. aSkipSides is a bitmask of the sides to skip when rendering. If 0 then no sides are skipped.

Both aDirtyRect and aBorderArea are in the local coordinate space of aForFrame

Definition at line 2233 of file nsCSSRendering.cpp.

{
  const nsStyleBackground* bgColor = nsCSSRendering::FindNonTransparentBackground(aStyleContext);
  
  if (nsnull==aBorderEdges) {  // Empty border segments
    return;
  }

  // Turn off rendering for all of the zero sized sides
  if (0 == aBorderEdges->mMaxBorderWidth.top) 
    aSkipSides |= (1 << NS_SIDE_TOP);
  if (0 == aBorderEdges->mMaxBorderWidth.right) 
    aSkipSides |= (1 << NS_SIDE_RIGHT);
  if (0 == aBorderEdges->mMaxBorderWidth.bottom) 
    aSkipSides |= (1 << NS_SIDE_BOTTOM);
  if (0 == aBorderEdges->mMaxBorderWidth.left) 
    aSkipSides |= (1 << NS_SIDE_LEFT);

  // Draw any dashed or dotted segments separately
  DrawDashedSegments(aRenderingContext, aBorderArea, aBorderEdges, aSkipSides, aGap);

  // Draw all the other sides
  nscoord twipsPerPixel;
  float p2t;
  p2t = aPresContext->PixelsToTwips();
  twipsPerPixel = (nscoord) p2t;/* XXX huh!*/

  if (0 == (aSkipSides & (1<<NS_SIDE_TOP))) {
    PRInt32 segmentCount = aBorderEdges->mEdges[NS_SIDE_TOP].Count();
    PRInt32 i;
    nsBorderEdge * leftEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(0));
    nscoord x = aBorderEdges->mMaxBorderWidth.left - leftEdge->mWidth;
    for (i=0; i<segmentCount; i++)
    {
      nsBorderEdge * borderEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(i));
      nscoord y = aBorderArea.y;
      if (PR_TRUE==aBorderEdges->mOutsideEdge) // segments of the outside edge are bottom-aligned
        y += aBorderEdges->mMaxBorderWidth.top - borderEdge->mWidth;
      nsRect inside(x, y, borderEdge->mLength, aBorderArea.height);
      x += borderEdge->mLength;
      nsRect outside(inside);
      nsMargin outsideMargin(0, borderEdge->mWidth, 0, 0);
      outside.Deflate(outsideMargin);
      DrawSide(aRenderingContext, NS_SIDE_TOP,
               borderEdge->mStyle,
               borderEdge->mColor,
               bgColor->mBackgroundColor,
               inside, outside,aSkipSides,
               twipsPerPixel, aGap);
    }
  }
  if (0 == (aSkipSides & (1<<NS_SIDE_LEFT))) {
    PRInt32 segmentCount = aBorderEdges->mEdges[NS_SIDE_LEFT].Count();
    PRInt32 i;
    nsBorderEdge * topEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(0));
    nscoord y = aBorderEdges->mMaxBorderWidth.top - topEdge->mWidth;
    for (i=0; i<segmentCount; i++)
    {
      nsBorderEdge * borderEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(i));
      nscoord x = aBorderArea.x + (aBorderEdges->mMaxBorderWidth.left - borderEdge->mWidth);
      nsRect inside(x, y, aBorderArea.width, borderEdge->mLength);
      y += borderEdge->mLength;
      nsRect outside(inside);
      nsMargin outsideMargin(borderEdge->mWidth, 0, 0, 0);
      outside.Deflate(outsideMargin);
      DrawSide(aRenderingContext, NS_SIDE_LEFT,
               borderEdge->mStyle,
               borderEdge->mColor,
               bgColor->mBackgroundColor,
               inside, outside, aSkipSides,
               twipsPerPixel, aGap);
    }
  }
  if (0 == (aSkipSides & (1<<NS_SIDE_BOTTOM))) {
    PRInt32 segmentCount = aBorderEdges->mEdges[NS_SIDE_BOTTOM].Count();
    PRInt32 i;
    nsBorderEdge * leftEdge =  (nsBorderEdge *)
      (aBorderEdges->mEdges[NS_SIDE_LEFT].ElementAt(aBorderEdges->mEdges[NS_SIDE_LEFT].Count()-1));
    nscoord x = aBorderEdges->mMaxBorderWidth.left - leftEdge->mWidth;
    for (i=0; i<segmentCount; i++)
    {
      nsBorderEdge * borderEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_BOTTOM].ElementAt(i));
      nscoord y = aBorderArea.y;
      if (PR_TRUE==aBorderEdges->mOutsideEdge) // segments of the outside edge are top-aligned
        y -= (aBorderEdges->mMaxBorderWidth.bottom - borderEdge->mWidth);
      nsRect inside(x, y, borderEdge->mLength, aBorderArea.height);
      x += borderEdge->mLength;
      nsRect outside(inside);
      nsMargin outsideMargin(0, 0, 0, borderEdge->mWidth);
      outside.Deflate(outsideMargin);
      DrawSide(aRenderingContext, NS_SIDE_BOTTOM,
               borderEdge->mStyle,
               borderEdge->mColor,
               bgColor->mBackgroundColor,
               inside, outside,aSkipSides,
               twipsPerPixel, aGap);
    }
  }
  if (0 == (aSkipSides & (1<<NS_SIDE_RIGHT))) {
    PRInt32 segmentCount = aBorderEdges->mEdges[NS_SIDE_RIGHT].Count();
    PRInt32 i;
    nsBorderEdge * topEdge =  (nsBorderEdge *)
      (aBorderEdges->mEdges[NS_SIDE_TOP].ElementAt(aBorderEdges->mEdges[NS_SIDE_TOP].Count()-1));
    nscoord y = aBorderEdges->mMaxBorderWidth.top - topEdge->mWidth;
    for (i=0; i<segmentCount; i++)
    {
      nsBorderEdge * borderEdge =  (nsBorderEdge *)(aBorderEdges->mEdges[NS_SIDE_RIGHT].ElementAt(i));
      nscoord width;
      if (PR_TRUE==aBorderEdges->mOutsideEdge)
      {
        width = aBorderArea.width - aBorderEdges->mMaxBorderWidth.right;
        width += borderEdge->mWidth;
      }
      else
      {
        width = aBorderArea.width;
      }
      nsRect inside(aBorderArea.x, y, width, borderEdge->mLength);
      y += borderEdge->mLength;
      nsRect outside(inside);
      nsMargin outsideMargin(0, 0, (borderEdge->mWidth), 0);
      outside.Deflate(outsideMargin);
      DrawSide(aRenderingContext, NS_SIDE_RIGHT,
               borderEdge->mStyle,
               borderEdge->mColor,
               bgColor->mBackgroundColor,
               inside, outside,aSkipSides,
               twipsPerPixel, aGap);
    }
  }
}

Here is the call graph for this function:

void nsCSSRendering::PaintOutline ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aDirtyRect,
const nsRect aBorderArea,
const nsStyleBorder aBorderStyle,
const nsStyleOutline aOutlineStyle,
nsStyleContext aStyleContext,
PRIntn  aSkipSides,
nsRect aGap = 0 
) [static]

Render the outline for an element using css rendering rules for borders.

aSkipSides is a bitmask of the sides to skip when rendering. If 0 then no sides are skipped.

Both aDirtyRect and aBorderArea are in the local coordinate space of aForFrame

Definition at line 2078 of file nsCSSRendering.cpp.

{
nsStyleCoord        bordStyleRadius[4];
PRInt16             borderRadii[4],i;
float               percent;
const nsStyleBackground* bgColor = nsCSSRendering::FindNonTransparentBackground(aStyleContext);
nscoord width, offset;

  // Get our style context's color struct.
  const nsStyleColor* ourColor = aStyleContext->GetStyleColor();

  aOutlineStyle.GetOutlineWidth(width);

  if (0 == width) {
    // Empty outline
    return;
  }

  // get the radius for our outline
  aOutlineStyle.mOutlineRadius.GetTop(bordStyleRadius[0]);      //topleft
  aOutlineStyle.mOutlineRadius.GetRight(bordStyleRadius[1]);    //topright
  aOutlineStyle.mOutlineRadius.GetBottom(bordStyleRadius[2]);   //bottomright
  aOutlineStyle.mOutlineRadius.GetLeft(bordStyleRadius[3]);     //bottomleft

  for(i=0;i<4;i++) {
    borderRadii[i] = 0;
    switch ( bordStyleRadius[i].GetUnit()) {
    case eStyleUnit_Percent:
      percent = bordStyleRadius[i].GetPercentValue();
      borderRadii[i] = (nscoord)(percent * aBorderArea.width);
      break;
    case eStyleUnit_Coord:
      borderRadii[i] = bordStyleRadius[i].GetCoordValue();
      break;
    default:
      break;
    }
  }

  nsRect* overflowArea = aForFrame->GetOverflowAreaProperty(PR_FALSE);
  if (!overflowArea) {
    NS_WARNING("Hmm, outline painting should always find an overflow area here");
    return;
  }

  // get the offset for our outline
  aOutlineStyle.GetOutlineOffset(offset);
  nsRect outside(*overflowArea);
  nsRect inside(outside);
  if (width + offset >= 0) {
    // the overflow area is exactly the outside edge of the outline
    inside.Deflate(width, width);
  } else {
    // the overflow area is exactly the rectangle containing the frame and its
    // children; we can compute the outline directly
    inside.Deflate(-offset, -offset);
    if (inside.width < 0 || inside.height < 0) {
      return; // Protect against negative outline sizes
    }
    outside = inside;
    outside.Inflate(width, width);
  }

  // rounded version of the border
  for(i=0;i<4;i++){
    if(borderRadii[i] > 0){
      PaintRoundedBorder(aPresContext, aRenderingContext, aForFrame, aDirtyRect,
                         outside, nsnull, &aOutlineStyle, aStyleContext, 
                         aSkipSides, borderRadii, aGap, PR_TRUE);
      return;
    }
  }


  PRUint8 outlineStyle = aOutlineStyle.GetOutlineStyle();
  //see if any sides are dotted or dashed
  if ((outlineStyle == NS_STYLE_BORDER_STYLE_DOTTED) || 
      (outlineStyle == NS_STYLE_BORDER_STYLE_DASHED))  {
    DrawDashedSides(0, aRenderingContext, aDirtyRect, ourColor, nsnull, &aOutlineStyle, PR_TRUE,
                    outside, inside, aSkipSides, aGap);
    return;
  }

  // Draw all the other sides

  /* XXX something is misnamed here!!!! */
  nscoord twipsPerPixel;/* XXX */
  float p2t;/* XXX */
  p2t = aPresContext->PixelsToTwips();/* XXX */
  twipsPerPixel = (nscoord) p2t;/* XXX */

  nscolor outlineColor(NS_RGB(0,0,0)); // default to black in case it is invert color and the platform does not support that
  PRBool  canDraw = PR_FALSE;
  PRBool  modeChanged=PR_FALSE;
 
  // see if the outline color is 'invert' or can invert.
  if (aOutlineStyle.GetOutlineInvert()) {
    canDraw = PR_TRUE;
    if( NS_SUCCEEDED(aRenderingContext.SetPenMode(nsPenMode_kInvert)) ) {
      modeChanged=PR_TRUE;
     }
  } else {
    canDraw = aOutlineStyle.GetOutlineColor(outlineColor);
  }

  if (PR_TRUE == canDraw) {
    DrawSide(aRenderingContext, NS_SIDE_BOTTOM,
             outlineStyle,
             outlineColor,
             bgColor->mBackgroundColor, outside, inside, aSkipSides,
             twipsPerPixel, aGap);

    DrawSide(aRenderingContext, NS_SIDE_LEFT,
             outlineStyle, 
             outlineColor,
             bgColor->mBackgroundColor,outside, inside,aSkipSides,
             twipsPerPixel, aGap);

    DrawSide(aRenderingContext, NS_SIDE_TOP,
             outlineStyle,
             outlineColor,
             bgColor->mBackgroundColor,outside, inside,aSkipSides,
             twipsPerPixel, aGap);

    DrawSide(aRenderingContext, NS_SIDE_RIGHT,
             outlineStyle,
             outlineColor,
             bgColor->mBackgroundColor,outside, inside,aSkipSides,
             twipsPerPixel, aGap);
             
    if(modeChanged ) {
      aRenderingContext.SetPenMode(nsPenMode_kNone);
    }  
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintRoundedBackground ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aBorderArea,
const nsStyleBackground aColor,
const nsStyleBorder aBorder,
PRInt16  aTheRadius[4],
PRBool  aCanPaintNonWhite 
) [static, protected]


See documentation in nsCSSRendering.h 3/26/99 dwc

Definition at line 3312 of file nsCSSRendering.cpp.

{
  RoundedRect   outerPath;
  QBCurve       cr1,cr2,cr3,cr4;
  QBCurve       UL,UR,LL,LR;
  PRInt32       curIndex,c1Index;
  nsFloatPoint  thePath[MAXPATHSIZE];
  static nsPoint       polyPath[MAXPOLYPATHSIZE];
  PRInt16       np;
  nscoord       twipsPerPixel;
  float         p2t;

  // needed for our border thickness
  p2t = aPresContext->PixelsToTwips();
  twipsPerPixel = NSToCoordRound(p2t);

  nscolor color = aColor.mBackgroundColor;
  if (!aCanPaintNonWhite) {
    color = NS_RGB(255, 255, 255);
  }
  aRenderingContext.SetColor(color);

  // Adjust for background-clip, if necessary
  if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
    NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING, "unknown background-clip value");

    // Get the radius to the outer edge of the padding.
    // -moz-border-radius is the radius to the outer edge of the border.
    NS_FOR_CSS_SIDES(side) {
      aTheRadius[side] -= aBorder.GetBorderWidth(side);
      aTheRadius[side] = PR_MAX(aTheRadius[side], 0);
    }
  }

  // set the rounded rect up, and let'er rip
  outerPath.Set(aBgClipArea.x,aBgClipArea.y,aBgClipArea.width,aBgClipArea.height,aTheRadius,twipsPerPixel);
  outerPath.GetRoundedBorders(UL,UR,LL,LR);

  // BUILD THE ENTIRE OUTSIDE PATH
  // TOP LINE ----------------------------------------------------------------
  UL.MidPointDivide(&cr1,&cr2);
  UR.MidPointDivide(&cr3,&cr4);
  np=0;
  thePath[np++].MoveTo(cr2.mAnc1.x,cr2.mAnc1.y);
  thePath[np++].MoveTo(cr2.mCon.x, cr2.mCon.y);
  thePath[np++].MoveTo(cr2.mAnc2.x, cr2.mAnc2.y);
  thePath[np++].MoveTo(cr3.mAnc1.x, cr3.mAnc1.y);
  thePath[np++].MoveTo(cr3.mCon.x, cr3.mCon.y);
  thePath[np++].MoveTo(cr3.mAnc2.x, cr3.mAnc2.y);

  polyPath[0].x = NSToCoordRound(thePath[0].x);
  polyPath[0].y = NSToCoordRound(thePath[0].y);
  curIndex = 1;
  GetPath(thePath,polyPath,&curIndex,eOutside,c1Index);

  // RIGHT LINE ----------------------------------------------------------------
  LR.MidPointDivide(&cr2,&cr3);
  np=0;
  thePath[np++].MoveTo(cr4.mAnc1.x,cr4.mAnc1.y);
  thePath[np++].MoveTo(cr4.mCon.x, cr4.mCon.y);
  thePath[np++].MoveTo(cr4.mAnc2.x, cr4.mAnc2.y);
  thePath[np++].MoveTo(cr2.mAnc1.x, cr2.mAnc1.y);
  thePath[np++].MoveTo(cr2.mCon.x, cr2.mCon.y);
  thePath[np++].MoveTo(cr2.mAnc2.x, cr2.mAnc2.y);
  GetPath(thePath,polyPath,&curIndex,eOutside,c1Index);

  // BOTTOM LINE ----------------------------------------------------------------
  LL.MidPointDivide(&cr2,&cr4);
  np=0;
  thePath[np++].MoveTo(cr3.mAnc1.x,cr3.mAnc1.y);
  thePath[np++].MoveTo(cr3.mCon.x, cr3.mCon.y);
  thePath[np++].MoveTo(cr3.mAnc2.x, cr3.mAnc2.y);
  thePath[np++].MoveTo(cr2.mAnc1.x, cr2.mAnc1.y);
  thePath[np++].MoveTo(cr2.mCon.x, cr2.mCon.y);
  thePath[np++].MoveTo(cr2.mAnc2.x, cr2.mAnc2.y);
  GetPath(thePath,polyPath,&curIndex,eOutside,c1Index);

  // LEFT LINE ----------------------------------------------------------------
  np=0;
  thePath[np++].MoveTo(cr4.mAnc1.x,cr4.mAnc1.y);
  thePath[np++].MoveTo(cr4.mCon.x, cr4.mCon.y);
  thePath[np++].MoveTo(cr4.mAnc2.x, cr4.mAnc2.y);
  thePath[np++].MoveTo(cr1.mAnc1.x, cr1.mAnc1.y);
  thePath[np++].MoveTo(cr1.mCon.x, cr1.mCon.y);
  thePath[np++].MoveTo(cr1.mAnc2.x, cr1.mAnc2.y);
  GetPath(thePath,polyPath,&curIndex,eOutside,c1Index);

  aRenderingContext.FillPolygon(polyPath,curIndex); 
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::PaintRoundedBorder ( nsPresContext aPresContext,
nsIRenderingContext aRenderingContext,
nsIFrame aForFrame,
const nsRect aDirtyRect,
const nsRect aBorderArea,
const nsStyleBorder aBorderStyle,
const nsStyleOutline aOutlineStyle,
nsStyleContext aStyleContext,
PRIntn  aSkipSides,
PRInt16  aBorderRadius[4],
nsRect aGap = 0,
PRBool  aIsOutline = PR_FALSE 
) [static, protected]

Render the border for an element using css rendering rules for borders.


See documentation in nsCSSRendering.h 3/26/99 dwc

aSkipSides is a bitmask of the sides to skip when rendering. If 0 then no sides are skipped. Both aDirtyRect and aBorderArea are in the local coordinate space of aForFrame

Definition at line 3415 of file nsCSSRendering.cpp.

{
  RoundedRect   outerPath;
  QBCurve       UL,LL,UR,LR;
  QBCurve       IUL,ILL,IUR,ILR;
  QBCurve       cr1,cr2,cr3,cr4;
  QBCurve       Icr1,Icr2,Icr3,Icr4;
  nsFloatPoint  thePath[MAXPATHSIZE];
  PRInt16       np;
  nsMargin      border;
  nscoord       twipsPerPixel,qtwips;
  float         p2t;

  NS_ASSERTION((aIsOutline && aOutlineStyle) || (!aIsOutline && aBorderStyle), "null params not allowed");
  if (!aIsOutline) {
    aBorderStyle->CalcBorderFor(aForFrame, border);
    if ((0 == border.left) && (0 == border.right) &&
        (0 == border.top) && (0 == border.bottom)) {
      return;
    }
  } else {
    nscoord width;
    if (!aOutlineStyle->GetOutlineWidth(width)) {
      return;
    }
    border.left   = width;
    border.right  = width;
    border.top    = width;
    border.bottom = width;
  }

  // needed for our border thickness
  p2t = aPresContext->PixelsToTwips();
  twipsPerPixel = NSToCoordRound(p2t);

  // Base our thickness check on the segment being less than a pixel and 1/2
  qtwips = twipsPerPixel >> 2;
  //qtwips = twipsPerPixel;

  outerPath.Set(aBorderArea.x,aBorderArea.y,aBorderArea.width,aBorderArea.height,aBorderRadius,twipsPerPixel);
  outerPath.GetRoundedBorders(UL,UR,LL,LR);
  outerPath.CalcInsetCurves(IUL,IUR,ILL,ILR,border);

  // TOP LINE -- construct and divide the curves first, then put together our top and bottom paths
  UL.MidPointDivide(&cr1,&cr2);
  UR.MidPointDivide(&cr3,&cr4);
  IUL.MidPointDivide(&Icr1,&Icr2);
  IUR.MidPointDivide(&Icr3,&Icr4);
  if(0!=border.top){
    np=0;
    thePath[np++].MoveTo(cr2.mAnc1.x,cr2.mAnc1.y);
    thePath[np++].MoveTo(cr2.mCon.x, cr2.mCon.y);
    thePath[np++].MoveTo(cr2.mAnc2.x, cr2.mAnc2.y);
    thePath[np++].MoveTo(cr3.mAnc1.x, cr3.mAnc1.y);
    thePath[np++].MoveTo(cr3.mCon.x, cr3.mCon.y);
    thePath[np++].MoveTo(cr3.mAnc2.x, cr3.mAnc2.y);
 
    thePath[np++].MoveTo(Icr3.mAnc2.x,Icr3.mAnc2.y);
    thePath[np++].MoveTo(Icr3.mCon.x, Icr3.mCon.y);
    thePath[np++].MoveTo(Icr3.mAnc1.x, Icr3.mAnc1.y);
    thePath[np++].MoveTo(Icr2.mAnc2.x, Icr2.mAnc2.y);
    thePath[np++].MoveTo(Icr2.mCon.x, Icr2.mCon.y);
    thePath[np++].MoveTo(Icr2.mAnc1.x, Icr2.mAnc1.y);
    RenderSide(thePath,aRenderingContext,aBorderStyle,aOutlineStyle,aStyleContext,NS_SIDE_TOP,border,qtwips, aIsOutline);
  }
  // RIGHT  LINE ----------------------------------------------------------------
  LR.MidPointDivide(&cr2,&cr3);
  ILR.MidPointDivide(&Icr2,&Icr3);
  if(0!=border.right){
    np=0;
    thePath[np++].MoveTo(cr4.mAnc1.x,cr4.mAnc1.y);
    thePath[np++].MoveTo(cr4.mCon.x, cr4.mCon.y);
    thePath[np++].MoveTo(cr4.mAnc2.x,cr4.mAnc2.y);
    thePath[np++].MoveTo(cr2.mAnc1.x,cr2.mAnc1.y);
    thePath[np++].MoveTo(cr2.mCon.x, cr2.mCon.y);
    thePath[np++].MoveTo(cr2.mAnc2.x,cr2.mAnc2.y);

    thePath[np++].MoveTo(Icr2.mAnc2.x,Icr2.mAnc2.y);
    thePath[np++].MoveTo(Icr2.mCon.x, Icr2.mCon.y);
    thePath[np++].MoveTo(Icr2.mAnc1.x,Icr2.mAnc1.y);
    thePath[np++].MoveTo(Icr4.mAnc2.x,Icr4.mAnc2.y);
    thePath[np++].MoveTo(Icr4.mCon.x, Icr4.mCon.y);
    thePath[np++].MoveTo(Icr4.mAnc1.x,Icr4.mAnc1.y);
    RenderSide(thePath,aRenderingContext,aBorderStyle,aOutlineStyle,aStyleContext,NS_SIDE_RIGHT,border,qtwips, aIsOutline);
  }

  // bottom line ----------------------------------------------------------------
  LL.MidPointDivide(&cr2,&cr4);
  ILL.MidPointDivide(&Icr2,&Icr4);
  if(0!=border.bottom){
    np=0;
    thePath[np++].MoveTo(cr3.mAnc1.x,cr3.mAnc1.y);
    thePath[np++].MoveTo(cr3.mCon.x, cr3.mCon.y);
    thePath[np++].MoveTo(cr3.mAnc2.x, cr3.mAnc2.y);
    thePath[np++].MoveTo(cr2.mAnc1.x, cr2.mAnc1.y);
    thePath[np++].MoveTo(cr2.mCon.x, cr2.mCon.y);
    thePath[np++].MoveTo(cr2.mAnc2.x, cr2.mAnc2.y);

    thePath[np++].MoveTo(Icr2.mAnc2.x,Icr2.mAnc2.y);
    thePath[np++].MoveTo(Icr2.mCon.x, Icr2.mCon.y);
    thePath[np++].MoveTo(Icr2.mAnc1.x, Icr2.mAnc1.y);
    thePath[np++].MoveTo(Icr3.mAnc2.x, Icr3.mAnc2.y);
    thePath[np++].MoveTo(Icr3.mCon.x, Icr3.mCon.y);
    thePath[np++].MoveTo(Icr3.mAnc1.x, Icr3.mAnc1.y);
    RenderSide(thePath,aRenderingContext,aBorderStyle,aOutlineStyle,aStyleContext,NS_SIDE_BOTTOM,border,qtwips, aIsOutline);
  }
  // left line ----------------------------------------------------------------
  if(0==border.left)
    return;
  np=0;
  thePath[np++].MoveTo(cr4.mAnc1.x,cr4.mAnc1.y);
  thePath[np++].MoveTo(cr4.mCon.x, cr4.mCon.y);
  thePath[np++].MoveTo(cr4.mAnc2.x, cr4.mAnc2.y);
  thePath[np++].MoveTo(cr1.mAnc1.x, cr1.mAnc1.y);
  thePath[np++].MoveTo(cr1.mCon.x, cr1.mCon.y);
  thePath[np++].MoveTo(cr1.mAnc2.x, cr1.mAnc2.y);


  thePath[np++].MoveTo(Icr1.mAnc2.x,Icr1.mAnc2.y);
  thePath[np++].MoveTo(Icr1.mCon.x, Icr1.mCon.y);
  thePath[np++].MoveTo(Icr1.mAnc1.x, Icr1.mAnc1.y);
  thePath[np++].MoveTo(Icr4.mAnc2.x, Icr4.mAnc2.y);
  thePath[np++].MoveTo(Icr4.mCon.x, Icr4.mCon.y);
  thePath[np++].MoveTo(Icr4.mAnc1.x, Icr4.mAnc1.y);

  RenderSide(thePath,aRenderingContext,aBorderStyle,aOutlineStyle,aStyleContext,NS_SIDE_LEFT,border,qtwips, aIsOutline);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsCSSRendering::RenderSide ( nsFloatPoint  aPoints[],
nsIRenderingContext aRenderingContext,
const nsStyleBorder aBorderStyle,
const nsStyleOutline aOutlineStyle,
nsStyleContext aStyleContext,
PRUint8  aSide,
nsMargin aBorThick,
nscoord  aTwipsPerPixel,
PRBool  aIsOutline = PR_FALSE 
) [static, protected]


See documentation in nsCSSRendering.h 3/26/99 dwc

Definition at line 3560 of file nsCSSRendering.cpp.

{
  QBCurve   thecurve;
  nscolor   sideColor = NS_RGB(0,0,0);
  static nsPoint   polypath[MAXPOLYPATHSIZE];
  PRInt32   curIndex,c1Index,c2Index,junk;
  PRInt8    border_Style;
  PRInt16   thickness;

  // Get our style context's color struct.
  const nsStyleColor* ourColor = aStyleContext->GetStyleColor();

  NS_ASSERTION((aIsOutline && aOutlineStyle) || (!aIsOutline && aBorderStyle), "null params not allowed");
  // set the style information
  if (!aIsOutline) {
    if (!GetBorderColor(ourColor, *aBorderStyle, aSide, sideColor)) {
      return;
    }
  } else {
    aOutlineStyle->GetOutlineColor(sideColor);
  }
  aRenderingContext.SetColor ( sideColor );

  thickness = 0;
  switch(aSide){
    case  NS_SIDE_LEFT:
      thickness = aBorThick.left;
      break;
    case  NS_SIDE_TOP:
      thickness = aBorThick.top;
      break;
    case  NS_SIDE_RIGHT:
      thickness = aBorThick.right;
      break;
    case  NS_SIDE_BOTTOM:
      thickness = aBorThick.bottom;
      break;
  }

  // if the border is thin, just draw it 
  if (thickness<=aTwipsPerPixel) {
    // NOTHING FANCY JUST DRAW OUR OUTSIDE BORDER
    thecurve.SetPoints(aPoints[0].x,aPoints[0].y,aPoints[1].x,aPoints[1].y,aPoints[2].x,aPoints[2].y);
    thecurve.SubDivide((nsIRenderingContext*)&aRenderingContext,nsnull,nsnull);
    aRenderingContext.DrawLine((nscoord)aPoints[2].x,(nscoord)aPoints[2].y,(nscoord)aPoints[3].x,(nscoord)aPoints[3].y);
    thecurve.SetPoints(aPoints[3].x,aPoints[3].y,aPoints[4].x,aPoints[4].y,aPoints[5].x,aPoints[5].y);
    thecurve.SubDivide((nsIRenderingContext*)&aRenderingContext,nsnull,nsnull);
  } else {
    
    if (!aIsOutline) {
      border_Style = aBorderStyle->GetBorderStyle(aSide);
    } else {
      border_Style = aOutlineStyle->GetOutlineStyle();
    }
    switch (border_Style){
      case NS_STYLE_BORDER_STYLE_OUTSET:
      case NS_STYLE_BORDER_STYLE_INSET:
      case NS_STYLE_BORDER_STYLE_BG_OUTSET:
      case NS_STYLE_BORDER_STYLE_BG_INSET:
      case NS_STYLE_BORDER_STYLE_BG_SOLID:
        {
          const nsStyleBackground* bgColor = nsCSSRendering::FindNonTransparentBackground(aStyleContext);
          if (border_Style == NS_STYLE_BORDER_STYLE_BG_SOLID) {
            nscolor colors[2]; 
            NS_Get3DColors(colors, bgColor->mBackgroundColor); 
            aRenderingContext.SetColor(colors[0]);
          } else {
            aRenderingContext.SetColor(MakeBevelColor(aSide, border_Style, bgColor->mBackgroundColor, sideColor, 
                                       !MOZ_BG_BORDER(border_Style)));
          }
        }
      case NS_STYLE_BORDER_STYLE_DOTTED:
      case NS_STYLE_BORDER_STYLE_DASHED:
        // break; XXX This is here until dotted and dashed are supported.  It is ok to have
        // dotted and dashed render in solid until this style is supported.  This code should
        // be moved when it is supported so that the above outset and inset will fall into the 
        // solid code below....
      case NS_STYLE_BORDER_STYLE_AUTO:
      case NS_STYLE_BORDER_STYLE_SOLID:
        polypath[0].x = NSToCoordRound(aPoints[0].x);
        polypath[0].y = NSToCoordRound(aPoints[0].y);
        curIndex = 1;
        GetPath(aPoints,polypath,&curIndex,eOutside,c1Index);
        c2Index = curIndex;
        if (curIndex >= MAXPOLYPATHSIZE)
          return;
        polypath[curIndex].x = NSToCoordRound(aPoints[6].x);
        polypath[curIndex].y = NSToCoordRound(aPoints[6].y);
        curIndex++;
        GetPath(aPoints,polypath,&curIndex,eInside,junk);
        if (curIndex >= MAXPOLYPATHSIZE)
          return;
        polypath[curIndex].x = NSToCoordRound(aPoints[0].x);
        polypath[curIndex].y = NSToCoordRound(aPoints[0].y);
        curIndex++;
        aRenderingContext.FillPolygon(polypath,curIndex);

       break;
      case NS_STYLE_BORDER_STYLE_DOUBLE:
        polypath[0].x = NSToCoordRound(aPoints[0].x);
        polypath[0].y = NSToCoordRound(aPoints[0].y);
        curIndex = 1;
        GetPath(aPoints,polypath,&curIndex,eOutside,c1Index);
        aRenderingContext.DrawPolyline(polypath,curIndex);
        polypath[0].x = NSToCoordRound(aPoints[6].x);
        polypath[0].y = NSToCoordRound(aPoints[6].y);
        curIndex = 1;
        GetPath(aPoints,polypath,&curIndex,eInside,c1Index);
        aRenderingContext.DrawPolyline(polypath,curIndex);
        break;
      case NS_STYLE_BORDER_STYLE_NONE:
      case NS_STYLE_BORDER_STYLE_HIDDEN:
        break;
      case NS_STYLE_BORDER_STYLE_RIDGE:
      case NS_STYLE_BORDER_STYLE_GROOVE:
        {
        const nsStyleBackground* bgColor = nsCSSRendering::FindNonTransparentBackground(aStyleContext);
        aRenderingContext.SetColor ( MakeBevelColor (aSide, border_Style, bgColor->mBackgroundColor,sideColor, PR_TRUE));

        polypath[0].x = NSToCoordRound(aPoints[0].x);
        polypath[0].y = NSToCoordRound(aPoints[0].y);
        curIndex = 1;
        GetPath(aPoints,polypath,&curIndex,eOutside,c1Index);
        if (curIndex >= MAXPOLYPATHSIZE)
          return;
        polypath[curIndex].x = NSToCoordRound((aPoints[5].x + aPoints[6].x)/2.0f);
        polypath[curIndex].y = NSToCoordRound((aPoints[5].y + aPoints[6].y)/2.0f);
        curIndex++;
        GetPath(aPoints,polypath,&curIndex,eCalcRev,c1Index,.5);
        if (curIndex >= MAXPOLYPATHSIZE)
          return;
        polypath[curIndex].x = NSToCoordRound(aPoints[0].x);
        polypath[curIndex].y = NSToCoordRound(aPoints[0].y);
        curIndex++;
        aRenderingContext.FillPolygon(polypath,curIndex);

        aRenderingContext.SetColor ( MakeBevelColor (aSide, 
                                                ((border_Style == NS_STYLE_BORDER_STYLE_RIDGE) ?
                                                NS_STYLE_BORDER_STYLE_GROOVE :
                                                NS_STYLE_BORDER_STYLE_RIDGE), 
                                                bgColor->mBackgroundColor,sideColor, PR_TRUE));
       
        polypath[0].x = NSToCoordRound((aPoints[0].x + aPoints[11].x)/2.0f);
        polypath[0].y = NSToCoordRound((aPoints[0].y + aPoints[11].y)/2.0f);
        curIndex = 1;
        GetPath(aPoints,polypath,&curIndex,eCalc,c1Index,.5);
        if (curIndex >= MAXPOLYPATHSIZE)
          return;
        polypath[curIndex].x = NSToCoordRound(aPoints[6].x) ;
        polypath[curIndex].y = NSToCoordRound(aPoints[6].y);
        curIndex++;
        GetPath(aPoints,polypath,&curIndex,eInside,c1Index);
        if (curIndex >= MAXPOLYPATHSIZE)
          return;
        polypath[curIndex].x = NSToCoordRound(aPoints[0].x);
        polypath[curIndex].y = NSToCoordRound(aPoints[0].y);
        curIndex++;
        aRenderingContext.FillPolygon(polypath,curIndex);
        }
        break;
      default:
        break;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nscolor nsCSSRendering::TransformColor ( nscolor  aMapColor,
PRBool  aNoBackGround 
) [static]

transform a color to a color that will show up on a printer if needed aMapColor - color to evaluate aIsPrinter - Is this a printing device return - the transformed color

Definition at line 1529 of file nsCSSRendering.cpp.

{
PRUint16  hue,sat,value;
nscolor   newcolor;

  newcolor = aMapColor;
  if (PR_TRUE == aNoBackGround){
    // convert the RBG to HSV so we can get the lightness (which is the v)
    NS_RGB2HSV(newcolor,hue,sat,value);
    // The goal here is to send white to black while letting colored
    // stuff stay colored... So we adopt the following approach.
    // Something with sat = 0 should end up with value = 0.  Something
    // with a high sat can end up with a high value and it's ok.... At
    // the same time, we don't want to make things lighter.  Do
    // something simple, since it seems to work.
    if (value > sat) {
      value = sat;
      // convert this color back into the RGB color space.
      NS_HSV2RGB(newcolor,hue,sat,value);
    }
  }
  return newcolor;
}

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files: