Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for (most of) border-image. #895

Merged
merged 3 commits into from Feb 22, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Large diffs are not rendered by default.

@@ -146,17 +146,26 @@ fn main() {
sub_clip,
ColorF::new(0.0, 1.0, 0.0, 1.0));
let border_side = webrender_traits::BorderSide {
width: 10.0,
color: ColorF::new(0.0, 0.0, 1.0, 1.0),
style: webrender_traits::BorderStyle::Groove,
};
let border_widths = webrender_traits::BorderWidths {
top: 10.0,
left: 10.0,
bottom: 10.0,
right: 10.0,
};
let border_details = webrender_traits::BorderDetails::Normal(webrender_traits::NormalBorder {
top: border_side,
right: border_side,
bottom: border_side,
left: border_side,
radius: webrender_traits::BorderRadius::uniform(20.0),
});
builder.push_border(LayoutRect::new(LayoutPoint::new(100.0, 100.0), LayoutSize::new(100.0, 100.0)),
sub_clip,
border_side,
border_side,
border_side,
border_side,
webrender_traits::BorderRadius::uniform(20.0));
border_widths,
border_details);


if false { // draw text?
@@ -1,6 +1,6 @@
[package]
name = "webrender"
version = "0.17.0"
version = "0.18.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
@@ -548,6 +548,7 @@ impl Frame {
&item.clip,
&info.stretch_size,
&info.tile_spacing,
None,
info.image_key,
info.image_rendering);
}

Large diffs are not rendered by default.

@@ -30,7 +30,7 @@ pub const MASK_DATA_GPU_SIZE: usize = 1;
/// may grow. Storing them as texel coords and normalizing
/// the UVs in the vertex shader means nothing needs to be
/// updated on the CPU when the texture size changes.
#[derive(Clone)]
#[derive(Copy, Clone, Debug)]
pub struct TexelRect {
pub uv0: DevicePoint,
pub uv1: DevicePoint,
@@ -45,6 +45,15 @@ impl Default for TexelRect {
}
}

impl TexelRect {
pub fn new(u0: u32, v0: u32, u1: u32, v1: u32) -> TexelRect {
TexelRect {
uv0: DevicePoint::new(u0 as f32, v0 as f32),
uv1: DevicePoint::new(u1 as f32, v1 as f32),
}
}
}

/// For external images, it's not possible to know the
/// UV coords of the image (or the image data itself)
/// until the render thread receives the frame and issues
@@ -136,6 +145,7 @@ pub struct ImagePrimitiveCpu {
pub kind: ImagePrimitiveKind,
pub color_texture_id: SourceTexture,
pub resource_address: GpuStoreAddress,
pub sub_rect: Option<TexelRect>,
}

#[derive(Debug, Clone)]
@@ -920,8 +930,18 @@ impl PrimitiveStore {

if let Some(cache_item) = cache_item {
let resource_rect = self.gpu_resource_rects.get_mut(image_cpu.resource_address);
resource_rect.uv0 = cache_item.uv0;
resource_rect.uv1 = cache_item.uv1;
match image_cpu.sub_rect {
Some(sub_rect) => {
resource_rect.uv0.x = cache_item.uv0.x + sub_rect.uv0.x;
resource_rect.uv0.y = cache_item.uv0.y + sub_rect.uv0.y;
resource_rect.uv1.x = cache_item.uv0.x + sub_rect.uv1.x;
resource_rect.uv1.y = cache_item.uv0.y + sub_rect.uv1.y;
}
None => {
resource_rect.uv0 = cache_item.uv0;
resource_rect.uv1 = cache_item.uv1;
}
}
}
image_cpu.color_texture_id = texture_id;
}
@@ -1,6 +1,6 @@
[package]
name = "webrender_traits"
version = "0.16.0"
version = "0.18.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
@@ -3,33 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use display_list::AuxiliaryListsBuilder;
use {BorderRadius, BorderDisplayItem, ClipRegion, ColorF, ComplexClipRegion};
use {BorderRadius, ClipRegion, ColorF, ComplexClipRegion};
use {FontKey, ImageKey, PipelineId, ScrollLayerId, ScrollLayerInfo, ServoScrollRootId};
use {ImageMask, ItemRange};
use {LayoutSize, LayoutPoint, LayoutRect};

impl BorderDisplayItem {
pub fn top_left_inner_radius(&self) -> LayoutSize {
LayoutSize::new((self.radius.top_left.width - self.left.width).max(0.0),
(self.radius.top_left.height - self.top.width).max(0.0))
}

pub fn top_right_inner_radius(&self) -> LayoutSize {
LayoutSize::new((self.radius.top_right.width - self.right.width).max(0.0),
(self.radius.top_right.height - self.top.width).max(0.0))
}

pub fn bottom_left_inner_radius(&self) -> LayoutSize {
LayoutSize::new((self.radius.bottom_left.width - self.left.width).max(0.0),
(self.radius.bottom_left.height - self.bottom.width).max(0.0))
}

pub fn bottom_right_inner_radius(&self) -> LayoutSize {
LayoutSize::new((self.radius.bottom_right.width - self.right.width).max(0.0),
(self.radius.bottom_right.height - self.bottom.width).max(0.0))
}
}

impl BorderRadius {
pub fn zero() -> BorderRadius {
BorderRadius {
@@ -5,8 +5,8 @@
use app_units::Au;
use std::mem;
use std::slice;
use {AuxiliaryLists, AuxiliaryListsDescriptor, BorderDisplayItem, BorderRadius};
use {BorderSide, BoxShadowClipMode, BoxShadowDisplayItem, BuiltDisplayList};
use {AuxiliaryLists, AuxiliaryListsDescriptor, BorderDisplayItem};
use {BoxShadowClipMode, BoxShadowDisplayItem, BuiltDisplayList};
use {BuiltDisplayListDescriptor, ClipRegion, ComplexClipRegion, ColorF};
use {DisplayItem, DisplayListMode, ExtendMode, FilterOp, YuvColorSpace};
use {FontKey, GlyphInstance, GradientDisplayItem, RadialGradientDisplayItem, GradientStop, IframeDisplayItem};
@@ -15,7 +15,7 @@ use {PushScrollLayerItem, PushStackingContextDisplayItem, RectangleDisplayItem,
use {ScrollPolicy, ServoScrollRootId, SpecificDisplayItem, StackingContext, TextDisplayItem};
use {WebGLContextId, WebGLDisplayItem, YuvImageDisplayItem};
use {LayoutTransform, LayoutPoint, LayoutRect, LayoutSize};
use {GlyphOptions, PropertyBinding};
use {BorderDetails, BorderWidths, GlyphOptions, PropertyBinding};

impl BuiltDisplayListDescriptor {
pub fn size(&self) -> usize {
@@ -186,17 +186,11 @@ impl DisplayListBuilder {
pub fn push_border(&mut self,
rect: LayoutRect,
clip: ClipRegion,
left: BorderSide,
top: BorderSide,
right: BorderSide,
bottom: BorderSide,
radius: BorderRadius) {
widths: BorderWidths,
details: BorderDetails) {
let item = BorderDisplayItem {
left: left,
top: top,
right: right,
bottom: bottom,
radius: radius,
details: details,
widths: widths,
};

let display_item = DisplayItem {
@@ -6,7 +6,7 @@
// for the serde implementations.

use app_units::Au;
use euclid::Point2D;
use euclid::{Point2D, SideOffsets2D};
use channel::{PayloadSender, MsgSender};
#[cfg(feature = "nightly")]
use core::nonzero::NonZero;
@@ -175,14 +175,50 @@ pub struct AuxiliaryListsDescriptor {
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderDisplayItem {
pub struct NormalBorder {
pub left: BorderSide,
pub right: BorderSide,
pub top: BorderSide,
pub bottom: BorderSide,
pub radius: BorderRadius,
}

#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum RepeatMode {
Stretch,
Repeat,
Round,
Space,
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct NinePatchDescriptor {
pub width: u32,
pub height: u32,
pub slice: SideOffsets2D<u32>,
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageBorder {
pub image_key: ImageKey,
pub patch: NinePatchDescriptor,
pub outset: SideOffsets2D<f32>,
pub repeat_horizontal: RepeatMode,
pub repeat_vertical: RepeatMode,
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum BorderDetails {
Normal(NormalBorder),
Image(ImageBorder),
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderDisplayItem {
pub widths: BorderWidths,
pub details: BorderDetails,
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderRadius {
pub top_left: LayoutSize,
@@ -191,10 +227,17 @@ pub struct BorderRadius {
pub bottom_right: LayoutSize,
}

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderWidths {
pub left: f32,
pub top: f32,
pub right: f32,
pub bottom: f32,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderSide {
pub width: f32,
pub color: ColorF,
pub style: BorderStyle,
}
@@ -270,13 +270,23 @@ impl YamlFrameReader {
let colors = broadcast(&colors, 4);
let styles = broadcast(&styles, 4);

let top = BorderSide { width: widths[0], color: colors[0], style: styles[0] };
let left = BorderSide { width: widths[1], color: colors[1], style: styles[1] };
let bottom = BorderSide { width: widths[2], color: colors[2], style: styles[2] };
let right = BorderSide { width: widths[3], color: colors[3], style: styles[3] };

let widths = BorderWidths { top: widths[0], left: widths[1], bottom: widths[2], right: widths[3] };
let top = BorderSide { color: colors[0], style: styles[0] };
let left = BorderSide { color: colors[1], style: styles[1] };
let bottom = BorderSide { color: colors[2], style: styles[2] };
let right = BorderSide { color: colors[3], style: styles[3] };
let details = BorderDetails::Normal(NormalBorder {
top: top,
left: left,
bottom: bottom,
right: right,
radius: radius,
});
let clip = self.to_clip_region(&item["clip"], &bounds, wrench).unwrap_or(*clip_region);
self.builder().push_border(bounds, clip, left, top, right, bottom, radius);
self.builder().push_border(bounds,
clip,
widths,
details);
}

fn handle_box_shadow(&mut self, wrench: &mut Wrench, clip_region: &ClipRegion, item: &Yaml) {
@@ -559,28 +559,38 @@ impl YamlFrameWriter {
},
Border(item) => {
str_node(&mut v, "type", "border");
let trbl = vec![&item.top, &item.right, &item.bottom, &item.left];
let widths: Vec<f32> = trbl.iter().map(|x| x.width).collect();
let colors: Vec<String> = trbl.iter().map(|x| color_to_string(x.color)).collect();
let styles: Vec<String> = trbl.iter().map(|x| {
match x.style {
BorderStyle::None => "none",
BorderStyle::Solid => "solid",
BorderStyle::Double => "double",
BorderStyle::Dotted => "dotted",
BorderStyle::Dashed => "dashed",
BorderStyle::Hidden => "hidden",
BorderStyle::Ridge => "ridge",
BorderStyle::Inset => "inset",
BorderStyle::Outset => "outset",
BorderStyle::Groove => "groove",
}.to_owned()
}).collect();
yaml_node(&mut v, "width", f32_vec_yaml(&widths, true));
yaml_node(&mut v, "color", string_vec_yaml(&colors, true));
yaml_node(&mut v, "style", string_vec_yaml(&styles, true));
if let Some(radius_node) = maybe_radius_yaml(&item.radius) {
yaml_node(&mut v, "radius", radius_node);
match item.details {
BorderDetails::Normal(ref details) => {
let trbl = vec![&details.top, &details.right, &details.bottom, &details.left];
let widths: Vec<f32> = vec![ item.widths.top,
item.widths.right,
item.widths.bottom,
item.widths.left ];
let colors: Vec<String> = trbl.iter().map(|x| color_to_string(x.color)).collect();
let styles: Vec<String> = trbl.iter().map(|x| {
match x.style {
BorderStyle::None => "none",
BorderStyle::Solid => "solid",
BorderStyle::Double => "double",
BorderStyle::Dotted => "dotted",
BorderStyle::Dashed => "dashed",
BorderStyle::Hidden => "hidden",
BorderStyle::Ridge => "ridge",
BorderStyle::Inset => "inset",
BorderStyle::Outset => "outset",
BorderStyle::Groove => "groove",
}.to_owned()
}).collect();
yaml_node(&mut v, "width", f32_vec_yaml(&widths, true));
yaml_node(&mut v, "color", string_vec_yaml(&colors, true));
yaml_node(&mut v, "style", string_vec_yaml(&styles, true));
if let Some(radius_node) = maybe_radius_yaml(&details.radius) {
yaml_node(&mut v, "radius", radius_node);
}
}
BorderDetails::Image(..) => {
println!("TODO: image border");
}
}
},
BoxShadow(item) => {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.