Cairo.jl icon indicating copy to clipboard operation
Cairo.jl copied to clipboard

Can't turn off font hinting / metrics

Open jkrumbiegel opened this issue 5 years ago • 6 comments

When animating a drawing text glyphs jitter around, I assume they align to the underlying device space integer grid. I've found cairo functions to turn off that behavior that are not exposed in Cairo.jl's API. But using them doesn't work, maybe I'm doing something wrong. I think this would be beneficial to have included in Cairo.jl.

That's the code to turn off hinting that I use

font_options_ptr = ccall((:cairo_font_options_create, C.libcairo), Ptr{Nothing}, ())

CAIRO_HINT_STYLE_NONE = 1
CAIRO_HINT_STYLE_FULL = 4
ccall(
    (:cairo_font_options_set_hint_style, C.libcairo), Nothing,
    (Ptr{Nothing}, Int32),
    font_options_ptr, CAIRO_HINT_STYLE_NONE)

CAIRO_HINT_METRICS_DEFAULT = 0
CAIRO_HINT_METRICS_OFF = 1
CAIRO_HINT_METRICS_ON = 2

ccall(
    (:cairo_font_options_set_hint_metrics, C.libcairo), Nothing,
    (Ptr{Nothing}, Int32),
    font_options_ptr, CAIRO_HINT_METRICS_OFF)

# cc is a cairo context
ccall(
    (:cairo_set_font_options, C.libcairo), Nothing,
    (Ptr{Nothing}, Ptr{Nothing}),
    cc.ptr, font_options_ptr)

ccall(
    (:cairo_font_options_destroy, C.libcairo), Nothing,
    (Ptr{Nothing},),
    font_options_ptr)

jkrumbiegel avatar Sep 12 '19 21:09 jkrumbiegel

  1. If you want them to be part of Cairo.jl just do a PR
  2. Fonthandling/rendering is highly backend/system specific, what system are you testing?
  3. Do i understand correctly, that you try to render the same text in the same position and get different glyph shapes?
  4. If possible just attach some frames from your animation here. (5. In a similar case i selected a font that was not subject to strong hinting)

lobingera avatar Sep 13 '19 08:09 lobingera

  1. If you want them to be part of Cairo.jl just do a PR

I would if I was sure that I got it working correctly. Although I've tried the font property ccalls with the setting antialiasing off and that had an obvious effect. Not the metrics though..

  1. Fonthandling/rendering is highly backend/system specific, what system are you testing?

I thought cairo was already the "backend" and it's just editing bezier curves of the fonts here, but anyway I'm running this on MacOS Mojave

  1. Do i understand correctly, that you try to render the same text in the same position and get different glyph shapes?

I'm trying to animate text position and rotation, and the text does not smoothly travel but it jiggles with every glyph.

  1. If possible just attach some frames from your animation here.

Here's a test gif:

hinting

(5. In a similar case i selected a font that was not subject to strong hinting)

Well should turning hinting off not be enough? That's part of my reason to post here, maybe someone has already solved that problem for themselves. It's weird that the documentation sounds like exactly what's happening, but my code has no effect. Unless I'm making a mistake.

jkrumbiegel avatar Sep 13 '19 16:09 jkrumbiegel

I thought MacOS doesn’t do font hinting. Of course, it’s possible that Cairo and macOS have some special arrangement....

cormullion avatar Sep 15 '19 12:09 cormullion

libcairo hands over the rendering of fonts to bitmaps (if needed) to another library, in most cases freetype, but 'system' font handling can be configured at compile or runtime. I don't know where the 'myth' of MacOS doesn't do hinting comes from (it's not the first time i read this), but keep in mind, that in any case if you want to do good approximation of the font design to a discrete bitmap some hinting will be part of this, sometimes by using the hints in the glyph description (like in Type1, TrueType), sometimes by auto-hinting (reading the outline and do some heuristics in conversion), sometimes by using a cached bitmap. It could be that in your case you signal Cairo not to use hinting, but the lower library has own ideas what to do.

I've seen similar effects like the above attached. non-axis aligned rendering of fonts is a major headache afacis no engine is handling it very well. See it like this: All single frames of your animation will look OK, it's the change in glyph placement and sub-features that make it jitter.

Without testing this:

  1. Render the chars/glyphs independently.
  2. Render your text (in higher resolution) to a bitmap and transform/copy/paste it.
  3. use charpath - i.e. get the character outlines into a cairo path

lobingera avatar Sep 15 '19 13:09 lobingera

The ‘myth’ is created by type designers like Peter Bilak, but he may be wrong, of course. 😇

cormullion avatar Sep 15 '19 13:09 cormullion

@cormullion I'm not using the same or 'correct' terminology. Afaics MacOS claims not to read-in hinting information in the font. I used hinting as the process of grid-fitting.

lobingera avatar Sep 15 '19 13:09 lobingera