* 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.
The unicode-linebreak crate treats the pipe character '|' as a break opportunity (BA/AL class). This causes ShapeSpan::build to split text like '|>' into separate ShapeWords. When these words are shaped independently, the font shaping engine cannot form ligatures that cross the word boundary.
This patch manually checks for the '|>' sequence during segmentation and skips the break opportunity, ensuring they remain in the same shaping run.
Added a unit test 'ligature_segmentation' to verify that '|>' remains a single word.
* Use HarfRust for shaping
* Replace ttf-parser with skrifa entirely
* Fix clippy lints
* Add shape plan cache
* Bump harfrust and skrifa
* Fix no_std build
* Simplify the shape plan cache
* Please the paperclip
* Cache font ID with plan
* Tune shape plan cache for "BiDi Processing" bench
Refactors the Editor's scrolling implementation to be pixel-based instead of line-based. This provides smoother and more granular scrolling, which works more consistently across different input devices (like trackpads).
- The `Action::Scroll` variant now takes `pixels: f32`.
- The `Editor` now processes scroll actions using pixel values directly.
- Examples have been updated to reflect the new scrolling behavior.
- Fix string formatting with modern interpolation syntax
- Improve Debug implementation with finish_non_exhaustive()
- Fix function placement in shape.rs to avoid items_after_statements warning
- Use more idiomatic Rust patterns (map_or_else, next_back)
- Clean up conditional imports in vi.rs
- Convert multiple methods to `const` functions for optimization and consistency
- Introduce `core_maths` for enhanced no-std compatibility
- Update `Cargo.toml` for the new optional dependency and feature adjustments
* Optimize BidiParagraphs with ASCII fast path - Added fast path for ASCII text that avoids BidiInfo allocation - Added some text shaping benchmarks
* refactor: fix clippy warnings and cleanup imports
- Skip expensive grapheme iteration for simple ASCII words
- 32% performance improvement for code-like text
- 5-7% improvement for general ASCII content
- No regressions for Unicode text processing
- Conservative ASCII detection maintains correctness
* Update editor.rs
* Makes sure indent_required is calculated according to the selection type
removed the redundant check for required_indent == 0,
introduced a slightly different path for when no selection = None, and calculated the required tab width and indent position accordingly.
* Undo typo
undid an accidental move of a redraw call outside of a loop
* Corrected indenting with rustfmt
formatted the code with rustfmt to pass the failing CI checks
* Variable font support
Here's a pretty naïve solution for variable fonts.
The iterator doesn't use the match keys' weight, but instead tries to
get the requested ideal weight, if the font is variable, otherwise it is
ignored and the actual (non-variable) weight is used. This is because I
didn't implement finding variable weight support for match keys; doing
so would be impossible without parsing TTF files when matching and I
didn't want to add that potentially expensive infrastructure if not
entirely necessary.
This is a breaking change, and I'm open for ideas on how to fix that
if it's an issue.
* cargo fmt
* Add variable font example to rich-text example