Skip to content

Switch Text Shaping to rustybuzz#378

Merged
CryZe merged 3 commits intoLiveSplit:masterfrom
CryZe:rustybuzz
Dec 27, 2020
Merged

Switch Text Shaping to rustybuzz#378
CryZe merged 3 commits intoLiveSplit:masterfrom
CryZe:rustybuzz

Conversation

@CryZe
Copy link
Copy Markdown
Collaborator

@CryZe CryZe commented Dec 27, 2020

rustybuzz is a more or less complete port of harfbuzz (state of the art) text shaping engine to Rust. This means our font handling is now about as good as the one found in a browser, except all the manual things you may need to do on top such as using different fonts for different parts of the text, because some glyphs are not available in the chosen font and handling image based glyphs such as those that are being used for emojis in some fonts. Overall though switching to rustybuzz seems to have already changed the appearance quite a bit. There is now proper kerning (though I thought rusttype already did that, but apparently not), proper ligature support and because this is state of the art, it also supports tabular numbers for example which is now activated for all the numbers that we are rendering. Unfortunately since rustybuzz does so much more work, it also heavily slowed down text shaping, which we do on every frame at the moment. So we really need to refactor the renderer to start caching a lot more stuff.

Text shaping with harfbuzz is not really fast, and rustybuzz is
apparently still a bit slower than harfbuzz. So compared to rusttype
switching to rustybuzz may slow us down quite a bit. It would be good to
know how much time the renderer, without measuring any actual rendering,
is actually taking up on the CPU.
rustybuzz is a more or less complete port of harfbuzz (state of the art)
text shaping engine to Rust. This means our font handling is now about
as good as the one found in a browser, except all the manual things you
may need to do on top such as using different fonts for different parts
of the text, because some glyphs are not available in the chosen font
and handling image based glyphs such as those that are being used for
emojis in some fonts. Overall though switching to rustybuzz seems to
already changed the appearance quite a bit. There is now proper kerning
(though I thought rusttype already did that, but apparently not), proper
ligature support and because this is state of the art, it also supports
tabular numbers for example which is now activated for all the numbers
that we are rendering. Unfortunately since rustybuzz does so much more
work, it also heavily slowed down text shaping, which we do on every
frame at the moment. So we really need to refactor the renderer to start
caching a lot more stuff.
@CryZe CryZe added enhancement An improvement for livesplit-core. rendering The issue or pull request is affecting the rendering. feature A new user visible feature for livesplit-core. performance Affects the performance of the code. labels Dec 27, 2020
@CryZe CryZe requested a review from wooferzfg December 27, 2020 17:10
Comment on lines +244 to 245
#[track_caller]
fn check_dims(state: &LayoutState, dims: [usize; 2], expected_hash_data: &str, name: &str) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a cool change. If the check fails, the error is marked where the caller called this function.

@CryZe
Copy link
Copy Markdown
Collaborator Author

CryZe commented Dec 27, 2020

Oops tabular numbers on the timer itself reveals some ugly digits (not really ugly, but the 1 isn't supposed to look like that). Time to update the timer font.

https://i.imgur.com/C6OghC5.png

@wooferzfg
Copy link
Copy Markdown
Member

The Dummy Rendering benchmarks are running into a lot of the following warnings in GitHub Actions:

Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 5.6s, enable flat sampling, or reduce sample count to 60.

Not sure if this is a problem?

@CryZe
Copy link
Copy Markdown
Collaborator Author

CryZe commented Dec 27, 2020

The benchmarks there barely matter, the idea was to upload them to some site, but the site turned out to not work well at all. Also I don't think this is that much of a problem, just means we really should focus on caching this stuff.

Turns out the tabular numbers of the timer font had some outdated
glyphs. This replaces those glyphs, but also turns off tabular number
support inside the font entirely. I'm not entirely sure that's what we
want to do, but it at least preserves the previous rendering.
}
}

// FIXME: There's kerning between e.g. ".1" now, which is maybe not quite
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an example of what this looks like?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is before I switched to tabular nums, but you can kind of see it here how .2 and .1 are differently aligned:

https://i.imgur.com/K20g1XW.png

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the font (which you can't change yet) doesn't have tnum support, then this will still happen.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kerning could be turned off, but we currently have tnum active for all the values of the key value components, even if they are "info text" components. So turning kerning off for components like Current Comparison would be suboptimal. Though we could introduce a flag in the key value component state that marks it as a "info time" as opposed to a "info text" component.

@CryZe CryZe merged commit 2391a08 into LiveSplit:master Dec 27, 2020
@CryZe CryZe added this to the v0.12 milestone Dec 27, 2020
CryZe added a commit that referenced this pull request Nov 14, 2021
- Runs now support custom variables that are key value pairs that either the
  user can specify in the run editor or are provided by a script like an auto
  splitter. [#201](#201)
- There is now an option in the run editor to generate a comparison based on a
  user specified goal time. This uses the same algorithm as the `Balanced PB`
  comparison but with the time specified instead of the personal best.
  [#209](#209)
- Images internally are now stored as is without being reencoded as Base64 which
  was done before in order to make it easier for the web LiveSplit One to
  display them. [#227](#227)
- The Splits.io API is now available under the optional `networking` feature.
  [#236](#236)
- All key value based components share the same component state type now.
  [#257](#257)
- The crate now properly supports `wasm-bindgen` and `WASI`.
  [#263](#263)
- There is now a dedicated component for displaying the comparison's segment
  time. [#264](#264)
- Compiling the crate without `std` is now supported. Most features are not
  supported at this time though.
  [#270](#270)
- [`Splitterino`](https://github.com/prefixaut/splitterino) splits can now be
  parsed. [#276](#276)
- The `Timer` component can now show a segment timer instead.
  [#288](#288)
- Gamepads are now supported on the web.
  [#310](#310)
- The underlying "skill curve" that the `Balanced PB` samples is now exposed in
  the API. [#330](#330)
- The layout states can now be updated, which means almost all of the
  allocations can be reused from the previous frame. This is a lot faster.
  [#334](#334)
- In order to calculate a layout state, the timer now provides a snapshot
  mechanism that ensures that the layout state gets calculated at a fixed point
  in time. [#339](#339)
- Text shaping is now done via `rustybuzz` which is a port of `harfbuzz`.
  [#378](#378)
- Custom fonts are now supported.
  [#385](#385)
- The renderer is not based on meshes anymore that are suitable for rendering
  with a 3D graphics API. Instead the renderer is now based on paths, which are
  suitable for rendering with a 2D graphics API such as Direct2D, Skia, HTML
  Canvas, and many more. The software renderer is now based on `tiny-skia` which
  is so fast that it actually outperforms any other rendering and is the
  recommended way to render.
  [#408](#408)
- Remove support for parsing `worstrun` splits. `worstrun` doesn't support
  splits anymore, so `livesplit-core` doesn't need to keep its parsing support.
  [#411](#411)
- Remove support for parsing `Llanfair 2` splits. `Llanfair 2` was never
  publicly available and is now deleted entirely.
  [#420](#420)
- Hotkeys are now supported on macOS.
  [#422](#422)
- The renderer is now based on two layers. A bottom layer that rarely needs to
  be rerendered and the top layer that needs to be rerendered on every frame.
  Additionally the renderer is now a scene manager which manages a scene that an
  actual rendering backend can then render out.
  [#430](#430)
- The hotkeys are now based on the [UI Events KeyboardEvent code
  Values](https://www.w3.org/TR/uievents-code/) web standard.
  [#440](#440)
- Timing is now based on `CLOCK_BOOTTIME` on Linux and `CLOCK_MONOTONIC` on
  macOS and iOS. This ensures that all platforms keep tracking time while the
  operating system is in a suspended state.
  [#445](#445)
- Segment time columns are now formatted as segment times.
  [#448](#448)
- Hotkeys can now be resolved to the US keyboard layout.
  [#452](#452)
- They hotkeys are now based on `keydown` instead of `keypress` in the web.
  `keydown` handles all keys whereas `keypress` only handles visual keys and is
  also deprecated. [#455](#455)
- Hotkeys can now be resolved to the user's keyboard layout on both Windows and
  macOS. [#459](#459) and
  [#460](#460)
- The `time` crate is now used instead of `chrono` for keeping track of time.
  [#462](#462)
- The scene manager now caches a lot more information. This improves the
  performance a lot as it does not need to reshape the text on every frame
  anymore, which is a very expensive operation.
  [#466](#466) and
  [#467](#467)
- The hotkeys on Linux are now based on `evdev`, which means Wayland is now
  supported. Additionally the hotkeys are not consuming the key press anymore.
  [#474](#474)
- When holding down a key, the hotkey doesn't repeat anymore on Linux, macOS and
  WebAssembly. The problem still occurs on Windows at this time.
  [#475](#475) and
  [#476](#476)
@CryZe CryZe deleted the rustybuzz branch November 16, 2021 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement An improvement for livesplit-core. feature A new user visible feature for livesplit-core. performance Affects the performance of the code. rendering The issue or pull request is affecting the rendering.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants