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(); }
nsRect nsFieldSetFrame::VisualBorderRectRelativeToSelf() const { WritingMode wm = GetWritingMode(); css::Side legendSide = wm.PhysicalSide(eLogicalSideBStart); nscoord legendBorder = StyleBorder()->GetComputedBorderWidth(legendSide); LogicalRect r(wm, LogicalPoint(wm, 0, 0), GetLogicalSize(wm)); nsSize containerSize = r.Size(wm).GetPhysicalSize(wm); if (legendBorder < mLegendRect.BSize(wm)) { nscoord off = (mLegendRect.BSize(wm) - legendBorder) / 2; r.BStart(wm) += off; r.BSize(wm) -= off; } return r.GetPhysicalRect(wm, containerSize); }
DrawResult nsFieldSetFrame::PaintBorderBackground( nsDisplayListBuilder* aBuilder, nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect) { // if the border is smaller than the legend. Move the border down // to be centered on the legend. // FIXME: This means border-radius clamping is incorrect; we should // override nsIFrame::GetBorderRadii. WritingMode wm = GetWritingMode(); nsRect rect = VisualBorderRectRelativeToSelf(); nscoord off = wm.IsVertical() ? rect.x : rect.y; rect += aPt; nsPresContext* presContext = PresContext(); uint32_t bgFlags = aBuilder->GetBackgroundPaintFlags(); PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages() ? PaintBorderFlags::SYNC_DECODE_IMAGES : PaintBorderFlags(); DrawResult result = nsCSSRendering::PaintBackground(presContext, aRenderingContext, this, aDirtyRect, rect, bgFlags); nsCSSRendering::PaintBoxShadowInner(presContext, aRenderingContext, this, rect, aDirtyRect); if (nsIFrame* legend = GetLegend()) { css::Side legendSide = wm.PhysicalSide(eLogicalSideBStart); nscoord legendBorderWidth = StyleBorder()->GetComputedBorderWidth(legendSide); // Use the rect of the legend frame, not mLegendRect, so we draw our // border under the legend's inline-start and -end margins. LogicalRect legendRect(wm, legend->GetRect() + aPt, rect.Size()); // Compute clipRect using logical coordinates, so that the legend space // will be clipped out of the appropriate physical side depending on mode. LogicalRect clipRect = LogicalRect(wm, rect, rect.Size()); DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); gfxContext* gfx = aRenderingContext.ThebesContext(); int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); // draw inline-start portion of the block-start side of the border clipRect.ISize(wm) = legendRect.IStart(wm) - clipRect.IStart(wm); clipRect.BSize(wm) = legendBorderWidth; gfx->Save(); gfx->Clip(NSRectToSnappedRect(clipRect.GetPhysicalRect(wm, rect.Size()), appUnitsPerDevPixel, *drawTarget)); result &= nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, borderFlags); gfx->Restore(); // draw inline-end portion of the block-start side of the border clipRect = LogicalRect(wm, rect, rect.Size()); clipRect.ISize(wm) = clipRect.IEnd(wm) - legendRect.IEnd(wm); clipRect.IStart(wm) = legendRect.IEnd(wm); clipRect.BSize(wm) = legendBorderWidth; gfx->Save(); gfx->Clip(NSRectToSnappedRect(clipRect.GetPhysicalRect(wm, rect.Size()), appUnitsPerDevPixel, *drawTarget)); result &= nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, borderFlags); gfx->Restore(); // draw remainder of the border (omitting the block-start side) clipRect = LogicalRect(wm, rect, rect.Size()); clipRect.BStart(wm) += legendBorderWidth; clipRect.BSize(wm) = BSize(wm) - (off + legendBorderWidth); gfx->Save(); gfx->Clip(NSRectToSnappedRect(clipRect.GetPhysicalRect(wm, rect.Size()), appUnitsPerDevPixel, *drawTarget)); result &= nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, borderFlags); gfx->Restore(); } else { result &= nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, nsRect(aPt, mRect.Size()), mStyleContext, borderFlags); } return result; }