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

Sync changes from mozilla-central gfx/wr #3848

Merged
merged 6 commits into from Feb 4, 2020

Bug 1571974: Make prim_store::get_line_decoration_sizes return an ori…

…ented LayoutSize. r=kvark

Without this change, get_line_decoration_sizes returns an (inline_size,
block_size) pair, where inline_size is parallel to the line being decorated, and
block_size perpendicular. However, these values are generally used as the
dimensions of an axis-aligned bounding box for the line, not as specific
parameters to the rendering process, so it makes sense to arrange them into a
LayoutSize value in this function, since it is already taking the orientation
into account anyway.

The caller, SceneBuilder::add_line, then doesn't need to swap the components,
and the adjustment of the clipping rectangle to avoid partial dots looks a bit
more natural: widths with widths, heights with heights.

Differential Revision: https://phabricator.services.mozilla.com/D60925

[ghsync] From https://hg.mozilla.org/mozilla-central/rev/9f54a1daf2f205d25f8d1b12ec09ed29176f9f2d
  • Loading branch information
Jim Blandy authored and moz-gfx committed Feb 4, 2020
commit d2cbd3f296c2f1c97f1b71d3860ec555b35eb59d
@@ -4129,14 +4129,32 @@ pub fn get_raster_rects(
Some((clipped.to_i32(), unclipped))
}

/// Get the inline (horizontal) and block (vertical) sizes
/// for a given line decoration.
pub fn get_line_decoration_sizes(
/// Choose the decoration mask tile size for a given line.
///
/// Given a line with overall size `rect_size` and the given `orientation`,
/// return the dimensions of a single mask tile for the decoration pattern
/// described by `style` and `wavy_line_thickness`.
///
/// If `style` is `Solid`, no mask tile is necessary; return `None`. The other
/// styles each have their own characteristic periods of repetition, so for each
/// one, this function returns a `LayoutSize` with the right aspect ratio and
/// whose specific size is convenient for the `cs_line_decoration.glsl` fragment
/// shader to work with. The shader uses a local coordinate space in which the
/// tile fills a rectangle with one corner at the origin, and with the size this
/// function returns.
///
/// The returned size is not necessarily in pixels; device scaling and other
/// concerns can still affect the actual task size.
///
/// Regardless of whether `orientation` is `Vertical` or `Horizontal`, the
/// `width` and `height` of the returned size are always horizontal and
/// vertical, respectively.
pub fn get_line_decoration_size(
rect_size: &LayoutSize,
orientation: LineOrientation,
style: LineStyle,
wavy_line_thickness: f32,
) -> Option<(f32, f32)> {
) -> Option<LayoutSize> {
let h = match orientation {
LineOrientation::Horizontal => rect_size.height,
LineOrientation::Vertical => rect_size.width,
@@ -4148,30 +4166,35 @@ pub fn get_line_decoration_sizes(
// quality on a wider range of inputs!
// See nsCSSRendering::PaintDecorationLine in Gecko.

match style {
let (parallel, perpendicular) = match style {
LineStyle::Solid => {
None
return None;
}
LineStyle::Dashed => {
let dash_length = (3.0 * h).min(64.0).max(1.0);

Some((2.0 * dash_length, 4.0))
(2.0 * dash_length, 4.0)
}
LineStyle::Dotted => {
let diameter = h.min(64.0).max(1.0);
let period = 2.0 * diameter;

Some((period, diameter))
(period, diameter)
}
LineStyle::Wavy => {
let line_thickness = wavy_line_thickness.max(1.0);
let slope_length = h - line_thickness;
let flat_length = ((line_thickness - 1.0) * 2.0).max(1.0);
let approx_period = 2.0 * (slope_length + flat_length);

Some((approx_period, h))
(approx_period, h)
}
}
};

Some(match orientation {
LineOrientation::Horizontal => LayoutSize::new(parallel, perpendicular),
LineOrientation::Vertical => LayoutSize::new(perpendicular, parallel),
})
}

fn update_opacity_binding(
@@ -27,7 +27,7 @@ use crate::prim_store::{PrimitiveInstance, PrimitiveSceneData};
use crate::prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore};
use crate::prim_store::{ScrollNodeAndClipChain, PictureIndex};
use crate::prim_store::{InternablePrimitive, SegmentInstanceIndex};
use crate::prim_store::{register_prim_chase_id, get_line_decoration_sizes};
use crate::prim_store::{register_prim_chase_id, get_line_decoration_size};
use crate::prim_store::{SpaceSnapper};
use crate::prim_store::backdrop::Backdrop;
use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
@@ -2749,33 +2749,28 @@ impl<'a> SceneBuilder<'a> {
// pixel ratio or transform.
let mut info = info.clone();

let size = get_line_decoration_sizes(
let size = get_line_decoration_size(
&info.rect.size,
orientation,
style,
wavy_line_thickness,
);

let cache_key = size.map(|(inline_size, block_size)| {
let size = match orientation {
LineOrientation::Horizontal => LayoutSize::new(inline_size, block_size),
LineOrientation::Vertical => LayoutSize::new(block_size, inline_size),
};

let cache_key = size.map(|size| {
// If dotted, adjust the clip rect to ensure we don't draw a final
// partial dot.
if style == LineStyle::Dotted {
let clip_size = match orientation {
LineOrientation::Horizontal => {
LayoutSize::new(
inline_size * (info.rect.size.width / inline_size).floor(),
size.width * (info.rect.size.width / size.width).floor(),
info.rect.size.height,
)
}
LineOrientation::Vertical => {
LayoutSize::new(
info.rect.size.width,
inline_size * (info.rect.size.height / inline_size).floor(),
size.height * (info.rect.size.height / size.height).floor(),
)
}
};
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.