зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1344082 - Create webrender commands for nsDisplayTableBorderCollapse. r=mstange
Gecko only draw one line for each collapsed border. In order to draw only one line border in webrender, I create normal border webrender command but only show top side of border for inline direction and left side for block direction. MozReview-Commit-ID: 7QChXuzVbg7
This commit is contained in:
Родитель
5068b9bf11
Коммит
cef7414265
|
@ -505,6 +505,7 @@ private:
|
|||
DECL_GFX_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, bool, false);
|
||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender());
|
||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.solid-color", LayersAllowSolidColorLayers, gfxPrefs::OverrideBase_WebRender());
|
||||
DECL_GFX_PREF(Live, "layers.advanced.table", LayersAllowTable, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.text-layers", LayersAllowTextLayers, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
|
||||
|
|
|
@ -27,6 +27,8 @@ UNIFIED_SOURCES += [
|
|||
'SpanningCellSorter.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
|
@ -49,6 +49,10 @@
|
|||
#include "nsStyleChangeList.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
#include "mozilla/layers/WebRenderDisplayItemLayer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::image;
|
||||
using namespace mozilla::layout;
|
||||
|
@ -1270,6 +1274,16 @@ public:
|
|||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx) override;
|
||||
virtual already_AddRefed<layers::Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aContainerParameters) override;
|
||||
virtual void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const StackingContextHelper& aSc,
|
||||
nsTArray<WebRenderParentCommand>& aParentCommands,
|
||||
WebRenderDisplayItemLayer* aLayer) override;
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters) override;
|
||||
NS_DISPLAY_DECL_NAME("TableBorderCollapse", TYPE_TABLE_BORDER_COLLAPSE)
|
||||
};
|
||||
|
||||
|
@ -1292,6 +1306,39 @@ nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder,
|
|||
static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt);
|
||||
}
|
||||
|
||||
already_AddRefed<layers::Layer>
|
||||
nsDisplayTableBorderCollapse::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aContainerParameters)
|
||||
{
|
||||
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayTableBorderCollapse::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const StackingContextHelper& aSc,
|
||||
nsTArray<WebRenderParentCommand>& aParentCommands,
|
||||
WebRenderDisplayItemLayer* aLayer)
|
||||
{
|
||||
static_cast<nsTableFrame*>(mFrame)->CreateWebRenderCommandsForBCBorders(aBuilder,
|
||||
aSc,
|
||||
aParentCommands,
|
||||
aLayer,
|
||||
ToReferenceFrame());
|
||||
}
|
||||
|
||||
LayerState
|
||||
nsDisplayTableBorderCollapse::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters)
|
||||
{
|
||||
if (gfxPrefs::LayersAllowTable()) {
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
return LAYER_NONE;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
|
||||
const nsRect& aDirtyRect, const nsDisplayListSet& aLists)
|
||||
|
@ -6315,6 +6362,19 @@ nsTableFrame::CalcBCBorders()
|
|||
|
||||
class BCPaintBorderIterator;
|
||||
|
||||
struct BCBorderParameters
|
||||
{
|
||||
uint8_t mBorderStyle;
|
||||
nscolor mBorderColor;
|
||||
nscolor mBGColor;
|
||||
nsRect mBorderRect;
|
||||
int32_t mAppUnitsPerDevPixel;
|
||||
uint8_t mStartBevelSide;
|
||||
nscoord mStartBevelOffset;
|
||||
uint8_t mEndBevelSide;
|
||||
nscoord mEndBevelOffset;
|
||||
};
|
||||
|
||||
struct BCBlockDirSeg
|
||||
{
|
||||
BCBlockDirSeg();
|
||||
|
@ -6328,10 +6388,18 @@ struct BCBlockDirSeg
|
|||
void GetBEndCorner(BCPaintBorderIterator& aIter,
|
||||
BCPixelSize aInlineSegBSize);
|
||||
|
||||
|
||||
Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter,
|
||||
BCPixelSize aInlineSegBSize);
|
||||
void Paint(BCPaintBorderIterator& aIter,
|
||||
DrawTarget& aDrawTarget,
|
||||
BCPixelSize aInlineSegBSize);
|
||||
void CreateWebRenderCommands(BCPaintBorderIterator& aIter,
|
||||
BCPixelSize aInlineSegBSize,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
const layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aPt);
|
||||
void AdvanceOffsetB();
|
||||
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
|
||||
|
||||
|
@ -6380,7 +6448,14 @@ struct BCInlineDirSeg
|
|||
BCPixelSize aIStartSegISize);
|
||||
void AdvanceOffsetI();
|
||||
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
|
||||
Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter);
|
||||
void Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget);
|
||||
void CreateWebRenderCommands(BCPaintBorderIterator& aIter,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
const layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aPt);
|
||||
|
||||
nscoord mOffsetI; // i-offset with respect to the table edge
|
||||
nscoord mOffsetB; // b-offset with respect to the table edge
|
||||
|
@ -6403,6 +6478,70 @@ struct BCInlineDirSeg
|
|||
// the owner of a segment
|
||||
};
|
||||
|
||||
struct BCPaintData
|
||||
{
|
||||
explicit BCPaintData(DrawTarget& aDrawTarget)
|
||||
: mDrawTarget(aDrawTarget)
|
||||
{
|
||||
}
|
||||
|
||||
DrawTarget& mDrawTarget;
|
||||
};
|
||||
|
||||
struct BCCreateWebRenderCommandsData
|
||||
{
|
||||
BCCreateWebRenderCommandsData(wr::DisplayListBuilder& aBuilder,
|
||||
const layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aOffsetToReferenceFrame)
|
||||
: mBuilder(aBuilder)
|
||||
, mSc(aSc)
|
||||
, mParentCommands(aParentCommands)
|
||||
, mLayer(aLayer)
|
||||
, mOffsetToReferenceFrame(aOffsetToReferenceFrame)
|
||||
{
|
||||
}
|
||||
|
||||
wr::DisplayListBuilder& mBuilder;
|
||||
const layers::StackingContextHelper& mSc;
|
||||
nsTArray<layers::WebRenderParentCommand>& mParentCommands;
|
||||
layers::WebRenderDisplayItemLayer* mLayer;
|
||||
const nsPoint& mOffsetToReferenceFrame;
|
||||
};
|
||||
|
||||
struct BCPaintBorderAction
|
||||
{
|
||||
explicit BCPaintBorderAction(DrawTarget& aDrawTarget)
|
||||
: mMode(Mode::PAINT)
|
||||
, mPaintData(aDrawTarget)
|
||||
{
|
||||
}
|
||||
|
||||
BCPaintBorderAction(wr::DisplayListBuilder& aBuilder,
|
||||
const layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aOffsetToReferenceFrame)
|
||||
: mMode(Mode::CREATE_WEBRENDER_COMMANDS)
|
||||
, mCreateWebRenderCommandsData(aBuilder, aSc, aParentCommands, aLayer, aOffsetToReferenceFrame)
|
||||
{
|
||||
mMode = Mode::CREATE_WEBRENDER_COMMANDS;
|
||||
}
|
||||
|
||||
enum class Mode {
|
||||
PAINT,
|
||||
CREATE_WEBRENDER_COMMANDS,
|
||||
};
|
||||
|
||||
Mode mMode;
|
||||
|
||||
union {
|
||||
BCPaintData mPaintData;
|
||||
BCCreateWebRenderCommandsData mCreateWebRenderCommandsData;
|
||||
};
|
||||
};
|
||||
|
||||
// Iterates over borders (iStart border, corner, bStart border) in the cell map within a damage area
|
||||
// from iStart to iEnd, bStart to bEnd. All members are in terms of the 1st in flow frames, except
|
||||
// where suffixed by InFlow.
|
||||
|
@ -6424,8 +6563,8 @@ public:
|
|||
bool SetDamageArea(const nsRect& aDamageRect);
|
||||
void First();
|
||||
void Next();
|
||||
void AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget);
|
||||
void AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget);
|
||||
void AccumulateOrDoActionInlineDirSegment(BCPaintBorderAction& aAction);
|
||||
void AccumulateOrDoActionBlockDirSegment(BCPaintBorderAction& aAction);
|
||||
void ResetVerInfo();
|
||||
void StoreColumnWidth(int32_t aIndex);
|
||||
bool BlockDirSegmentOwnsCorner();
|
||||
|
@ -7048,31 +7187,26 @@ BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter,
|
|||
mLength += mBEndOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint the block-dir segment
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aDrawTarget - the draw target
|
||||
* @param aInlineSegBSize - the width of the inline-dir segment joining the
|
||||
* corner at the start
|
||||
*/
|
||||
void
|
||||
BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
DrawTarget& aDrawTarget,
|
||||
Maybe<BCBorderParameters>
|
||||
BCBlockDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter,
|
||||
BCPixelSize aInlineSegBSize)
|
||||
{
|
||||
BCBorderParameters result;
|
||||
|
||||
// get the border style, color and paint the segment
|
||||
LogicalSide side =
|
||||
aIter.IsDamageAreaIEndMost() ? eLogicalSideIEnd : eLogicalSideIStart;
|
||||
int32_t relColIndex = aIter.GetRelativeColIndex();
|
||||
nsTableColFrame* col = mCol; if (!col) ABORT0();
|
||||
nsTableColFrame* col = mCol; if (!col) ABORT1(Nothing());
|
||||
nsTableCellFrame* cell = mFirstCell; // ???
|
||||
nsIFrame* owner = nullptr;
|
||||
uint8_t style = NS_STYLE_BORDER_STYLE_SOLID;
|
||||
nscolor color = 0xFFFFFFFF;
|
||||
result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID;
|
||||
result.mBorderColor = 0xFFFFFFFF;
|
||||
result.mBGColor = aIter.mTableBgColor;
|
||||
|
||||
// All the tables frames have the same presContext, so we just use any one
|
||||
// that exists here:
|
||||
int32_t appUnitsPerDevPixel = col->PresContext()->AppUnitsPerDevPixel();
|
||||
result.mAppUnitsPerDevPixel = col->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
switch (mOwner) {
|
||||
case eTableOwner:
|
||||
|
@ -7123,7 +7257,7 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
|||
break;
|
||||
}
|
||||
if (owner) {
|
||||
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &style, &color);
|
||||
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle, &result.mBorderColor);
|
||||
}
|
||||
BCPixelSize smallHalf, largeHalf;
|
||||
DivideBCBorderSize(mWidth, smallHalf, largeHalf);
|
||||
|
@ -7138,17 +7272,16 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
|||
|
||||
// Convert logical to physical sides/coordinates for DrawTableBorderSegment.
|
||||
|
||||
nsRect physicalRect = segRect.GetPhysicalRect(aIter.mTableWM,
|
||||
aIter.mTable->GetSize());
|
||||
result.mBorderRect = segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize());
|
||||
// XXX For reversed vertical writing-modes (with direction:rtl), we need to
|
||||
// invert physicalRect's y-position here, with respect to the table.
|
||||
// However, it's not worth fixing the border positions here until the
|
||||
// ordering of the table columns themselves is also fixed (bug 1180528).
|
||||
|
||||
uint8_t startBevelSide = aIter.mTableWM.PhysicalSide(mBStartBevelSide);
|
||||
uint8_t endBevelSide = aIter.mTableWM.PhysicalSide(bEndBevelSide);
|
||||
nscoord startBevelOffset = mBStartBevelOffset;
|
||||
nscoord endBevelOffset = bEndBevelOffset;
|
||||
result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mBStartBevelSide);
|
||||
result.mEndBevelSide = aIter.mTableWM.PhysicalSide(bEndBevelSide);
|
||||
result.mStartBevelOffset = mBStartBevelOffset;
|
||||
result.mEndBevelOffset = bEndBevelOffset;
|
||||
// In vertical-rl mode, the 'start' and 'end' of the block-dir (horizontal)
|
||||
// border segment need to be swapped because DrawTableBorderSegment will
|
||||
// apply the 'start' bevel at the left edge, and 'end' at the right.
|
||||
|
@ -7160,15 +7293,78 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
|||
// end of the border-segment. We've got them reversed, since our block dir
|
||||
// is RTL, so we have to swap them here.)
|
||||
if (aIter.mTableWM.IsVerticalRL()) {
|
||||
Swap(startBevelSide, endBevelSide);
|
||||
Swap(startBevelOffset, endBevelOffset);
|
||||
Swap(result.mStartBevelSide, result.mEndBevelSide);
|
||||
Swap(result.mStartBevelOffset, result.mEndBevelOffset);
|
||||
}
|
||||
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color,
|
||||
aIter.mTableBgColor, physicalRect,
|
||||
appUnitsPerDevPixel,
|
||||
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint the block-dir segment
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aDrawTarget - the draw target
|
||||
* @param aInlineSegBSize - the width of the inline-dir segment joining the
|
||||
* corner at the start
|
||||
*/
|
||||
void
|
||||
BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
|
||||
DrawTarget& aDrawTarget,
|
||||
BCPixelSize aInlineSegBSize)
|
||||
{
|
||||
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter, aInlineSegBSize);
|
||||
if (param.isNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, param->mBorderStyle, param->mBorderColor,
|
||||
param->mBGColor, param->mBorderRect,
|
||||
param->mAppUnitsPerDevPixel,
|
||||
nsPresContext::AppUnitsPerCSSPixel(),
|
||||
startBevelSide, startBevelOffset,
|
||||
endBevelSide, endBevelOffset);
|
||||
param->mStartBevelSide, param->mStartBevelOffset,
|
||||
param->mEndBevelSide, param->mEndBevelOffset);
|
||||
}
|
||||
|
||||
void
|
||||
BCBlockDirSeg::CreateWebRenderCommands(BCPaintBorderIterator& aIter,
|
||||
BCPixelSize aInlineSegBSize,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
const layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aOffset)
|
||||
{
|
||||
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.
|
||||
|
||||
LayoutDeviceRect borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aOffset,
|
||||
param->mAppUnitsPerDevPixel));
|
||||
WrRect transformedRect = aSc.ToRelativeWrRect(borderRect);
|
||||
WrBorderSide wrSide[4];
|
||||
NS_FOR_CSS_SIDES(i) {
|
||||
wrSide[i] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), NS_STYLE_BORDER_STYLE_NONE);
|
||||
}
|
||||
wrSide[eSideLeft] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), param->mBorderStyle);
|
||||
|
||||
WrBorderRadius borderRadii = wr::ToWrBorderRadius( {0, 0}, {0, 0}, {0, 0}, {0, 0} );
|
||||
|
||||
// All border style is set to none except left side. So setting the widths of
|
||||
// each side to width of rect is fine.
|
||||
WrBorderWidths borderWidths = wr::ToWrBorderWidths(transformedRect.width,
|
||||
transformedRect.width,
|
||||
transformedRect.width,
|
||||
transformedRect.width);
|
||||
WrClipRegionToken clipRegion = aBuilder.PushClipRegion(transformedRect);
|
||||
transformedRect.width *= 2.0f;
|
||||
aBuilder.PushBorder(transformedRect,
|
||||
clipRegion,
|
||||
borderWidths,
|
||||
wrSide[0], wrSide[1], wrSide[2], wrSide[3],
|
||||
borderRadii);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7263,29 +7459,27 @@ BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter,
|
|||
mIEndBevelSide = (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint the inline-dir segment
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
||||
Maybe<BCBorderParameters>
|
||||
BCInlineDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter)
|
||||
{
|
||||
BCBorderParameters result;
|
||||
|
||||
// get the border style, color and paint the segment
|
||||
LogicalSide side =
|
||||
aIter.IsDamageAreaBEndMost() ? eLogicalSideBEnd : eLogicalSideBStart;
|
||||
nsIFrame* rg = aIter.mRg; if (!rg) ABORT0();
|
||||
nsIFrame* row = aIter.mRow; if (!row) ABORT0();
|
||||
nsIFrame* rg = aIter.mRg; if (!rg) ABORT1(Nothing());
|
||||
nsIFrame* row = aIter.mRow; if (!row) ABORT1(Nothing());
|
||||
nsIFrame* cell = mFirstCell;
|
||||
nsIFrame* col;
|
||||
nsIFrame* owner = nullptr;
|
||||
|
||||
// All the tables frames have the same presContext, so we just use any one
|
||||
// that exists here:
|
||||
int32_t appUnitsPerDevPixel = row->PresContext()->AppUnitsPerDevPixel();
|
||||
result.mAppUnitsPerDevPixel = row->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
uint8_t style = NS_STYLE_BORDER_STYLE_SOLID;
|
||||
nscolor color = 0xFFFFFFFF;
|
||||
result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID;
|
||||
result.mBorderColor = 0xFFFFFFFF;
|
||||
result.mBGColor = aIter.mTableBgColor;
|
||||
|
||||
switch (mOwner) {
|
||||
case eTableOwner:
|
||||
|
@ -7298,7 +7492,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
|||
NS_ASSERTION(aIter.IsTableBStartMost() || aIter.IsTableBEndMost(),
|
||||
"col group can own border only at the table edge");
|
||||
col = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1);
|
||||
if (!col) ABORT0();
|
||||
if (!col) ABORT1(Nothing());
|
||||
owner = col->GetParent();
|
||||
break;
|
||||
case eAjaColOwner:
|
||||
|
@ -7334,7 +7528,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
|||
break;
|
||||
}
|
||||
if (owner) {
|
||||
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &style, &color);
|
||||
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle, &result.mBorderColor);
|
||||
}
|
||||
BCPixelSize smallHalf, largeHalf;
|
||||
DivideBCBorderSize(mWidth, smallHalf, largeHalf);
|
||||
|
@ -7344,13 +7538,12 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
|||
nsPresContext::CSSPixelsToAppUnits(mWidth));
|
||||
|
||||
// Convert logical to physical sides/coordinates for DrawTableBorderSegment.
|
||||
nsRect physicalRect = segRect.GetPhysicalRect(aIter.mTableWM,
|
||||
aIter.mTable->GetSize());
|
||||
uint8_t startBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide);
|
||||
uint8_t endBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide);
|
||||
nscoord startBevelOffset =
|
||||
result.mBorderRect = segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize());
|
||||
result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide);
|
||||
result.mEndBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide);
|
||||
result.mStartBevelOffset =
|
||||
nsPresContext::CSSPixelsToAppUnits(mIStartBevelOffset);
|
||||
nscoord endBevelOffset = mIEndBevelOffset;
|
||||
result.mEndBevelOffset = mIEndBevelOffset;
|
||||
// With inline-RTL directionality, the 'start' and 'end' of the inline-dir
|
||||
// border segment need to be swapped because DrawTableBorderSegment will
|
||||
// apply the 'start' bevel physically at the left or top edge, and 'end' at
|
||||
|
@ -7364,15 +7557,73 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
|||
// "end" will be reversed from this physical-coord view, so we have to swap
|
||||
// them here.
|
||||
if (!aIter.mTableWM.IsBidiLTR()) {
|
||||
Swap(startBevelSide, endBevelSide);
|
||||
Swap(startBevelOffset, endBevelOffset);
|
||||
Swap(result.mStartBevelSide, result.mEndBevelSide);
|
||||
Swap(result.mStartBevelOffset, result.mEndBevelOffset);
|
||||
}
|
||||
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color,
|
||||
aIter.mTableBgColor, physicalRect,
|
||||
appUnitsPerDevPixel,
|
||||
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint the inline-dir segment
|
||||
* @param aIter - iterator containing the structural information
|
||||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
|
||||
{
|
||||
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter);
|
||||
if (param.isNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, param->mBorderStyle, param->mBorderColor,
|
||||
param->mBGColor, param->mBorderRect,
|
||||
param->mAppUnitsPerDevPixel,
|
||||
nsPresContext::AppUnitsPerCSSPixel(),
|
||||
startBevelSide, startBevelOffset,
|
||||
endBevelSide, endBevelOffset);
|
||||
param->mStartBevelSide, param->mStartBevelOffset,
|
||||
param->mEndBevelSide, param->mEndBevelOffset);
|
||||
}
|
||||
|
||||
void
|
||||
BCInlineDirSeg::CreateWebRenderCommands(BCPaintBorderIterator& aIter,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
const layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aPt)
|
||||
{
|
||||
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter);
|
||||
if (param.isNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: Currently, we don't support border with m{Start,End}Bevel{Side,Offset} attributes.
|
||||
|
||||
LayoutDeviceRect borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aPt,
|
||||
param->mAppUnitsPerDevPixel));
|
||||
WrRect transformedRect = aSc.ToRelativeWrRect(borderRect);
|
||||
WrBorderSide wrSide[4];
|
||||
NS_FOR_CSS_SIDES(i) {
|
||||
wrSide[i] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), NS_STYLE_BORDER_STYLE_NONE);
|
||||
}
|
||||
wrSide[eSideTop] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), param->mBorderStyle);
|
||||
|
||||
WrBorderRadius borderRadii = wr::ToWrBorderRadius( {0, 0}, {0, 0}, {0, 0}, {0, 0} );
|
||||
|
||||
// All border style is set to none except top side. So setting the widths of
|
||||
// each side to height of rect is fine.
|
||||
WrBorderWidths borderWidths = wr::ToWrBorderWidths(transformedRect.height,
|
||||
transformedRect.height,
|
||||
transformedRect.height,
|
||||
transformedRect.height);
|
||||
WrClipRegionToken clipRegion = aBuilder.PushClipRegion(transformedRect);
|
||||
transformedRect.height *= 2.0f;
|
||||
aBuilder.PushBorder(transformedRect,
|
||||
clipRegion,
|
||||
borderWidths,
|
||||
wrSide[0], wrSide[1], wrSide[2], wrSide[3],
|
||||
borderRadii);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7429,7 +7680,7 @@ BCPaintBorderIterator::BlockDirSegmentOwnsCorner()
|
|||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget)
|
||||
BCPaintBorderIterator::AccumulateOrDoActionInlineDirSegment(BCPaintBorderAction& aAction)
|
||||
{
|
||||
|
||||
int32_t relColIndex = GetRelativeColIndex();
|
||||
|
@ -7462,7 +7713,17 @@ BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget
|
|||
if (mInlineSeg.mLength > 0) {
|
||||
mInlineSeg.GetIEndCorner(*this, iStartSegISize);
|
||||
if (mInlineSeg.mWidth > 0) {
|
||||
mInlineSeg.Paint(*this, aDrawTarget);
|
||||
if (aAction.mMode == BCPaintBorderAction::Mode::PAINT) {
|
||||
mInlineSeg.Paint(*this, aAction.mPaintData.mDrawTarget);
|
||||
} else {
|
||||
MOZ_ASSERT(aAction.mMode == BCPaintBorderAction::Mode::CREATE_WEBRENDER_COMMANDS);
|
||||
mInlineSeg.CreateWebRenderCommands(*this,
|
||||
aAction.mCreateWebRenderCommandsData.mBuilder,
|
||||
aAction.mCreateWebRenderCommandsData.mSc,
|
||||
aAction.mCreateWebRenderCommandsData.mParentCommands,
|
||||
aAction.mCreateWebRenderCommandsData.mLayer,
|
||||
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame);
|
||||
}
|
||||
}
|
||||
mInlineSeg.AdvanceOffsetI();
|
||||
}
|
||||
|
@ -7472,12 +7733,13 @@ BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget
|
|||
mBlockDirInfo[relColIndex].mWidth = iStartSegISize;
|
||||
mBlockDirInfo[relColIndex].mLastCell = mCell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint if necessary a block-dir segment, otherwise accumulate it
|
||||
* @param aDrawTarget - the draw target
|
||||
*/
|
||||
void
|
||||
BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget)
|
||||
BCPaintBorderIterator::AccumulateOrDoActionBlockDirSegment(BCPaintBorderAction& aAction)
|
||||
{
|
||||
BCBorderOwner borderOwner = eCellOwner;
|
||||
BCBorderOwner ignoreBorderOwner;
|
||||
|
@ -7504,7 +7766,18 @@ BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget)
|
|||
if (blockDirSeg.mLength > 0) {
|
||||
blockDirSeg.GetBEndCorner(*this, inlineSegBSize);
|
||||
if (blockDirSeg.mWidth > 0) {
|
||||
blockDirSeg.Paint(*this, aDrawTarget, inlineSegBSize);
|
||||
if (aAction.mMode == BCPaintBorderAction::Mode::PAINT) {
|
||||
blockDirSeg.Paint(*this, aAction.mPaintData.mDrawTarget, inlineSegBSize);
|
||||
} else {
|
||||
MOZ_ASSERT(aAction.mMode == BCPaintBorderAction::Mode::CREATE_WEBRENDER_COMMANDS);
|
||||
blockDirSeg.CreateWebRenderCommands(*this,
|
||||
inlineSegBSize,
|
||||
aAction.mCreateWebRenderCommandsData.mBuilder,
|
||||
aAction.mCreateWebRenderCommandsData.mSc,
|
||||
aAction.mCreateWebRenderCommandsData.mParentCommands,
|
||||
aAction.mCreateWebRenderCommandsData.mLayer,
|
||||
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame);
|
||||
}
|
||||
}
|
||||
blockDirSeg.AdvanceOffsetB();
|
||||
}
|
||||
|
@ -7529,14 +7802,8 @@ BCPaintBorderIterator::ResetVerInfo()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to paint BCBorders, this does not use currently display lists although
|
||||
* it will do this in future
|
||||
* @param aDrawTarget - the rendering context
|
||||
* @param aDirtyRect - inside this rectangle the BC Borders will redrawn
|
||||
*/
|
||||
void
|
||||
nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
|
||||
nsTableFrame::IterateBCBorders(BCPaintBorderAction& aAction, const nsRect& aDirtyRect)
|
||||
{
|
||||
// We first transfer the aDirtyRect into cellmap coordinates to compute which
|
||||
// cell borders need to be painted
|
||||
|
@ -7555,7 +7822,7 @@ nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
|
|||
// this we the now active segment with the current border. These
|
||||
// segments are stored in mBlockDirInfo to be used on the next row
|
||||
for (iter.First(); !iter.mAtEnd; iter.Next()) {
|
||||
iter.AccumulateOrPaintBlockDirSegment(aDrawTarget);
|
||||
iter.AccumulateOrDoActionBlockDirSegment(aAction);
|
||||
}
|
||||
|
||||
// Next, paint all of the inline-dir border segments from bStart to bEnd reuse
|
||||
|
@ -7563,10 +7830,36 @@ nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
|
|||
// corner calculations
|
||||
iter.Reset();
|
||||
for (iter.First(); !iter.mAtEnd; iter.Next()) {
|
||||
iter.AccumulateOrPaintInlineDirSegment(aDrawTarget);
|
||||
iter.AccumulateOrDoActionInlineDirSegment(aAction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to paint BCBorders, this does not use currently display lists although
|
||||
* it will do this in future
|
||||
* @param aDrawTarget - the rendering context
|
||||
* @param aDirtyRect - inside this rectangle the BC Borders will redrawn
|
||||
*/
|
||||
void
|
||||
nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
|
||||
{
|
||||
BCPaintBorderAction action(aDrawTarget);
|
||||
IterateBCBorders(action, aDirtyRect);
|
||||
}
|
||||
|
||||
void
|
||||
nsTableFrame::CreateWebRenderCommandsForBCBorders(wr::DisplayListBuilder& aBuilder,
|
||||
const mozilla::layers::StackingContextHelper& aSc,
|
||||
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
|
||||
layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aOffsetToReferenceFrame)
|
||||
{
|
||||
BCPaintBorderAction action(aBuilder, aSc, aParentCommands, aLayer, aOffsetToReferenceFrame);
|
||||
// We always draw whole table border for webrender. Passing the table rect as
|
||||
// dirty rect.
|
||||
IterateBCBorders(action, GetRect());
|
||||
}
|
||||
|
||||
bool
|
||||
nsTableFrame::RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsDisplayList.h"
|
||||
#include "TableArea.h"
|
||||
|
||||
struct BCPaintBorderAction;
|
||||
class nsTableCellFrame;
|
||||
class nsTableCellMap;
|
||||
class nsTableColFrame;
|
||||
|
@ -29,6 +30,9 @@ namespace mozilla {
|
|||
class WritingMode;
|
||||
class LogicalMargin;
|
||||
struct TableReflowInput;
|
||||
namespace layers {
|
||||
class StackingContextHelper;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
struct BCPropertyData;
|
||||
|
@ -302,6 +306,11 @@ public:
|
|||
bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
|
||||
nsStyleContext* aNewStyleContext);
|
||||
void PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect);
|
||||
void CreateWebRenderCommandsForBCBorders(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const mozilla::layers::StackingContextHelper& aSc,
|
||||
nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
|
||||
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
|
||||
const nsPoint& aPt);
|
||||
|
||||
virtual void MarkIntrinsicISizesDirty() override;
|
||||
// For border-collapse tables, the caller must not add padding and
|
||||
|
@ -604,6 +613,8 @@ protected:
|
|||
|
||||
virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
|
||||
|
||||
void IterateBCBorders(BCPaintBorderAction& aAction, const nsRect& aDirtyRect);
|
||||
|
||||
public:
|
||||
bool IsRowInserted() const;
|
||||
void SetRowInserted(bool aValue);
|
||||
|
|
Загрузка…
Ссылка в новой задаче