mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1606771 - Implement border-image-repeat: round in WebRender. r=jrmuizel,kvark
border-image-repeat: Round is equivalent to Repeat with the pattern size adjusted to fill the area with a whole number of repetitions. This is done by adjusting the segment's stretch_size in the shader so that it fits a whole number of times in the segment's size. Differential Revision: https://phabricator.services.mozilla.com/D59370 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
7c24851526
commit
725d18b7cb
@ -112,7 +112,9 @@ void multi_brush_vs(
|
||||
#define BRUSH_FLAG_SEGMENT_RELATIVE 2
|
||||
#define BRUSH_FLAG_SEGMENT_REPEAT_X 4
|
||||
#define BRUSH_FLAG_SEGMENT_REPEAT_Y 8
|
||||
#define BRUSH_FLAG_TEXEL_RECT 16
|
||||
#define BRUSH_FLAG_SEGMENT_REPEAT_X_ROUND 16
|
||||
#define BRUSH_FLAG_SEGMENT_REPEAT_Y_ROUND 32
|
||||
#define BRUSH_FLAG_TEXEL_RECT 64
|
||||
|
||||
#define INVALID_SEGMENT_INDEX 0xffff
|
||||
|
||||
|
@ -103,20 +103,35 @@ void image_brush_vs(
|
||||
uv0 = res.uv_rect.p0 + segment_data.xy * uv_size;
|
||||
uv1 = res.uv_rect.p0 + segment_data.zw * uv_size;
|
||||
|
||||
#ifdef WR_FEATURE_REPETITION
|
||||
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) {
|
||||
stretch_size.x = local_rect.size.y / dy * dx;
|
||||
}
|
||||
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) {
|
||||
stretch_size.y = local_rect.size.x / dx * dy;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifdef WR_FEATURE_REPETITION
|
||||
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) {
|
||||
stretch_size.x = dx;
|
||||
}
|
||||
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) {
|
||||
stretch_size.y = dy;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WR_FEATURE_REPETITION
|
||||
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X_ROUND) != 0) {
|
||||
float nx = max(1.0, round(segment_rect.size.x / stretch_size.x));
|
||||
stretch_size.x = segment_rect.size.x / nx;
|
||||
}
|
||||
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y_ROUND) != 0) {
|
||||
float ny = max(1.0, round(segment_rect.size.y / stretch_size.y));
|
||||
stretch_size.y = segment_rect.size.y / ny;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
float perspective_interpolate = (brush_flags & BRUSH_FLAG_PERSPECTIVE_INTERPOLATION) != 0 ? 1.0 : 0.0;
|
||||
|
@ -1351,38 +1351,43 @@ impl NinePatchDescriptor {
|
||||
repeat_horizontal: RepeatMode,
|
||||
repeat_vertical: RepeatMode
|
||||
) {
|
||||
if uv_rect.uv1.x > uv_rect.uv0.x &&
|
||||
uv_rect.uv1.y > uv_rect.uv0.y {
|
||||
|
||||
// Use segment relative interpolation for all
|
||||
// instances in this primitive.
|
||||
let mut brush_flags =
|
||||
BrushFlags::SEGMENT_RELATIVE |
|
||||
BrushFlags::SEGMENT_TEXEL_RECT;
|
||||
|
||||
// Enable repeat modes on the segment.
|
||||
if repeat_horizontal == RepeatMode::Repeat {
|
||||
brush_flags |= BrushFlags::SEGMENT_REPEAT_X;
|
||||
}
|
||||
if repeat_vertical == RepeatMode::Repeat {
|
||||
brush_flags |= BrushFlags::SEGMENT_REPEAT_Y;
|
||||
}
|
||||
|
||||
let segment = BrushSegment::new(
|
||||
rect,
|
||||
true,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
[
|
||||
uv_rect.uv0.x,
|
||||
uv_rect.uv0.y,
|
||||
uv_rect.uv1.x,
|
||||
uv_rect.uv1.y,
|
||||
],
|
||||
brush_flags,
|
||||
);
|
||||
|
||||
segments.push(segment);
|
||||
if uv_rect.uv1.x < uv_rect.uv0.x || uv_rect.uv1.y < uv_rect.uv0.y {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use segment relative interpolation for all
|
||||
// instances in this primitive.
|
||||
let mut brush_flags =
|
||||
BrushFlags::SEGMENT_RELATIVE |
|
||||
BrushFlags::SEGMENT_TEXEL_RECT;
|
||||
|
||||
// Enable repeat modes on the segment.
|
||||
if repeat_horizontal == RepeatMode::Repeat {
|
||||
brush_flags |= BrushFlags::SEGMENT_REPEAT_X;
|
||||
} else if repeat_horizontal == RepeatMode::Round {
|
||||
brush_flags |= BrushFlags::SEGMENT_REPEAT_X | BrushFlags::SEGMENT_REPEAT_X_ROUND;
|
||||
}
|
||||
|
||||
if repeat_vertical == RepeatMode::Repeat {
|
||||
brush_flags |= BrushFlags::SEGMENT_REPEAT_Y;
|
||||
} else if repeat_vertical == RepeatMode::Round {
|
||||
brush_flags |= BrushFlags::SEGMENT_REPEAT_Y | BrushFlags::SEGMENT_REPEAT_Y_ROUND;
|
||||
}
|
||||
|
||||
let segment = BrushSegment::new(
|
||||
rect,
|
||||
true,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
[
|
||||
uv_rect.uv0.x,
|
||||
uv_rect.uv0.y,
|
||||
uv_rect.uv1.x,
|
||||
uv_rect.uv1.y,
|
||||
],
|
||||
brush_flags,
|
||||
);
|
||||
|
||||
segments.push(segment);
|
||||
}
|
||||
|
||||
// Build the list of image segments
|
||||
|
@ -403,16 +403,20 @@ bitflags! {
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct BrushFlags: u8 {
|
||||
/// Apply perspective interpolation to UVs
|
||||
const PERSPECTIVE_INTERPOLATION = 0x1;
|
||||
const PERSPECTIVE_INTERPOLATION = 1;
|
||||
/// Do interpolation relative to segment rect,
|
||||
/// rather than primitive rect.
|
||||
const SEGMENT_RELATIVE = 0x2;
|
||||
const SEGMENT_RELATIVE = 2;
|
||||
/// Repeat UVs horizontally.
|
||||
const SEGMENT_REPEAT_X = 0x4;
|
||||
const SEGMENT_REPEAT_X = 4;
|
||||
/// Repeat UVs vertically.
|
||||
const SEGMENT_REPEAT_Y = 0x8;
|
||||
const SEGMENT_REPEAT_Y = 8;
|
||||
/// Horizontally follow border-image-repeat: round
|
||||
const SEGMENT_REPEAT_X_ROUND = 16;
|
||||
/// Vorizontally follow border-image-repeat: round
|
||||
const SEGMENT_REPEAT_Y_ROUND = 32;
|
||||
/// The extra segment data is a texel rect.
|
||||
const SEGMENT_TEXEL_RECT = 0x10;
|
||||
const SEGMENT_TEXEL_RECT = 64;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -715,9 +715,7 @@ ImgDrawResult nsCSSRendering::CreateWebRenderCommandsForBorderWithStyleBorder(
|
||||
return ImgDrawResult::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (aStyleBorder.mBorderImageRepeatH == StyleBorderImageRepeat::Round ||
|
||||
aStyleBorder.mBorderImageRepeatH == StyleBorderImageRepeat::Space ||
|
||||
aStyleBorder.mBorderImageRepeatV == StyleBorderImageRepeat::Round ||
|
||||
if (aStyleBorder.mBorderImageRepeatH == StyleBorderImageRepeat::Space ||
|
||||
aStyleBorder.mBorderImageRepeatV == StyleBorderImageRepeat::Space) {
|
||||
return ImgDrawResult::NOT_SUPPORTED;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user