Add retained paints and shared text selection
This commit is contained in:
1 parent
1e6d3b1edd
commit
a33fbca966
42 files changed
+2424
-470
No files matched your search
+29
-18
@@ -1,4 +1,4 @@
|
||||
use crate::{Align, GlyphAtlas, GlyphKey, PlacedGlyph, RegionAlign, Textures, UiColor, util::Vec2};
|
||||
use crate::{Align, GlyphAtlas, GlyphKey, PaintId, PlacedGlyph, RegionAlign, Textures, util::Vec2};
|
||||
use parley::{
|
||||
Alignment, AlignmentOptions, FontContext, FontFamily, FontFamilyName, FontStyle, FontWeight,
|
||||
GenericFamily, Layout, LayoutContext, LineHeight, PositionedLayoutItem, StyleProperty,
|
||||
@@ -32,7 +32,7 @@ pub struct FontDiagnostics {
|
||||
|
||||
pub struct TextData {
|
||||
pub font_cx: FontContext,
|
||||
pub layout_cx: LayoutContext<UiColor>,
|
||||
pub layout_cx: LayoutContext<PaintId>,
|
||||
scale_cx: ScaleContext,
|
||||
pub atlas: GlyphAtlas,
|
||||
/// Physical pixels per dp -- a second copy of
|
||||
@@ -240,8 +240,13 @@ impl TextData {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn place(&mut self, buffer: &TextBuffer, textures: &mut Textures) -> Vec<PlacedGlyph> {
|
||||
pub fn place(
|
||||
&mut self,
|
||||
buffer: &TextBuffer,
|
||||
textures: &mut Textures,
|
||||
) -> (Vec<PlacedGlyph>, Vec<PaintId>) {
|
||||
let mut placed = Vec::new();
|
||||
let mut paints = Vec::new();
|
||||
for line in buffer.layout.lines() {
|
||||
for item in line.items() {
|
||||
let PositionedLayoutItem::GlyphRun(run) = item else {
|
||||
@@ -250,7 +255,10 @@ impl TextData {
|
||||
let font = run.run().font();
|
||||
let font_size = run.run().font_size();
|
||||
let coords = run.run().normalized_coords();
|
||||
let run_color = run.style().brush;
|
||||
let run_color = run.style().brush.clone();
|
||||
if !paints.contains(&run_color) {
|
||||
paints.push(run_color.clone());
|
||||
}
|
||||
let Some(font_ref) = FontRef::from_index(font.data.as_ref(), font.index as usize)
|
||||
else {
|
||||
continue;
|
||||
@@ -301,12 +309,12 @@ impl TextData {
|
||||
glyph.x.floor() + entry.left as f32,
|
||||
glyph.y.floor() - entry.top as f32,
|
||||
),
|
||||
color: run_color,
|
||||
paint: run_color.slot(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
placed
|
||||
(placed, paints)
|
||||
}
|
||||
|
||||
pub fn render(
|
||||
@@ -318,11 +326,12 @@ impl TextData {
|
||||
density: f32,
|
||||
) -> RenderedText {
|
||||
buffer.shape(self, attrs, width, density);
|
||||
let glyphs = self.place(buffer, textures);
|
||||
let (glyphs, paints) = self.place(buffer, textures);
|
||||
RenderedText {
|
||||
glyphs: std::sync::Arc::new(glyphs),
|
||||
paints: std::sync::Arc::new(paints),
|
||||
size: buffer.size(),
|
||||
color: attrs.color,
|
||||
color: attrs.color.clone(),
|
||||
generation: self.atlas.generation(),
|
||||
}
|
||||
}
|
||||
@@ -359,7 +368,7 @@ impl Family {
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct SpanStyle {
|
||||
pub range: Range<usize>,
|
||||
pub color: Option<UiColor>,
|
||||
pub color: Option<PaintId>,
|
||||
pub family: Option<Family>,
|
||||
pub font_size: Option<f32>,
|
||||
pub bold: bool,
|
||||
@@ -379,7 +388,7 @@ impl SpanStyle {
|
||||
underline: false,
|
||||
}
|
||||
}
|
||||
pub fn color(mut self, color: UiColor) -> Self {
|
||||
pub fn color(mut self, color: PaintId) -> Self {
|
||||
self.color = Some(color);
|
||||
self
|
||||
}
|
||||
@@ -407,7 +416,7 @@ impl SpanStyle {
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct TextAttrs {
|
||||
pub color: UiColor,
|
||||
pub color: PaintId,
|
||||
pub font_size: f32,
|
||||
pub line_height: f32,
|
||||
pub family: Family,
|
||||
@@ -421,7 +430,7 @@ impl Default for TextAttrs {
|
||||
fn default() -> Self {
|
||||
let size = 16.0;
|
||||
Self {
|
||||
color: UiColor::WHITE,
|
||||
color: PaintId::WHITE,
|
||||
font_size: size,
|
||||
line_height: size * LINE_HEIGHT_MULT,
|
||||
family: Family::SansSerif,
|
||||
@@ -436,7 +445,7 @@ impl Default for TextAttrs {
|
||||
/// them apart is how they get out of step.
|
||||
pub struct TextBuffer {
|
||||
text: String,
|
||||
layout: Layout<UiColor>,
|
||||
layout: Layout<PaintId>,
|
||||
spans: Vec<SpanStyle>,
|
||||
shaped: Option<(TextAttrs, Option<f32>, f32)>,
|
||||
}
|
||||
@@ -464,7 +473,7 @@ impl TextBuffer {
|
||||
&self.text
|
||||
}
|
||||
|
||||
pub fn layout(&self) -> &Layout<UiColor> {
|
||||
pub fn layout(&self) -> &Layout<PaintId> {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
@@ -515,11 +524,11 @@ impl TextBuffer {
|
||||
builder.push_default(StyleProperty::LineHeight(LineHeight::Absolute(
|
||||
attrs.line_height * density,
|
||||
)));
|
||||
builder.push_default(StyleProperty::Brush(attrs.color));
|
||||
builder.push_default(StyleProperty::Brush(attrs.color.clone()));
|
||||
for (span, family) in self.spans.iter().zip(&span_families) {
|
||||
let range = span.range.clone();
|
||||
if let Some(color) = span.color {
|
||||
builder.push(StyleProperty::Brush(color), range.clone());
|
||||
if let Some(color) = &span.color {
|
||||
builder.push(StyleProperty::Brush(color.clone()), range.clone());
|
||||
}
|
||||
if let Some(family) = family {
|
||||
builder.push(StyleProperty::FontFamily(family.family()), range.clone());
|
||||
@@ -563,8 +572,10 @@ fn hash_coords(coords: &[i16]) -> u64 {
|
||||
#[derive(Clone)]
|
||||
pub struct RenderedText {
|
||||
pub glyphs: std::sync::Arc<Vec<PlacedGlyph>>,
|
||||
/// The unique handles whose compact slots the glyphs above carry.
|
||||
pub paints: std::sync::Arc<Vec<PaintId>>,
|
||||
pub size: Vec2,
|
||||
pub color: UiColor,
|
||||
pub color: PaintId,
|
||||
/// The [`GlyphAtlas::generation`] the glyphs above were placed against.
|
||||
/// A holder must re-render rather than re-emit these quads once the
|
||||
/// atlas has moved on (`GlyphAtlas::clear`'s doc says what happens
|
||||
|
||||
Reference in new issue
Block a user