Release 1.2.0 (2026-08-23)

- API documentation, published at
  <https://ocaml.org/p/ifs-fractals> and built locally with `dune build
  @doc`. The library has an interface file, `lib/ifs_fractals.mli`, in
  which every type, function and predefined fractal carries a
  documentation comment, and `doc/index.mld` is the landing page of the
  package. The interface also settles what the library actually offers:
  the plumbing of the PNG writer (`output_png`, `add_chunk`,
  `crc_table`, `encode`, `ramp_color`) and of the Fractint reader
  (`words`, `group_entries`, `thresholds`, `cumulate`, ...) is no longer
  exported, along with `select_image`, `pixel_of_point`, `accumulate`
  and `viewport`. Everything the command and the documented API use is
  unchanged.
- Fixed: `sierpinski` drew an empty window and `koch` a speck in the
  middle of one. Both had their coefficients written in the order of a
  Fractint table — `a b c d e f` for `x' = a*x + b*y + e` — rather than
  the order of `kf`, so neither described the fractal it was named after,
  and neither landed in the region its record asked to display. The
  transforms are reordered and both viewports now frame the attractor:
  `sierpinski` is the triangle on (0,0), (2,0), (1, √3), and `koch` the
  curve from (0,0) to (1,0). This had been the case since the first
  commit, in 2010.
- A test suite, run with `dune test`: the affine maps and the projection,
  the chaos game, the framing of an attractor, the Fractint parser and
  the errors it reports, and the PNG writer, whose output is decoded and
  checked rather than counted in bytes. It needs no display and no new
  dependency.
- The predefined fractals moved out of `lib/ifs_fractals.ml` into their own
  `lib/fractals.ml`, together with the `point`, `transfo` and `ifs` types,
  so that adding or tuning a fractal no longer touches the code that draws
  it. `Ifs_fractals` re-exports them, so the library API is unchanged, and
  so is the toplevel workflow (the loader now uses `#mod_use` for the new
  file).
- `show fs n` draws a fractal, waits for a keypress and closes the window.
  Unlike `draw`, it leaves the program inside an event call, which is what
  lets the window manager's close button work.
- Fixed: after the graphics window was closed — by `Graphics.close_graph`
  or by the window manager — `draw` failed with `Graphic_failure "graphic
  screen not opened"` instead of opening a new window. `window_open` is now
  a function that asks the graphics library rather than a stale flag.
- Fractals can be read from Fractint `.ifs` files: `ifs-fractals -f
  FILE.ifs NAME` from the command line, `load_fractint` from the library.
  The format's plain weights are converted to cumulative thresholds (or
  derived from each map's determinant when the file gives none), and the
  viewport, which the format does not record, is fitted to the attractor
  by `fit`. `example/classics.ifs` collects a dozen classic systems to
  try it on.
- Three-dimensional systems — Fractint's `(3D)` entries, twelve or
  thirteen numbers per transform — are read and drawn as well, projected
  orthographically from a direction given by `-v YAW,PITCH` in degrees
  (`?yaw` and `?pitch` in the library). Reading a file now returns a
  `system`, either `Flat of ifs` or `Solid of ifs3`; `draw_system`,
  `show_system` and `save_png_system` take either.