support rsvg_handle_get_intrinsic_size_in_pixels

librsvg 2.52+ has this new bit of API for finding the SVG dimensions
This commit is contained in:
John Cupitt 2022-04-28 13:01:17 +01:00
parent f06c9f3bcf
commit 20fd8ac0fc
3 changed files with 95 additions and 5 deletions

6
.gitignore vendored
View File

@ -1,4 +1,6 @@
compile
release
build
debug
.pytest_cache
.dirstamp
a.out
@ -29,8 +31,6 @@ tags
*.o
*.a
fuzz/*_fuzzer
Vips-8.0.gir
Vips-8.0.typelib
.*.swp
*.lo
*.bak

View File

@ -24,6 +24,8 @@
* - librsvg can no longer render very large images :(
* 14/10/21
* - allow utf-8 headers for svg detection
* 28/4/22
* - support rsvg_handle_get_intrinsic_size_in_pixels()
*/
/*
@ -317,8 +319,75 @@ vips_foreign_load_svg_get_flags( VipsForeignLoad *load )
return( VIPS_FOREIGN_SEQUENTIAL );
}
#ifdef HAVE_RSVG_HANDLE_GET_INTRINSIC_SIZE_IN_PIXELS
static int
vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out )
vips_foreign_load_svg_get_size( VipsForeignLoadSvg *svg,
int *out_width, int *out_height )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( svg );
double width;
double height;
double scale;
/* If the SVG does not define a width or height we will fall back to
* this size. The SVG will be rendered to fit this viewport
* by rsvg_handle_render_document() below.
*/
width = 1928;
height = 1080;
/* Get dimensions with the default scale.
*/
rsvg_handle_set_dpi( svg->page, 72.0 );
rsvg_handle_get_intrinsic_size_in_pixels( svg->page, &width, &height );
if( width <= 0 || height <= 0 ) {
vips_error( class->nickname, "%s", _( "bad dimensions" ) );
return( -1 );
}
/* Calculate dimensions at required dpi/scale.
*/
scale = svg->scale * svg->dpi / 72.0;
if( scale != 1.0 ) {
double scaled_width;
double scaled_height;
rsvg_handle_set_dpi( svg->page, svg->dpi * svg->scale );
rsvg_handle_get_intrinsic_size_in_pixels( svg->page,
&scaled_width, &scaled_height );
if( scaled_width == width &&
scaled_height == height ) {
/* SVG without width and height always reports the same
* dimensions regardless of dpi. Apply dpi/scale using
* cairo instead.
*/
svg->cairo_scale = scale;
width = width * scale;
height = height * scale;
}
else {
/* SVG with width and height reports correctly scaled
* dimensions.
*/
width = scaled_width;
height = scaled_height;
}
}
*out_width = VIPS_ROUND_UINT( width );
*out_height = VIPS_ROUND_UINT( height );
return ( 0 );
}
#else /*!HAVE_RSVG_HANDLE_GET_INTRINSIC_SIZE_IN_PIXELS*/
static int
vips_foreign_load_svg_get_size( VipsForeignLoadSvg *svg,
int *out_width, int *out_height )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( svg );
@ -326,7 +395,6 @@ vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out )
int width;
int height;
double scale;
double res;
/* Calculate dimensions at default dpi/scale.
*/
@ -366,6 +434,24 @@ vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out )
}
}
*out_width = width;
*out_height = height;
return ( 0 );
}
#endif/*HAVE_RSVG_HANDLE_GET_INTRINSIC_SIZE_IN_PIXELS*/
static int
vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out )
{
int width;
int height;
double res;
if( vips_foreign_load_svg_get_size( svg, &width, &height ) )
return( -1 );
/* We need pixels/mm for vips.
*/
res = svg->dpi / 25.4;

View File

@ -354,6 +354,10 @@ if librsvg_dep.found() and cairo_dep.found()
if librsvg_dep.version().version_compare('>=2.46')
cfg_var.set('HAVE_RSVG_HANDLE_RENDER_DOCUMENT', '1')
endif
# 2.56 for rsvg_handle_get_intrinsic_size_in_pixels
if librsvg_dep.version().version_compare('>=2.52')
cfg_var.set('HAVE_RSVG_HANDLE_GET_INTRINSIC_SIZE_IN_PIXELS', '1')
endif
endif
openslide_dep = dependency('openslide', version: '>=3.3.0', required: get_option('openslide'))