--- a/gfx/layers/ipc/WebRenderMessages.ipdlh
+++ b/gfx/layers/ipc/WebRenderMessages.ipdlh
@@ -6,16 +6,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include LayersSurfaces;
include LayersMessages;
include protocol PTexture;
using WrBorderRadius from "mozilla/webrender/webrender_ffi.h";
using WrBorderSide from "mozilla/webrender/webrender_ffi.h";
+using WrBorderWidths from "mozilla/webrender/webrender_ffi.h";
+using WrNinePatchDescriptor from "mozilla/webrender/webrender_ffi.h";
+using WrSideOffsets2Df32 from "mozilla/webrender/webrender_ffi.h";
+using WrRepeatMode from "mozilla/webrender/webrender_ffi.h";
using WrColor from "mozilla/webrender/webrender_ffi.h";
using WrLayoutSize from "mozilla/webrender/webrender_ffi.h";
using WrRect from "mozilla/webrender/webrender_ffi.h";
using WrPoint from "mozilla/webrender/webrender_ffi.h";
using WrGradientStop from "mozilla/webrender/webrender_ffi.h";
using WrGradientExtendMode from "mozilla/webrender/webrender_ffi.h";
using WrGlyphArray from "mozilla/webrender/webrender_ffi.h";
using WrMixBlendMode from "mozilla/webrender/webrender_ffi.h";
@@ -58,23 +62,35 @@ struct OpDPPushRect {
WrRect bounds;
WrRect clip;
WrColor color;
};
struct OpDPPushBorder {
WrRect bounds;
WrRect clip;
+ WrBorderWidths widths;
WrBorderSide top;
WrBorderSide right;
WrBorderSide bottom;
WrBorderSide left;
WrBorderRadius radius;
};
+struct OpDPPushBorderImage {
+ WrRect bounds;
+ WrRect clip;
+ WrBorderWidths widths;
+ ImageKey key;
+ WrNinePatchDescriptor patch;
+ WrSideOffsets2Df32 outset;
+ WrRepeatMode repeat_horizontal;
+ WrRepeatMode repeat_vertical;
+};
+
struct OpDPPushLinearGradient {
WrRect bounds;
WrRect clip;
WrPoint startPoint;
WrPoint endPoint;
WrGradientExtendMode extendMode;
WrGradientStop[] stops;
};
@@ -131,16 +147,17 @@ struct OpDPPushBoxShadow {
union WebRenderCommand {
OpDPPushStackingContext;
OpDPPopStackingContext;
OpDPPushScrollLayer;
OpDPPopScrollLayer;
OpDPPushRect;
OpDPPushBorder;
+ OpDPPushBorderImage;
OpDPPushLinearGradient;
OpDPPushRadialGradient;
OpDPPushImage;
OpDPPushIframe;
OpDPPushText;
OpDPPushBoxShadow;
};
--- a/gfx/layers/wr/WebRenderBorderLayer.cpp
+++ b/gfx/layers/wr/WebRenderBorderLayer.cpp
@@ -57,18 +57,20 @@ WebRenderBorderLayer::RenderLayer(wr::Di
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
nullptr,
1.0f,
//GetAnimations(),
transform,
WrMixBlendMode::Normal);
aBuilder.PushBorder(wr::ToWrRect(rect), wr::ToWrRect(clip),
- wr::ToWrBorderSide(mWidths[0], mColors[0], mBorderStyles[0]),
- wr::ToWrBorderSide(mWidths[1], mColors[1], mBorderStyles[1]),
- wr::ToWrBorderSide(mWidths[2], mColors[2], mBorderStyles[2]),
- wr::ToWrBorderSide(mWidths[3], mColors[3], mBorderStyles[3]),
- wr::ToWrBorderRadius(mCorners[0], mCorners[1], mCorners[3], mCorners[2]));
+ wr::ToWrBorderWidths(mWidths[0], mWidths[1], mWidths[2], mWidths[3]),
+ wr::ToWrBorderSide(mColors[0], mBorderStyles[0]),
+ wr::ToWrBorderSide(mColors[1], mBorderStyles[1]),
+ wr::ToWrBorderSide(mColors[2], mBorderStyles[2]),
+ wr::ToWrBorderSide(mColors[3], mBorderStyles[3]),
+ wr::ToWrBorderRadius(mCorners[eCornerTopLeft], mCorners[eCornerTopRight],
+ mCorners[eCornerBottomLeft], mCorners[eCornerBottomRight]));
aBuilder.PopStackingContext();
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -117,20 +117,27 @@ WebRenderBridgeChild::ProcessWebrenderCo
case WebRenderCommand::TOpDPPushRect: {
const OpDPPushRect& op = cmd.get_OpDPPushRect();
builder.PushRect(op.bounds(), op.clip(), op.color());
break;
}
case WebRenderCommand::TOpDPPushBorder: {
const OpDPPushBorder& op = cmd.get_OpDPPushBorder();
builder.PushBorder(op.bounds(), op.clip(),
- op.top(), op.right(), op.bottom(), op.left(),
+ op.widths(), op.top(), op.right(), op.bottom(), op.left(),
op.radius());
break;
}
+ case WebRenderCommand::TOpDPPushBorderImage: {
+ const OpDPPushBorderImage& op = cmd.get_OpDPPushBorderImage();
+ builder.PushBorderImage(op.bounds(), op.clip(),
+ op.widths(), op.key(), op.patch(), op.outset(),
+ op.repeat_horizontal(), op.repeat_vertical());
+ break;
+ }
case WebRenderCommand::TOpDPPushLinearGradient: {
const OpDPPushLinearGradient& op = cmd.get_OpDPPushLinearGradient();
builder.PushLinearGradient(op.bounds(), op.clip(),
op.startPoint(), op.endPoint(),
op.stops(), op.extendMode());
break;
}
case WebRenderCommand::TOpDPPushRadialGradient: {
--- a/gfx/layers/wr/WebRenderMessageUtils.h
+++ b/gfx/layers/wr/WebRenderMessageUtils.h
@@ -208,27 +208,111 @@ struct ParamTraits<WrGradientStop>
};
template<>
struct ParamTraits<WrBorderSide>
{
static void
Write(Message* aMsg, const WrBorderSide& aParam)
{
- WriteParam(aMsg, aParam.width);
WriteParam(aMsg, aParam.color);
WriteParam(aMsg, aParam.style);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrBorderSide* aResult)
{
+ return ReadParam(aMsg, aIter, &aResult->color)
+ && ReadParam(aMsg, aIter, &aResult->style);
+ }
+};
+
+template<>
+struct ParamTraits<WrBorderWidths>
+{
+ static void
+ Write(Message* aMsg, const WrBorderWidths& aParam)
+ {
+ WriteParam(aMsg, aParam.left);
+ WriteParam(aMsg, aParam.top);
+ WriteParam(aMsg, aParam.right);
+ WriteParam(aMsg, aParam.bottom);
+ }
+
+ static bool
+ Read(const Message* aMsg, PickleIterator* aIter, WrBorderWidths* aResult)
+ {
+ return ReadParam(aMsg, aIter, &aResult->left)
+ && ReadParam(aMsg, aIter, &aResult->top)
+ && ReadParam(aMsg, aIter, &aResult->right)
+ && ReadParam(aMsg, aIter, &aResult->bottom);
+ }
+};
+
+template<>
+struct ParamTraits<WrSideOffsets2Du32>
+{
+ static void
+ Write(Message* aMsg, const WrSideOffsets2Du32& aParam)
+ {
+ WriteParam(aMsg, aParam.top);
+ WriteParam(aMsg, aParam.right);
+ WriteParam(aMsg, aParam.bottom);
+ WriteParam(aMsg, aParam.left);
+ }
+
+ static bool
+ Read(const Message* aMsg, PickleIterator* aIter, WrSideOffsets2Du32* aResult)
+ {
+ return ReadParam(aMsg, aIter, &aResult->top)
+ && ReadParam(aMsg, aIter, &aResult->right)
+ && ReadParam(aMsg, aIter, &aResult->bottom)
+ && ReadParam(aMsg, aIter, &aResult->left);
+ }
+};
+
+template<>
+struct ParamTraits<WrSideOffsets2Df32>
+{
+ static void
+ Write(Message* aMsg, const WrSideOffsets2Df32& aParam)
+ {
+ WriteParam(aMsg, aParam.top);
+ WriteParam(aMsg, aParam.right);
+ WriteParam(aMsg, aParam.bottom);
+ WriteParam(aMsg, aParam.left);
+ }
+
+ static bool
+ Read(const Message* aMsg, PickleIterator* aIter, WrSideOffsets2Df32* aResult)
+ {
+ return ReadParam(aMsg, aIter, &aResult->top)
+ && ReadParam(aMsg, aIter, &aResult->right)
+ && ReadParam(aMsg, aIter, &aResult->bottom)
+ && ReadParam(aMsg, aIter, &aResult->left);
+ }
+};
+
+template<>
+struct ParamTraits<WrNinePatchDescriptor>
+{
+ static void
+ Write(Message* aMsg, const WrNinePatchDescriptor& aParam)
+ {
+ WriteParam(aMsg, aParam.width);
+ WriteParam(aMsg, aParam.height);
+ WriteParam(aMsg, aParam.slice);
+ }
+
+ static bool
+ Read(const Message* aMsg, PickleIterator* aIter, WrNinePatchDescriptor* aResult)
+ {
return ReadParam(aMsg, aIter, &aResult->width)
- && ReadParam(aMsg, aIter, &aResult->color)
- && ReadParam(aMsg, aIter, &aResult->style);
+ && ReadParam(aMsg, aIter, &aResult->height)
+ && ReadParam(aMsg, aIter, &aResult->slice);
}
};
template<>
struct ParamTraits<WrLayoutSize>
{
static void
Write(Message* aMsg, const WrLayoutSize& aParam)
@@ -397,11 +481,20 @@ template<>
struct ParamTraits<WrGradientExtendMode>
: public ContiguousEnumSerializer<
WrGradientExtendMode,
WrGradientExtendMode::Clamp,
WrGradientExtendMode::Sentinel>
{
};
+template<>
+struct ParamTraits<WrRepeatMode>
+ : public ContiguousEnumSerializer<
+ WrRepeatMode,
+ WrRepeatMode::Stretch,
+ WrRepeatMode::Sentinel>
+{
+};
+
} // namespace IPC
#endif // GFX_WEBRENDERMESSAGEUTILS_H
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -477,25 +477,40 @@ DisplayListBuilder::PushIFrame(const WrR
PipelineId aPipeline)
{
wr_dp_push_iframe(mWrState, aBounds, aClip, aPipeline);
}
void
DisplayListBuilder::PushBorder(const WrRect& aBounds,
const WrRect& aClip,
+ const WrBorderWidths& aWidths,
const WrBorderSide& aTop,
const WrBorderSide& aRight,
const WrBorderSide& aBottom,
const WrBorderSide& aLeft,
const WrBorderRadius& aRadius)
{
wr_dp_push_border(mWrState, aBounds, aClip,
- aTop, aRight, aBottom, aLeft,
- aRadius);
+ aWidths, aTop, aRight, aBottom, aLeft, aRadius);
+}
+
+void
+DisplayListBuilder::PushBorderImage(const WrRect& aBounds,
+ const WrRect& aClip,
+ const WrBorderWidths& aWidths,
+ wr::ImageKey aImage,
+ const WrNinePatchDescriptor& aPatch,
+ const WrSideOffsets2Df32& aOutset,
+ const WrRepeatMode& aRepeatHorizontal,
+ const WrRepeatMode& aRepeatVertical)
+{
+ wr_dp_push_border_image(mWrState, aBounds, aClip,
+ aWidths, aImage, aPatch, aOutset,
+ aRepeatHorizontal, aRepeatVertical);
}
void
DisplayListBuilder::PushText(const WrRect& aBounds,
const WrRect& aClip,
const gfx::Color& aColor,
wr::FontKey aFontKey,
Range<const WrGlyphInstance> aGlyphBuffer,
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -170,22 +170,32 @@ public:
wr::ImageKey aImage);
void PushIFrame(const WrRect& aBounds,
const WrRect& aClip,
wr::PipelineId aPipeline);
void PushBorder(const WrRect& aBounds,
const WrRect& aClip,
+ const WrBorderWidths& aWidths,
const WrBorderSide& aTop,
const WrBorderSide& aRight,
const WrBorderSide& aBbottom,
const WrBorderSide& aLeft,
const WrBorderRadius& aRadius);
+ void PushBorderImage(const WrRect& aBounds,
+ const WrRect& aClip,
+ const WrBorderWidths& aWidths,
+ wr::ImageKey aImage,
+ const WrNinePatchDescriptor& aPatch,
+ const WrSideOffsets2Df32& aOutset,
+ const WrRepeatMode& aRepeatHorizontal,
+ const WrRepeatMode& aRepeatVertical);
+
void PushText(const WrRect& aBounds,
const WrRect& aClip,
const gfx::Color& aColor,
wr::FontKey aFontKey,
Range<const WrGlyphInstance> aGlyphBuffer,
float aGlyphSize);
void PushBoxShadow(const WrRect& aRect,
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -172,20 +172,19 @@ static inline WrBorderStyle ToWrBorderSt
case NS_STYLE_BORDER_STYLE_OUTSET:
return WrBorderStyle::Outset;
default:
MOZ_ASSERT(false);
}
return WrBorderStyle::None;
}
-static inline WrBorderSide ToWrBorderSide(const LayerCoord width, const gfx::Color& color, const uint8_t& style)
+static inline WrBorderSide ToWrBorderSide(const gfx::Color& color, const uint8_t& style)
{
WrBorderSide bs;
- bs.width = width;
bs.color = ToWrColor(color);
bs.style = ToWrBorderStyle(style);
return bs;
}
static inline WrPoint ToWrPoint(const LayerPoint point)
{
WrPoint lp;
@@ -208,16 +207,74 @@ static inline WrBorderRadius ToWrBorderR
WrBorderRadius br;
br.top_left = ToWrLayoutSize(topLeft);
br.top_right = ToWrLayoutSize(topRight);
br.bottom_left = ToWrLayoutSize(bottomLeft);
br.bottom_right = ToWrLayoutSize(bottomRight);
return br;
}
+static inline WrBorderWidths ToWrBorderWidths(float top, float right, float bottom, float left)
+{
+ WrBorderWidths bw;
+ bw.top = top;
+ bw.right = right;
+ bw.bottom = bottom;
+ bw.left = left;
+ return bw;
+}
+
+static inline WrNinePatchDescriptor ToWrNinePatchDescriptor(uint32_t width, uint32_t height,
+ const WrSideOffsets2Du32& slice)
+{
+ WrNinePatchDescriptor patch;
+ patch.width = width;
+ patch.height = height;
+ patch.slice = slice;
+ return patch;
+}
+
+static inline WrSideOffsets2Du32 ToWrSideOffsets2Du32(uint32_t top, uint32_t right, uint32_t bottom, uint32_t left)
+{
+ WrSideOffsets2Du32 offset;
+ offset.top = top;
+ offset.right = right;
+ offset.bottom = bottom;
+ offset.left = left;
+ return offset;
+}
+
+static inline WrSideOffsets2Df32 ToWrSideOffsets2Df32(float top, float right, float bottom, float left)
+{
+ WrSideOffsets2Df32 offset;
+ offset.top = top;
+ offset.right = right;
+ offset.bottom = bottom;
+ offset.left = left;
+ return offset;
+}
+
+static inline WrRepeatMode ToWrRepeatMode(uint8_t repeatMode)
+{
+ switch (repeatMode) {
+ case NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH:
+ return WrRepeatMode::Stretch;
+ case NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT:
+ return WrRepeatMode::Repeat;
+ case NS_STYLE_BORDER_IMAGE_REPEAT_ROUND:
+ return WrRepeatMode::Round;
+ case NS_STYLE_BORDER_IMAGE_REPEAT_SPACE:
+ return WrRepeatMode::Space;
+ default:
+ MOZ_ASSERT(false);
+ }
+
+ return WrRepeatMode::Stretch;
+}
+
template<class T>
static inline WrRect ToWrRect(const gfx::RectTyped<T>& rect)
{
WrRect r;
r.x = rect.x;
r.y = rect.y;
r.width = rect.width;
r.height = rect.height;
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1,28 +1,29 @@
use std::ffi::CString;
use std::{mem, slice};
use std::path::PathBuf;
use std::os::raw::{c_void, c_char};
use gleam::gl;
-use webrender_traits::{BorderSide, BorderStyle, BorderRadius, BorderWidths, BorderDetails, NormalBorder};
+use webrender_traits::{BorderSide, BorderStyle, BorderRadius, BorderWidths, NormalBorder};
+use webrender_traits::{BorderDetails, ImageBorder, NinePatchDescriptor, RepeatMode};
use webrender_traits::{PipelineId, ClipRegion, PropertyBinding};
use webrender_traits::{Epoch, ExtendMode, ColorF, GlyphInstance, GradientStop, ImageDescriptor};
use webrender_traits::{FilterOp, ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering, MixBlendMode};
use webrender_traits::{ExternalImageId, RenderApi, FontKey};
use webrender_traits::{DeviceUintSize, ExternalEvent};
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform};
use webrender_traits::{BoxShadowClipMode, LayerPixel, ServoScrollRootId, IdNamespace};
use webrender_traits::{BuiltDisplayListDescriptor, AuxiliaryListsDescriptor};
use webrender_traits::{BuiltDisplayList, AuxiliaryLists};
use webrender::renderer::{Renderer, RendererOptions};
use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource};
use webrender::{ApiRecordingReceiver, BinaryRecorder};
use app_units::Au;
-use euclid::TypedPoint2D;
+use euclid::{TypedPoint2D, SideOffsets2D};
extern crate webrender_traits;
static ENABLE_RECORDING: bool = false;
// This macro adds some checks to make sure we notice when the memory representation of
// types change.
macro_rules! check_ffi_type {
@@ -766,37 +767,56 @@ pub extern fn wr_dp_push_box_shadow(stat
blur_radius,
spread_radius,
border_radius,
clip_mode.to_box_shadow_clip_mode());
}
#[no_mangle]
pub extern fn wr_dp_push_border(state: &mut WrState, rect: WrRect, clip: WrRect,
- top: WrBorderSide, right: WrBorderSide, bottom: WrBorderSide, left: WrBorderSide,
+ widths: WrBorderWidths,
+ top: WrBorderSide, right: WrBorderSide,
+ bottom: WrBorderSide, left: WrBorderSide,
radius: WrBorderRadius) {
assert!( unsafe { is_in_main_thread() });
let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
- let border_widths = BorderWidths {
- left: left.width,
- top: top.width,
- right: right.width,
- bottom: bottom.width
- };
let border_details = BorderDetails::Normal(NormalBorder {
left: left.to_border_side(),
right: right.to_border_side(),
top: top.to_border_side(),
bottom: bottom.to_border_side(),
radius: radius.to_border_radius(),
});
state.frame_builder.dl_builder.push_border(
rect.to_rect(),
clip_region,
- border_widths,
+ widths.to_border_widths(),
+ border_details);
+}
+
+#[no_mangle]
+pub extern fn wr_dp_push_border_image(state: &mut WrState, rect: WrRect, clip: WrRect,
+ widths: WrBorderWidths,
+ image: ImageKey, patch: WrNinePatchDescriptor,
+ outset: WrSideOffsets2D<f32>,
+ repeat_horizontal: WrRepeatMode,
+ repeat_vertical: WrRepeatMode) {
+ assert!( unsafe { is_in_main_thread() });
+ let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
+ let border_details = BorderDetails::Image(ImageBorder {
+ image_key: image,
+ patch: patch.to_nine_patch_descriptor(),
+ outset: outset.to_side_offsets_2d(),
+ repeat_horizontal: repeat_horizontal.to_repeat_mode(),
+ repeat_vertical: repeat_vertical.to_repeat_mode(),
+ });
+ state.frame_builder.dl_builder.push_border(
+ rect.to_rect(),
+ clip_region,
+ widths.to_border_widths(),
border_details);
}
#[no_mangle]
pub extern fn wr_dp_push_linear_gradient(state: &mut WrState, rect: WrRect, clip: WrRect,
start_point: WrPoint, end_point: WrPoint,
stops: * const WrGradientStop, stops_count: usize,
extend_mode: WrGradientExtendMode) {
@@ -884,30 +904,106 @@ impl WrBorderRadius
bottom_left: self.bottom_left.to_layout_size(),
bottom_right: self.bottom_right.to_layout_size() }
}
}
#[repr(C)]
pub struct WrBorderSide
{
- width: f32,
color: WrColor,
style: BorderStyle
}
impl WrBorderSide
{
pub fn to_border_side(&self) -> BorderSide
{
BorderSide { color: self.color.to_color(), style: self.style }
}
}
#[repr(C)]
+pub struct WrBorderWidths
+{
+ left: f32,
+ top: f32,
+ right: f32,
+ bottom: f32,
+}
+
+impl WrBorderWidths
+{
+ pub fn to_border_widths(&self) -> BorderWidths
+ {
+ BorderWidths { left: self.left, top: self.top, right: self.right, bottom: self.bottom }
+ }
+}
+
+#[repr(C)]
+pub struct WrNinePatchDescriptor
+{
+ width: u32,
+ height: u32,
+ slice: WrSideOffsets2D<u32>,
+}
+
+impl WrNinePatchDescriptor
+{
+ pub fn to_nine_patch_descriptor(&self) -> NinePatchDescriptor
+ {
+ NinePatchDescriptor {
+ width: self.width,
+ height: self.height,
+ slice: self.slice.to_side_offsets_2d(),
+ }
+ }
+}
+
+#[repr(C)]
+pub struct WrSideOffsets2D<T>
+{
+ top: T,
+ right: T,
+ bottom: T,
+ left: T,
+}
+
+impl<T: Copy> WrSideOffsets2D<T>
+{
+ pub fn to_side_offsets_2d(&self) -> SideOffsets2D<T>
+ {
+ SideOffsets2D::new(self.top, self.right, self.bottom, self.left)
+ }
+}
+
+#[repr(C)]
+pub enum WrRepeatMode
+{
+ Stretch,
+ Repeat,
+ Round,
+ Space,
+}
+
+impl WrRepeatMode
+{
+ pub fn to_repeat_mode(self) -> RepeatMode
+ {
+ match self
+ {
+ WrRepeatMode::Stretch => RepeatMode::Stretch,
+ WrRepeatMode::Repeat => RepeatMode::Repeat,
+ WrRepeatMode::Round => RepeatMode::Round,
+ WrRepeatMode::Space => RepeatMode::Space,
+ }
+ }
+}
+
+#[repr(C)]
pub struct WrGradientStop
{
offset: f32,
color: WrColor,
}
impl WrGradientStop
{
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -149,16 +149,26 @@ enum class WrMixBlendMode: uint32_t
enum class WrGradientExtendMode : uint32_t
{
Clamp = 0,
Repeat = 1,
Sentinel /* this must be last, for IPC serialization purposes */
};
+enum class WrRepeatMode : uint32_t
+{
+ Stretch = 0,
+ Repeat = 1,
+ Round = 2,
+ Space = 3,
+
+ Sentinel /* this must be last, for IPC serialization purposes */
+};
+
// -----
// Typedefs for struct fields and function signatures below.
// -----
typedef uint64_t WrImageIdType;
// -----
// Structs used in C++ code with corresponding types in Rust code
@@ -224,24 +234,22 @@ struct WrGradientStop {
bool operator==(const WrGradientStop& aRhs) const
{
return offset == aRhs.offset && color == aRhs.color;
}
};
struct WrBorderSide {
- float width;
WrColor color;
WrBorderStyle style;
bool operator==(const WrBorderSide& aRhs) const
{
- return width == aRhs.width && color == aRhs.color &&
- style == aRhs.style;
+ return color == aRhs.color && style == aRhs.style;
}
};
struct WrLayoutSize
{
float width;
float height;
@@ -259,16 +267,67 @@ struct WrBorderRadius {
bool operator==(const WrBorderRadius& aRhs) const
{
return top_left == aRhs.top_left && top_right == aRhs.top_right &&
bottom_left == aRhs.bottom_left && bottom_right == aRhs.bottom_right;
}
};
+struct WrBorderWidths {
+ float left;
+ float top;
+ float right;
+ float bottom;
+
+ bool operator==(const WrBorderWidths& aRhs) const
+ {
+ return left == aRhs.left && top == aRhs.top &&
+ right == aRhs.right && bottom == aRhs.bottom;
+ }
+};
+
+struct WrSideOffsets2Du32 {
+ uint32_t top;
+ uint32_t right;
+ uint32_t bottom;
+ uint32_t left;
+
+ bool operator==(const WrSideOffsets2Du32& aRhs) const
+ {
+ return top == aRhs.top && right == aRhs.right &&
+ bottom == aRhs.bottom && left == aRhs.left;
+ }
+};
+
+struct WrSideOffsets2Df32 {
+ float top;
+ float right;
+ float bottom;
+ float left;
+
+ bool operator==(const WrSideOffsets2Df32& aRhs) const
+ {
+ return top == aRhs.top && right == aRhs.right &&
+ bottom == aRhs.bottom && left == aRhs.left;
+ }
+};
+
+struct WrNinePatchDescriptor {
+ uint32_t width;
+ uint32_t height;
+ WrSideOffsets2Du32 slice;
+
+ bool operator==(const WrNinePatchDescriptor& aRhs) const
+ {
+ return width == aRhs.width && height == aRhs.height &&
+ slice == aRhs.slice;
+ }
+};
+
struct WrRect
{
float x;
float y;
float width;
float height;
bool operator==(const WrRect& aRhs) const
@@ -534,21 +593,30 @@ WR_FUNC;
WR_INLINE void
wr_dp_push_text(WrState* wrState, WrRect bounds, WrRect clip, WrColor color,
WrFontKey font_Key, const WrGlyphInstance* glyphs,
uint32_t glyph_count, float glyph_size)
WR_FUNC;
WR_INLINE void
wr_dp_push_border(WrState* wrState, WrRect bounds, WrRect clip,
+ WrBorderWidths widths,
WrBorderSide top, WrBorderSide right, WrBorderSide bottom, WrBorderSide left,
WrBorderRadius radius)
WR_FUNC;
WR_INLINE void
+wr_dp_push_border_image(WrState* wrState, WrRect bounds, WrRect clip,
+ WrBorderWidths widths,
+ WrImageKey image, WrNinePatchDescriptor patch, WrSideOffsets2Df32 outset,
+ WrRepeatMode repeat_horizontal,
+ WrRepeatMode repeat_vertical)
+WR_FUNC;
+
+WR_INLINE void
wr_dp_push_linear_gradient(WrState* wrState, WrRect bounds, WrRect clip,
WrPoint startPoint, WrPoint endPoint,
const WrGradientStop* stops, size_t stopsCount,
WrGradientExtendMode extendMode)
WR_FUNC;
WR_INLINE void
wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrRect clip,
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4153,24 +4153,30 @@ nsDisplayOutline::CreateWebRenderCommand
{
MOZ_ASSERT(mBorderRenderer.isSome());
Rect outlineTransformedRect = aLayer->RelativeToParent(mBorderRenderer->mOuterRect);
nsCSSBorderRenderer* br = mBorderRenderer.ptr();
WrBorderSide side[4];
NS_FOR_CSS_SIDES(i) {
- side[i] = wr::ToWrBorderSide(br->mBorderWidths[i], ToDeviceColor(br->mBorderColors[i]), br->mBorderStyles[i]);
- }
- WrBorderRadius borderRadius = wr::ToWrBorderRadius(LayerSize(br->mBorderRadii[0].width, br->mBorderRadii[0].height),
- LayerSize(br->mBorderRadii[1].width, br->mBorderRadii[1].height),
- LayerSize(br->mBorderRadii[3].width, br->mBorderRadii[3].height),
- LayerSize(br->mBorderRadii[2].width, br->mBorderRadii[2].height));
+ side[i] = wr::ToWrBorderSide(ToDeviceColor(br->mBorderColors[i]), br->mBorderStyles[i]);
+ }
+
+ WrBorderRadius borderRadius =
+ wr::ToWrBorderRadius(
+ LayerSize(br->mBorderRadii[eCornerTopLeft].width, br->mBorderRadii[eCornerTopLeft].height),
+ LayerSize(br->mBorderRadii[eCornerTopRight].width, br->mBorderRadii[eCornerTopRight].height),
+ LayerSize(br->mBorderRadii[eCornerBottomLeft].width, br->mBorderRadii[eCornerBottomLeft].height),
+ LayerSize(br->mBorderRadii[eCornerBottomRight].width, br->mBorderRadii[eCornerBottomRight].height));
+
aBuilder.PushBorder(wr::ToWrRect(outlineTransformedRect),
wr::ToWrRect(outlineTransformedRect),
+ wr::ToWrBorderWidths(br->mBorderWidths[0], br->mBorderWidths[1],
+ br->mBorderWidths[2], br->mBorderWidths[3]),
side[0], side[1], side[2], side[3],
borderRadius);
}
bool
nsDisplayOutline::IsInvisibleInRect(const nsRect& aRect)
{
const nsStyleOutline* outline = mFrame->StyleOutline();