Beispiel #1
0
// Deflate the rect by the specified margin
void nsRect::Deflate(const nsMargin &aMargin)
{
  x += aMargin.left;
  y += aMargin.top;
  width = PR_MAX(0, width - aMargin.LeftRight());
  height = PR_MAX(0, height - aMargin.TopBottom());
}
Beispiel #2
0
NS_IMETHODIMP
nsBox::GetPadding(nsMargin& aMargin)
{
  const nsStyleDisplay *disp = GetStyleDisplay();
  if (disp->mAppearance && gTheme) {
    // Go to the theme for the padding.
    nsPresContext *context = PresContext();
    if (gTheme->ThemeSupportsWidget(context, this, disp->mAppearance)) {
      nsIntMargin margin(0, 0, 0, 0);
      PRBool useThemePadding;

      useThemePadding = gTheme->GetWidgetPadding(context->DeviceContext(),
                                                 this, disp->mAppearance,
                                                 &margin);
      if (useThemePadding) {
        aMargin.top = context->DevPixelsToAppUnits(margin.top);
        aMargin.right = context->DevPixelsToAppUnits(margin.right);
        aMargin.bottom = context->DevPixelsToAppUnits(margin.bottom);
        aMargin.left = context->DevPixelsToAppUnits(margin.left);
        return NS_OK;
      }
    }
  }

  aMargin.SizeTo(0,0,0,0);
  GetStylePadding()->GetPadding(aMargin);

  return NS_OK;
}
Beispiel #3
0
NS_IMETHODIMP
nsBox::GetBorder(nsMargin& aMargin)
{
  aMargin.SizeTo(0,0,0,0);
    
  const nsStyleDisplay* disp = GetStyleDisplay();
  if (disp->mAppearance && gTheme) {
    // Go to the theme for the border.
    nsPresContext *context = PresContext();
    if (gTheme->ThemeSupportsWidget(context, this, disp->mAppearance)) {
      nsIntMargin margin(0, 0, 0, 0);
      gTheme->GetWidgetBorder(context->DeviceContext(), this,
                              disp->mAppearance, &margin);
      aMargin.top = context->DevPixelsToAppUnits(margin.top);
      aMargin.right = context->DevPixelsToAppUnits(margin.right);
      aMargin.bottom = context->DevPixelsToAppUnits(margin.bottom);
      aMargin.left = context->DevPixelsToAppUnits(margin.left);
      return NS_OK;
    }
  }

  aMargin = GetStyleBorder()->GetActualBorder();

  return NS_OK;
}
Beispiel #4
0
NS_IMETHODIMP
nsScrollbarFrame::GetMargin(nsMargin& aMargin)
{
  aMargin.SizeTo(0,0,0,0);

  if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
    nsPresContext* presContext = PresContext();
    nsITheme* theme = presContext->GetTheme();
    if (theme) {
      nsIntSize size;
      bool isOverridable;
      nsRefPtr<nsRenderingContext> rc =
        presContext->PresShell()->GetReferenceRenderingContext();
      theme->GetMinimumWidgetSize(rc, this, NS_THEME_SCROLLBAR, &size,
                                  &isOverridable);
      if (IsHorizontal()) {
        aMargin.top = -presContext->DevPixelsToAppUnits(size.height);
      }
      else {
        if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
          aMargin.right = -presContext->DevPixelsToAppUnits(size.width);
        }
        else {
          aMargin.left = -presContext->DevPixelsToAppUnits(size.width);
        }
      }
      return NS_OK;
    }
  }

  return nsBox::GetMargin(aMargin);
}
// Helper function to compute the offset needed to center a child
// page-frame's margin-box inside our content-box.
nscoord
nsSimplePageSequenceFrame::ComputeCenteringMargin(
  nscoord aContainerContentBoxWidth,
  nscoord aChildPaddingBoxWidth,
  const nsMargin& aChildPhysicalMargin)
{
  // We'll be centering our child's margin-box, so get the size of that:
  nscoord childMarginBoxWidth =
    aChildPaddingBoxWidth + aChildPhysicalMargin.LeftRight();

  // When rendered, our child's rect will actually be scaled up by the
  // print-preview scale factor, via ComputePageSequenceTransform().
  // We really want to center *that scaled-up rendering* inside of
  // aContainerContentBoxWidth.  So, we scale up its margin-box here...
  auto ppScale = PresContext()->GetPrintPreviewScale();
  nscoord scaledChildMarginBoxWidth =
    NSToCoordRound(childMarginBoxWidth * ppScale);

  // ...and see we how much space is left over, when we subtract that scaled-up
  // size from the container width:
  nscoord scaledExtraSpace =
    aContainerContentBoxWidth - scaledChildMarginBoxWidth;

  if (scaledExtraSpace <= 0) {
    // (Don't bother centering if there's zero/negative space.)
    return 0;
  }

  // To center the child, we want to give it an additional left-margin of half
  // of the extra space.  And then, we have to scale that space back down, so
  // that it'll produce the correct scaled-up amount when we render (because
  // rendering will scale it back up):
  return NSToCoordRound(scaledExtraSpace * 0.5 / ppScale);
}
Beispiel #6
0
NS_IMETHODIMP
nsBox::GetMargin(nsMargin& aMargin)
{
  aMargin.SizeTo(0,0,0,0);
  GetStyleMargin()->GetMargin(aMargin);

  return NS_OK;
}
Beispiel #7
0
nsresult
nsBox::GetMargin(nsMargin& aMargin)
{
  aMargin.SizeTo(0,0,0,0);
  StyleMargin()->GetMargin(aMargin);

  return NS_OK;
}
// Helper-function that lets us clone the button's reflow state, but with its
// ComputedWidth and ComputedHeight reduced by the amount of renderer-specific
// focus border and padding that we're using. (This lets us provide a more
// appropriate content-box size for descendents' percent sizes to resolve
// against.)
static nsHTMLReflowState
CloneReflowStateWithReducedContentBox(
  const nsHTMLReflowState& aButtonReflowState,
  const nsMargin& aFocusPadding)
{
  nscoord adjustedWidth =
    aButtonReflowState.ComputedWidth() - aFocusPadding.LeftRight();
  adjustedWidth = std::max(0, adjustedWidth);

  // (Only adjust height if it's an actual length.)
  nscoord adjustedHeight = aButtonReflowState.ComputedHeight();
  if (adjustedHeight != NS_INTRINSICSIZE) {
    adjustedHeight -= aFocusPadding.TopBottom();
    adjustedHeight = std::max(0, adjustedHeight);
  }

  nsHTMLReflowState clone(aButtonReflowState);
  clone.SetComputedWidth(adjustedWidth);
  clone.SetComputedHeight(adjustedHeight);

  return clone;
}
Beispiel #9
0
NS_IMETHODIMP
nsIFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding)
{
  aBorderAndPadding.SizeTo(0, 0, 0, 0);
  nsresult rv = GetBorder(aBorderAndPadding);
  if (NS_FAILED(rv))
    return rv;

  nsMargin padding;
  rv = GetPadding(padding);
  if (NS_FAILED(rv))
    return rv;

  aBorderAndPadding += padding;

  return rv;
}
Beispiel #10
0
nsresult
TableBackgroundPainter::TableBackgroundData::SetBCBorder(nsMargin& aBorder,
                                                         TableBackgroundPainter* aPainter)
{
  NS_PRECONDITION(aPainter, "null painter");
  if (!mSynthBorder) {
    mSynthBorder = new (aPainter->mPresContext)
                        nsStyleBorder(aPainter->mZeroBorder);
    if (!mSynthBorder) return NS_ERROR_OUT_OF_MEMORY;
  }

  NS_FOR_CSS_SIDES(side) {
    mSynthBorder->SetBorderWidth(side, aBorder.Side(side));
  }
  
  mBorder = mSynthBorder;
  return NS_OK;
}
Beispiel #11
0
nsresult
nsScrollbarFrame::GetScrollbarMargin(
  nsMargin& aMargin,
  mozilla::ScrollFrameHelper::eScrollbarSide aSide)
{
  nsresult rv = NS_ERROR_FAILURE;
  aMargin.SizeTo(0,0,0,0);

  if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
    nsPresContext* presContext = PresContext();
    nsITheme* theme = presContext->GetTheme();
    if (theme) {
      LayoutDeviceIntSize size;
      bool isOverridable;
      theme->GetMinimumWidgetSize(presContext, this, NS_THEME_SCROLLBAR, &size,
                                  &isOverridable);
      if (IsHorizontal()) {
        aMargin.top = -presContext->DevPixelsToAppUnits(size.height);
      }
      else {
        aMargin.left = -presContext->DevPixelsToAppUnits(size.width);
      }
      rv = NS_OK;
    }
  }

  if (NS_FAILED(rv)) {
    rv = nsBox::GetMargin(aMargin);
  }

  if (NS_SUCCEEDED(rv) && aSide == ScrollFrameHelper::eScrollbarOnLeft) {
    Swap(aMargin.left, aMargin.right);
  }

  return rv;
}
void
nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
                                               nsHTMLReflowMetrics& aDesiredSize,
                                               const nsHTMLReflowState& aReflowState,
                                               nsIFrame* aFirstKid,
                                               nsMargin aFocusPadding,
                                               nsReflowStatus& aStatus)
{
  nsSize availSize(aReflowState.ComputedWidth(), NS_INTRINSICSIZE);

  // Indent the child inside us by the focus border. We must do this separate
  // from the regular border.
  availSize.width -= aFocusPadding.LeftRight();
  
  // See whether out availSize's width is big enough.  If it's smaller than our
  // intrinsic min width, that means that the kid wouldn't really fit; for a
  // better look in such cases we adjust the available width and our left
  // offset to allow the kid to spill left into our padding.
  nscoord xoffset = aFocusPadding.left + aReflowState.mComputedBorderPadding.left;
  nscoord extrawidth = GetMinWidth(aReflowState.rendContext) -
    aReflowState.ComputedWidth();
  if (extrawidth > 0) {
    nscoord extraleft = extrawidth / 2;
    nscoord extraright = extrawidth - extraleft;
    NS_ASSERTION(extraright >=0, "How'd that happen?");
    
    // Do not allow the extras to be bigger than the relevant padding
    extraleft = std::min(extraleft, aReflowState.mComputedPadding.left);
    extraright = std::min(extraright, aReflowState.mComputedPadding.right);
    xoffset -= extraleft;
    availSize.width += extraleft + extraright;
  }
  availSize.width = std::max(availSize.width,0);
  
  nsHTMLReflowState reflowState(aPresContext, aReflowState, aFirstKid,
                                availSize);

  ReflowChild(aFirstKid, aPresContext, aDesiredSize, reflowState,
              xoffset,
              aFocusPadding.top + aReflowState.mComputedBorderPadding.top,
              0, aStatus);

  // Compute our desired height before vertically centering our children
  nscoord actualDesiredHeight = 0;
  if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
    actualDesiredHeight = aReflowState.ComputedHeight();
  } else {
    actualDesiredHeight = aDesiredSize.height + aFocusPadding.TopBottom();

    // Make sure we obey min/max-height in the case when we're doing intrinsic
    // sizing (we get it for free when we have a non-intrinsic
    // aReflowState.ComputedHeight()).  Note that we do this before adjusting
    // for borderpadding, since mComputedMaxHeight and mComputedMinHeight are
    // content heights.
    actualDesiredHeight = NS_CSS_MINMAX(actualDesiredHeight,
                                        aReflowState.mComputedMinHeight,
                                        aReflowState.mComputedMaxHeight);
  }

  // center child vertically in the content area
  nscoord yoff = (actualDesiredHeight - aFocusPadding.TopBottom() - aDesiredSize.height) / 2;
  if (yoff < 0) {
    yoff = 0;
  }

  // Place the child
  FinishReflowChild(aFirstKid, aPresContext, &reflowState, aDesiredSize,
                    xoffset,
                    yoff + aFocusPadding.top + aReflowState.mComputedBorderPadding.top, 0);

  if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE)
    aDesiredSize.ascent = aFirstKid->GetBaseline();

  // Adjust the baseline by our offset (since we moved the child's
  // baseline by that much), and set our actual desired height.
  aDesiredSize.ascent += yoff;
  aDesiredSize.height = actualDesiredHeight;
}
void
nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
                                               nsHTMLReflowMetrics& aButtonDesiredSize,
                                               const nsHTMLReflowState& aButtonReflowState,
                                               nsIFrame* aFirstKid)
{
  // Buttons have some bonus renderer-determined border/padding,
  // which occupies part of the button's content-box area:
  const nsMargin focusPadding = mRenderer.GetAddedButtonBorderAndPadding();

  WritingMode wm = aFirstKid->GetWritingMode();
  LogicalSize availSize = aButtonReflowState.ComputedSize(GetWritingMode());
  availSize.BSize(wm) = NS_INTRINSICSIZE;

  // Indent the child inside us by the focus border. We must do this separate
  // from the regular border.
  availSize.ISize(wm) -= LogicalMargin(wm, focusPadding).IStartEnd(wm);

  // See whether out availSize's width is big enough.  If it's smaller than our
  // intrinsic min width, that means that the kid wouldn't really fit; for a
  // better look in such cases we adjust the available width and our left
  // offset to allow the kid to spill left into our padding.
  nscoord xoffset = focusPadding.left +
    aButtonReflowState.ComputedPhysicalBorderPadding().left;
  nscoord extrawidth = GetMinISize(aButtonReflowState.rendContext) -
    aButtonReflowState.ComputedWidth();
  if (extrawidth > 0) {
    nscoord extraleft = extrawidth / 2;
    nscoord extraright = extrawidth - extraleft;
    NS_ASSERTION(extraright >=0, "How'd that happen?");

    // Do not allow the extras to be bigger than the relevant padding
    extraleft = std::min(extraleft, aButtonReflowState.ComputedPhysicalPadding().left);
    extraright = std::min(extraright, aButtonReflowState.ComputedPhysicalPadding().right);
    xoffset -= extraleft;
    availSize.Width(wm) = availSize.Width(wm) + extraleft + extraright;
  }
  availSize.Width(wm) = std::max(availSize.Width(wm), 0);

  // Give child a clone of the button's reflow state, with height/width reduced
  // by focusPadding, so that descendants with height:100% don't protrude.
  nsHTMLReflowState adjustedButtonReflowState =
    CloneReflowStateWithReducedContentBox(aButtonReflowState, focusPadding);

  nsHTMLReflowState contentsReflowState(aPresContext,
                                        adjustedButtonReflowState,
                                        aFirstKid, availSize);

  nsReflowStatus contentsReflowStatus;
  nsHTMLReflowMetrics contentsDesiredSize(aButtonReflowState);
  ReflowChild(aFirstKid, aPresContext,
              contentsDesiredSize, contentsReflowState,
              xoffset,
              focusPadding.top + aButtonReflowState.ComputedPhysicalBorderPadding().top,
              0, contentsReflowStatus);
  MOZ_ASSERT(NS_FRAME_IS_COMPLETE(contentsReflowStatus),
             "We gave button-contents frame unconstrained available height, "
             "so it should be complete");

  // Compute the button's content-box height:
  nscoord buttonContentBoxHeight = 0;
  if (aButtonReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
    // Button has a fixed height -- that's its content-box height.
    buttonContentBoxHeight = aButtonReflowState.ComputedHeight();
  } else {
    // Button is intrinsically sized -- it should shrinkwrap the
    // button-contents' height, plus any focus-padding space:
    buttonContentBoxHeight =
      contentsDesiredSize.Height() + focusPadding.TopBottom();

    // Make sure we obey min/max-height in the case when we're doing intrinsic
    // sizing (we get it for free when we have a non-intrinsic
    // aButtonReflowState.ComputedHeight()).  Note that we do this before
    // adjusting for borderpadding, since mComputedMaxHeight and
    // mComputedMinHeight are content heights.
    buttonContentBoxHeight =
      NS_CSS_MINMAX(buttonContentBoxHeight,
                    aButtonReflowState.ComputedMinHeight(),
                    aButtonReflowState.ComputedMaxHeight());
  }

  // Center child vertically in the button
  // (technically, inside of the button's focus-padding area)
  nscoord extraSpace =
    buttonContentBoxHeight - focusPadding.TopBottom() -
    contentsDesiredSize.Height();

  nscoord yoffset = std::max(0, extraSpace / 2);

  // Adjust yoffset to be in terms of the button's frame-rect, instead of
  // its focus-padding rect:
  yoffset += focusPadding.top + aButtonReflowState.ComputedPhysicalBorderPadding().top;

  // Place the child
  FinishReflowChild(aFirstKid, aPresContext,
                    contentsDesiredSize, &contentsReflowState,
                    xoffset, yoffset, 0);

  // Make sure we have a useful 'ascent' value for the child
  if (contentsDesiredSize.BlockStartAscent() ==
      nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
    WritingMode wm = aButtonReflowState.GetWritingMode();
    contentsDesiredSize.SetBlockStartAscent(aFirstKid->GetLogicalBaseline(wm));
  }

  // OK, we're done with the child frame.
  // Use what we learned to populate the button frame's reflow metrics.
  //  * Button's height & width are content-box size + border-box contribution:
  aButtonDesiredSize.Width() = aButtonReflowState.ComputedWidth() +
    aButtonReflowState.ComputedPhysicalBorderPadding().LeftRight();

  aButtonDesiredSize.Height() = buttonContentBoxHeight +
    aButtonReflowState.ComputedPhysicalBorderPadding().TopBottom();

  //  * Button's ascent is its child's ascent, plus the child's y-offset
  // within our frame:
  aButtonDesiredSize.SetBlockStartAscent(contentsDesiredSize.BlockStartAscent() +
                                         yoffset);

  aButtonDesiredSize.SetOverflowAreasToDesiredBounds();
}
void
nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
                                               nsHTMLReflowMetrics& aDesiredSize,
                                               const nsHTMLReflowState& aReflowState,
                                               nsIFrame* aFirstKid,
                                               nsMargin aFocusPadding,
                                               nsReflowStatus& aStatus)
{
  nsSize availSize(aReflowState.ComputedWidth(), NS_INTRINSICSIZE);

  // Indent the child inside us by the focus border. We must do this separate
  // from the regular border.
  availSize.width -= aFocusPadding.LeftRight();
  
  // See whether out availSize's width is big enough.  If it's smaller than our
  // intrinsic min width, that means that the kid wouldn't really fit; for a
  // better look in such cases we adjust the available width and our left
  // offset to allow the kid to spill left into our padding.
  nscoord xoffset = aFocusPadding.left + aReflowState.mComputedBorderPadding.left;
  nscoord extrawidth = GetMinWidth(aReflowState.rendContext) -
    aReflowState.ComputedWidth();
  if (extrawidth > 0) {
    nscoord extraleft = extrawidth / 2;
    nscoord extraright = extrawidth - extraleft;
    NS_ASSERTION(extraright >=0, "How'd that happen?");
    
    // Do not allow the extras to be bigger than the relevant padding
    extraleft = std::min(extraleft, aReflowState.mComputedPadding.left);
    extraright = std::min(extraright, aReflowState.mComputedPadding.right);
    xoffset -= extraleft;
    availSize.width += extraleft + extraright;
  }
  availSize.width = std::max(availSize.width,0);
  
  nsHTMLReflowState reflowState(aPresContext, aReflowState, aFirstKid,
                                availSize);

  ReflowChild(aFirstKid, aPresContext, aDesiredSize, reflowState,
              xoffset,
              aFocusPadding.top + aReflowState.mComputedBorderPadding.top,
              0, aStatus);
  
  // calculate the min internal height so the contents gets centered correctly.
  // XXXbz this assumes border-box sizing.
  nscoord minInternalHeight = aReflowState.mComputedMinHeight -
    aReflowState.mComputedBorderPadding.TopBottom();
  minInternalHeight = std::max(minInternalHeight, 0);

  // center child vertically
  nscoord yoff = 0;
  if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
    yoff = (aReflowState.ComputedHeight() - aDesiredSize.height)/2;
    if (yoff < 0) {
      yoff = 0;
    }
  } else if (aDesiredSize.height < minInternalHeight) {
    yoff = (minInternalHeight - aDesiredSize.height) / 2;
  }

  // Place the child
  FinishReflowChild(aFirstKid, aPresContext, &reflowState, aDesiredSize,
                    xoffset,
                    yoff + aFocusPadding.top + aReflowState.mComputedBorderPadding.top, 0);

  if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE)
    aDesiredSize.ascent = aFirstKid->GetBaseline();

  // Adjust the baseline by our offset (since we moved the child's
  // baseline by that much).
  aDesiredSize.ascent += yoff;
}
nsresult
nsGroupBoxFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding)
{
  aBorderAndPadding.SizeTo(0,0,0,0);
  return NS_OK;
}
Beispiel #16
0
NS_IMETHODIMP
nsGroupBoxFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding)
{
  aBorderAndPadding.SizeTo(0,0,0,0);
  return NS_OK;
}