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

Windows 7 font issues

Open ma-laforge opened this issue 9 years ago • 16 comments
trafficstars

Hi,

I could not find an issue on this, but I am having font issues Cairo (I presume). I notice it on Gtk displays.

  1. The standard typefaces (I believe they are supposed to be standard) do not appear to be available in Windows. It looks like Cairo always reverts to a default font in Windows.
  2. I also get issues displaying unicode exponent characters (all except 1, 2, 3). Consequently, I cannot use the output from showoff.jl to display with scientific notation in a Gtk window.
  3. Although I can select Windows fonts from a Windows session (ex "Times"), These fonts still do not appear to support the exponent characters.

Sample Code

using Gtk
using Cairo

bold = false
DISPLAYSTRING = "min:−3, supnum: ⁰¹²³⁴⁵⁶⁷⁸⁹, supmin: ⁻², Greek: αΑβΒφϕΦγΓ"
FONTNAMES = ["Sans", "Serif", "Fantasy", "Monospace"]
weight = bold? Cairo.FONT_WEIGHT_BOLD: Cairo.FONT_WEIGHT_NORMAL
slant = Cairo.FONT_SLANT_NORMAL
_size = 12

canvas = @GtkCanvas
win = @GtkWindow(canvas, "Test Window")

@guarded draw(canvas) do widget
    ctx = getgc(canvas)
    h = height(ctx)
    pitch = h/(length(FONTNAMES)+1)

    set_font_size(ctx, _size)
    y = 0

    for fontname in FONTNAMES
        y += pitch
        text = "$fontname: $DISPLAYSTRING"
        Cairo.move_to(ctx, 0, y)
        select_font_face(ctx, fontname, slant,  weight)
        show_text(ctx, text)
    end
end

showall(win)

ma-laforge avatar Jun 02 '16 00:06 ma-laforge

My mistake: Apparently this API is for "toy" examples only. Font availability is not guaranteed.

ma-laforge avatar Jun 02 '16 00:06 ma-laforge

I looked a the provided examples in Samples.md, but do not see a good example of how one can successfully draw text across different platforms using a Unicode-capapable typeface. As far as I can tell, the Cairo documentation seems to discourage the use of select_font_face, as demonstrated in sample_text.jl.

To be honest, the select_font_face API does appear to be sufficient for my own needs... or at least it would be if it allowed met to auto-select a reasonable-looking serif font with good unicode support.

ma-laforge avatar Jun 02 '16 01:06 ma-laforge

To make a longer story short: the libcairo font interface is rather low level, that's why you find some pango interfacing there also (and that's also the reason why in Compose.jl there is more pango adaptation incl. font selection).

The examples in Samples.md are drawing examples only.

lobingera avatar Jun 02 '16 05:06 lobingera

you can use the exported text interface. This here works (...tested on linux... fontselecting and finding fonts is a major headache in Windows).

s = Cairo.CairoImageSurface(800,200,Cairo.FORMAT_RGB24);
c = Cairo.CairoContext(s);
t = Cairo.set_font_face(c,"Arial Bold 16")
DISPLAYSTRING = "min:−3, supnum: ⁰¹²³⁴⁵⁶⁷⁸⁹, supmin: ⁻², Greek: αΑβΒφϕΦγΓ"
set_source_rgb(c,1,1,1)
paint(c)
set_source_rgb(c,0,0,0)
text(c,10,100,DISPLAYSTRING)
write_to_png(s,"a1.png")

a1

lobingera avatar Jun 02 '16 05:06 lobingera

Interesting...

The Pango set_font_face interface seems to "honour" the 4 fonts that are supposedly supported by Cairo: Sans, Serif, Fantasy, & Monospace... Even in my Windows 7 installation.

Even stranger: unlike select_font_face, it does not supports the Times font...

Sadly, the set_font_face()/text() solution is inadequate for my application. Cairo's transform operations don't get applied when I use it. That means I cannot rotate my text.

Thanks for the help anyways.

ma-laforge avatar Jun 02 '16 22:06 ma-laforge

s = Cairo.CairoImageSurface(800,200,Cairo.FORMAT_RGB24);
c = Cairo.CairoContext(s);
t = Cairo.set_font_face(c,"Arial Bold 16")
DISPLAYSTRING = "min:−3, supnum: ⁰¹²³⁴⁵⁶⁷⁸⁹, supmin: ⁻², Greek: αΑβΒφϕΦγΓ"
set_source_rgb(c,1,1,1)
paint(c)
set_source_rgb(c,0,0,0)
text(c,10,200,DISPLAYSTRING,angle=15.0)

a1

lobingera avatar Jun 03 '16 05:06 lobingera

That's good.

... But text() appears to change the meaning of font size... which now make Cairo.text_extents() completely inaccurate.

Question Are we supposed to use a different tool to get text extents & figure out display coordinates?

Moreover The behaviour of this text() function seems unconventional to me: This function reset transforms before applying the rotation, which limits its usefulness:

  1. Save context
  2. reset context
  3. Draw rotated text in native coordinate system.
  4. Restore context

I would have expected:

  1. Save context
  2. Draw rotated text on top of current coordinate system.
  3. Restore context.

ma-laforge avatar Jun 04 '16 19:06 ma-laforge

To your

I would have expected:

well, just implement it. You can see from the implementation of text how to use update_layout which is the main interface between cairo's CTM and pango's internal CTM. As i wrote above, Cairo.jl is using both variants to show text.

The major problem (and more of a problem in Windows OS) is to correctly find and select an installed font (for proper definition of installed). Just look into https://www.cairographics.org/manual/cairo-text.html, esp. https://www.cairographics.org/manual/cairo-text.html#cairo-select-font-face and https://developer.gnome.org/pango/unstable/pango-Cairo-Rendering.html.

lobingera avatar Jun 05 '16 06:06 lobingera

btw, i ran your code (changing font size) on my linux box and get: screenshot from 2016-06-05 09 51 28

I have no font called Fantasy, but the other defaults seem to work. Can you please post a screenshot of your problem?

lobingera avatar Jun 05 '16 07:06 lobingera

well, just implement it.

Fair enough. I will take a closer look at the code then.

The major problem (and more of a problem in Windows OS) is to correctly find and select an installed font (for proper definition of installed). Just look into [...]

Thanks for the references.

Windows snapshot cairofonts_win

Linux snapshot cairofonts_linux

Fantasy does map to a font on my Linux... but it has limited unicode support. It would not work well with showoff.jl (for example).

ma-laforge avatar Jun 06 '16 01:06 ma-laforge

I know it's not helpful, but i could reproduce your problem on a Win7. I really see this as font selection problem, because only some glyphs are not available, but the general text setting is working.

lobingera avatar Jun 11 '16 09:06 lobingera

I know it's not helpful, but i could reproduce your problem on a Win7.

Well, it is good to know. That means it is probably not a setup issue on my system.

I really see this as font selection problem, because only some glyphs are not available, but the general text setting is working.

Agreed.

I guess my question is:

Is this a bug? It is clear to me that Cairo can find reasonable fonts for Sans, Serif, Monospace (though not Fantasy), as shown below:

Windows 7 + set_font_face/text

cairofonts_win7highlevel

(Generated using slightly altered code):

using Gtk
using Cairo

test_lowlevel = false

bold = false
DISPLAYSTRING = "min:−3, supnum: ⁰¹²³⁴⁵⁶⁷⁸⁹, supmin: ⁻², Greek: αΑβΒφϕΦγΓ"
FONTNAMES = ["Sans", "Serif", "Fantasy", "Monospace"]
weight = bold? Cairo.FONT_WEIGHT_BOLD: Cairo.FONT_WEIGHT_NORMAL
slant = Cairo.FONT_SLANT_NORMAL
_size = 12 #12, 20

canvas = @GtkCanvas
win = @GtkWindow(canvas, "Test Window")

@guarded draw(canvas) do widget
    ctx = getgc(widget)
    h = height(ctx)
    pitch = h/(length(FONTNAMES)+1)
    y = 0

    for fontname in FONTNAMES
        y += pitch
        disptext = "$fontname: $DISPLAYSTRING"

        if test_lowlevel
            set_font_size(ctx, _size)
            select_font_face(ctx, fontname, slant,  weight)
            Cairo.move_to(ctx, 0, y)
            show_text(ctx, disptext)
        else
            fmtstr = (bold?" Bold":"") * " $_size"
            Cairo.set_font_face(ctx,"$fontname $fmtstr")
            Cairo.text(ctx,0,y,disptext)
        end
    end
end

showall(win)

I admit there might be more going on in the backend, but I would have expected even the low-level interface to be able to find proper mappings for the "default fonts".

ma-laforge avatar Jun 12 '16 18:06 ma-laforge

What would you consider the bug?

I read today i little bit into libcairo sources and i'm reasonably confused how even the default fonts are selected (per OS). cairo (the library, not Cairo.jl) makes no guarantees for the fonts except the cairo:$family which seems to be built-in in all cairo variants (there is a long list of option for building the library).

To your https://github.com/JuliaGraphics/Cairo.jl/issues/138#issuecomment-223174666: I can think about doing a 'simple' text setting example (incl. coordination transformation) that should work on Sans-Serif and Serif basis, but solving general font selection (OS agnostic) is out of my reach. Maybe like this: If the example doesn't show all glyphs (like in your subscript/greek/math example) it's an indication you need to solve this first, locally.

lobingera avatar Jun 13 '16 12:06 lobingera

[...cairo...] makes no guarantees for the fonts except the cairo:$family which seems to be built-in in all cairo variants

I saw that too... but I was not able to make it work. I tried running the above code with FONTNAMES = ["Cairo:Sans", "Cairo:Serif", "Cairo:Fantasy", "Cairo:Monospace"]... but this did not work for me.

(there is a long list of option for building the library).

Maybe that's the problem... I need to figure out how to compile the fonts in, or something.


Well, I think it sounds like there is no issue with Cairo.jl. Feel free to close this issue.

ma-laforge avatar Jun 13 '16 22:06 ma-laforge

@ma-laforge Maybe a last check: Which version of libcairo are you using?

cairo_version = ccall((:cairo_version,Cairo._jl_libcairo),Int32,())

lobingera avatar Jun 14 '16 08:06 lobingera

Not sure what the version number means, but I get: 11402

ma-laforge avatar Jun 14 '16 16:06 ma-laforge

Hopefully old enough to close. Please reopen if still an issue on modern Windows.

ViralBShah avatar Aug 12 '24 18:08 ViralBShah