Giter Site home page Giter Site logo

font-kit's People

Contributors

atouchet avatar be-ing avatar bilelmoussaoui avatar bors-servo avatar derekdreery avatar eijebong avatar emilio avatar evilpie avatar fkaa avatar fschutt avatar idursun avatar ikatson avatar jayvdb avatar jdm avatar jneem avatar jrmuizel avatar kaiwk avatar kevinyang372 avatar manishearth avatar mrobinson avatar osspial avatar pcwalton avatar raphlinus avatar razrfalcon avatar richo avatar simlay avatar srijs avatar twilco avatar xiaopengli89 avatar zacps avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

font-kit's Issues

Fallback list in select_best_match

Currently, fonts for sans/serif/monospace/fantasy/etc. are hardcoded for Win and Mac. And there are only one font for each type.

The problem is that it doesn't guarantee that this font is present. For example, a default Win10 contains the Impact font, but the one used by TravisCI - doesn't.

Here is the list of font families available in a Travis instance:

  • Arial
  • Bahnschrift
  • Calibri
  • Cambria
  • Cambria Math
  • Comic Sans MS
  • Consolas
  • Courier New
  • Ebrima
  • Gadugi
  • Georgia
  • Ink Free
  • Javanese Text
  • Leelawadee UI
  • Lucida Console
  • Malgun Gothic
  • Microsoft Himalaya
  • Microsoft JhengHei
  • Microsoft JhengHei UI
  • Microsoft New Tai Lue
  • Microsoft PhagsPa
  • Microsoft Tai Le
  • Microsoft YaHei
  • Microsoft YaHei UI
  • Microsoft Yi Baiti
  • Mongolian Baiti
  • MV Boli
  • Myanmar Text
  • Nirmala UI
  • Segoe MDL2 Assets
  • Segoe Print
  • Segoe UI
  • Segoe UI Emoji
  • Segoe UI Historic
  • Segoe UI Symbol
  • SimSun
  • NSimSun
  • Times New Roman
  • Trebuchet MS
  • Verdana
  • Webdings
  • Wingdings
  • Yu Gothic
  • Yu Gothic UI

Not sure with one we can use as fantasy. Maybe Ink Free?

Index out of range when rasterizing '|' on Source Code Pro with Freetype

There may be more cases to reproduce this, but this is easily repeatable:

  • OS: Ubuntu 18.04
  • Font: Source Code Pro (Regular)
  • Char: |
  • Glyph: 968
  • Requested format: Rgb24
  • Code: alacritty/alacritty#1720
Complete backtrace
thread 'main' panicked at 'index 89 out of range for slice of length 88', src/libcore/slice/mod.rs:2349:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:59
             at src/libstd/panicking.rs:210
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:225
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:488
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:395
   6: rust_begin_unwind
             at src/libstd/panicking.rs:322
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:95
   8: core::slice::slice_index_len_fail
             at src/libcore/slice/mod.rs:2349
   9: <core::ops::range::Range<usize> as core::slice::SliceIndex<[T]>>::index
             at /rustc/96d1334e567237b1507cd277938e7ae2de75ff51/src/libcore/slice/mod.rs:2514
  10: core::slice::<impl core::ops::index::Index<I> for [T]>::index
             at /rustc/96d1334e567237b1507cd277938e7ae2de75ff51/src/libcore/slice/mod.rs:2331
  11: font_kit::canvas::Canvas::blit_from_with
             at /home/zac/projects/font-kit/src/canvas.rs:153
  12: font_kit::canvas::Canvas::blit_from
             at /home/zac/projects/font-kit/src/canvas.rs:89
  13: font_kit::loaders::freetype::Font::rasterize_glyph
             at /home/zac/projects/font-kit/src/loaders/freetype.rs:754
  14: <font::fontkit::FontKitRasterizer as font::Rasterize>::get_glyph
             at font/src/fontkit/mod.rs:144
  15: alacritty::renderer::GlyphCache::get::{{closure}}
             at src/renderer/mod.rs:276
  16: <std::collections::hash::map::Entry<'a, K, V>>::or_insert_with
             at /rustc/96d1334e567237b1507cd277938e7ae2de75ff51/src/libstd/collections/hash/map.rs:2695
  17: alacritty::renderer::GlyphCache::get
             at src/renderer/mod.rs:273
  18: alacritty::renderer::GlyphCache::load_glyphs_for_font
             at src/renderer/mod.rs:204
  19: alacritty::renderer::GlyphCache::new
             at src/renderer/mod.rs:195
  20: alacritty::display::Display::new_glyph_cache::{{closure}}
             at src/display.rs:250
  21: alacritty::renderer::QuadRenderer::with_loader
             at src/renderer/mod.rs:713
  22: alacritty::display::Display::new_glyph_cache
             at src/display.rs:250
  23: alacritty::display::Display::new
             at src/display.rs:156
  24: alacritty::run
             at src/main.rs:127
  25: alacritty::main
             at src/main.rs:79
  26: std::rt::lang_start::{{closure}}
             at /rustc/96d1334e567237b1507cd277938e7ae2de75ff51/src/libstd/rt.rs:74
  27: std::panicking::try::do_call
             at src/libstd/rt.rs:59
             at src/libstd/panicking.rs:307
  28: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:102
  29: std::rt::lang_start_internal
             at src/libstd/panicking.rs:286
             at src/libstd/panic.rs:398
             at src/libstd/rt.rs:58
  30: std::rt::lang_start
             at /rustc/96d1334e567237b1507cd277938e7ae2de75ff51/src/libstd/rt.rs:74
  31: main
  32: __libc_start_main
  33: _start

Logging values in the loop:

Start 0 width 3 bytes 3 len 88
Start 8 width 3 bytes 3 len 88
Start 16 width 3 bytes 3 len 88
Start 24 width 3 bytes 3 len 88
Start 32 width 3 bytes 3 len 88
Start 40 width 3 bytes 3 len 88
Start 48 width 3 bytes 3 len 88
Start 56 width 3 bytes 3 len 88
Start 64 width 3 bytes 3 len 88
Start 72 width 3 bytes 3 len 88
Start 80 width 3 bytes 3 len 88
<panic 89 out of range>

All types except FamilyName::Title returning an error on Linux

use font_kit::source::SystemSource;
use font_kit::properties::*;
use font_kit::family_name::FamilyName;

SystemSource::new().select_best_match(&[FamilyName::Serif], &Properties::default()).unwrap()
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: NotFound', libcore/result.rs:1009:5

Add a Font method to access OpenType tables

Any type of shaping will require access to OpenType table data.

I think the model of what we need is getTableData from SkTypeface. This signature allocates and copies, but the alternative is to have more complex lifetime invariants.

For CoreText, the underlying function is CTFontCopyTable, which appears to be misnamed, as it seems to return a CFDataRef. It might be possible to use that to avoid copying. But that would require designing appropriate types; if the data reference were an associated type, it would make Font not object-safe, which I think is undesirable.

I may be able to work around this, possibly for a while, by using copy_font_data and using HarfBuzz-provided functions for table access, so I'm not sure how urgent this is.

Unique font id

The font loader should have an "Id" type that efficiently impl's PartialEq and Hash, that is guaranteed (with reasonably high confidence) to be equal when the fonts are equal. Such an Id is necessary for caching of any resource associated with a font (rendered glyphs, HarfBuzz font and face objects, table data, coverage bitmaps). Currently font-kit tends to use PostScript name for this purpose, but it's easy to see how this might fail uniqueness (for example, when a web font stack contains a different version of a font already present in the system). It should also be cheap to compute, because we will need it for every typeface that comes back from a fallback query.

Skia's SkTypeface has a uniqueID method. Its implementation largely rests on using a cache - when going from a native font object (for example, a DirectWrite font) to an SkTypeface, there's a comparison procedure to compare equality with existing fonts in the cache. An example for DirectWrite shows a fairly complex set of heuristics - it starts with pointer equality and other checks based on the way the font is loaded, then compares a bunch of name strings.

I'm not at all convinced font-kit should be based on a cache the way Skia does it, but it might be useful as a reference.

In any case, we should export the type, then implementations can refine the tactics to compare equality efficiently and reliably, without breaking client code - for example, an initial implementation can be based on PostScript name. This is one reason I agree with @pcwalton it should be a type and not a small integer. Another reason is so the Debug formatting is informative.

Type mismatch on Raspberry Pi 3B+

Hello.

WHile trying to build amethyst for a few tests, I ended up having compilation errors on font-kit. Looks like many types are mismatching on this device. I'll be attaching a log as a file as it takes quite a bit of vertical space.
Here's my current rust compiler toolchains

installed toolchains
--------------------
stable-armv7-unknown-linux-gnueabihf
nightly-armv7-unknown-linux-gnueabihf
active toolchain
----------------
stable-armv7-unknown-linux-gnueabihf (default)
rustc 1.29.2 (17a9dc751 2018-10-05)

Thank you and have a nice day.

build log here

3 failed tests with rust 1.33.0 (2aa4c46cf 2019-02-28)

cargo test fails with rust 1.33.0 (2aa4c46cf 2019-02-28), on Ubuntu Linux x86_64 18.04.2, although both examples (list-fonts and render-glyph) work fine:

$ RUST_BACKTRACE=1 cargo test --release
    Finished release [optimized] target(s) in 0.10s
     Running target/release/deps/font_kit-1114c272e27097b8

running 30 tests
test test::analyze_file ... ok
test loaders::freetype::test::get_pcf_postscript_name ... ok
test test::get_empty_glyph_outline ... ok
test test::analyze_bytes ... ok
test test::fail_to_lookup_font_by_postscript_name ... ok
test test::get_font_data ... ok
test test::get_font_metrics ... ok
test test::get_font_full_name ... ok
test test::get_glyph_count ... ok
test test::get_font_properties ... ok
test test::get_fully_hinted_glyph_outline ... ok
test test::get_glyph_outline_eb_garamond_exclam ... ok
test test::get_glyph_outline_inconsolata_J ... ok
test test::get_glyph_advance_and_origin ... ok
test test::get_glyph_for_char ... ok
test test::load_font_from_file ... ok
test test::load_font_from_memory ... ok
test test::load_fonts_from_opentype_collection ... ok
test test::get_glyph_typographic_bounds ... ok
test test::lookup_all_fonts_in_a_family_in_system_font_directories ... ignored
test test::get_glyph_outline ... ok
test test::get_vertically_hinted_glyph_outline ... ok
test test::lookup_font_by_postscript_name ... ok
test test::lookup_all_fonts_in_a_family ... FAILED
test test::lookup_single_bold_font ... FAILED
test test::lookup_single_italic_font ... FAILED
test test::lookup_single_regular_font ... ok
test test::rasterize_glyph_with_full_hinting ... ok
test test::rasterize_glyph_with_grayscale_aa ... ok
test test::rasterize_glyph_bilevel ... ok

failures:

---- test::lookup_all_fonts_in_a_family stdout ----
thread 'test::lookup_all_fonts_in_a_family' panicked at 'assertion failed: family.fonts().len() > 2', src/test.rs:96:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:209
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::begin_panic
   6: font_kit::test::lookup_all_fonts_in_a_family
   7: <F as alloc::boxed::FnBox<A>>::call_box
             at src/libtest/lib.rs:1475
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libcore/ops/function.rs:231
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/liballoc/boxed.rs:734
   8: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
   9: test::run_test::run_test_inner::{{closure}}
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/panicking.rs:276
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/panic.rs:388
             at src/libtest/lib.rs:1430

---- test::lookup_single_bold_font stdout ----
thread 'test::lookup_single_bold_font' panicked at 'assertion failed: `(left == right)`
  left: `"DejaVuSans"`,
 right: `"DejaVuSans-Bold"`', src/test.rs:80:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:209
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:340
   7: font_kit::test::lookup_single_bold_font
   8: <F as alloc::boxed::FnBox<A>>::call_box
             at src/libtest/lib.rs:1475
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libcore/ops/function.rs:231
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/liballoc/boxed.rs:734
   9: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
  10: test::run_test::run_test_inner::{{closure}}
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/panicking.rs:276
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/panic.rs:388
             at src/libtest/lib.rs:1430

---- test::lookup_single_italic_font stdout ----
thread 'test::lookup_single_italic_font' panicked at 'assertion failed: `(left == right)`
  left: `"DejaVuSans"`,
 right: `"DejaVuSans-Oblique"`', src/test.rs:90:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:209
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:340
   7: font_kit::test::lookup_single_italic_font
   8: <F as alloc::boxed::FnBox<A>>::call_box
             at src/libtest/lib.rs:1475
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libcore/ops/function.rs:231
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/liballoc/boxed.rs:734
   9: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
  10: test::run_test::run_test_inner::{{closure}}
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/panicking.rs:276
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/panic.rs:388
             at src/libtest/lib.rs:1430


failures:
    test::lookup_all_fonts_in_a_family
    test::lookup_single_bold_font
    test::lookup_single_italic_font

test result: FAILED. 26 passed; 3 failed; 1 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--lib'

Clipped rendering on Windows

Looks like a rendering canvas doesn't have an enough space.

>cargo run --example render-glyph -- ArialMT { 32
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target\debug\examples\render-glyph.exe ArialMT { 32`
glyph 94:






            ▓▓██████
          ██████████
        ▒▒████▒▒
        ▓▓██▓▓
        ▓▓██▓▓
        ▓▓██▓▓
        ▓▓██▓▓
        ▓▓██▓▓
        ▓▓██▓▓
        ████▓▓
        ████▒▒
      ▒▒████▒▒
    ▒▒████▓▓
░░████████
░░████▒▒
░░████████
    ▒▒████▓▓
      ▒▒████▒▒
      ░░████▒▒
        ████▓▓
        ▓▓██▓▓
        ▓▓██▓▓
        ▓▓██▓▓

Works correctly on Linux. Not sure about macOS.

@pcwalton I'm not familiar with dwrite. Can you take a look?

List writing systems supported by a font

So we can check which languages/scripts can be handled by this font.

This is very useful for the font fallback resolution, when we need to find a font that can be used to write a specified text.

Default Caseless Matching of possibly-localized family names

Servo would like to implement CSS on top of font-kit. The spec (relevant bits below):

  • Is very specific about (case-insensitive) string comparison for font family names
  • Requires accepting alternative (localized) family names of any given font

Source::select_family_by_name looks like the appropriate API for looking up system fonts matching a given family name string. Some research is needed, to figure out whether the underlying APIs (fontconfig/CoreText/DirectWrite) of the respective default Source for each supported platform behaves as CSS requires on these two points, or if can be configured to do so.

An alternative could be to enumerate all available fonts and their family names, and maintain a Rust (hash?) map where keys are normalized with default case fold. But I suspect this would have significant startup cost.


https://drafts.csswg.org/css-fonts/#font-family-casing

User agents must match these names case insensitively, using the "Default Caseless Matching" algorithm outlined in the Unicode specification [UNICODE]. This algorithm is detailed in section 3.13 entitled "Default Case Algorithms". Specifically, the algorithm must be applied without normalizing the strings involved and without applying any language-specific tailorings. The case folding method specified by this algorithm uses the case mappings with status field ‘C’ or ‘F’ in the CaseFolding.txt file of the Unicode Character Database [UNICODE].

[…]

Implementors should take care to verify that a given caseless string comparison implementation uses this precise algorithm and not assume that a given platform string matching routine follows it, as many of these have locale-specific behavior or use some level of string normalization [UAX15].

https://drafts.csswg.org/css-fonts/#font-style-matching

On systems containing fonts with multiple localized font family names, user agents must match any of these names independent of the underlying system locale or platform API used.

https://drafts.csswg.org/css-fonts/#family-name-value

Some font formats allow fonts to carry multiple localizations of the family name. User agents must recognize and correctly match all of these names independent of the underlying platform localization, system API used or document encoding:

Origin has no effect in freetype rasterize_glyph

The origin argument translates the glyph in the CoreText loader but not the freetype one. In addition, the default seems to be the top-left alignment in freetype, but bottom-left in CoreText.

Issues with fontkit and Roboto Thin

We're experiencing some strange issues when using fontkit and the Google font "Roboto-Thin"

When working with this font locally(localhost - http), everything works fine, but once we deploy our app to a production server(https), i.e. minimize, package(zip) and upload, the letter "a" in the Roboto-Thin font is gone.

I have done some console.log of the Fontkit.font object returned from this font. The letter "a" has acii code 97. If I understand the fontkit.font properly, I can see that characterSet entry 68 refers to 97. Then, when I look into the _glyphs array, I can see that the entry 68 has codePoints set to [97] on my localhost. However, on the https production server, the same _glyphs entry has codePoints set to an empty array(codePoints: []). I assume this is the reason why we can't see the letter "a" there.

In summary:

  • I'm parsing the same Roboto-Thin.ttf file on my localhost and on the production server(xhr request to same url).- the font can be downloaded from Google fonts.
  • On my localhost, I get correct Font data back from fontkit
  • On a https production server, I get different font data for the same font where codePoints for _glyphs[68] is empty.

It's a very strange problem. Have you experienced this before, and do you have any tip on what the cause could be?

Thanks


Alf

Build breaks on Windows

The build breaks on Windows because dwrote published a patch version yesterday that changed an API signature. This issue is more for general information. I've asked them to yank it and republish under 0.6.

Testing whether "shaping information is available for a character"

Servo would like to implement CSS on top of font-kit. This includes:

https://drafts.csswg.org/css-fonts/#font-matching-algorithm

A font is considered to support a given character if (1) the character is contained in the font's character map and (2) if required by the containing script, shaping information is available for that character.

Some legacy fonts may include a given character in the character map but lack the shaping information (e.g. OpenType layout tables or Graphite tables) necessary for correctly rendering text runs containing that character.

I think font.glyph_for_char(c).is_some() implements (1). But how can (2) be achieved? I’m not quite sure what it means excatly, and I don’t see an obvious API in HarfBuzz either.

Script-aware fallback

Clearly one of the trickier aspects to integrating with a text layout system is script aware fallback. Issue #28 is one way, provide metadata. The problem is, it's not really supported by platform text libraries.

What is supported, and used by most web browsers, is an API for choosing a fallback font based on a Unicode code point and other data, generally locale preferences. In CoreText, that's the not-well-documented CTFontCopyDefaultCascadeListForLanguages. In DirectWrite, it's IDWriteFontFallback with IDWriteTextAnalysisSource. In discussions with @pcwalton and further thought, I think the best thing to do is to implement an abstraction for those API's in font-kit.

This will change and increase the API surface of font-kit quite a bit. In particular, we need to adopt a locale representation, and have code to plumb that to platform API calls. I suggest we use fluent-locale-rs, as this has promise to be a standard across the Rust ecosystem.

Discussion is welcome, as is an offer to implement the functionality. However, I'm also quite willing to do it myself, especially as I expect this to interact with the design of the rest of skribo, including its API.

select_family_by_name_arial test fails on Windows 10

---- test::select_family_by_name_arial stdout ----
thread 'test::select_family_by_name_arial' panicked at 'assertion failed: `(left == right)`
  left: `14`,
 right: `8`', tests\select_font.rs:116:9
stack backtrace:
   0: backtrace::backtrace::trace_unsynchronized
             at C:\Program Files\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.29\src\backtrace\mod.rs:66
   1: std::sys_common::backtrace::_print
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\sys_common\backtrace.rs:47
   2: std::sys_common::backtrace::print
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\sys_common\backtrace.rs:36
   3: std::panicking::default_hook::{{closure}}
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:200
   4: std::panicking::default_hook
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:211
   5: std::panicking::rust_panic_with_hook
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:477
   6: std::panicking::continue_panic_fmt
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:384
   7: std::panicking::begin_panic_fmt
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:339
   8: select_font::test::select_family_by_name_arial
             at .\tests\select_font.rs:116
   9: select_font::test::select_family_by_name_arial::{{closure}}
             at .\tests\select_font.rs:114
  10: core::ops::function::FnOnce::call_once<closure,()>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libcore\ops\function.rs:231
  11: alloc::boxed::{{impl}}::call_once<(),FnOnce<()>>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\liballoc\boxed.rs:766
  12: panic_unwind::__rust_maybe_catch_panic
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libpanic_unwind\lib.rs:82
  13: std::panicking::try
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libstd\panicking.rs:275
  14: std::panic::catch_unwind
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libstd\panic.rs:394
  15: test::run_test::run_test_inner::{{closure}}
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libtest\lib.rs:1466
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

failures:
    test::select_family_by_name_arial

test result: FAILED. 8 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test select_font'

Colored emojis

How to retrieve a colored emoji from a font?

We have Loader::outline, but for emojis we have to return an SVG? I have no idea how this is implemented in existing software...

Use a thinner fontconfig crate

servo-fontconfig is pretty heavy (as a build dependency), since it uses bundled C sources:

  • servo-fontconfig - 1.7MiB
  • servo-freetype-sys - 1.8MiB
  • expat-sys - 0.5MiB

So to build font-kit on Linux we have to download ~4MiB of useless code, because it will use system libraries anyway.

There are no alternatives for now, but it's still a problem, imho.

The Weight property is ignored on Linux

extern crate font_kit;

fn main() {
    let names = vec![font_kit::family_name::FamilyName::Title("Arial".to_string())];
    let properties = font_kit::properties::Properties {
        style: font_kit::properties::Style::Normal,
        weight: font_kit::properties::Weight::BOLD,
        stretch: font_kit::properties::Stretch::NORMAL,
    };
    let handle = font_kit::source::SystemSource::new().select_best_match(&names, &properties).unwrap();
    println!("{:?}", handle); // Path { path: "/usr/share/fonts/corefonts/arial.ttf", font_index: 0 }
}
~> fc-match 'Arial :weight=700' --format="%{file}\n"
/usr/share/fonts/corefonts/arialbd.ttf

glyph_for char returns Some(0) on missing cmap

At least on CoreText (haven't tested the other loaders), the glyph_for_char method returns Some(0) instead of None for codepoints missing from the cmap.

I'm not sure this will be my primary method for determining script coverage for itemization, but I figured I'd record it as something that should be fixed.

Support for Arabic or RTL languages

Will this library support RTL languages?

The substitutions happen one character at a time in this library, so I'm not sure how this could be achieved. Yet getting the correct glyphs is important for languages that have joining characters.

Publish to crates.io

Can't be done until cocoa, core-foundation, core-graphics, and core-text are published to crates.io. Also dwrote-rs needs the additions to be merged.

No acccess to device horizontal metrics

This is actually an architectural question about whether layout based on font-kit should be sensitive to font-size or whether layout should be considered scale-invariant and scaling should strictly be a rendering question.

In any case, the advance method on Font only gives access to font-unit advance, without any way to access the hdmx table.

Font size is scalar

The point_size argument to rasterize_glyph (and raster_bounds) is a scalar, but in general we might need an affine transform (to apply fake-italic). If we used a full 3x2 affine, this would also subsume the origin argument.

Suggested baseline in Metrics

Is there a way to get a suggested baseline from Metrics? Right now I'm just using:

(fontsize-in-px / (ascent + descent)) * ascent

I don't see anything wrong with using what I have but just wondering if that is the correct approach.

Rasterization of whitespace glyph causes panic

Might be Windows-specific.

Minimal repro:

let font = SystemSource::new().select_by_postscript_name("ArialMT")
                              .unwrap()
                              .load()
                              .unwrap();
let glyph_id = font.glyph_for_char(' ').unwrap();
font.rasterize_glyph(
    &mut canvas,
    glyph_id,
    font_size,
    &Point2D::zero(),
    HintingOptions::Vertical(font_size),
    RasterizationOptions::GrayscaleAa
); // <--- Panic

Here's the backtrace:

thread 'main' panicked at 'assertion failed: hr == 0', C:\Users\foobar\.cargo\registry\src\github.com-1ecc6299db9ec823\dwrote-0.5.1\src\glyph_run_analysis.rs:72:13
stack backtrace:
   0: std::sys::windows::backtrace::set_frames
             at C:\projects\rust\src\libstd\sys\windows\backtrace\mod.rs:104
   1: std::sys::windows::backtrace::set_frames
             at C:\projects\rust\src\libstd\sys\windows\backtrace\mod.rs:104
   2: std::sys_common::backtrace::_print
             at C:\projects\rust\src\libstd\sys_common\backtrace.rs:71
   3: std::sys_common::backtrace::_print
             at C:\projects\rust\src\libstd\sys_common\backtrace.rs:71
   4: std::panicking::default_hook::{{closure}}
             at C:\projects\rust\src\libstd\panicking.rs:211
   5: std::panicking::default_hook
             at C:\projects\rust\src\libstd\panicking.rs:227
   6: std::panicking::rust_panic_with_hook
             at C:\projects\rust\src\libstd\panicking.rs:475
   7: std::panicking::begin_panic<str*>
             at C:\projects\rust\src\libstd\panicking.rs:409
   8: dwrote::glyph_run_analysis::GlyphRunAnalysis::create_alpha_texture
             at C:\Users\foobar\.cargo\registry\src\github.com-1ecc6299db9ec823\dwrote-0.5.1\src\glyph_run_analysis.rs:72
   9: font_kit::loaders::directwrite::Font::rasterize_glyph
             at C:\Users\foobar\.cargo\registry\src\github.com-1ecc6299db9ec823\font-kit-0.1.0\src\loaders\directwrite.rs:399
  10: foobar::main
             at .\src\main.rs:288
  11: std::rt::lang_start::{{closure}}<()>
             at C:\projects\rust\src\libstd\rt.rs:74
  12: std::rt::lang_start_internal::{{closure}}
             at C:\projects\rust\src\libstd\rt.rs:59
  13: std::rt::lang_start_internal::{{closure}}
             at C:\projects\rust\src\libstd\rt.rs:59
  14: panic_unwind::__rust_maybe_catch_panic
             at C:\projects\rust\src\libpanic_unwind\lib.rs:105
  15: std::panicking::try
             at C:\projects\rust\src\libstd\panicking.rs:289
  16: std::panicking::try
             at C:\projects\rust\src\libstd\panicking.rs:289
  17: std::panicking::try
             at C:\projects\rust\src\libstd\panicking.rs:289
  18: std::rt::lang_start<()>
             at C:\projects\rust\src\libstd\rt.rs:74
  19: main
  20: invoke_main
             at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:74
  21: invoke_main
             at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:74
  22: BaseThreadInitThunk
  23: RtlUserThreadStart
error: process didn't exit successfully: `target\debug\foobar.exe` (exit code: 101)

Support/Enable LCD filtering for subpixel antialiased text

Currently, when rendering a glyph on Linux using the FreeType renderer and RasterizationOptions::SubpixelAa there is no LCD filtering.

It looks like this, with very noticeable color fringing:
image

To enable filtering with FreeType FT_Library_SetLcdFilter should be set, but I don't know how that would work on other platforms.

The easiest solution would be to keep it transparent to the user and always use FT_LCD_FILTER_DEFAULT with FreeType. I could try to make a pull request for that if this solution works for you.

Mismatched types compiletime error.

On 32 bit linux with libfreetype6-dev 2.6.1-0.1ubuntu2.3.

I am getting this error when compiling this library (as a dependency):

error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:130:39                   
    |                                                                                                                               
130 |                                       font_data.len() as i64,                                                                 
    |                                       ^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                                          
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:157:39                   
    |                                                                                                                               
157 |                                       mmap.len() as i64,                                                                      
    |                                       ^^^^^^^^^^^^^^^^^ expected i32, found i64                                               
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:194:61                   
    |                                                                                                                               
194 |                                                             font_data.len() as u64,                                           
    |                                                             ^^^^^^^^^^^^^^^^^^^^^^ expected u32, found u64                    
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:196:61                   
    |                                                                                                                               
196 |                                                             CHUNK_SIZE as u64);                                               
    |                                                             ^^^^^^^^^^^^^^^^^ expected u32, found u64                         
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:197:25                   
    |                                                                                                                               
197 |             if n_read < CHUNK_SIZE as u64 {                                                                                   
    |                         ^^^^^^^^^^^^^^^^^ expected u32, found u64                                                             
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:219:39                   
    |                                                                                                                               
219 |                                       font_data.len() as i64,                                                                 
    |                                       ^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                                          
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:243:39                   
    |                                                                                                                               
243 |                                       mmap.len() as i64,                                                                      
    |                                       ^^^^^^^^^^^^^^^^^ expected i32, found i64                                               
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:325:48                   
    |                                                                                                                               
325 |             (*self.freetype_face).face_flags & (FT_FACE_FLAG_FIXED_WIDTH as i64) != 0                                         
    |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                      
                                                                                                                                    
error[E0277]: no implementation for `i32 & i64`                                                                                     
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:325:46                   
    |                                                                                                                               
325 |             (*self.freetype_face).face_flags & (FT_FACE_FLAG_FIXED_WIDTH as i64) != 0                                         
    |                                              ^ no implementation for `i32 & i64`                                              
    |                                                                                                                               
    = help: the trait `std::ops::BitAnd<i64>` is not implemented for `i32`                                                          
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:337:59                   
    |                                                                                                                               
337 |                 _ if ((*self.freetype_face).style_flags & (FT_STYLE_FLAG_ITALIC) as i64) != 0 => {                            
    |                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64               
                                                                                                                                    
error[E0277]: no implementation for `i32 & i64`                                                                                     
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:337:57                   
    |                                                                                                                               
337 |                 _ if ((*self.freetype_face).style_flags & (FT_STYLE_FLAG_ITALIC) as i64) != 0 => {                            
    |                                                         ^ no implementation for `i32 & i64`                                   
    |                                                                                                                               
    = help: the trait `std::ops::BitAnd<i64>` is not implemented for `i32`                                                          
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:401:45                   
    |                                                                                                                               
401 |                                             f32_to_ft_fixed_26_6(size),                                                       
    |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                                
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:523:72                   
    |                                                                                                                               
523 |             let mut point_position = Point2D::new(ft_fixed_26_6_to_f32(point_position.x),                                     
    |                                                                        ^^^^^^^^^^^^^^^^ expected i64, found i32               
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
523 |             let mut point_position = Point2D::new(ft_fixed_26_6_to_f32(point_position.x.into()),                              
    |                                                                        ^^^^^^^^^^^^^^^^^^^^^^^                                
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:524:72                   
    |                                                                                                                               
524 |                                                   ft_fixed_26_6_to_f32(point_position.y));                                    
    |                                                                        ^^^^^^^^^^^^^^^^ expected i64, found i32               
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
524 |                                                   ft_fixed_26_6_to_f32(point_position.y.into()));                             
    |                                                                        ^^^^^^^^^^^^^^^^^^^^^^^                                
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:543:60                   
    |                                                                                                                               
543 |             Ok(Rect::new(Point2D::new(ft_fixed_26_6_to_f32(metrics.horiBearingX),                                             
    |                                                            ^^^^^^^^^^^^^^^^^^^^ expected i64, found i32                       
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
543 |             Ok(Rect::new(Point2D::new(ft_fixed_26_6_to_f32(metrics.horiBearingX.into()),                                      
    |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^                                        
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:544:60                   
    |                                                                                                                               
544 |                                       ft_fixed_26_6_to_f32(metrics.horiBearingY - metrics.height)),                           
    |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i64, found i32      
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
544 |                                       ft_fixed_26_6_to_f32((metrics.horiBearingY - metrics.height).into())),                  
    |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                     
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:545:59                   
    |                                                                                                                               
545 |                          Size2D::new(ft_fixed_26_6_to_f32(metrics.width),                                                     
    |                                                           ^^^^^^^^^^^^^ expected i64, found i32                               
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
545 |                          Size2D::new(ft_fixed_26_6_to_f32(metrics.width.into()),                                              
    |                                                           ^^^^^^^^^^^^^^^^^^^^                                                
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:546:59                   
    |                                                                                                                               
546 |                                      ft_fixed_26_6_to_f32(metrics.height))))                                                  
    |                                                           ^^^^^^^^^^^^^^ expected i64, found i32                              
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
546 |                                      ft_fixed_26_6_to_f32(metrics.height.into()))))                                           
    |                                                           ^^^^^^^^^^^^^^^^^^^^^                                               
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:561:51                   
    |                                                                                                                               
561 |             Ok(Vector2D::new(ft_fixed_26_6_to_f32(advance.x), ft_fixed_26_6_to_f32(advance.y)))                               
    |                                                   ^^^^^^^^^ expected i64, found i32                                           
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
561 |             Ok(Vector2D::new(ft_fixed_26_6_to_f32(advance.x.into()), ft_fixed_26_6_to_f32(advance.y)))                        
    |                                                   ^^^^^^^^^^^^^^^^                                                            
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:561:84                   
    |                                                                                                                               
561 |             Ok(Vector2D::new(ft_fixed_26_6_to_f32(advance.x), ft_fixed_26_6_to_f32(advance.y)))                               
    |                                                                                    ^^^^^^^^^ expected i64, found i32          
help: you can cast an `i32` to `i64`, which will sign-extend the source value                                                       
    |                                                                                                                               
561 |             Ok(Vector2D::new(ft_fixed_26_6_to_f32(advance.x), ft_fixed_26_6_to_f32(advance.y.into())))                        
    |                                                                                    ^^^^^^^^^^^^^^^^                           
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:628:41                   
    |                                                                                                                               
628 |                                         buffer.len() as i64) == 0 {                                                           
    |                                         ^^^^^^^^^^^^^^^^^^^ expected i32, found i64                                           
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:716:20                   
    |                                                                                                                               
716 |                 x: f32_to_ft_fixed_26_6(origin.x),                                                                            
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                                                     
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:717:20                   
    |                                                                                                                               
717 |                 y: f32_to_ft_fixed_26_6(origin.y),                                                                            
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                                                     
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:722:41                   
    |                                                                                                                               
722 |                                         f32_to_ft_fixed_26_6(point_size),                                                     
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64                              
                                                                                                                                    
error[E0308]: mismatched types                                                                                                      
   --> /home/matias/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.1.0/src/loaders/freetype.rs:981:43                   
    |                                                                                                                               
981 |         assert_eq!(FT_Set_Char_Size(face, ((*face).units_per_EM as i64) << 6, 0, 0, 0), 0);                                   
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found i64   

Implement a fast has_character method

I'm looking for a Source method that will return a list of fonts that contain a specified character. I've tried to implement this via Loader::glyph_for_char, but it's extremely slow. On my machine (Linux), with 212 font families, it takes up to 3 seconds to find a right font.

On the other hand, fontconfig can do this instantly:

> fc-list ":charset=672c"
/usr/share/fonts/droid/DroidSansFallback.ttf: Droid Sans Fallback:style=Regular
/usr/share/fonts/droid/DroidSansFallbackLegacy.ttf: Droid Sans Fallback:style=Regular
/usr/share/fonts/droid/DroidSansJapanese.ttf: Droid Sans Japanese:style=Regular

It takes no time at all. I don't know does it uses a cache or parses only font headers or else.

The problem is to find similar methods for Windows and Mac. And I'm not familiar with their API. @raphlinus do you have any suggestions?

I found GetFontUnicodeRanges and ScriptGetCMap, but I'm not sure how good they are. Also, both of them are not from DirectWrite.

Qt uses EnumFontFamiliesEx.

SystemSource::new() leaks memory

The following program persistenly increases its memory usage.

use font_kit::source::SystemSource;

fn main() {
    loop { SystemSource::new(); }
}

PlatformError on Windows

System details:
OS: Windows 10 1903
rustc 1.38.0-nightly (69656fa4c 2019-07-13)

How to reproduce:
repo: https://github.com/Aloxaf/silicon
Command: cargo run -- some_rust_source.rs -o test.png

Error:
thread 'main' panicked at 'this will panic.: PlatformError', src\libcore\result.rs:1051:5
BackTrace:

stack backtrace:
   0: backtrace::backtrace::trace_unsynchronized
             at C:\Program Files\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.29\src\backtrace\mod.rs:66
   1: std::sys_common::backtrace::_print
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\sys_common\backtrace.rs:47
   2: std::sys_common::backtrace::print
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\sys_common\backtrace.rs:36
   3: std::panicking::default_hook::{{closure}}
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:200
   4: std::panicking::default_hook
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:214
   5: std::panicking::rust_panic_with_hook
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:477
   6: std::panicking::continue_panic_fmt
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:384
   7: std::panicking::rust_begin_panic
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:311
   8: core::panicking::panic_fmt
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libcore\panicking.rs:85
   9: core::result::unwrap_failed<font_kit::error::GlyphLoadingError>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libcore\macros.rs:18
  10: core::result::Result<(), font_kit::error::GlyphLoadingError>::expect<(),font_kit::error::GlyphLoadingError>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libcore\result.rs:879
  11: silicon::font::PositionedGlyph::draw<closure>
             at .\src\font.rs:286
  12: silicon::font::FontCollection::draw_text_mut<image::dynimage::DynamicImage>
             at .\src\font.rs:253
  13: silicon::formatter::ImageFormatter::draw_line_number
             at .\src\formatter.rs:177
  14: silicon::formatter::ImageFormatter::format
             at .\src\formatter.rs:230
  15: silicon::run
             at .\src\main.rs:48
  16: silicon::main
             at .\src\main.rs:76
  17: std::rt::lang_start::{{closure}}<()>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libstd\rt.rs:64
  18: std::rt::lang_start_internal::{{closure}}
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\rt.rs:49
  19: std::panicking::try::do_call<closure,i32>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:296
  20: panic_unwind::__rust_maybe_catch_panic
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libpanic_unwind\lib.rs:82
  21: std::panicking::try
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panicking.rs:275
  22: std::panic::catch_unwind
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\panic.rs:394
  23: std::rt::lang_start_internal
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\/src\libstd\rt.rs:48
  24: std::rt::lang_start<()>
             at /rustc/69656fa4cbafc378fd63f9186d93b0df3cdd9320\src\libstd\rt.rs:64
  25: main
  26: invoke_main
             at d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  27: __scrt_common_main_seh
             at d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  28: BaseThreadInitThunk
  29: RtlUserThreadStart
error: process didn't exit successfully: `target\debug\silicon.exe main.rs -o test.png` (exit code: 101)

I identified the following in src\font.rs:286 as the problem:

self.font
            .rasterize_glyph(
                &mut canvas,
                self.id,
                self.size,
                &FontTransform::identity(),
                &origin,
                HintingOptions::None,
                RasterizationOptions::GrayscaleAa,
            )
            .expect("this will panic.");

DirectWrite glyph rasterization seem to be offset

The glyph rasterization using the DirectWrite loader seems to cut off the glyph on the right edge of the canvas. FreeType seems to work correctly but I run into the #14 issue and only the first glyph rasterized works.

Forcibly increasing the raster bound size in the render-glyph example seems to give the correct results.

Output of render-glyph example:

render-glyph (DirectWrite)
d:/projects/font-kit $ cargo run --example render-glyph -- "Calibri" "H" 24
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s
     Running `target\debug\examples\render-glyph.exe` Calibri H 24
glyph 44:
  ████              ██
  ████              ██
  ████              ██
  ████              ██
  ████              ██
  ████              ██
  ████████████████████
  ████████████████████
  ████              ██
  ████              ██
  ████              ██
  ████              ██
  ████              ██
  ████              ██
  ████              ██
                      
                      
d:/projects/font-kit $ cargo run --example render-glyph -- "Calibri" "e" 24
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s
     Running `target\debug\examples\render-glyph.exe` Calibri e 24
glyph 286:
      ░░████████▒▒  
    ▒▒████████████▓▓
  ░░████        ▓▓██
  ▓▓██░░        ░░██
  ▓▓████████████████
  ▓▓████████████████
  ▓▓██░░            
  ▓▓██▒▒            
  ▒▒████▒▒        ██
    ▓▓██████████████
      ▒▒██████████░░
                    
render-glyph (FreeType)
d:/projects/font-kit $ cargo run --features loader-freetype-default --example render-glyph -- "Calibri" "e" 24
    Finished dev [unoptimized + debuginfo] target(s) in 5.50s
     Running `target\debug\examples\render-glyph.exe Calibri e 24`
glyph 286:
      ░░░░▒▒░░░░    
  ░░▒▒▓▓██████▓▓░░  
░░▓▓██▓▓░░░░▒▒▓▓▓▓░░
░░██▓▓        ▒▒██▒▒
▓▓██░░        ░░██▓▓
▓▓██▒▒▒▒▒▒▒▒▒▒▓▓██▓▓
▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒
▓▓██░░              
▓▓██▒▒              
▒▒██▓▓░░        ░░░░
░░▓▓██▓▓▒▒▒▒▒▒▒▒▓▓░░
  ░░▒▒▓▓██████▓▓▒▒░░
      ░░░░░░░░░░    
d:/projects/font-kit $ cargo run --features loader-freetype-default --example render-glyph -- "Calibri" "H" 24
    Finished dev [unoptimized + debuginfo] target(s) in 0.18s
     Running `target\debug\examples\render-glyph.exe Calibri H 24`
glyph 44:
░░░░              ░░░░
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▓▓
▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓██░░          ░░██▓▓
▓▓▓▓░░          ░░▓▓▓▓
░░░░              ░░░░
render-glyph (DirectWrite) with bounds.size.x += 1
d:/projects/font-kit $ cargo run --example render-glyph -- "Calibri" "H" 24
   Compiling font-kit v0.1.0 (D:\projects\font-kit)
    Finished dev [unoptimized + debuginfo] target(s) in 1.70s
     Running `target\debug\examples\render-glyph.exe Calibri H 24`
glyph 44:
  ████              ████
  ████              ████
  ████              ████
  ████              ████
  ████              ████
  ████              ████
  ██████████████████████
  ██████████████████████
  ████              ████
  ████              ████
  ████              ████
  ████              ████
  ████              ████
  ████              ████
  ████              ████
                        
                        
d:/projects/font-kit $ cargo run --example render-glyph -- "Calibri" "e" 24
    Finished dev [unoptimized + debuginfo] target(s) in 0.18s
     Running `target\debug\examples\render-glyph.exe Calibri e 24`
glyph 286:
      ░░████████▒▒    
    ▒▒████████████▓▓  
  ░░████        ▓▓██▒▒
  ▓▓██░░        ░░██▓▓
  ▓▓████████████████▓▓
  ▓▓████████████████▓▓
  ▓▓██░░              
  ▓▓██▒▒              
  ▒▒████▒▒        ██▒▒
    ▓▓██████████████▒▒
      ▒▒██████████░░  
                        

Create an issue template

  1. Should note that tests are CI-only and will fail on a local machine.
  2. Should ask a user about OS, OS version and other generic info.

Segfault https://github.com/pcwalton/font-kit/blob/master/examples/list-fonts.rs

   Compiling font-kit v0.1.0 (/shareddata/share/Prog/Rust/font-kit)                                                                      
    Finished dev [unoptimized + debuginfo] target(s) in 34.28s                                                                           
     Running `target/debug/examples/list-fonts`
Loading fonts… 242 / 248 [====================================================================================>--] 97.58 % 142.13/s 0s zsh: segmentation fault (core dumped)  cargo run --example list-fonts

Additional collaborators?

It would be nice, if you could add me as a collaborator to this project. At least temporarily.
Currently, I'm trying to maintain my own fork, but it's troublesome, since there are a lot of changes/fixes and most of them are depending on each other. And the patches review process is pretty slow at the moment.

Invalid Fantasy font on Windows

The current fantasy-style font for Windows is hardcoded as Papyrus, but there are no such font. At least on a default Win10 machine.

core_text::Font::from_file is unsound

It creates a memory-mapped buffer from a file, and this file can be modified by any other process on the computer or even another thread in the same executable, but it isn't marked unsafe.

This is exactly why Mmap::map itself is unsafe.

Invalid select_best_match result on Linux

extern crate font_kit;

fn main() {
    let names = vec![
        font_kit::family_name::FamilyName::Title("Invalid".to_string()),
        font_kit::family_name::FamilyName::Title("Times New Roman".to_string()),
    ];
    let properties = font_kit::properties::Properties::default();
    let handle = font_kit::source::SystemSource::new().select_best_match(&names, &properties).unwrap();
    println!("{:?}", handle);
}

Prints: Path { path: "/usr/share/fonts/corefonts/arial.ttf", font_index: 0 }

Works correctly on Windows. Didn't tested on macOS.

Support resolving of default Windows fonts

There are font families like MS Shell Dlg 2 which will not be resolved at the moment:

> cargo run --example match-font -- "MS Shell Dlg 2"
Error: NotFound

I'm not sure if it's possible to resolve them via winapi, but they are defined here: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes\

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.