mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1571974: Make prim_store::get_line_decoration_sizes return an oriented 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 --HG-- extra : rebase_source : 093d572a7a35bddc6e070fc08d511f7f164a4d89 extra : source : 3549dd471446c291864822736f4587c81741cd56
This commit is contained in:
parent
3d5caced73
commit
3e1f7b939b
@ -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,20 +4166,20 @@ 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);
|
||||
@ -4169,9 +4187,14 @@ pub fn get_line_decoration_sizes(
|
||||
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(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user