rsvg-private.h 19.3 KB
Newer Older
1 2
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 sts=4 expandtab: */
3
/*
4
   rsvg-private.h: Internals of RSVG
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

   Copyright (C) 2000 Eazel, Inc.
   Copyright (C) 2002 Dom Lachowicz <cinamod@hotmail.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this program; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Author: Raph Levien <raph@artofcode.com>
*/

#ifndef RSVG_PRIVATE_H
#define RSVG_PRIVATE_H

Christian Persch's avatar
Christian Persch committed
30 31
#include <cairo.h>

32
#include "rsvg.h"
33
#include "rsvg-path-builder.h"
34 35 36

#include <libxml/SAX.h>
#include <libxml/xmlmemory.h>
Dom Lachowicz's avatar
Dom Lachowicz committed
37
#include <pango/pango.h>
38
#include <glib.h>
39
#include <glib-object.h>
40
#include <math.h>
41

42 43 44 45
#if defined(HAVE_FLOAT_H)
# include <float.h>
#endif

46 47 48
G_BEGIN_DECLS 

typedef struct RsvgSaxHandler RsvgSaxHandler;
49
typedef struct RsvgDrawingCtx RsvgDrawingCtx;
Caleb Michael Moore's avatar
Caleb Michael Moore committed
50
typedef struct RsvgRender RsvgRender;
51
typedef GHashTable RsvgPropertyBag;
52 53
typedef struct _RsvgState RsvgState;
typedef struct _RsvgDefs RsvgDefs;
54
typedef struct _RsvgNode RsvgNode;
55
typedef struct _RsvgFilter RsvgFilter;
Caleb Michael Moore's avatar
Caleb Michael Moore committed
56
typedef struct _RsvgNodeChars RsvgNodeChars;
57

58 59 60 61 62
/* prepare for gettext */
#ifndef _
#define _(X) X
#endif

Dom Lachowicz's avatar
Dom Lachowicz committed
63 64 65 66
#ifndef N_
#define N_(X) X
#endif

67 68 69 70 71
#ifndef M_PI
#  ifdef G_PI
#    define M_PI G_PI
#  else
#    define M_PI 3.14159265358979323846
72 73
#  endif                        /* G_PI */
#endif                          /*  M_PI  */
74

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
#ifndef DBL_EPSILON
/* 1e-7 is a conservative value.  it's less than 2^(1-24) which is
 * the epsilon value for a 32-bit float.  The regular value for this
 * with 64-bit doubles is 2^(1-53) or approximately 1e-16.
 */
# define DBL_EPSILON 1e-7
#endif

/* RSVG_ONE_MINUS_EPSILON:
 *
 * DBL_EPSILON is the difference between 1 and the least value greater
 * than 1 that is representable in the given floating-point type.  Then
 * 1.0+DBL_EPSILON looks like:
 *
 *         1.00000000000...0000000001 * 2**0
 *
 * while 1.0-DBL_EPSILON looks like:
 *
 *         0.11111111111...1111111111 * 2**0
 *
 * and so represented as:
 *
 *         1.1111111111...11111111110 * 2**-1
 *
 * so, in fact, 1.0-(DBL_EPSILON*.5) works too, but I don't think it
 * really matters.  So, I'll go with the simple 1.0-DBL_EPSILON here.
 *
 * The following python session shows these observations:
 *
 *         >>> 1.0 + 2**(1-53)
 *         1.0000000000000002
 *         >>> 1.0 + 2**(1-54)
 *         1.0
 *         >>> 1.0 - 2**(1-53)
 *         0.99999999999999978
 *         >>> 1.0 - 2**(1-54)
 *         0.99999999999999989
 *         >>> 1.0 - 2**(1-53)*.5
 *         0.99999999999999989
 *         >>> 1.0 - 2**(1-55)
 *         1.0
 */
#define RSVG_ONE_MINUS_EPSILON (1.0 - DBL_EPSILON)

119
struct RsvgSaxHandler {
120 121 122 123
    void (*free) (RsvgSaxHandler * self);
    void (*start_element) (RsvgSaxHandler * self, const char *name, RsvgPropertyBag * atts);
    void (*end_element) (RsvgSaxHandler * self, const char *name);
    void (*characters) (RsvgSaxHandler * self, const char *ch, int len);
124 125
};

126 127 128 129 130 131 132 133
/* Reading state for an RsvgHandle */
typedef enum {
    RSVG_HANDLE_STATE_START,
    RSVG_HANDLE_STATE_READING,
    RSVG_HANDLE_STATE_CLOSED_OK,
    RSVG_HANDLE_STATE_CLOSED_ERROR
} RsvgHandleState;

134
struct RsvgHandlePrivate {
135 136
    RsvgHandleFlags flags;

137 138
    RsvgHandleState state;

139 140 141 142 143 144
    gboolean is_disposed;

    RsvgSizeFunc size_func;
    gpointer user_data;
    GDestroyNotify user_data_destroy;

145
    GPtrArray *all_nodes;
146

147
    RsvgDefs *defs; /* lookup table for nodes that have an id="foo" attribute */
148 149 150 151 152
    RsvgNode *currentnode;
    /* this is the root level of the displayable tree, essentially what the
       file is converted into at the end */
    RsvgNode *treebase;

153 154 155 156 157
    /* Stack of element names while parsing; used to know when to stop parsing
     * the current element.
     */
    GSList *element_name_stack;

158 159 160 161 162 163 164 165 166 167 168 169
    GHashTable *css_props;

    /* not a handler stack. each nested handler keeps
     * track of its parent
     */
    RsvgSaxHandler *handler;
    int handler_nest;

    GHashTable *entities;       /* g_malloc'd string -> xmlEntityPtr */

    xmlParserCtxtPtr ctxt;
    GError **error;
170
    GCancellable *cancellable;
171 172 173 174 175 176 177 178 179

    double dpi_x;
    double dpi_y;

    GString *title;
    GString *desc;
    GString *metadata;

    gchar *base_uri;
180
    GFile *base_gfile;
181

182 183 184
    gboolean in_loop;		/* see get_dimension() */

    GInputStream *data_input_stream; /* for rsvg_handle_write of svgz data */
185 186

    gboolean is_testing; /* Are we being run from the test suite? */
187 188
};

189
/* Keep this in sync with rust/src/viewbox.rs::RsvgViewBox */
190
typedef struct {
Christian Persch's avatar
Christian Persch committed
191
    cairo_rectangle_t rect;
192 193
    gboolean active;
} RsvgViewBox;
194

195
/*Contextual information for the drawing phase*/
196

197
struct RsvgDrawingCtx {
198
    RsvgRender *render;
199
    RsvgState *state;
200 201 202 203 204 205 206
    GError **error;
    RsvgDefs *defs;
    PangoContext *pango_context;
    double dpi_x, dpi_y;
    RsvgViewBox vb;
    GSList *vb_stack;
    GSList *drawsub_stack;
207
    GSList *acquired_nodes;
208
    gboolean is_testing;
209 210
};

Caleb Michael Moore's avatar
Caleb Michael Moore committed
211 212
/*Abstract base class for context for our backends (one as yet)*/

213 214 215 216 217 218 219 220 221
typedef enum {
  RSVG_RENDER_TYPE_INVALID,

  RSVG_RENDER_TYPE_BASE,

  RSVG_RENDER_TYPE_CAIRO = 8,
  RSVG_RENDER_TYPE_CAIRO_CLIP
} RsvgRenderType;

Caleb Michael Moore's avatar
Caleb Michael Moore committed
222
struct RsvgRender {
223 224
    RsvgRenderType type;

225 226
    void (*free) (RsvgRender * self);

227 228 229
    PangoContext    *(*create_pango_context)    (RsvgDrawingCtx * ctx);
    void             (*render_pango_layout)	    (RsvgDrawingCtx * ctx, PangoLayout *layout,
                                                 double x, double y);
230
    void             (*render_path_builder)     (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder);
231 232
    void             (*render_surface)          (RsvgDrawingCtx * ctx, cairo_surface_t *surface,
                                                 double x, double y, double w, double h);
233 234 235 236
    void             (*pop_discrete_layer)      (RsvgDrawingCtx * ctx);
    void             (*push_discrete_layer)     (RsvgDrawingCtx * ctx);
    void             (*add_clipping_rect)       (RsvgDrawingCtx * ctx, double x, double y,
                                                 double w, double h);
237 238
    cairo_surface_t *(*get_surface_of_node)     (RsvgDrawingCtx * ctx, RsvgNode * drawable,
                                                 double w, double h);
Caleb Michael Moore's avatar
Caleb Michael Moore committed
239 240
};

241 242 243 244
static inline RsvgRender *
_rsvg_render_check_type (RsvgRender *render,
                         RsvgRenderType type)
{
245
  g_assert ((render->type & type) == type);
246 247 248 249 250
  return render;
}

#define _RSVG_RENDER_CIC(render, render_type, RenderCType) \
  ((RenderCType*) _rsvg_render_check_type ((render), (render_type)))
251

252
/* Keep this in sync with rust/src/length.rs:LengthUnit */
253 254 255 256 257 258 259 260 261 262
typedef enum {
    LENGTH_UNIT_DEFAULT,
    LENGTH_UNIT_PERCENT,
    LENGTH_UNIT_FONT_EM,
    LENGTH_UNIT_FONT_EX,
    LENGTH_UNIT_INCH,
    LENGTH_UNIT_RELATIVE_LARGER,
    LENGTH_UNIT_RELATIVE_SMALLER
} LengthUnit;

263
/* Keep this in sync with rust/src/length.rs:LengthDir */
264 265 266 267 268 269
typedef enum {
    LENGTH_DIR_HORIZONTAL,
    LENGTH_DIR_VERTICAL,
    LENGTH_DIR_BOTH
} LengthDir;

270
/* Keep this in sync with rust/src/length.rs:RsvgLength */
271 272 273 274 275 276
typedef struct {
    double length;
    LengthUnit unit;
    LengthDir dir;
} RsvgLength;

277
/* Keep this in sync with rust/src/bbox.rs:RsvgBbox */
278
typedef struct {
Christian Persch's avatar
Christian Persch committed
279
    cairo_rectangle_t rect;
Christian Persch's avatar
Christian Persch committed
280
    cairo_matrix_t affine;
281
    gboolean virgin;
282 283
} RsvgBbox;

284
typedef enum {
285
    objectBoundingBox, userSpaceOnUse
286 287
} RsvgCoordUnits;

288
/* Keep this in sync with rust/src/node.rs:NodeType */
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
typedef enum {
    RSVG_NODE_TYPE_INVALID = 0,

    RSVG_NODE_TYPE_CHARS,
    RSVG_NODE_TYPE_CIRCLE,
    RSVG_NODE_TYPE_CLIP_PATH,
    RSVG_NODE_TYPE_COMPONENT_TRANFER_FUNCTION,
    RSVG_NODE_TYPE_DEFS,
    RSVG_NODE_TYPE_ELLIPSE,
    RSVG_NODE_TYPE_FILTER,
    RSVG_NODE_TYPE_GROUP,
    RSVG_NODE_TYPE_IMAGE,
    RSVG_NODE_TYPE_LIGHT_SOURCE,
    RSVG_NODE_TYPE_LINE,
    RSVG_NODE_TYPE_LINEAR_GRADIENT,
    RSVG_NODE_TYPE_MARKER,
    RSVG_NODE_TYPE_MASK,
    RSVG_NODE_TYPE_PATH,
    RSVG_NODE_TYPE_PATTERN,
    RSVG_NODE_TYPE_POLYGON,
    RSVG_NODE_TYPE_POLYLINE,
    RSVG_NODE_TYPE_RADIAL_GRADIENT,
    RSVG_NODE_TYPE_RECT,
    RSVG_NODE_TYPE_STOP,
    RSVG_NODE_TYPE_SVG,
    RSVG_NODE_TYPE_SWITCH,
    RSVG_NODE_TYPE_SYMBOL,
    RSVG_NODE_TYPE_TEXT,
    RSVG_NODE_TYPE_TREF,
    RSVG_NODE_TYPE_TSPAN,
    RSVG_NODE_TYPE_USE,

    /* Filter primitives */
322
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_FIRST,              /* just a marker; not a valid type */
323
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_BLEND,
324
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_COLOR_MATRIX,
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPONENT_TRANSFER,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPOSITE,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_CONVOLVE_MATRIX,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_DIFFUSE_LIGHTING,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_DISPLACEMENT_MAP,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_ERODE,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_FLOOD,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_GAUSSIAN_BLUR,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_IMAGE,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_SPECULAR_LIGHTING,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_TILE,
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_TURBULENCE,
340
    RSVG_NODE_TYPE_FILTER_PRIMITIVE_LAST                /* just a marker; not a valid type */
341 342
} RsvgNodeType;

343 344 345 346 347
typedef void (* CNodeSetAtts) (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *pbag);
typedef void (* CNodeDraw) (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate);
typedef void (* CNodeFree) (gpointer impl);

/* Implemented in rust/src/node.rs */
348
/* Call node = rsvg_node_unref (node) when you are done with the node */
349 350 351 352 353 354 355
G_GNUC_INTERNAL
RsvgNode *rsvg_rust_cnode_new (RsvgNodeType  node_type,
                               RsvgNode     *parent,
                               RsvgState    *state,
                               gpointer      impl,
                               CNodeSetAtts  set_atts_fn,
                               CNodeDraw     draw_fn,
356
                               CNodeFree     free_fn) G_GNUC_WARN_UNUSED_RESULT;
357 358 359 360

/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
gpointer rsvg_rust_cnode_get_impl (RsvgNode *node);
361

362
/* Implemented in rust/src/node.rs */
363
G_GNUC_INTERNAL
364
RsvgNodeType rsvg_node_get_type (RsvgNode *node);
365

366 367 368 369
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
gboolean rsvg_node_is_same (RsvgNode *node1, RsvgNode *node2);

370
/* Implemented in rust/src/node.rs */
371
/* Call this as newref = rsvg_node_ref (node);  You don't own the node anymore, just the newref! */
372
G_GNUC_INTERNAL
373 374 375 376 377 378
RsvgNode *rsvg_node_ref (RsvgNode *node) G_GNUC_WARN_UNUSED_RESULT;

/* Implemented in rust/src/node.rs */
/* Call this as node = rsvg_node_unref (node);  Then node will be NULL and you don't own it anymore! */
G_GNUC_INTERNAL
RsvgNode *rsvg_node_unref (RsvgNode *node) G_GNUC_WARN_UNUSED_RESULT;
379 380

/* Implemented in rust/src/node.rs */
381 382 383
G_GNUC_INTERNAL
RsvgState *rsvg_node_get_state (RsvgNode *node);

384 385
/* Implemented in rust/src/node.rs
 *
386
 * Returns a new strong reference to the parent (or NULL); use rsvg_node_unref()
387 388
 * when you are done.
 */
389
G_GNUC_INTERNAL
390
RsvgNode *rsvg_node_get_parent (RsvgNode *node) G_GNUC_WARN_UNUSED_RESULT;
391

392 393 394 395
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
void rsvg_node_add_child (RsvgNode *node, RsvgNode *child);

396
/* Implemented in rust/src/node.rs */
397 398 399
G_GNUC_INTERNAL
void rsvg_node_set_atts (RsvgNode *node, RsvgHandle *handle, RsvgPropertyBag *atts);

400
/* Implemented in rust/src/node.rs */
401 402 403
G_GNUC_INTERNAL
void rsvg_node_draw (RsvgNode *node, RsvgDrawingCtx *draw, int dominate);

404 405 406 407
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
void rsvg_node_set_attribute_parse_error (RsvgNode *node, const char *attr_name, const char *description);

408 409 410
/* Used to iterate among a node's children with rsvg_node_foreach_child().
 * If this caller-supplied function returns FALSE, iteration will stop.
 * Otherwise, iteration will continue to the next child node.
411 412
 *
 * Keep this in sync with rust/src/node.rs:NodeForeachChild
413 414 415
 */
typedef gboolean (* RsvgNodeForeachChildFn) (RsvgNode *node, gpointer data);

416
/* Implemented in rust/src/node.rs */
417 418
G_GNUC_INTERNAL
void rsvg_node_foreach_child (RsvgNode *node, RsvgNodeForeachChildFn fn, gpointer data);
419 420 421 422 423
/* generic function for drawing all of the children of a particular node */

/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
void rsvg_node_draw_children (RsvgNode *node, RsvgDrawingCtx *ctx, int dominate);
424

Caleb Michael Moore's avatar
Caleb Michael Moore committed
425
struct _RsvgNodeChars {
426
    GString *contents;
Caleb Michael Moore's avatar
Caleb Michael Moore committed
427 428
};

429
typedef void (*RsvgPropertyBagEnumFunc) (const char *key, const char *value, gpointer user_data);
Dom Lachowicz's avatar
Dom Lachowicz committed
430

431
G_GNUC_INTERNAL
432
RsvgPropertyBag	    *rsvg_property_bag_new       (const char **atts);
433
G_GNUC_INTERNAL
434
RsvgPropertyBag	    *rsvg_property_bag_dup       (RsvgPropertyBag * bag);
435
G_GNUC_INTERNAL
436
void                 rsvg_property_bag_free      (RsvgPropertyBag * bag);
437
G_GNUC_INTERNAL
438
const char          *rsvg_property_bag_lookup    (RsvgPropertyBag * bag, const char *key);
439
G_GNUC_INTERNAL
440
guint                rsvg_property_bag_size	     (RsvgPropertyBag * bag);
441
G_GNUC_INTERNAL
442 443
void                 rsvg_property_bag_enumerate (RsvgPropertyBag * bag, RsvgPropertyBagEnumFunc func,
                                                  gpointer user_data);
444
/* for some reason this one's public... */
445 446
GdkPixbuf *rsvg_pixbuf_from_data_with_size_data (const guchar * buff,
                                                 size_t len,
447
                                                 gpointer data,
448
                                                 const char *base_uri, GError ** error);
449
G_GNUC_INTERNAL
450
gboolean     rsvg_eval_switch_attributes	(RsvgPropertyBag * atts, gboolean * p_has_cond);
451
G_GNUC_INTERNAL
452
gchar       *rsvg_get_base_uri_from_filename    (const gchar * file_name);
453

454
G_GNUC_INTERNAL
455
void rsvg_pop_discrete_layer    (RsvgDrawingCtx * ctx);
456
G_GNUC_INTERNAL
457
void rsvg_push_discrete_layer   (RsvgDrawingCtx * ctx);
458

459
G_GNUC_INTERNAL
460
RsvgNode *rsvg_drawing_ctx_acquire_node         (RsvgDrawingCtx * ctx, const char *url);
461
G_GNUC_INTERNAL
462
RsvgNode *rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type);
463
G_GNUC_INTERNAL
464 465
void rsvg_drawing_ctx_release_node              (RsvgDrawingCtx * ctx, RsvgNode *node);

466
G_GNUC_INTERNAL
467 468 469
void rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, RsvgNode *node);
G_GNUC_INTERNAL
void rsvg_drawing_ctx_draw_node_from_stack            (RsvgDrawingCtx *ctx, RsvgNode *node, int dominate);
470

471
G_GNUC_INTERNAL
472
void rsvg_render_path_builder   (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder);
473
G_GNUC_INTERNAL
474 475
void rsvg_render_surface        (RsvgDrawingCtx * ctx, cairo_surface_t *surface,
                                 double x, double y, double w, double h);
476

477
G_GNUC_INTERNAL
478
double rsvg_get_normalized_stroke_width (RsvgDrawingCtx *ctx);
479 480 481 482 483 484 485 486

G_GNUC_INTERNAL
const char *rsvg_get_start_marker (RsvgDrawingCtx *ctx);
G_GNUC_INTERNAL
const char *rsvg_get_middle_marker (RsvgDrawingCtx *ctx);
G_GNUC_INTERNAL
const char *rsvg_get_end_marker (RsvgDrawingCtx *ctx);

487
G_GNUC_INTERNAL
488
void rsvg_render_free           (RsvgRender * render);
489
G_GNUC_INTERNAL
490
void rsvg_drawing_ctx_add_clipping_rect     (RsvgDrawingCtx * ctx, double x, double y, double w, double h);
491
G_GNUC_INTERNAL
492
cairo_surface_t *rsvg_cairo_surface_from_pixbuf (const GdkPixbuf *pixbuf);
493
G_GNUC_INTERNAL
494
GdkPixbuf *rsvg_cairo_surface_to_pixbuf (cairo_surface_t *surface);
495
G_GNUC_INTERNAL
496
cairo_surface_t *rsvg_get_surface_of_node (RsvgDrawingCtx * ctx, RsvgNode * drawable, double w, double h);
497

498
G_GNUC_INTERNAL
499
void rsvg_drawing_ctx_free (RsvgDrawingCtx * handle);
500 501

/* Implemented in rust/src/bbox.rs */
502
G_GNUC_INTERNAL
Christian Persch's avatar
Christian Persch committed
503
void rsvg_bbox_init     (RsvgBbox * self, cairo_matrix_t *matrix);
504 505

/* Implemented in rust/src/bbox.rs */
506
G_GNUC_INTERNAL
507
void rsvg_bbox_insert   (RsvgBbox * dst, RsvgBbox * src);
508 509

/* Implemented in rust/src/bbox.rs */
510
G_GNUC_INTERNAL
511
void rsvg_bbox_clip     (RsvgBbox * dst, RsvgBbox * src);
512 513

/* This is implemented in rust/src/length.rs */
514
G_GNUC_INTERNAL
515
double rsvg_length_normalize (const RsvgLength *length, RsvgDrawingCtx * ctx);
516 517 518 519 520 521 522 523

/* This is implemented in rust/src/length.rs */
G_GNUC_INTERNAL
double rsvg_length_hand_normalize (const RsvgLength *length,
                                   double pixels_per_inch,
                                   double width_or_height,
                                   double font_size);

524
G_GNUC_INTERNAL
525 526
double rsvg_drawing_ctx_get_normalized_font_size (RsvgDrawingCtx * ctx);

527 528 529 530 531 532
G_GNUC_INTERNAL
cairo_matrix_t rsvg_drawing_ctx_get_current_state_affine (RsvgDrawingCtx *ctx);

G_GNUC_INTERNAL
void rsvg_drawing_ctx_set_current_state_affine (RsvgDrawingCtx *ctx, cairo_matrix_t *affine);

533
G_GNUC_INTERNAL
534
double _rsvg_css_accumulate_baseline_shift (RsvgState * state, RsvgDrawingCtx * ctx);
535 536

/* Implemented in rust/src/length.rs */
537
G_GNUC_INTERNAL
538 539
RsvgLength rsvg_length_parse (const char *str, LengthDir dir);

540
G_GNUC_INTERNAL
541
void rsvg_drawing_ctx_push_view_box (RsvgDrawingCtx * ctx, double w, double h);
542
G_GNUC_INTERNAL
543
void rsvg_drawing_ctx_pop_view_box  (RsvgDrawingCtx * ctx);
544 545 546
G_GNUC_INTERNAL
void rsvg_drawing_ctx_get_view_box_size (RsvgDrawingCtx *ctx, double *out_width, double *out_height);

547 548 549
G_GNUC_INTERNAL
void rsvg_drawing_ctx_get_dpi (RsvgDrawingCtx *ctx, double *out_dpi_x, double *out_dpi_y);

550
G_GNUC_INTERNAL
551
void rsvg_SAX_handler_struct_init (void);
552
G_GNUC_INTERNAL
553
char *rsvg_get_url_string (const char *str, const char **out_rest);
554
G_GNUC_INTERNAL
555
void rsvg_return_if_fail_warning (const char *pretty_function,
556
                                  const char *expression, GError ** error);
557

558
G_GNUC_INTERNAL
559 560 561 562 563
char *_rsvg_handle_acquire_data (RsvgHandle *handle,
                                 const char *uri,
                                 char **content_type,
                                 gsize *len,
                                 GError **error);
564 565 566
G_GNUC_INTERNAL
GInputStream *_rsvg_handle_acquire_stream (RsvgHandle *handle,
                                           const char *uri,
567
                                           char **content_type,
568 569
                                           GError **error);

570 571 572
G_GNUC_INTERNAL
xmlParserCtxtPtr rsvg_free_xml_parser_and_doc (xmlParserCtxtPtr ctxt) G_GNUC_WARN_UNUSED_RESULT;

573

574 575 576 577 578 579
#define rsvg_return_if_fail(expr, error)    G_STMT_START{			\
     if G_LIKELY(expr) { } else                                     \
       {                                                            \
           rsvg_return_if_fail_warning (G_STRFUNC,                  \
                                        #expr, error);              \
           return;                                                  \
580 581
       };				}G_STMT_END

582 583 584 585 586 587
#define rsvg_return_val_if_fail(expr,val,error)	G_STMT_START{       \
     if G_LIKELY(expr) { } else                                     \
       {                                                            \
           rsvg_return_if_fail_warning (G_STRFUNC,                  \
                                        #expr, error);              \
           return (val);                                            \
588 589
       };				}G_STMT_END

590
G_END_DECLS
591

592
#endif