dbuenzli / vg

Declarative 2D vector graphics for OCaml
http://erratique.ch/software/vg
ISC License
86 stars 12 forks source link

Multiple Images #30

Closed davesnx closed 2 years ago

davesnx commented 2 years ago

Hey @dbuenzli,

I'm not familiar with cairo's backend and got a little lost with the difference between target/renderable and surface.

I read on the docs once you create a renderable with target

Multiple images. Multiple images rendering is supported. For each renderable the above procedure is performed on ctx. If you want to have each renderable on a single page on backends that support it you should handle this between two renderable using Cairo's API.

While using stored_target

Multiple images. Multiple image rendering is supported on `Pdf and `Ps target, each renderable creates a new page of the renderable size. Multiple image rendering is not supported on `Png and `Svg and Invalid_argument is raised by Vg.Vgr.render if multiple images are rendered.

These are quotes from https://erratique.ch/software/vg/doc/Vgr_cairo/index.html

I don't seem to understand yet what's the difference between rendering on a context or rendering in a new page.

So, my question is if I create a surface from a PNG and a renderable as PNG, should I be able to render the surface PNG into the renderable? or that's exactly what is not supported in Vg?

Sharing the minimum example below

let buffer = Buffer.create 2048
let surface = Cairo.PNG.create "./static/71291184.png"
let target = Vgr_cairo.stored_target fmt
let renderer = Vgr.create target (`Buffer buffer)

(* Your tiplet example *)
let a = Float.pi_div_2
let da = Float.two_pi /. 3.0
let dotPath = Path.empty |> (Path.circle Point.o 0.08)
let dot c da =
  ((Image.const c) |> (Image.cut dotPath)) |>
    (Image.move (Vector.polar 0.05 (a +. da)))
let red = dot (Color.v_srgb 0.608 0.067 0.118 ~a:0.75) da
let green = dot (Color.v_srgb 0.314 0.784 0.471 ~a:0.75) 0.0
let blue = dot (Color.v_srgb 0.000 0.439 0.722 ~a:0.75) (-. da)
let triplet = (red |> (Image.blend green)) |> (Image.blend blue)
let bottom = triplet |> (Image.move (Point.v 0.95 0.35))
let image = bottom
let _ = ignore (Vgr.render renderer (`Image (size, view, image)))
(* render the triplet *)
let _ = ignore (Vgr.render renderer `End)

Sorry for opening such basic questions and Thanks for reading.

dbuenzli commented 2 years ago

Questions are welcome but better answered on the OCaml forum (you can log in there with your github account). Please post there next time.

The sentence "should I be able to render the surface PNG into the renderable" does not make sense, I think I think you misunderstand what a renderable is. Here's a definition.

Now:

  1. If you have a Vgcairo.target rendering a renderable applies the procedure described there each time you render on the underlying cairo context.
  2. If you have a Vgcairo.stored_target rendering a renderable renders it on the underlying context. If you render a subsequent one it will create a new page to render it, if the format supports it, otherwise Invalid_argument.

If you think the documentation can be improved please send a PR.