コード例 #1
0
nscoord
nsFloatManager::FloatInfo::LineRight(WritingMode aWM,
                                     ShapeType aShapeType,
                                     const nscoord aBStart,
                                     const nscoord aBEnd) const
{
  if (aShapeType == ShapeType::Margin) {
    return LineRight();
  }

  MOZ_ASSERT(aShapeType == ShapeType::ShapeOutside);
  const StyleShapeOutside& shapeOutside = mFrame->StyleDisplay()->mShapeOutside;
  if (shapeOutside.GetType() == StyleShapeSourceType::None) {
    return LineRight();
  }

  if (shapeOutside.GetType() == StyleShapeSourceType::Box) {
    nscoord radii[8];
    bool hasRadii = mFrame->GetShapeBoxBorderRadii(radii);

    if (!hasRadii) {
      return ShapeBoxRect().XMost();
    }

    // Get the physical side for line-right since border-radii are in
    // the physical axis.
    mozilla::Side lineRightSide =
      aWM.PhysicalSide(aWM.LogicalSideForLineRelativeDir(eLineRelativeDirRight));
    nscoord blockStartCornerRadiusL =
      radii[SideToHalfCorner(lineRightSide, false, false)];
    nscoord blockStartCornerRadiusB =
      radii[SideToHalfCorner(lineRightSide, false, true)];
    nscoord blockEndCornerRadiusL =
      radii[SideToHalfCorner(lineRightSide, true, false)];
    nscoord blockEndCornerRadiusB =
      radii[SideToHalfCorner(lineRightSide, true, true)];

    if (aWM.IsLineInverted()) {
      // This happens only when aWM is vertical-lr. Need to swap blockStart
      // and blockEnd corners.
      std::swap(blockStartCornerRadiusL, blockEndCornerRadiusL);
      std::swap(blockStartCornerRadiusB, blockEndCornerRadiusB);
    }

    nscoord lineRightDiff =
      ComputeEllipseLineInterceptDiff(
        ShapeBoxRect().y, ShapeBoxRect().YMost(),
        blockStartCornerRadiusL, blockStartCornerRadiusB,
        blockEndCornerRadiusL, blockEndCornerRadiusB,
        aBStart, aBEnd);
    return ShapeBoxRect().XMost() - lineRightDiff;
  }

  // XXX: Other shape source types are not implemented yet.

  return LineRight();
}
コード例 #2
0
void
nsTextControlFrame::Reflow(nsPresContext*   aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
                           nsReflowStatus&          aStatus)
{
  MarkInReflow();
  DO_GLOBAL_REFLOW_COUNT("nsTextControlFrame");
  DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);

  // make sure that the form registers itself on the initial/first reflow
  if (mState & NS_FRAME_FIRST_REFLOW) {
    nsFormControlFrame::RegUnRegAccessKey(this, true);
  }

  // set values of reflow's out parameters
  WritingMode wm = aReflowState.GetWritingMode();
  LogicalSize
    finalSize(wm,
              aReflowState.ComputedISize() +
              aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm),
              aReflowState.ComputedBSize() +
              aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm));
  aDesiredSize.SetSize(wm, finalSize);

  // computation of the ascent wrt the input height
  nscoord lineHeight = aReflowState.ComputedBSize();
  float inflation = nsLayoutUtils::FontSizeInflationFor(this);
  if (!IsSingleLineTextControl()) {
    lineHeight = nsHTMLReflowState::CalcLineHeight(GetContent(), StyleContext(),
                                                   NS_AUTOHEIGHT, inflation);
  }
  RefPtr<nsFontMetrics> fontMet;
  nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet),
                                        inflation);
  // now adjust for our borders and padding
  aDesiredSize.SetBlockStartAscent(
    nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight,
                                           wm.IsLineInverted()) +
    aReflowState.ComputedLogicalBorderPadding().BStart(wm));

  // overflow handling
  aDesiredSize.SetOverflowAreasToDesiredBounds();
  // perform reflow on all kids
  nsIFrame* kid = mFrames.FirstChild();
  while (kid) {
    ReflowTextControlChild(kid, aPresContext, aReflowState, aStatus, aDesiredSize);
    kid = kid->GetNextSibling();
  }

  // take into account css properties that affect overflow handling
  FinishAndStoreOverflow(&aDesiredSize);

  aStatus = NS_FRAME_COMPLETE;
  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
}
コード例 #3
0
nscoord
nsFormControlFrame::GetLogicalBaseline(WritingMode aWritingMode) const
{
  NS_ASSERTION(!NS_SUBTREE_DIRTY(this),
               "frame must not be dirty");
  // Treat radio buttons and checkboxes as having an intrinsic baseline
  // at the block-end of the control (use the block-end content edge rather
  // than the margin edge).
  // For "inverted" lines (typically in writing-mode:vertical-lr), use the
  // block-start end instead.
  return aWritingMode.IsLineInverted()
    ? GetLogicalUsedBorderAndPadding(aWritingMode).BStart(aWritingMode)
    : BSize(aWritingMode) -
         GetLogicalUsedBorderAndPadding(aWritingMode).BEnd(aWritingMode);
}
コード例 #4
0
ファイル: nsCaret.cpp プロジェクト: Nazi-Nigger/gecko-dev
void
nsCaret::ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset,
                           nsRect* aCaretRect, nsRect* aHookRect)
{
  NS_ASSERTION(aFrame, "Should have a frame here");

  WritingMode wm = aFrame->GetWritingMode();
  bool isVertical = wm.IsVertical();

  nscoord bidiIndicatorSize;
  *aCaretRect = GetGeometryForFrame(aFrame, aFrameOffset, &bidiIndicatorSize);

  // on RTL frames the right edge of mCaretRect must be equal to framePos
  const nsStyleVisibility* vis = aFrame->StyleVisibility();
  if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
    if (isVertical) {
      aCaretRect->y -= aCaretRect->height;
    } else {
      aCaretRect->x -= aCaretRect->width;
    }
  }

  // Simon -- make a hook to draw to the left or right of the caret to show keyboard language direction
  aHookRect->SetEmpty();
  if (!IsBidiUI()) {
    return;
  }

  bool isCaretRTL;
  nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard();
  // if bidiKeyboard->IsLangRTL() fails, there is no way to tell the
  // keyboard direction, or the user has no right-to-left keyboard
  // installed, so we never draw the hook.
  if (bidiKeyboard && NS_SUCCEEDED(bidiKeyboard->IsLangRTL(&isCaretRTL))) {
    // If keyboard language is RTL, draw the hook on the left; if LTR, to the right
    // The height of the hook rectangle is the same as the width of the caret
    // rectangle.
    if (isVertical) {
      bool isSidewaysLR = wm.IsVerticalLR() && !wm.IsLineInverted();
      if (isSidewaysLR) {
        aHookRect->SetRect(aCaretRect->x + bidiIndicatorSize,
                           aCaretRect->y + (!isCaretRTL ? bidiIndicatorSize * -1 :
                                                          aCaretRect->height),
                           aCaretRect->height,
                           bidiIndicatorSize);
      } else {
        aHookRect->SetRect(aCaretRect->XMost() - bidiIndicatorSize,
                           aCaretRect->y + (isCaretRTL ? bidiIndicatorSize * -1 :
                                                         aCaretRect->height),
                           aCaretRect->height,
                           bidiIndicatorSize);
      }
    } else {
      aHookRect->SetRect(aCaretRect->x + (isCaretRTL ? bidiIndicatorSize * -1 :
                                                       aCaretRect->width),
                         aCaretRect->y + bidiIndicatorSize,
                         bidiIndicatorSize,
                         aCaretRect->width);
    }
  }
}
コード例 #5
0
ファイル: nsCaret.cpp プロジェクト: Nazi-Nigger/gecko-dev
/* static */ nsRect
nsCaret::GetGeometryForFrame(nsIFrame* aFrame,
                             int32_t   aFrameOffset,
                             nscoord*  aBidiIndicatorSize)
{
  nsPoint framePos(0, 0);
  nsRect rect;
  nsresult rv = aFrame->GetPointFromOffset(aFrameOffset, &framePos);
  if (NS_FAILED(rv)) {
    if (aBidiIndicatorSize) {
      *aBidiIndicatorSize = 0;
    }
    return rect;
  }

  nsIFrame* frame = aFrame->GetContentInsertionFrame();
  if (!frame) {
    frame = aFrame;
  }
  NS_ASSERTION(!(frame->GetStateBits() & NS_FRAME_IN_REFLOW),
               "We should not be in the middle of reflow");
  nscoord baseline = frame->GetCaretBaseline();
  nscoord ascent = 0, descent = 0;
  RefPtr<nsFontMetrics> fm;
  nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm),
    nsLayoutUtils::FontSizeInflationFor(aFrame));
  NS_ASSERTION(fm, "We should be able to get the font metrics");
  if (fm) {
    ascent = fm->MaxAscent();
    descent = fm->MaxDescent();
  }
  nscoord height = ascent + descent;
  WritingMode wm = aFrame->GetWritingMode();
  bool vertical = wm.IsVertical();
  if (vertical) {
    if (wm.IsLineInverted()) {
      framePos.x = baseline - descent;
    } else {
      framePos.x = baseline - ascent;
    }
  } else {
    framePos.y = baseline - ascent;
  }
  Metrics caretMetrics = ComputeMetrics(aFrame, aFrameOffset, height);
  rect = nsRect(framePos, vertical ? nsSize(height, caretMetrics.mCaretWidth) :
                                     nsSize(caretMetrics.mCaretWidth, height));

  // Clamp the inline-position to be within our scroll frame. If we don't, then
  // it clips us, and we don't appear at all. See bug 335560.
  nsIFrame *scrollFrame =
    nsLayoutUtils::GetClosestFrameOfType(aFrame, nsGkAtoms::scrollFrame);
  if (scrollFrame) {
    // First, use the scrollFrame to get at the scrollable view that we're in.
    nsIScrollableFrame *sf = do_QueryFrame(scrollFrame);
    nsIFrame *scrolled = sf->GetScrolledFrame();
    nsRect caretInScroll = rect + aFrame->GetOffsetTo(scrolled);

    // Now see if the caret extends beyond the view's bounds. If it does,
    // then snap it back, put it as close to the edge as it can.
    if (vertical) {
      nscoord overflow = caretInScroll.YMost() -
        scrolled->GetVisualOverflowRectRelativeToSelf().height;
      if (overflow > 0) {
        rect.y -= overflow;
      }
    } else {
      nscoord overflow = caretInScroll.XMost() -
        scrolled->GetVisualOverflowRectRelativeToSelf().width;
      if (overflow > 0) {
        rect.x -= overflow;
      }
    }
  }

  if (aBidiIndicatorSize) {
    *aBidiIndicatorSize = caretMetrics.mBidiIndicatorSize;
  }
  return rect;
}
コード例 #6
0
ファイル: nsBRFrame.cpp プロジェクト: cstipkovic/gecko-dev
void
BRFrame::Reflow(nsPresContext* aPresContext,
                ReflowOutput& aMetrics,
                const ReflowInput& aReflowInput,
                nsReflowStatus& aStatus)
{
  MarkInReflow();
  DO_GLOBAL_REFLOW_COUNT("BRFrame");
  DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
  WritingMode wm = aReflowInput.GetWritingMode();
  LogicalSize finalSize(wm);
  finalSize.BSize(wm) = 0; // BR frames with block size 0 are ignored in quirks
                           // mode by nsLineLayout::VerticalAlignFrames .
                           // However, it's not always 0.  See below.
  finalSize.ISize(wm) = 0;
  aMetrics.SetBlockStartAscent(0);

  // Only when the BR is operating in a line-layout situation will it
  // behave like a BR. Additionally, we suppress breaks from BR inside
  // of ruby frames. To determine if we're inside ruby, we have to rely
  // on the *parent's* ShouldSuppressLineBreak() method, instead of our
  // own, because we may have custom "display" value that makes our
  // ShouldSuppressLineBreak() return false.
  nsLineLayout* ll = aReflowInput.mLineLayout;
  if (ll && !GetParent()->StyleContext()->ShouldSuppressLineBreak()) {
    // Note that the compatibility mode check excludes AlmostStandards
    // mode, since this is the inline box model.  See bug 161691.
    if ( ll->LineIsEmpty() ||
         aPresContext->CompatibilityMode() == eCompatibility_FullStandards ) {
      // The line is logically empty; any whitespace is trimmed away.
      //
      // If this frame is going to terminate the line we know
      // that nothing else will go on the line. Therefore, in this
      // case, we provide some height for the BR frame so that it
      // creates some vertical whitespace.  It's necessary to use the
      // line-height rather than the font size because the
      // quirks-mode fix that doesn't apply the block's min
      // line-height makes this necessary to make BR cause a line
      // of the full line-height

      // We also do this in strict mode because BR should act like a
      // normal inline frame.  That line-height is used is important
      // here for cases where the line-height is less than 1.
      RefPtr<nsFontMetrics> fm =
        nsLayoutUtils::GetInflatedFontMetricsForFrame(this);
      if (fm) {
        nscoord logicalHeight = aReflowInput.CalcLineHeight();
        finalSize.BSize(wm) = logicalHeight;
        aMetrics.SetBlockStartAscent(nsLayoutUtils::GetCenteredFontBaseline(
                                       fm, logicalHeight, wm.IsLineInverted()));
      }
      else {
        aMetrics.SetBlockStartAscent(aMetrics.BSize(wm) = 0);
      }

      // XXX temporary until I figure out a better solution; see the
      // code in nsLineLayout::VerticalAlignFrames that zaps minY/maxY
      // if the width is zero.
      // XXX This also fixes bug 10036!
      // Warning: nsTextControlFrame::CalculateSizeStandard depends on
      // the following line, see bug 228752.
      // The code below in AddInlinePrefISize also adds 1 appunit to width
      finalSize.ISize(wm) = 1;
    }

    // Return our reflow status
    uint32_t breakType = aReflowInput.mStyleDisplay->PhysicalBreakType(wm);
    if (NS_STYLE_CLEAR_NONE == breakType) {
      breakType = NS_STYLE_CLEAR_LINE;
    }

    aStatus = NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER |
      NS_INLINE_MAKE_BREAK_TYPE(breakType);
    ll->SetLineEndsInBR(true);
  }
  else {
    aStatus = NS_FRAME_COMPLETE;
  }

  aMetrics.SetSize(wm, finalSize);
  aMetrics.SetOverflowAreasToDesiredBounds();

  mAscent = aMetrics.BlockStartAscent();

  NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics);
}