Make basic text shaping the default shaping strategy
This commit is contained in:
parent
57a276e165
commit
33b5a90019
24 changed files with 140 additions and 10 deletions
|
|
@ -62,6 +62,7 @@ impl text::Renderer for Null {
|
||||||
_size: f32,
|
_size: f32,
|
||||||
_font: Font,
|
_font: Font,
|
||||||
_bounds: Size,
|
_bounds: Size,
|
||||||
|
_needs_shaping: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
(0.0, 20.0)
|
(0.0, 20.0)
|
||||||
}
|
}
|
||||||
|
|
@ -74,6 +75,7 @@ impl text::Renderer for Null {
|
||||||
_bounds: Size,
|
_bounds: Size,
|
||||||
_point: Point,
|
_point: Point,
|
||||||
_nearest_only: bool,
|
_nearest_only: bool,
|
||||||
|
_advanced_shape: bool,
|
||||||
) -> Option<text::Hit> {
|
) -> Option<text::Hit> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,15 @@ pub struct Text<'a, Font> {
|
||||||
|
|
||||||
/// The vertical alignment of the [`Text`].
|
/// The vertical alignment of the [`Text`].
|
||||||
pub vertical_alignment: alignment::Vertical,
|
pub vertical_alignment: alignment::Vertical,
|
||||||
|
|
||||||
|
/// Whether the [`Text`] needs advanced shaping and font fallback.
|
||||||
|
///
|
||||||
|
/// You will need to enable this flag if the text contains a complex
|
||||||
|
/// script, the font used needs it, and/or multiple fonts in your system
|
||||||
|
/// may be needed to display all of the glyphs.
|
||||||
|
///
|
||||||
|
/// Advanced shaping is expensive! You should only enable it when necessary.
|
||||||
|
pub advanced_shape: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of hit testing on text.
|
/// The result of hit testing on text.
|
||||||
|
|
@ -77,11 +86,19 @@ pub trait Renderer: crate::Renderer {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Self::Font,
|
font: Self::Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32);
|
) -> (f32, f32);
|
||||||
|
|
||||||
/// Measures the width of the text as if it were laid out in a single line.
|
/// Measures the width of the text as if it were laid out in a single line.
|
||||||
fn measure_width(&self, content: &str, size: f32, font: Self::Font) -> f32 {
|
fn measure_width(
|
||||||
let (width, _) = self.measure(content, size, font, Size::INFINITY);
|
&self,
|
||||||
|
content: &str,
|
||||||
|
size: f32,
|
||||||
|
font: Self::Font,
|
||||||
|
advanced_shape: bool,
|
||||||
|
) -> f32 {
|
||||||
|
let (width, _) =
|
||||||
|
self.measure(content, size, font, Size::INFINITY, advanced_shape);
|
||||||
|
|
||||||
width
|
width
|
||||||
}
|
}
|
||||||
|
|
@ -101,6 +118,7 @@ pub trait Renderer: crate::Renderer {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
nearest_only: bool,
|
nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<Hit>;
|
) -> Option<Hit>;
|
||||||
|
|
||||||
/// Loads a [`Self::Font`] from its bytes.
|
/// Loads a [`Self::Font`] from its bytes.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ where
|
||||||
vertical_alignment: alignment::Vertical,
|
vertical_alignment: alignment::Vertical,
|
||||||
font: Option<Renderer::Font>,
|
font: Option<Renderer::Font>,
|
||||||
style: <Renderer::Theme as StyleSheet>::Style,
|
style: <Renderer::Theme as StyleSheet>::Style,
|
||||||
|
advanced_shape: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Renderer> Text<'a, Renderer>
|
impl<'a, Renderer> Text<'a, Renderer>
|
||||||
|
|
@ -43,6 +44,7 @@ where
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Top,
|
vertical_alignment: alignment::Vertical::Top,
|
||||||
style: Default::default(),
|
style: Default::default(),
|
||||||
|
advanced_shape: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,6 +100,20 @@ where
|
||||||
self.vertical_alignment = alignment;
|
self.vertical_alignment = alignment;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enables advanced text shaping and font fallback for the [`Text`].
|
||||||
|
///
|
||||||
|
/// You will need to enable this if the text contains a complex script, the
|
||||||
|
/// font used needs it, and/or multiple fonts in your system may be needed
|
||||||
|
/// to display all of the glyphs.
|
||||||
|
///
|
||||||
|
/// If your text isn't displaying properly, try enabling this!
|
||||||
|
///
|
||||||
|
/// Advanced shaping is expensive! You should only enable it when necessary.
|
||||||
|
pub fn advanced_shape(mut self) -> Self {
|
||||||
|
self.advanced_shape = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Widget<Message, Renderer> for Text<'a, Renderer>
|
impl<'a, Message, Renderer> Widget<Message, Renderer> for Text<'a, Renderer>
|
||||||
|
|
@ -129,6 +145,7 @@ where
|
||||||
size,
|
size,
|
||||||
self.font.unwrap_or_else(|| renderer.default_font()),
|
self.font.unwrap_or_else(|| renderer.default_font()),
|
||||||
bounds,
|
bounds,
|
||||||
|
self.advanced_shape,
|
||||||
);
|
);
|
||||||
|
|
||||||
let size = limits.resolve(Size::new(width, height));
|
let size = limits.resolve(Size::new(width, height));
|
||||||
|
|
@ -156,6 +173,7 @@ where
|
||||||
theme.appearance(self.style.clone()),
|
theme.appearance(self.style.clone()),
|
||||||
self.horizontal_alignment,
|
self.horizontal_alignment,
|
||||||
self.vertical_alignment,
|
self.vertical_alignment,
|
||||||
|
self.advanced_shape,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -180,6 +198,7 @@ pub fn draw<Renderer>(
|
||||||
appearance: Appearance,
|
appearance: Appearance,
|
||||||
horizontal_alignment: alignment::Horizontal,
|
horizontal_alignment: alignment::Horizontal,
|
||||||
vertical_alignment: alignment::Vertical,
|
vertical_alignment: alignment::Vertical,
|
||||||
|
advanced_shape: bool,
|
||||||
) where
|
) where
|
||||||
Renderer: text::Renderer,
|
Renderer: text::Renderer,
|
||||||
{
|
{
|
||||||
|
|
@ -205,6 +224,7 @@ pub fn draw<Renderer>(
|
||||||
font: font.unwrap_or_else(|| renderer.default_font()),
|
font: font.unwrap_or_else(|| renderer.default_font()),
|
||||||
horizontal_alignment,
|
horizontal_alignment,
|
||||||
vertical_alignment,
|
vertical_alignment,
|
||||||
|
advanced_shape,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,6 +254,7 @@ where
|
||||||
vertical_alignment: self.vertical_alignment,
|
vertical_alignment: self.vertical_alignment,
|
||||||
font: self.font,
|
font: self.font,
|
||||||
style: self.style.clone(),
|
style: self.style.clone(),
|
||||||
|
advanced_shape: self.advanced_shape,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ pub trait Text {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32);
|
) -> (f32, f32);
|
||||||
|
|
||||||
/// Tests whether the provided point is within the boundaries of [`Text`]
|
/// Tests whether the provided point is within the boundaries of [`Text`]
|
||||||
|
|
@ -65,6 +66,7 @@ pub trait Text {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
nearest_only: bool,
|
nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<text::Hit>;
|
) -> Option<text::Hit>;
|
||||||
|
|
||||||
/// Loads a [`Font`] from its bytes.
|
/// Loads a [`Font`] from its bytes.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,15 @@ pub struct Text {
|
||||||
pub horizontal_alignment: alignment::Horizontal,
|
pub horizontal_alignment: alignment::Horizontal,
|
||||||
/// The vertical alignment of the text
|
/// The vertical alignment of the text
|
||||||
pub vertical_alignment: alignment::Vertical,
|
pub vertical_alignment: alignment::Vertical,
|
||||||
|
/// Whether the text needs advanced shaping and font fallback.
|
||||||
|
///
|
||||||
|
/// You will need to enable this flag if the text contains a complex
|
||||||
|
/// script, the font used needs it, and/or multiple fonts in your system
|
||||||
|
/// may be needed to display all of the glyphs.
|
||||||
|
///
|
||||||
|
/// Advanced shaping is expensive! You should only enable it when
|
||||||
|
/// necessary.
|
||||||
|
pub advanced_shape: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Text {
|
impl Default for Text {
|
||||||
|
|
@ -37,6 +46,7 @@ impl Default for Text {
|
||||||
font: Font::default(),
|
font: Font::default(),
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Top,
|
vertical_alignment: alignment::Vertical::Top,
|
||||||
|
advanced_shape: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,15 @@ pub enum Primitive {
|
||||||
horizontal_alignment: alignment::Horizontal,
|
horizontal_alignment: alignment::Horizontal,
|
||||||
/// The vertical alignment of the text
|
/// The vertical alignment of the text
|
||||||
vertical_alignment: alignment::Vertical,
|
vertical_alignment: alignment::Vertical,
|
||||||
|
/// Whether the text needs advanced shaping and font fallback.
|
||||||
|
///
|
||||||
|
/// You will need to enable this flag if the text contains a complex
|
||||||
|
/// script, the font used needs it, and/or multiple fonts in your system
|
||||||
|
/// may be needed to display all of the glyphs.
|
||||||
|
///
|
||||||
|
/// Advanced shaping is expensive! You should only enable it when
|
||||||
|
/// necessary.
|
||||||
|
advanced_shape: bool,
|
||||||
},
|
},
|
||||||
/// A quad primitive
|
/// A quad primitive
|
||||||
Quad {
|
Quad {
|
||||||
|
|
|
||||||
|
|
@ -138,8 +138,10 @@ where
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
needs_shaping: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
self.backend().measure(content, size, font, bounds)
|
self.backend()
|
||||||
|
.measure(content, size, font, bounds, needs_shaping)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_test(
|
fn hit_test(
|
||||||
|
|
@ -150,6 +152,7 @@ where
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
nearest_only: bool,
|
nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<text::Hit> {
|
) -> Option<text::Hit> {
|
||||||
self.backend().hit_test(
|
self.backend().hit_test(
|
||||||
content,
|
content,
|
||||||
|
|
@ -158,6 +161,7 @@ where
|
||||||
bounds,
|
bounds,
|
||||||
point,
|
point,
|
||||||
nearest_only,
|
nearest_only,
|
||||||
|
advanced_shape,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,6 +178,7 @@ where
|
||||||
font: text.font,
|
font: text.font,
|
||||||
horizontal_alignment: text.horizontal_alignment,
|
horizontal_alignment: text.horizontal_alignment,
|
||||||
vertical_alignment: text.vertical_alignment,
|
vertical_alignment: text.vertical_alignment,
|
||||||
|
advanced_shape: text.advanced_shape,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,13 @@ impl backend::Text for Backend {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
delegate!(self, backend, backend.measure(contents, size, font, bounds))
|
delegate!(
|
||||||
|
self,
|
||||||
|
backend,
|
||||||
|
backend.measure(contents, size, font, bounds, advanced_shape)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_test(
|
fn hit_test(
|
||||||
|
|
@ -60,6 +65,7 @@ impl backend::Text for Backend {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
position: Point,
|
position: Point,
|
||||||
nearest_only: bool,
|
nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<text::Hit> {
|
) -> Option<text::Hit> {
|
||||||
delegate!(
|
delegate!(
|
||||||
self,
|
self,
|
||||||
|
|
@ -70,7 +76,8 @@ impl backend::Text for Backend {
|
||||||
font,
|
font,
|
||||||
bounds,
|
bounds,
|
||||||
position,
|
position,
|
||||||
nearest_only
|
nearest_only,
|
||||||
|
advanced_shape
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ geometry = ["iced_graphics/geometry"]
|
||||||
raw-window-handle = "0.5"
|
raw-window-handle = "0.5"
|
||||||
softbuffer = "0.2"
|
softbuffer = "0.2"
|
||||||
tiny-skia = "0.9"
|
tiny-skia = "0.9"
|
||||||
cosmic-text = "0.8"
|
|
||||||
bytemuck = "1"
|
bytemuck = "1"
|
||||||
rustc-hash = "1.1"
|
rustc-hash = "1.1"
|
||||||
kurbo = "0.9"
|
kurbo = "0.9"
|
||||||
|
|
@ -23,6 +22,10 @@ version = "0.8"
|
||||||
path = "../graphics"
|
path = "../graphics"
|
||||||
features = ["tiny-skia"]
|
features = ["tiny-skia"]
|
||||||
|
|
||||||
|
[dependencies.cosmic-text]
|
||||||
|
git = "https://github.com/hecrj/cosmic-text.git"
|
||||||
|
rev = "ad111a1df10d5da503620f4b841de5d41ebd4e73"
|
||||||
|
|
||||||
[dependencies.twox-hash]
|
[dependencies.twox-hash]
|
||||||
version = "1.6"
|
version = "1.6"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,7 @@ impl Backend {
|
||||||
font,
|
font,
|
||||||
horizontal_alignment,
|
horizontal_alignment,
|
||||||
vertical_alignment,
|
vertical_alignment,
|
||||||
|
advanced_shape,
|
||||||
} => {
|
} => {
|
||||||
let physical_bounds =
|
let physical_bounds =
|
||||||
(primitive.bounds() + translation) * scale_factor;
|
(primitive.bounds() + translation) * scale_factor;
|
||||||
|
|
@ -238,6 +239,7 @@ impl Backend {
|
||||||
*font,
|
*font,
|
||||||
*horizontal_alignment,
|
*horizontal_alignment,
|
||||||
*vertical_alignment,
|
*vertical_alignment,
|
||||||
|
*advanced_shape,
|
||||||
pixels,
|
pixels,
|
||||||
clip_mask,
|
clip_mask,
|
||||||
);
|
);
|
||||||
|
|
@ -626,8 +628,10 @@ impl backend::Text for Backend {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
self.text_pipeline.measure(contents, size, font, bounds)
|
self.text_pipeline
|
||||||
|
.measure(contents, size, font, bounds, advanced_shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_test(
|
fn hit_test(
|
||||||
|
|
@ -638,6 +642,7 @@ impl backend::Text for Backend {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
nearest_only: bool,
|
nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<text::Hit> {
|
) -> Option<text::Hit> {
|
||||||
self.text_pipeline.hit_test(
|
self.text_pipeline.hit_test(
|
||||||
contents,
|
contents,
|
||||||
|
|
@ -646,6 +651,7 @@ impl backend::Text for Backend {
|
||||||
bounds,
|
bounds,
|
||||||
point,
|
point,
|
||||||
nearest_only,
|
nearest_only,
|
||||||
|
advanced_shape,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ impl Frame {
|
||||||
font: text.font,
|
font: text.font,
|
||||||
horizontal_alignment: text.horizontal_alignment,
|
horizontal_alignment: text.horizontal_alignment,
|
||||||
vertical_alignment: text.vertical_alignment,
|
vertical_alignment: text.vertical_alignment,
|
||||||
|
advanced_shape: text.advanced_shape,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ impl Pipeline {
|
||||||
font: Font,
|
font: Font,
|
||||||
horizontal_alignment: alignment::Horizontal,
|
horizontal_alignment: alignment::Horizontal,
|
||||||
vertical_alignment: alignment::Vertical,
|
vertical_alignment: alignment::Vertical,
|
||||||
|
advanced_shape: bool,
|
||||||
pixels: &mut tiny_skia::PixmapMut<'_>,
|
pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||||
clip_mask: Option<&tiny_skia::Mask>,
|
clip_mask: Option<&tiny_skia::Mask>,
|
||||||
) {
|
) {
|
||||||
|
|
@ -63,6 +64,7 @@ impl Pipeline {
|
||||||
content,
|
content,
|
||||||
font,
|
font,
|
||||||
size,
|
size,
|
||||||
|
advanced_shape,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (_, buffer) = self.render_cache.allocate(font_system, key);
|
let (_, buffer) = self.render_cache.allocate(font_system, key);
|
||||||
|
|
@ -130,6 +132,7 @@ impl Pipeline {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
||||||
|
|
||||||
|
|
@ -140,6 +143,7 @@ impl Pipeline {
|
||||||
size,
|
size,
|
||||||
font,
|
font,
|
||||||
bounds,
|
bounds,
|
||||||
|
advanced_shape,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -161,6 +165,7 @@ impl Pipeline {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
_nearest_only: bool,
|
_nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<Hit> {
|
) -> Option<Hit> {
|
||||||
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
||||||
|
|
||||||
|
|
@ -171,6 +176,7 @@ impl Pipeline {
|
||||||
size,
|
size,
|
||||||
font,
|
font,
|
||||||
bounds,
|
bounds,
|
||||||
|
advanced_shape,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -390,6 +396,7 @@ impl Cache {
|
||||||
.family(to_family(key.font.family))
|
.family(to_family(key.font.family))
|
||||||
.weight(to_weight(key.font.weight))
|
.weight(to_weight(key.font.weight))
|
||||||
.stretch(to_stretch(key.font.stretch)),
|
.stretch(to_stretch(key.font.stretch)),
|
||||||
|
!key.advanced_shape,
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ = entry.insert(buffer);
|
let _ = entry.insert(buffer);
|
||||||
|
|
@ -420,6 +427,7 @@ struct Key<'a> {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyHash = u64;
|
type KeyHash = u64;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ path = "../graphics"
|
||||||
[dependencies.glyphon]
|
[dependencies.glyphon]
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
git = "https://github.com/hecrj/glyphon.git"
|
git = "https://github.com/hecrj/glyphon.git"
|
||||||
rev = "1d26d92b19407c5dabe4625944d4a6babbbf0715"
|
rev = "446cf0803065b52ba5fb9a30fe0addb6d7b5f9d9"
|
||||||
|
|
||||||
[dependencies.encase]
|
[dependencies.encase]
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
|
||||||
|
|
@ -354,8 +354,10 @@ impl backend::Text for Backend {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
self.text_pipeline.measure(contents, size, font, bounds)
|
self.text_pipeline
|
||||||
|
.measure(contents, size, font, bounds, advanced_shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_test(
|
fn hit_test(
|
||||||
|
|
@ -366,6 +368,7 @@ impl backend::Text for Backend {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
nearest_only: bool,
|
nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<core::text::Hit> {
|
) -> Option<core::text::Hit> {
|
||||||
self.text_pipeline.hit_test(
|
self.text_pipeline.hit_test(
|
||||||
contents,
|
contents,
|
||||||
|
|
@ -374,6 +377,7 @@ impl backend::Text for Backend {
|
||||||
bounds,
|
bounds,
|
||||||
point,
|
point,
|
||||||
nearest_only,
|
nearest_only,
|
||||||
|
advanced_shape,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,7 @@ impl Frame {
|
||||||
font: text.font,
|
font: text.font,
|
||||||
horizontal_alignment: text.horizontal_alignment,
|
horizontal_alignment: text.horizontal_alignment,
|
||||||
vertical_alignment: text.vertical_alignment,
|
vertical_alignment: text.vertical_alignment,
|
||||||
|
advanced_shape: text.advanced_shape,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ impl<'a> Layer<'a> {
|
||||||
font: Font::MONOSPACE,
|
font: Font::MONOSPACE,
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Top,
|
vertical_alignment: alignment::Vertical::Top,
|
||||||
|
advanced_shape: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
overlay.text.push(text);
|
overlay.text.push(text);
|
||||||
|
|
@ -116,6 +117,7 @@ impl<'a> Layer<'a> {
|
||||||
font,
|
font,
|
||||||
horizontal_alignment,
|
horizontal_alignment,
|
||||||
vertical_alignment,
|
vertical_alignment,
|
||||||
|
advanced_shape,
|
||||||
} => {
|
} => {
|
||||||
let layer = &mut layers[current_layer];
|
let layer = &mut layers[current_layer];
|
||||||
|
|
||||||
|
|
@ -127,6 +129,7 @@ impl<'a> Layer<'a> {
|
||||||
font: *font,
|
font: *font,
|
||||||
horizontal_alignment: *horizontal_alignment,
|
horizontal_alignment: *horizontal_alignment,
|
||||||
vertical_alignment: *vertical_alignment,
|
vertical_alignment: *vertical_alignment,
|
||||||
|
advanced_shape: *advanced_shape,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,14 @@ pub struct Text<'a> {
|
||||||
|
|
||||||
/// The vertical alignment of the [`Text`].
|
/// The vertical alignment of the [`Text`].
|
||||||
pub vertical_alignment: alignment::Vertical,
|
pub vertical_alignment: alignment::Vertical,
|
||||||
|
|
||||||
|
/// Whether the text needs advanced shaping and font fallback.
|
||||||
|
///
|
||||||
|
/// You will need to enable this flag if the text contains a complex
|
||||||
|
/// script, the font used needs it, and/or multiple fonts in your system
|
||||||
|
/// may be needed to display all of the glyphs.
|
||||||
|
///
|
||||||
|
/// Advanced shaping is expensive! You should only enable it when
|
||||||
|
/// necessary.
|
||||||
|
pub advanced_shape: bool,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ impl Pipeline {
|
||||||
height: (section.bounds.height * scale_factor)
|
height: (section.bounds.height * scale_factor)
|
||||||
.ceil(),
|
.ceil(),
|
||||||
},
|
},
|
||||||
|
advanced_shape: section.advanced_shape,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -213,6 +214,7 @@ impl Pipeline {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> (f32, f32) {
|
) -> (f32, f32) {
|
||||||
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
||||||
|
|
||||||
|
|
@ -223,6 +225,7 @@ impl Pipeline {
|
||||||
size,
|
size,
|
||||||
font,
|
font,
|
||||||
bounds,
|
bounds,
|
||||||
|
advanced_shape,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -244,6 +247,7 @@ impl Pipeline {
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
point: Point,
|
point: Point,
|
||||||
_nearest_only: bool,
|
_nearest_only: bool,
|
||||||
|
advanced_shape: bool,
|
||||||
) -> Option<Hit> {
|
) -> Option<Hit> {
|
||||||
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
let mut measurement_cache = self.measurement_cache.borrow_mut();
|
||||||
|
|
||||||
|
|
@ -254,6 +258,7 @@ impl Pipeline {
|
||||||
size,
|
size,
|
||||||
font,
|
font,
|
||||||
bounds,
|
bounds,
|
||||||
|
advanced_shape,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -364,6 +369,7 @@ impl Cache {
|
||||||
.family(to_family(key.font.family))
|
.family(to_family(key.font.family))
|
||||||
.weight(to_weight(key.font.weight))
|
.weight(to_weight(key.font.weight))
|
||||||
.stretch(to_stretch(key.font.stretch)),
|
.stretch(to_stretch(key.font.stretch)),
|
||||||
|
!key.advanced_shape,
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ = entry.insert(buffer);
|
let _ = entry.insert(buffer);
|
||||||
|
|
@ -388,6 +394,7 @@ struct Key<'a> {
|
||||||
size: f32,
|
size: f32,
|
||||||
font: Font,
|
font: Font,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
|
advanced_shape: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyHash = u64;
|
type KeyHash = u64;
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,7 @@ where
|
||||||
color: custom_style.icon_color,
|
color: custom_style.icon_color,
|
||||||
horizontal_alignment: alignment::Horizontal::Center,
|
horizontal_alignment: alignment::Horizontal::Center,
|
||||||
vertical_alignment: alignment::Vertical::Center,
|
vertical_alignment: alignment::Vertical::Center,
|
||||||
|
advanced_shape: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -292,6 +293,7 @@ where
|
||||||
},
|
},
|
||||||
alignment::Horizontal::Left,
|
alignment::Horizontal::Left,
|
||||||
alignment::Vertical::Center,
|
alignment::Vertical::Center,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -500,6 +500,7 @@ where
|
||||||
},
|
},
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Center,
|
vertical_alignment: alignment::Vertical::Center,
|
||||||
|
advanced_shape: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,6 +366,7 @@ where
|
||||||
text_size,
|
text_size,
|
||||||
font.unwrap_or_else(|| renderer.default_font()),
|
font.unwrap_or_else(|| renderer.default_font()),
|
||||||
Size::new(f32::INFINITY, f32::INFINITY),
|
Size::new(f32::INFINITY, f32::INFINITY),
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
width.round()
|
width.round()
|
||||||
|
|
@ -628,6 +629,7 @@ pub fn draw<'a, T, Renderer>(
|
||||||
},
|
},
|
||||||
horizontal_alignment: alignment::Horizontal::Right,
|
horizontal_alignment: alignment::Horizontal::Right,
|
||||||
vertical_alignment: alignment::Vertical::Center,
|
vertical_alignment: alignment::Vertical::Center,
|
||||||
|
advanced_shape: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -653,6 +655,7 @@ pub fn draw<'a, T, Renderer>(
|
||||||
},
|
},
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Center,
|
vertical_alignment: alignment::Vertical::Center,
|
||||||
|
advanced_shape: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,7 @@ where
|
||||||
},
|
},
|
||||||
alignment::Horizontal::Left,
|
alignment::Horizontal::Left,
|
||||||
alignment::Vertical::Center,
|
alignment::Vertical::Center,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -463,6 +463,7 @@ where
|
||||||
&icon.code_point.to_string(),
|
&icon.code_point.to_string(),
|
||||||
icon.size.unwrap_or_else(|| renderer.default_size()),
|
icon.size.unwrap_or_else(|| renderer.default_size()),
|
||||||
icon.font,
|
icon.font,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut text_node = layout::Node::new(
|
let mut text_node = layout::Node::new(
|
||||||
|
|
@ -975,6 +976,7 @@ pub fn draw<Renderer>(
|
||||||
bounds: icon_layout.bounds(),
|
bounds: icon_layout.bounds(),
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Top,
|
vertical_alignment: alignment::Vertical::Top,
|
||||||
|
advanced_shape: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1079,6 +1081,7 @@ pub fn draw<Renderer>(
|
||||||
if text.is_empty() { placeholder } else { &text },
|
if text.is_empty() { placeholder } else { &text },
|
||||||
size,
|
size,
|
||||||
font,
|
font,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
let render = |renderer: &mut Renderer| {
|
let render = |renderer: &mut Renderer| {
|
||||||
|
|
@ -1106,6 +1109,7 @@ pub fn draw<Renderer>(
|
||||||
size,
|
size,
|
||||||
horizontal_alignment: alignment::Horizontal::Left,
|
horizontal_alignment: alignment::Horizontal::Left,
|
||||||
vertical_alignment: alignment::Vertical::Center,
|
vertical_alignment: alignment::Vertical::Center,
|
||||||
|
advanced_shape: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1311,7 +1315,7 @@ where
|
||||||
let text_before_cursor = value.until(cursor_index).to_string();
|
let text_before_cursor = value.until(cursor_index).to_string();
|
||||||
|
|
||||||
let text_value_width =
|
let text_value_width =
|
||||||
renderer.measure_width(&text_before_cursor, size, font);
|
renderer.measure_width(&text_before_cursor, size, font, true);
|
||||||
|
|
||||||
let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0);
|
let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0);
|
||||||
|
|
||||||
|
|
@ -1346,6 +1350,7 @@ where
|
||||||
Size::INFINITY,
|
Size::INFINITY,
|
||||||
Point::new(x + offset, text_bounds.height / 2.0),
|
Point::new(x + offset, text_bounds.height / 2.0),
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
.map(text::Hit::cursor)?;
|
.map(text::Hit::cursor)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,7 @@ where
|
||||||
Default::default(),
|
Default::default(),
|
||||||
self.text_alignment,
|
self.text_alignment,
|
||||||
alignment::Vertical::Center,
|
alignment::Vertical::Center,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue