Chris00 / ocaml-cairo

Binding to Cairo, a 2D Vector Graphics Library.
GNU Lesser General Public License v3.0
54 stars 8 forks source link

Ft and Pango modules #11

Closed bobot closed 5 years ago

bobot commented 6 years ago

I was trying to migrate mlpost from cairo to cairo2 (backtracking/mlpost#8). Things are well namespaced, and it uses dune! great! But I'm quite puzzled by the presence or not of the module Ft. Where is it? It is not in the list of font to implement.

aryx commented 6 years ago

I had the same issue. With the cairo lib I can use the pango font library (pango_cairo.ml). Is there a similar functionality with cairo2?

Chris00 commented 6 years ago

The module Ft does not exist at the moment but it would not be too difficult to create a minimal one in the vein of the cairo library. Access to Fontconfig functions would be limited to a minimum (and they would not appear explicitly).

Chris00 commented 6 years ago

I was thinking an interface along such as

module Ft : sig
  type face
  (** A FreeType face. *)

  val face : ?index:int -> string -> face

  type flags = [`Vertical_layout | `Force_autohint]

  val create_for_ft_face : ?flags:flags -> face -> [`Ft] Font_face.t

  val create_for_pattern : ?options:Font_options.t ->
                           string -> [`Ft] Font_face.t

  val scaled_font_lock_face : [`Ft] Scaled_font.t -> face
  val scaled_font_unlock_face : [`Ft] Scaled_font.t -> unit

  module Synthesize : sig
    type t = Bold | Oblique

    val get : [`Ft] Font_face.t -> t list
    val set : [`Ft] Font_face.t -> t list -> unit
    val unset : [`Ft] Font_face.t -> t list -> unit
  end
end

Would that be OK for you?

Chris00 commented 6 years ago

@aryx A minimal Pango binding may also be envisioned. The only problem is lack of time...

aryx commented 6 years ago

Do you know why the cairo(1) package didn't get an update for recent ocaml (e.g., 4.07). Is cairo2 better than cairo(1) in the long term?

bobot commented 6 years ago

It is ok. Are you doing the init_freetype yourself?`

Mlpost use a binding to some other function of freetype or fontconfig: https://github.com/backtracking/mlpost/blob/07093cb/src/ml_mlpost_ft.c . If it is possible for you to add them it would be great but already providing a .h that define a conversion between your type and the C one (e.g. FT_face_val) would be safer.

Thank you

Chris00 commented 6 years ago

Do you know why the cairo(1) package didn't get an update for recent ocaml (e.g., 4.07).

I am not the author of that package so I do not know.

Is cairo2 better than cairo(1) in the long term?

At least it is my intention to keep it working in the future — albeit I can't promise to react fast because I am very busy.

Chris00 commented 6 years ago

Are you doing the init_freetype yourself?`

Yes, it is done on demand. Is it a problem?

Chris00 commented 6 years ago

I pushed a minimal implementation. It is completely untested. cairo_ocaml.h contains an access macro to Ft_face. @bobot May you please test it? Also a PR with an example of use would be appreciated.

Chris00 commented 6 years ago

[The commit close this issue. Reopen it if it does not work.]

bobot commented 6 years ago

Ok I'm going to test it in mlpost (simplified since we both use dune), and I should be able to provide a minimal example.

Are you doing the init_freetype yourself?`

Yes, it is done on demand. Is it a problem?

It is not a problem for mlpost. But for such binding, as for any global datastructure, I think it is good to keep the possibility to work on multithreaded (and one day multicore) context. Do you mind a PR that adds an optional ft_library optional argument?

Chris00 commented 6 years ago

I have pushed a commit to allow to pass an optional Ft.library.

bobot commented 6 years ago

Thank you a lot!

Chris00 commented 6 years ago

There were some typos. Make sure to git reset --hard origin/master.

Chris00 commented 6 years ago

@aryx I am looking to Pango bindings — to be in the Cairo_gtk module. It mostly uses PangoFontMap * but there is also PangoCairoFontMap *. Do you know whether the two are incompatible or can PangoCairoFontMap * be used anywhere PangoFontMap * is required, or is there an explicit cast to make?

Chris00 commented 6 years ago

@aryx I have added a Cairo_pango module. There is a minimal example inspired from the documentation but it would be nice to have more testing — especially concerning functions using the Font_map.t and cairo_font types and the possible cast to Pango corresponding types. A PR with additional examples would be helpful to the community (I am not much versed in Pango).

aryx commented 6 years ago

I have compilation problems on my Linux Ubuntu machine (18.04). I'm using OPAM with ocaml 4.02.3. Here is the output of make:

dune build @install @examples ocamlc src/.cairo.objs/cairo.{cmi,cmti} (exit 2) (cd _build/default && /home/pad/.opam/4.02.3/bin/ocamlc.opt -w @a-4-29-40-41-42-44-45-48-58-59-60-40 -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I src/.cairo.objs -no-alias-deps -o src/.cairo.objs/cairo.cmi -c -intf src/cairo.mli) File "src/cairo.mli", line 537, characters 9-63: Warning 50: unattached documentation comment (ignored) File "src/cairo.mli", line 538, characters 8-43: Warning 50: unattached documentation comment (ignored) File "src/cairo.mli", line 539, characters 11-43: Warning 50: unattached documentation comment (ignored) File "src/cairo.mli", line 540, characters 12-45: Warning 50: unattached documentation comment (ignored) File "src/cairo.mli", line 541, characters 10-64: Warning 50: unattached documentation comment (ignored) File "src/cairo.mli", line 1: Error: Some fatal warnings were triggered (5 occurrences) ocamlc pango/cairo_pango_stubs.o In file included from cairo_pango_stubs.c:20:0: cairo_pango_stubs.c: In function 'caml_pango_cairo_font_map_set_default': /home/pad/.opam/4.02.3/lib/ocaml/caml/memory.h:88:29: warning: unused variable 'camlframe' [-Wunused-variable] struct camlroots_block caml__frame = caml_local_roots ^ /home/pad/.opam/4.02.3/lib/ocaml/caml/memory.h:91:3: note: in expansion of macro 'CAMLparam0' CAMLparam0 (); \ ^~~~~~ cairo_pango_stubs.c:69:3: note: in expansion of macro 'CAMLparam1' CAMLparam1(vfm); ^~~~~~ ocamlc src/cairo_stubs.o cairo_stubs.c: In function 'caml_cairo_Ft_new_face': cairo_stubs.c:1107:19: warning: pointer targets in passing argument 2 of 'FT_New_Face' differ in signedness [-Wpointer-sign] (const FcChar8 ) String_val(vpath), ^ In file included from /usr/include/cairo/cairo-ft.h:47:0, from cairo_ocaml.h:147, from cairo_ocaml_types.h:3, from cairo_stubs.c:35: /usr/include/freetype2/freetype/freetype.h:2093:3: note: expected 'const char ' but argument is of type 'const FcChar8 {aka const unsigned char *}' FT_New_Face( FT_Library library, ^~~ cairo_stubs.c: In function 'caml_cairo_ft_synthesize_set': cairo_stubs.c:1208:3: warning: 'synth_flags' is used uninitialized in this function [-Wuninitialized] cairo_ft_font_face_set_synthesize(FONT_FACE_VAL(vff), synth_flags); ^~~~~~~~~~~~~~ cairo_stubs.c: In function 'caml_cairo_ft_synthesize_unset': cairo_stubs.c:1217:3: warning: 'synth_flags' is used uninitialized in this function [-Wuninitialized] cairo_ft_font_face_unset_synthesize(FONT_FACE_VAL(vff), synth_flags); ^~~~~~~~~~~~~~~~ Makefile:6: recipe for target 'build' failed make: *** [build] Error 1

aryx commented 6 years ago

Otherwise, here is an example of my use of Pango with Cairo1:

https://github.com/aryx/fork-efuns/blob/master/graphics/gtk_cairo/graphics_efuns.ml

Chris00 commented 6 years ago

I fixed the above problems (some specific to 4.02). May you try again? (git reset --hard origin/master needed as I modified the history.)

Chris00 commented 6 years ago

Note that I will also depend on the conf-freetype package (maybe optionally).

aryx commented 6 years ago

It works! Thanks a lot. I was able to compile this new version and to port efuns from cairo1 to cairo2. Everything works. I got a segmentation fault in my application at some point, but I'm not sure it's related to cairo2 though. I'll try to investigate more if it happens again.

Chris00 commented 6 years ago

On 6 September 2018 at 05:33 GMT, Yoann Padioleau wrote:

Everything works. I got a segmentation fault in my application at some point, but I'm not sure it's related to cairo2 though. I'll try to investigate more if it happens again.

Thanks for reporting. I wrote the code in a haste so another pair of eyeballs to check it will be great.

Chris00 commented 6 years ago

Travis is all green as well as AppVeyor. Once both of you have made more tests, I'll do a release.

aryx commented 6 years ago

Yep, I get some segfaults and many Cairo errors. Here is a trace:

In callback for signal expose_event, uncaught exception: Cairo.Error(SURFACE_FINISHED) fucking callback

In callback for signal expose_event, uncaught exception: Cairo.Error(SURFACE_FINISHED) Segmentation fault (core dumped)

Not sure it's related to Pango, but I definitely do not get them with the cairo1 OCaml binding.

Chris00 commented 6 years ago

@aryx What code? Could you post a minimal example?

Chris00 commented 6 years ago

I'm a bit surprised that the thing crashes because of the exception. If you trigger the exception yourself, does it crash as well?

Chris00 commented 6 years ago

If you were using a Gtk application, I reverted the tentative fix for https://github.com/Chris00/ocaml-cairo/issues/10 (and added a test to show why). Please try again with HEAD.

aryx commented 5 years ago

I can not install cairo2-pango on my new machine. I have opam 2.0.2 and opam switch 4.02.3 but I think the problem is that the OPAM file for cairo2-pango depends on lablgtk2 instead of lablgtk.

$ opam install cairo2-pango The following dependencies couldn't be met:

I think they removed lablgtk2 and now simply use lablgtk.

Chris00 commented 5 years ago

There is this disparity between the findlib package name and the opam name which trips me all the time...

aryx commented 5 years ago

Do you know how I can hack my own opam repository so I don't have to wait for a new release?

Chris00 commented 5 years ago

I suppose you can (or can pin the package). Hopefully, the update to the opam repository should not take more than a few hours.