An open API service indexing awesome lists of open source software.

https://github.com/vidarh/skrift

A pure Ruby conversion (*not* wrapper) of the libschrift TrueType font renderer
https://github.com/vidarh/skrift

font-renderer ruby ttf

Last synced: about 1 year ago
JSON representation

A pure Ruby conversion (*not* wrapper) of the libschrift TrueType font renderer

Awesome Lists containing this project

README

          

# Skrift

Vidar Hokstad

This started out as a Ruby port of `libschrift`. If you need
performance, and don't mind a C dependency, consider that over this.

If you're fine with slower rendering (*cache* glyphs after rendering)
and want *pure Ruby*, consider this gem, with the caveat that the
rewrite is *new* and likely buggy.

## Name

"Skrift" is Norwegian for "text", "writing", or "scripture", and so a
close cognate of "Schrift". Since I'm Norwegian, it seemed like an
appropriate way to set this apart from `libschrift` and ensure that if
anyone want to do a gem directly wrapping the C librarly the name remains
available.

## License

While it's rewritten in Ruby and changed reasonably since, given it owes
so much to `libschrift`, I decided to stick with the same license (the
ISC License), since it's very permissive. See `LICENSE.md`

## This code is opinionated

Firstly, the choice to start by rewriting `libschrift` is because that
library is an excellent demonstration of a minimalist feature set and
compact code that I wanted.

However, on top of the structure inherited largely from `libschrift`,
while working on this code, I've formed my own opinions on it which
applies to *this library*, and which the author of `libschrift` may or
may not agree with. These are *my responsibility*:

* Small code size is a virtue as long as it improves rather than hinders
understanding. Any feature will be weighed against complexity cost.

* Features that add a lot of complexity may be better written as a
separate library (I will happily work with you to ensure it's easy for
users to combine your library with `Skrift`)

* Hinting is predominantly important with low resolution. With the trend
firmly being towards 4K or 8K displays, putting a lot of effort into
hinting is pointless. I will *consider* hinting if someone wants to
contribute hinting code, but not at the cost of a lot of complexity (
unless you build it as a standalone extension)

* The current algo uses anti-aliasing. I will *consider* adding support
for monochrome rendering for the same reason as above, but currently, AA
is still *necessary* for best possible results at small sizes, at least
on FHD displays, so since it's already here, I'll *keep* the AA
support as long as lower resolution displays are still around.

* Feature "completeness" for the sake of completeness are not of interest.
E.g. I have no interest in parsing the parts of the TTF or OTF formats
this library won't use (but if you write a *compact*, well written
TTF/ OTF parser in pure Ruby, I *might* consider tearing out the
font parsing from this gem if using yours simplifies the `Skrift` code)

* Idiomatic Ruby is favoured over maximising efficiency (but
pathologically low performance is not good - I'm open to changes)

* Lowering coupling is favoured (be it for testing, or ease of improving
the code), but architecture acrobatics should be avoided. That is,
make it *possible* to test or use individual stages of the rendering
pipeline, but don't force library users to care - setup should be
minimal, and defaults sane. Factories and abstract interfaces should
stay in Java or be used to scare small children, not be found in
Ruby code.


## Contributions and Potential Improvements

Contributions are welcome, keeping the above in mind. If your
contributions are potentially unrelated to the specific purpose of this
library, I might propose you put them in a separate gem instead, and
might then offer to help create easy integration points so your code can
safely extent this library if a user chooses to use both.

Some possible areas for extension, and my current thoughts on them
(*talk to me* if you want to work on something)

### X11 or Wayland (or Windows, or Mac) integration

No.

I will happily ensure there necessary APIs are there so that you can
*wrap* or integrate with `Skrift`, or so that you can render to something
that makes it convenient. E.g. the current rendering to 8 bit
greyscale already makes `Skrift` (thanks to `libschrift` doing this from
the start) integrate easily with `XRender` for X11 support.

I will not, however, put platform specific code in `Skrift` itself (I
*will* accept code well-written code to make use of "platform specific"
data *from the font files*, however, because they can be useful on other
platforms)

I use this code for rendering to `X11` myself. It does not require
pushing platform specific code into this library.

### Performance

Performance improvements are welcome *but not if they add a lot of
complexity*. C-extensions or similar will not be accepted - if you
want a C dependency, just use `libschrift`.

If you have a suggestion that involves using C in a limited way to speed
up specifics, I'd suggest providing a *separate* gem to replace/extend
the appropriate code the same way `oily_png` provides code to speed up
`chunky_png`. I'm happy to discuss specifics.

### Grid snapping

Where I'm *most likely* to consider a hinter is a *limited* hinter
to dynamically rescale glyphs to allow using a variable spaced font
snapped to a grid for e.g. terminal use in a somewhat intelligent way (I
don't expect this is likely to look good, but I'm open to be convinced
even if it only works on some fonts, though it might well be better as a
standalone conversion tool unless it works well on a broad range of
fonts)

### Transformations

The current code already applies linear affine transformations to the
glyphs. I'd be supportive of *compact* contributions to make it easier to
apply a broader set of transforms during rendering to allow for more
flexible layout. Please discuss API first if you want anything merged, or
if you just want stable extension points to do this in a separate
library.

### Outlines

You can currently extract outlines, and so can of course replace the
rendering stage and render unfilled outlines on your own. That said, I'd
be supportive both of low complexity changes to render the fonts as
outlines *and* of low complexity changes to "grow" outlines (e.g. to
be able to render an outline in one colour and a filled version in the
desired size in another colour - you can't do this by just scaling). The
code that'd need to change to replace the rasteriser is tiny.

### Text Layout

Specifically, *text layout* is perhaps out of scope of this library, but
I'm happy to discuss it - if nothing else I'd be supportive of an
extension in a separate gem and/or ensuring the basics is well
supported.