Skip to content

Commit

Permalink
Bug 1393907 - Handle bevel borders. r=kats
Browse files Browse the repository at this point in the history
Since bevel only appear outmost border of table. I collect all bevel border
and combined them as a single border with four sides.

MozReview-Commit-ID: Bvu8Zf56YDF
  • Loading branch information
mephisto41 committed Jan 24, 2018
1 parent 47b9708 commit b2c0abd
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 13 deletions.
10 changes: 5 additions & 5 deletions layout/reftests/writing-mode/tables/reftest.list
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fuzzy-if(skiaContent,3,750) == vertical-table-2b.html vertical-table-2-ref.html
== vertical-table-colspan-2.html vertical-table-colspan-2-ref.html
== vertical-table-specified-width-1.html vertical-table-specified-width-1-ref.html
asserts(1) == vertical-table-specified-width-2.html vertical-table-specified-width-2-ref.html # bug 1179741
fuzzy-if(cocoaWidget,141,24) fails-if(webrender) == vertical-border-collapse-1.html vertical-border-collapse-1-ref.html # bug 1393907 for webrender
fuzzy-if(cocoaWidget,141,24) == vertical-border-collapse-1.html vertical-border-collapse-1-ref.html
fuzzy-if(cocoaWidget,141,24) fails-if(webrender) == vertical-border-collapse-2.html vertical-border-collapse-2-ref.html # bug 1393907 for webrender

== fixed-table-layout-002-vlr.html fixed-table-layout-002-ref.html
Expand Down Expand Up @@ -80,10 +80,10 @@ fuzzy-if(Android,244,27) == table-caption-left-1.html table-caption-left-1-ref.h
fuzzy-if(Android,244,27) == table-caption-right-1.html table-caption-right-1-ref.html

== border-collapse-bevels-1a.html border-collapse-bevels-1-ref.html
fuzzy-if(cocoaWidget,23,162) fails-if(webrender) == border-collapse-bevels-1b.html border-collapse-bevels-1-ref.html # bug 1393907 for webrender
fuzzy-if(cocoaWidget,23,162) fails-if(webrender) == border-collapse-bevels-1c.html border-collapse-bevels-1-ref.html # bug 1393907 for webrender
fuzzy-if(cocoaWidget,23,162) fails-if(webrender) == border-collapse-bevels-1d.html border-collapse-bevels-1-ref.html # bug 1393907 for webrender
fuzzy-if(cocoaWidget,23,162) fails-if(webrender) == border-collapse-bevels-1e.html border-collapse-bevels-1-ref.html # bug 1393907 for webrender
fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1b.html border-collapse-bevels-1-ref.html
fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1c.html border-collapse-bevels-1-ref.html
fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1d.html border-collapse-bevels-1-ref.html
fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1e.html border-collapse-bevels-1-ref.html

== vertical-rl-row-progression-1a.html vertical-rl-row-progression-1-ref.html
== vertical-rl-row-progression-1b.html vertical-rl-row-progression-1-ref.html
Expand Down
128 changes: 120 additions & 8 deletions layout/tables/nsTableFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6527,7 +6527,8 @@ struct BCBlockDirSeg
BCPixelSize aInlineSegBSize,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
const nsPoint& aPt);
const nsPoint& aPt,
Maybe<BCBorderParameters>* aBevelBorders);
void AdvanceOffsetB();
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);

Expand Down Expand Up @@ -6581,7 +6582,8 @@ struct BCInlineDirSeg
void CreateWebRenderCommands(BCPaintBorderIterator& aIter,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
const nsPoint& aPt);
const nsPoint& aPt,
Maybe<BCBorderParameters>* aBevelBorders);

nscoord mOffsetI; // i-offset with respect to the table edge
nscoord mOffsetB; // b-offset with respect to the table edge
Expand Down Expand Up @@ -6628,6 +6630,7 @@ struct BCCreateWebRenderCommandsData
wr::DisplayListBuilder& mBuilder;
const layers::StackingContextHelper& mSc;
const nsPoint& mOffsetToReferenceFrame;
Maybe<BCBorderParameters> mBevelBorders[4];
};

struct BCPaintBorderAction
Expand All @@ -6647,6 +6650,16 @@ struct BCPaintBorderAction
mMode = Mode::CREATE_WEBRENDER_COMMANDS;
}

~BCPaintBorderAction()
{
// mCreateWebRenderCommandsData is in a union which means the destructor
// wouldn't be called when BCPaintBorderAction get destroyed. So call the
// destructor here explicitly.
if (mMode == Mode::CREATE_WEBRENDER_COMMANDS) {
mCreateWebRenderCommandsData.~BCCreateWebRenderCommandsData();
}
}

enum class Mode {
PAINT,
CREATE_WEBRENDER_COMMANDS,
Expand Down Expand Up @@ -7459,17 +7472,45 @@ BCBlockDirSeg::CreateWebRenderCommands(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
const nsPoint& aOffset)
const nsPoint& aOffset,
Maybe<BCBorderParameters>* aBevelBorders)
{
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter, aInlineSegBSize);
if (param.isNothing()) {
return;
}

//TODO: Currently, we don't support border with m{Start,End}Bevel{Side,Offset} attributes.
if (param->mStartBevelOffset != 0 || param->mEndBevelOffset != 0) {
// If both bevel offsets are non zero, the parameters of two bevels should
// be the same. So we choose start bevel side here.
mozilla::Side bevelSide = param->mStartBevelOffset != 0 ? param->mStartBevelSide : param->mEndBevelSide;

// The left border is going to be beveled on its right edge because that's
// the edge that intersects other borders (in this case the top and bottom borders).
// Correspondingly, if the bevel side is "right" that means we are operating on
// the left border, and so store the parameters for that entry in aBevelBorders.
// Same goes for the other directions.
switch (bevelSide) {
case eSideTop:
aBevelBorders[eSideBottom] = param;
break;
case eSideBottom:
aBevelBorders[eSideTop] = param;
break;
case eSideLeft:
aBevelBorders[eSideRight] = param;
break;
case eSideRight:
aBevelBorders[eSideLeft] = param;
break;
}

return;
}

LayoutDeviceRect borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aOffset,
param->mAppUnitsPerDevPixel));

wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(borderRect);
wr::BorderSide wrSide[4];
NS_FOR_CSS_SIDES(i) {
Expand Down Expand Up @@ -7720,14 +7761,35 @@ void
BCInlineDirSeg::CreateWebRenderCommands(BCPaintBorderIterator& aIter,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
const nsPoint& aPt)
const nsPoint& aPt,
Maybe<BCBorderParameters>* aBevelBorders)
{
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter);
if (param.isNothing()) {
return;
}

//TODO: Currently, we don't support border with m{Start,End}Bevel{Side,Offset} attributes.
if (param->mStartBevelOffset != 0 || param->mEndBevelOffset != 0) {
mozilla::Side bevelSide = param->mStartBevelOffset != 0 ? param->mStartBevelSide : param->mEndBevelSide;

// See detailed comment on equivalent code in BCBlockDirSeg::CreateWebRenderCommands.
switch (bevelSide) {
case eSideTop:
aBevelBorders[eSideBottom] = param;
break;
case eSideBottom:
aBevelBorders[eSideTop] = param;
break;
case eSideLeft:
aBevelBorders[eSideRight] = param;
break;
case eSideRight:
aBevelBorders[eSideLeft] = param;
break;
}

return;
}

LayoutDeviceRect borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aPt,
param->mAppUnitsPerDevPixel));
Expand Down Expand Up @@ -7849,7 +7911,8 @@ BCPaintBorderIterator::AccumulateOrDoActionInlineDirSegment(BCPaintBorderAction&
mInlineSeg.CreateWebRenderCommands(*this,
aAction.mCreateWebRenderCommandsData.mBuilder,
aAction.mCreateWebRenderCommandsData.mSc,
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame);
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame,
aAction.mCreateWebRenderCommandsData.mBevelBorders);
}
}
mInlineSeg.AdvanceOffsetI();
Expand Down Expand Up @@ -7901,7 +7964,8 @@ BCPaintBorderIterator::AccumulateOrDoActionBlockDirSegment(BCPaintBorderAction&
inlineSegBSize,
aAction.mCreateWebRenderCommandsData.mBuilder,
aAction.mCreateWebRenderCommandsData.mSc,
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame);
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame,
aAction.mCreateWebRenderCommandsData.mBevelBorders);
}
}
blockDirSeg.AdvanceOffsetB();
Expand Down Expand Up @@ -7981,6 +8045,54 @@ nsTableFrame::CreateWebRenderCommandsForBCBorders(wr::DisplayListBuilder& aBuild
// We always draw whole table border for webrender. Passing the table rect as
// dirty rect.
IterateBCBorders(action, GetRect());

LayoutDeviceRect allBorderRect;
wr::BorderSide wrSide[4];
wr::BorderWidths wrWidths;
wr::BorderRadius borderRadii = wr::EmptyBorderRadius();
bool backfaceIsVisible = false;
NS_FOR_CSS_SIDES(side) {
auto param = action.mCreateWebRenderCommandsData.mBevelBorders[side];
LayoutDeviceRect borderRect;
nscolor borderColor = NS_RGBA(0, 0, 0, 255);
uint8_t borderStyle = NS_STYLE_BORDER_STYLE_NONE;
if (param.isSome()) {
borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aOffsetToReferenceFrame,
param->mAppUnitsPerDevPixel));
borderColor = param->mBorderColor;
borderStyle = param->mBorderStyle;
backfaceIsVisible |= param->mBackfaceIsVisible;
}

wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(borderRect);
allBorderRect = allBorderRect.Union(borderRect);
wrSide[side] = wr::ToBorderSide(ToDeviceColor(borderColor), borderStyle);
switch (side) {
case eSideTop:
wrWidths.top = transformedRect.size.height;
break;
case eSideBottom:
wrWidths.bottom = transformedRect.size.height;
break;
case eSideLeft:
wrWidths.left = transformedRect.size.width;
break;
case eSideRight:
wrWidths.right = transformedRect.size.width;
break;
}
}

if (!allBorderRect.IsEmpty()) {
Range<const wr::BorderSide> wrsides(wrSide, 4);
wr::LayoutRect allTransformedRect = aSc.ToRelativeLayoutRect(allBorderRect);
aBuilder.PushBorder(allTransformedRect,
allTransformedRect,
backfaceIsVisible,
wrWidths,
wrsides,
borderRadii);
}
}

bool
Expand Down

0 comments on commit b2c0abd

Please sign in to comment.