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 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Implement support for (most of) border-image.

Add support for borders that use:
 * border-image-source (images only, not gradients yet).
 * border-image-slice
 * border-image-repeat (repeat + stretch only, for now).
 * border-image-outset

The major part of the work is supporting sub-rects when drawing images.

The rest of the work is simply generating image primitives from the
border-image display item description.
  • Loading branch information
gw3583 committed Feb 19, 2017
commit 2af0a01dc29589cd2b922dea03a639be97cbce12
@@ -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;
}
@@ -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,
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.