render: preserve responsive image grid geometry
This commit is contained in:
1 parent
7ddf52eb27
commit
9471591c6c
5 files changed
+104
-15
No files matched your search
@@ -105,8 +105,11 @@ pub struct TextEngine {
|
||||
font_system: FontSystem,
|
||||
swash: SwashCache,
|
||||
items: Vec<InlineItem>,
|
||||
replaced: Vec<(f32, f32)>,
|
||||
}
|
||||
|
||||
const REPLACED_CONTEXT_BIT: usize = 1usize << (usize::BITS - 1);
|
||||
|
||||
impl Default for TextEngine {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
@@ -129,7 +132,12 @@ impl TextEngine {
|
||||
}
|
||||
db.set_sans_serif_family(FAMILY);
|
||||
let font_system = FontSystem::new_with_locale_and_db("en-US".to_string(), db);
|
||||
TextEngine { font_system, swash: SwashCache::new(), items: Vec::new() }
|
||||
TextEngine {
|
||||
font_system,
|
||||
swash: SwashCache::new(),
|
||||
items: Vec::new(),
|
||||
replaced: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Number of inline formatting contexts collected (for debug/stats).
|
||||
@@ -258,6 +266,12 @@ impl TextEngine {
|
||||
/// None for max-content), returning its shaped (width, height). Called by
|
||||
/// taffy's measure function during layout.
|
||||
pub fn measure(&mut self, idx: usize, width: Option<f32>) -> (f32, f32) {
|
||||
if idx & REPLACED_CONTEXT_BIT != 0 {
|
||||
let (iw, ih) = self.replaced[idx & !REPLACED_CONTEXT_BIT];
|
||||
return width
|
||||
.map(|width| (width, width * ih / iw))
|
||||
.unwrap_or((iw, ih));
|
||||
}
|
||||
let TextEngine { font_system, items, .. } = self;
|
||||
let item = &mut items[idx];
|
||||
item.buffer.set_size(font_system, width.map(|w| w.max(0.0)), None);
|
||||
@@ -265,6 +279,51 @@ impl TextEngine {
|
||||
buffer_size(&item.buffer)
|
||||
}
|
||||
|
||||
/// Register a replaced element's intrinsic size as a taffy measure
|
||||
/// context. Percentage-sized image leaves still need their intrinsic
|
||||
/// max-content contribution while an auto-sized ancestor is measured.
|
||||
pub fn register_replaced(&mut self, width: f32, height: f32) -> usize {
|
||||
let index = self.replaced.len();
|
||||
self.replaced.push((width, height));
|
||||
REPLACED_CONTEXT_BIT | index
|
||||
}
|
||||
|
||||
/// Measure either a shaped text context or an intrinsic replaced element.
|
||||
/// Replaced boxes transfer a definite axis through their intrinsic ratio;
|
||||
/// with neither axis definite they contribute their natural size.
|
||||
pub fn measure_taffy(
|
||||
&mut self,
|
||||
idx: usize,
|
||||
known: taffy::Size<Option<f32>>,
|
||||
available: taffy::Size<taffy::AvailableSpace>,
|
||||
) -> taffy::Size<f32> {
|
||||
if idx & REPLACED_CONTEXT_BIT != 0 {
|
||||
let (iw, ih) = self.replaced[idx & !REPLACED_CONTEXT_BIT];
|
||||
return match (known.width, known.height) {
|
||||
(Some(width), Some(height)) => taffy::Size { width, height },
|
||||
(Some(width), None) => taffy::Size {
|
||||
width,
|
||||
height: width * ih / iw,
|
||||
},
|
||||
(None, Some(height)) => taffy::Size {
|
||||
width: height * iw / ih,
|
||||
height,
|
||||
},
|
||||
(None, None) => taffy::Size {
|
||||
width: iw,
|
||||
height: ih,
|
||||
},
|
||||
};
|
||||
}
|
||||
let width = known.width.or(match available.width {
|
||||
taffy::AvailableSpace::Definite(width) => Some(width),
|
||||
taffy::AvailableSpace::MinContent => Some(0.0),
|
||||
taffy::AvailableSpace::MaxContent => None,
|
||||
});
|
||||
let (width, height) = self.measure(idx, width);
|
||||
taffy::Size { width, height }
|
||||
}
|
||||
|
||||
/// After layout, pin each context to its final content-box origin and
|
||||
/// clip, reshaping once at the resolved width so paint draws the same
|
||||
/// line breaks the box was sized for.
|
||||
@@ -628,7 +687,12 @@ impl TextEngine {
|
||||
/// translate()` of the container's ancestors, shifting both the glyph
|
||||
/// origin and the clip so shaped text moves with a transformed box.
|
||||
pub fn paint_item(&mut self, idx: usize, pixmap: &mut tiny_skia::Pixmap, offset: (f32, f32)) {
|
||||
let TextEngine { font_system, swash, items } = self;
|
||||
let TextEngine {
|
||||
font_system,
|
||||
swash,
|
||||
items,
|
||||
..
|
||||
} = self;
|
||||
let Some(item) = items.get_mut(idx) else { return };
|
||||
let (ox, oy) = (item.origin.0 + offset.0, item.origin.1 + offset.1);
|
||||
// The glyph origin shifts by the container's accumulated translate,
|
||||
|
||||
Reference in new issue
Block a user