From 22c600d2e0000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <fygrave@gmail.com>
Subject: [PATCH 0/7] Implement the librsvg 2.46/2.52 viewport and geometry API

Applications written against modern librsvg do not fail against this branch
at run time; they fail at compile time, on a handful of types and functions
that simply do not exist here:

  coot#355        'RsvgLength' / 'RsvgRectangle' was not declared in this scope
                  'rsvg_handle_get_intrinsic_dimensions' was not declared
                  'rsvg_handle_render_document' was not declared
  timg#142        same four
  xournalpp#7070  'RsvgRectangle' and 'viewport' not being defined
  hyprcursor#84   'RsvgRectangle' was not declared in this scope
                  'rsvg_handle_render_document'... did you mean
                  'rsvg_handle_render_cairo'?
  RawTherapee     rtengine/svgrender.cc, guarded by #ifdef SVG_BACKEND_RSVG,
                  with lunasvg as the alternative backend

The union of what those five need is small: RsvgRectangle, RsvgLength,
RsvgUnit, rsvg_handle_render_document(), rsvg_handle_get_intrinsic_
dimensions() and rsvg_handle_get_intrinsic_size_in_pixels().  None of them
uses render_layer(), render_element(), the geometry queries, or even
rsvg_handle_set_stylesheet(), which this branch already grew in 2.40.23.

This series implements the whole 2.46 set anyway, plus the 2.52 pixel query.
The reason is patch 7: the version this branch advertises has to reach 2.52
before any of those projects' configure checks pass, and advertising 2.46
while shipping only part of it would reproduce exactly the build failure the
series exists to fix, just in a different set of projects.  set_stylesheet is
the existing demonstration of this: it has been here since 2.40.23 and is
still invisible to anything testing for >= 2.48.

The series follows the precedent set by commit 1463a1e3f ("rsvg: introduce
rsvg_handle_set_stylesheet"), which deliberately matched the signature
introduced upstream in 2.48.

  1  css: Rename the internal RsvgLength to RsvgInternalLength
  2  rsvg: Add the public RsvgRectangle, RsvgUnit and RsvgLength types
  3  cairo: Add rsvg_handle_render_document() and rsvg_handle_render_layer()
  4  cairo: Add the 2.46 geometry queries and rsvg_handle_render_element()
  5  rsvg: Add rsvg_handle_get_intrinsic_dimensions() and the 2.52 pixel query
  6  tests: Cover the viewport and geometry API
  7  meta: Bump version to 2.52.0 and add the rsvg_*_version globals

Patch 3 is the only one that needs real review.  The rest is additive or
mechanical.

What the patches do not change
------------------------------

The whole series modifies seven lines of pre-existing logic, all of them in
rsvg_node_svg_draw(), all of them the same edit (sself->vbox to a local
copy).  Everything else is new code, new declarations, or the rename in
patch 1.  1368 insertions, 43 deletions, of which 32 deletions are the
rename and 431 insertions are the new test.

That was a deliberate constraint: rsvg_handle_render_cairo() had to keep
running the code it runs today.  The new drawing-context constructor is a
sibling of rsvg_cairo_new_drawing_ctx() rather than a rewrite of it, and the
outermost-<svg> override is gated on a drawing-context field that only the
new entry points ever set.

Verification, against e6aa73e1f as the baseline:

  - All 137 convertible SVGs under tests/ render byte-identically through
    rsvg-convert before and after the series.  Zero pixel differences.
  - The existing suite passes at every commit.  (librsvg:errors times out on
    slow or loaded machines, but it does so on the baseline too: 2 of 3 runs
    here, against an unmodified build.  Its own comment already notes that
    515-billion-laughs needs more time on slow CPUs.)
  - An interleaved benchmark of rsvg_handle_render_cairo(), minimum of 12
    rounds: 143.9 ms baseline against 145.6 ms patched, with a baseline
    spread of 143.9-460.2 ms.  No difference outside noise.
  - The new tests/api pass at 13 subtests.

Two deliberate approximations
-----------------------------

Neither affects the projects listed above, and both were chosen to avoid
adding work to the rendering path.

This build keeps one bounding box per element, the union of the fill and
stroke extents, so get_geometry_for_layer() and get_geometry_for_element()
report it as both the ink and the logical rectangle.  Splitting the two
would mean an extra extents computation for every path drawn.  The FIXME at
rsvg-cairo-draw.c:630 already anticipates this.

Absolute lengths are normalized to inches while parsing, so a length
authored in cm, mm, pt or pc is reported as RSVG_UNIT_IN with an equivalent
value.  Arithmetic over the result is unchanged, including the width to
height ratio, which is what callers reading these values actually use; timg
says so in as many words ("We ignore the unit, but this will still result in
proper aspect ratio").  Only the authored spelling is lost.  Fixing this
properly means teaching the parser to keep the unit, which is a larger and
independent change.

One thing worth deciding separately
-----------------------------------

Patch 7 is a project-level decision rather than a code review: it changes
what this branch claims to be, and every downstream pkg_check_modules result
follows from it.  It is last in the series so it can be dropped or deferred
without touching the rest.  Note that the soname stays librsvg-2.so.2 either
way, so nothing needs relinking; under meson the installed filename does not
change at all, and under autotools it tracks the version as usual.

Unrelated, but visible from here: libcroco3-dev no longer exists in current
Debian and Ubuntu, and I had to pull the .deb out of an older pool to build
this branch at all.  For a branch whose value is being buildable where Rust
is not available, that dependency is going to be the next thing to bite
packagers.

Sergey Fedorov (7):
  css: Rename the internal RsvgLength to RsvgInternalLength
  rsvg: Add the public RsvgRectangle, RsvgUnit and RsvgLength types
  cairo: Add rsvg_handle_render_document() and rsvg_handle_render_layer()
  cairo: Add the 2.46 geometry queries and rsvg_handle_render_element()
  rsvg: Add rsvg_handle_get_intrinsic_dimensions() and the 2.52 pixel query
  tests: Cover the viewport and geometry API
  meta: Bump version to 2.52.0 and add the rsvg_*_version globals

 configure.ac          |   4 +-
 librsvg-features.c    |   6 +
 librsvg-features.h.in |  30 +++
 librsvg/rsvg.h        |  87 +++++++++
 meson.build           |   2 +-
 rsvg-base.c           | 175 ++++++++++++++++-
 rsvg-cairo-render.c   | 516 ++++++++++++++++++++++++++++++++++++++++++++++++++
 rsvg-cairo.h          |  30 +++
 rsvg-css.c            |   8 +-
 rsvg-filter.c         |   6 +-
 rsvg-filter.h         |   2 +-
 rsvg-image.h          |   2 +-
 rsvg-marker.h         |   2 +-
 rsvg-mask.h           |   2 +-
 rsvg-paint-server.c   |   2 +-
 rsvg-paint-server.h   |   6 +-
 rsvg-private.h        |  16 +-
 rsvg-shapes.c         |   8 +-
 rsvg-structure.c      |  38 +++-
 rsvg-structure.h      |   4 +-
 rsvg-styles.h         |   8 +-
 rsvg-text.c           |   2 +-
 rsvg.symbols          |  14 ++
 tests/Makefile.am     |   5 +
 tests/api.c           | 431 +++++++++++++++++++++++++++++++++++++++++
 tests/meson.build     |   1 +
 tests/styles.c        |   4 +-
 27 files changed, 1368 insertions(+), 43 deletions(-)
 create mode 100644 tests/api.c

--
2.43.0

