Ellipsize (#467)
* feat: add Ellipsize enum * chore: API changes needed for ellipsize Decided not to change "layout()" function for now to avoid breaking the interface. For now. * chore: shape ellipsis * feat: Ellipsize::Start Since it can only have 1 line, it's easier to implement. * DROPME: temporarily change rich-text for testing * test(ellipsize): Testing Ellipsize::Start Long text in small buffer should produce ellipsis glyphs * fix: do not need font_system anymore We moved ellipsis shaping elsewhere so no need to pass font_system to layout function (which also was recreating a new one in the tests every time making them take forever). * feat: Ellipsize::End * improv(ellipsize): use a single ellipsis shape * improv: Ellipsie::End && Wrap::None There is no need to layout the whole line if it's not going to fit. * fix: mixed bidi text when Ellipsize::End && Wrap::None * chore: clean up and simplify when line.RTL==span.RTL * fix(ellipsize): last word is not (word_count -1) if iter().rev() * refactor(layout): extract the layout algorithm to make it more readable * improv(ellipsize): Ellipsize::Start && Wrap::None we iterate in reverse and only layout what's going to be visible * Revert: delete the previous approach of post processing ellipsis * doc: explain the interaction between Ellipsize and Wrap * chore: lower the scope * feat: Ellipsize the last line of a paragraph For now only the number of lines is supported * fix: clear ellipsized field on visual lines This was causing ellipsis to show on random lines * chore: remove old tests will add better tests soon * chore: clean up changes from previous attempt * fix: consider the ellipsis width when doing alignment * feat(ellipsize): add `Height` limit to `Ellipsize` * fix: ellipsize the start of the last line correctly * fix: ellipsize at the start of mixed bidi lines * feat: Ellipsize::Middle * fix: consider ellipsize::middle when calculating alignment correction * refactor: improve readability * refactor: deduplicate "fit_glyphs" * refactor: combine backward and forward layout into one (wip) * fix: Backward works in the unified layout_spans * chore: clean up * fix: Ellipsize::Middle * fix: handle large words in bidi boundaries * chore: clean up and some refactoring * fix: ellipsis is now the same level as the surrounding text * fix: try to fit more when ellipsizing::middle * improv: ellipsis now have the same level as the neighbors This makes ellipsized RTL text inside a LTR line more readable. before: Hello سلام...خوبی؟ Hello خولی؟...سلام * fix: some extra words were being rendered in Ellipsize::Middle This was causing the last word (if it's not the same level as the rest) to be rendered outside the buffer. * test: a few test cases for ellipsize * fix: assign the correct byte range to ellipsis this should fix the panic when selecting or clicking on or near the ellipsis in the editor.
This commit is contained in:
parent
4fd11f0e5e
commit
4819bc30fa
18 changed files with 1568 additions and 313 deletions
|
|
@ -11,8 +11,8 @@ use unicode_segmentation::UnicodeSegmentation;
|
|||
|
||||
use crate::{
|
||||
Affinity, Align, Attrs, AttrsList, BidiParagraphs, BorrowedWithFontSystem, BufferLine, Color,
|
||||
Cursor, FontSystem, Hinting, LayoutCursor, LayoutGlyph, LayoutLine, LineEnding, LineIter,
|
||||
Motion, Renderer, Scroll, ShapeLine, Shaping, Wrap,
|
||||
Cursor, Ellipsize, FontSystem, Hinting, LayoutCursor, LayoutGlyph, LayoutLine, LineEnding,
|
||||
LineIter, Motion, Renderer, Scroll, ShapeLine, Shaping, Wrap,
|
||||
};
|
||||
|
||||
/// A line of visible text for rendering
|
||||
|
|
@ -214,6 +214,7 @@ pub struct Buffer {
|
|||
/// True if a redraw is requires. Set to false after processing
|
||||
redraw: bool,
|
||||
wrap: Wrap,
|
||||
ellipsize: Ellipsize,
|
||||
monospace_width: Option<f32>,
|
||||
tab_width: u16,
|
||||
hinting: Hinting,
|
||||
|
|
@ -229,6 +230,7 @@ impl Clone for Buffer {
|
|||
scroll: self.scroll,
|
||||
redraw: self.redraw,
|
||||
wrap: self.wrap,
|
||||
ellipsize: self.ellipsize,
|
||||
monospace_width: self.monospace_width,
|
||||
tab_width: self.tab_width,
|
||||
hinting: self.hinting,
|
||||
|
|
@ -258,6 +260,7 @@ impl Buffer {
|
|||
scroll: Scroll::default(),
|
||||
redraw: false,
|
||||
wrap: Wrap::WordOrGlyph,
|
||||
ellipsize: Ellipsize::None,
|
||||
monospace_width: None,
|
||||
tab_width: 8,
|
||||
hinting: Hinting::default(),
|
||||
|
|
@ -298,6 +301,7 @@ impl Buffer {
|
|||
self.metrics.font_size,
|
||||
self.width_opt,
|
||||
self.wrap,
|
||||
self.ellipsize,
|
||||
self.monospace_width,
|
||||
self.tab_width,
|
||||
self.hinting,
|
||||
|
|
@ -542,6 +546,7 @@ impl Buffer {
|
|||
self.metrics.font_size,
|
||||
self.width_opt,
|
||||
self.wrap,
|
||||
self.ellipsize,
|
||||
self.monospace_width,
|
||||
self.tab_width,
|
||||
self.hinting,
|
||||
|
|
@ -590,6 +595,20 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the current [`Ellipsize`]
|
||||
pub const fn ellipsize(&self) -> Ellipsize {
|
||||
self.ellipsize
|
||||
}
|
||||
|
||||
/// Set the current [`Ellipsize`]
|
||||
pub fn set_ellipsize(&mut self, font_system: &mut FontSystem, ellipsize: Ellipsize) {
|
||||
if ellipsize != self.ellipsize {
|
||||
self.ellipsize = ellipsize;
|
||||
self.relayout(font_system);
|
||||
self.shape_until_scroll(font_system, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current `monospace_width`
|
||||
pub const fn monospace_width(&self) -> Option<f32> {
|
||||
self.monospace_width
|
||||
|
|
@ -1406,6 +1425,11 @@ impl BorrowedWithFontSystem<'_, Buffer> {
|
|||
self.inner.set_wrap(self.font_system, wrap);
|
||||
}
|
||||
|
||||
/// Set the current [`Ellipsize`]
|
||||
pub fn set_ellipsize(&mut self, ellipsize: Ellipsize) {
|
||||
self.inner.set_ellipsize(self.font_system, ellipsize);
|
||||
}
|
||||
|
||||
/// Set the current buffer dimensions
|
||||
pub fn set_size(&mut self, width_opt: Option<f32>, height_opt: Option<f32>) {
|
||||
self.inner.set_size(self.font_system, width_opt, height_opt);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use core::mem;
|
||||
|
||||
use crate::{
|
||||
Align, Attrs, AttrsList, Cached, FontSystem, Hinting, LayoutLine, LineEnding, ShapeLine,
|
||||
Shaping, Wrap,
|
||||
Align, Attrs, AttrsList, Cached, Ellipsize, FontSystem, Hinting, LayoutLine, LineEnding,
|
||||
ShapeLine, Shaping, Wrap,
|
||||
};
|
||||
|
||||
/// A line (or paragraph) of text that is shaped and laid out
|
||||
|
|
@ -242,6 +244,7 @@ impl BufferLine {
|
|||
font_size: f32,
|
||||
width_opt: Option<f32>,
|
||||
wrap: Wrap,
|
||||
ellipsize: Ellipsize,
|
||||
match_mono_width: Option<f32>,
|
||||
tab_width: u16,
|
||||
hinting: Hinting,
|
||||
|
|
@ -258,6 +261,7 @@ impl BufferLine {
|
|||
font_size,
|
||||
width_opt,
|
||||
wrap,
|
||||
ellipsize,
|
||||
align,
|
||||
&mut layout,
|
||||
match_mono_width,
|
||||
|
|
|
|||
|
|
@ -152,6 +152,29 @@ impl Display for Align {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
pub enum Ellipsize {
|
||||
/// No Ellipsizing
|
||||
#[default]
|
||||
None,
|
||||
/// Ellipsizes the start of the last visual line that fits within the `EllipsizeHeightLimit`
|
||||
Start(EllipsizeHeightLimit),
|
||||
/// Ellipsizes the middle of the last visual line that fits within the `EllipsizeHeightLimit`.
|
||||
Middle(EllipsizeHeightLimit),
|
||||
/// Ellipsizes the end of the last visual line that fits within the `EllipsizeHeightLimit`.
|
||||
End(EllipsizeHeightLimit),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum EllipsizeHeightLimit {
|
||||
/// Number of lines to show before ellipsizing the rest. Only works if `Wrap` is NOT set to
|
||||
/// `Wrap::None`. Otherwise, it will be ignored and the behavior will be the same as `Lines(1)`
|
||||
Lines(usize),
|
||||
/// Ellipsizes the last line that fits within the given height limit. If `Wrap` is set to
|
||||
/// `Wrap::None`, the behavior will be the same as `Lines(1)`
|
||||
Height(f32),
|
||||
}
|
||||
|
||||
/// Metrics hinting strategy
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
|
||||
pub enum Hinting {
|
||||
|
|
|
|||
1591
src/shape.rs
1591
src/shape.rs
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use cosmic_text::{
|
||||
fontdb::Database, Attrs, AttrsOwned, Buffer, Color, Family, FontSystem, Metrics, Shaping,
|
||||
SwashCache,
|
||||
fontdb::Database, Align, Attrs, AttrsOwned, Buffer, Color, Ellipsize, Family, FontSystem,
|
||||
Metrics, Shaping, SwashCache, Wrap,
|
||||
};
|
||||
use tiny_skia::{Paint, Pixmap, Rect, Transform};
|
||||
|
||||
|
|
@ -29,6 +29,9 @@ pub struct DrawTestCfg {
|
|||
line_height: f32,
|
||||
canvas_width: u32,
|
||||
canvas_height: u32,
|
||||
wrap: Wrap,
|
||||
ellipsize: Ellipsize,
|
||||
alignment: Option<Align>,
|
||||
}
|
||||
|
||||
impl Default for DrawTestCfg {
|
||||
|
|
@ -42,6 +45,9 @@ impl Default for DrawTestCfg {
|
|||
line_height: 20.0,
|
||||
canvas_width: 300,
|
||||
canvas_height: 300,
|
||||
wrap: Wrap::WordOrGlyph,
|
||||
ellipsize: Ellipsize::None,
|
||||
alignment: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -76,6 +82,21 @@ impl DrawTestCfg {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn wrap(mut self, wrap: Wrap) -> Self {
|
||||
self.wrap = wrap;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ellipsize(mut self, ellipsize: Ellipsize) -> Self {
|
||||
self.ellipsize = ellipsize;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn alignment(mut self, alignment: Option<Align>) -> Self {
|
||||
self.alignment = alignment;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn validate_text_rendering(self) {
|
||||
let repo_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
// Create a db with just the fonts in our fonts dir to make sure we only test those
|
||||
|
|
@ -88,11 +109,18 @@ impl DrawTestCfg {
|
|||
let mut buffer = Buffer::new(&mut font_system, metrics);
|
||||
let mut buffer = buffer.borrow_with(&mut font_system);
|
||||
let margins = 5;
|
||||
buffer.set_wrap(self.wrap);
|
||||
buffer.set_ellipsize(self.ellipsize);
|
||||
buffer.set_size(
|
||||
Some((self.canvas_width - margins * 2) as f32),
|
||||
Some((self.canvas_height - margins * 2) as f32),
|
||||
);
|
||||
buffer.set_text(&self.text, &self.font.as_attrs(), Shaping::Advanced, None);
|
||||
buffer.set_text(
|
||||
&self.text,
|
||||
&self.font.as_attrs(),
|
||||
Shaping::Advanced,
|
||||
self.alignment,
|
||||
);
|
||||
buffer.shape_until_scroll(true);
|
||||
|
||||
// Black
|
||||
|
|
|
|||
161
tests/ellipsize_rendering.rs
Normal file
161
tests/ellipsize_rendering.rs
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
use common::DrawTestCfg;
|
||||
use cosmic_text::{Align, Attrs, Ellipsize, EllipsizeHeightLimit, Family, Wrap};
|
||||
|
||||
mod common;
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_ltr_end_single_line() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_ltr_end_single_line")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("The quick brown fox jumps over the lazy dog.")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(1)))
|
||||
.canvas(180, 50)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_ltr_end_single_line_aligned_right() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_ltr_end_single_line_aligned_right")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("The quick brown fox jumps over the lazy dog.")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(1)))
|
||||
.alignment(Some(Align::Right))
|
||||
.canvas(180, 50)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_rtl_end_single_line() {
|
||||
let attrs = Attrs::new().family(Family::Name("Noto Sans"));
|
||||
DrawTestCfg::new("ellipsize_rtl_end_single_line")
|
||||
.font_size(22., 28.)
|
||||
.font_attrs(attrs)
|
||||
.text("توانا بود هرکه دانا بود.")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(1)))
|
||||
.canvas(180, 55)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_mixed_end_single_line() {
|
||||
let attrs = Attrs::new().family(Family::Name("Noto Sans"));
|
||||
DrawTestCfg::new("ellipsize_mixed_end_single_line")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("Hello سلام mixed RTL/LTR world with extra words")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(1)))
|
||||
.canvas(190, 50)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_ltr_start_single_line() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_ltr_start_single_line")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("The quick brown fox jumps over the lazy dog.")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::Start(EllipsizeHeightLimit::Lines(1)))
|
||||
.canvas(180, 50)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_ltr_middle_single_line() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_ltr_middle_single_line")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("The quick brown fox jumps over the lazy dog.")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(1)))
|
||||
.canvas(180, 50)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_ltr_end_two_lines() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_ltr_end_two_lines")
|
||||
.font_size(18., 24.)
|
||||
.font_attrs(attrs)
|
||||
.text("Pack my box with five dozen liquor jugs. Sphinx of black quartz, judge my vow.")
|
||||
.wrap(Wrap::Word)
|
||||
.ellipsize(Ellipsize::End(EllipsizeHeightLimit::Lines(2)))
|
||||
.canvas(200, 80)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_mixed_middle_single_line() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_mixed_middle_single_line")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("Hello سلام mixed RTL/LTR world with extra words")
|
||||
.wrap(Wrap::None)
|
||||
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(1)))
|
||||
.canvas(180, 50)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_mixed_ltr_rtl_middle_two_lines() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_mixed_ltr_rtl_middle_two_lines")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("First line is LTR خط دوم از راست به چپ")
|
||||
.wrap(Wrap::WordOrGlyph)
|
||||
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(2)))
|
||||
.canvas(180, 80)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_mixed_rtl_ltr_middle_two_lines() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_mixed_rtl_ltr_middle_two_lines")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("خط اول از راست به چپ Second line is LTR and has more words")
|
||||
.wrap(Wrap::WordOrGlyph)
|
||||
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(2)))
|
||||
.canvas(210, 80)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_ltr_single_word_middle_two_lines() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_ltr_single_word_middle_two_lines")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("AVeryLongWordThatExceedsTheWidth")
|
||||
.wrap(Wrap::WordOrGlyph)
|
||||
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(2)))
|
||||
.canvas(180, 80)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsize_mixed_ltr_rtl_ltr_middle_three_lines() {
|
||||
let attrs = Attrs::new().family(Family::Name("Inter"));
|
||||
DrawTestCfg::new("ellipsize_mixed_ltr_rtl_ltr_middle_three_lines")
|
||||
.font_size(20., 26.)
|
||||
.font_attrs(attrs)
|
||||
.text("This is some LTR text that keeps و یه مشت متن فارسیی.zippy")
|
||||
.wrap(Wrap::WordOrGlyph)
|
||||
.ellipsize(Ellipsize::Middle(EllipsizeHeightLimit::Lines(3)))
|
||||
.canvas(200, 100)
|
||||
.validate_text_rendering();
|
||||
}
|
||||
3
tests/images/ellipsize_ltr_end_single_line.png
Normal file
3
tests/images/ellipsize_ltr_end_single_line.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0de01fa40e15779c52c39652369f6c636ce0c018c3ef488d99cc7cfcd0d53eb4
|
||||
size 4957
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cb2f9fccbe5dd17854cc9975cba81a8357ca299d1970585dac025d81beaa6a29
|
||||
size 5099
|
||||
3
tests/images/ellipsize_ltr_end_two_lines.png
Normal file
3
tests/images/ellipsize_ltr_end_two_lines.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ab08b3a7061db4e32ece8aec5bc6c4a32939fa91186c31f76eb901adcdbdd0fc
|
||||
size 12218
|
||||
3
tests/images/ellipsize_ltr_middle_single_line.png
Normal file
3
tests/images/ellipsize_ltr_middle_single_line.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:181b48bf70119b2df56521c287b2cd1b60ab1677ebaa03ea5f01dee522693370
|
||||
size 5412
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0fb2a94c8892736ae1e05ef5d42e541eff7eae8826cae6e19fb34727b1ff6ee6
|
||||
size 12179
|
||||
3
tests/images/ellipsize_ltr_start_single_line.png
Normal file
3
tests/images/ellipsize_ltr_start_single_line.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e2a705f931aae72c693a2a1ae56ad2455ee3a8f7f2309ca99864eedbf7c59d40
|
||||
size 5518
|
||||
3
tests/images/ellipsize_mixed_end_single_line.png
Normal file
3
tests/images/ellipsize_mixed_end_single_line.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6438bf5df040bfe61566af722823f2f78d519e4719547c766fbe19e2dc4a07f6
|
||||
size 5985
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4cf481f25cf06518eddfc8794322bb13998f39709076a2d07ece2e2528d7364e
|
||||
size 16096
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:36156e31793901ede07b4db53ddf671b5c134afe82a8328fd7eacad1cebcd339
|
||||
size 8960
|
||||
3
tests/images/ellipsize_mixed_middle_single_line.png
Normal file
3
tests/images/ellipsize_mixed_middle_single_line.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:88bf081f80aac508baa685718fce15e3acf888b43c199aa902494a2c47ed22e3
|
||||
size 5501
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:56fcff35d50673ec790dfacc82b55513f643628d6745a7eec2a7082b4ced04f7
|
||||
size 12004
|
||||
3
tests/images/ellipsize_rtl_end_single_line.png
Normal file
3
tests/images/ellipsize_rtl_end_single_line.png
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0e9d984a59003766fda15d1bb35069d6f5a9638b00c0560f2fad3431c0283aa9
|
||||
size 5585
|
||||
Loading…
Add table
Add a link
Reference in a new issue