Cookies info

This website uses Google cookies to analyse traffic. Information about your use of our site is shared with Google for that purpose. See details.

Rendering SVG documents

Rendering SVG documents

Once that an SVG document has been created, it can be rendered over a drawing surface using the following function:

/*
    Draw an SVG document, over the specified drawing surface, with the given
    quality.

    This function returns:

    - SVGT_BAD_HANDLE_ERROR if specified document handle is not valid

    - SVGT_BAD_HANDLE_ERROR if specified surface handle is not valid

    - SVGT_ILLEGAL_ARGUMENT_ERROR if specified rendering quality is not a valid
      value from the SVGTRenderingQuality enumeration

    - SVGT_NO_ERROR if the operation was completed successfully
*/
SVGTErrorCode svgtDocDraw(SVGTHandle svgDoc,
                          SVGTHandle surface,
                          SVGTRenderingQuality renderingQuality);

The third parameter influences the quality (and speed) of the drawing process, it can be one of the following values:

For example, suppose that we want to clear the drawing surface with a dark blue color, then draw over it a transparent background representing mountains and clouds (background.svg), and finally put on top of it a user interface (ui.svg). The code would be the following:

/* load SVG files */
SVGTHandle background = loadSvg("background.svg");
SVGTHandle ui = loadSvg("ui.svg");
/* create a drawing surface */
SVGTHandle surface = svgtSurfaceCreate(1024, 512);
/* clear the surface with a dark blue color */
svgtSurfaceClear(surface, 0.06f, 0.02f, 0.75f, 1.0f);
/* draw the background */
svgtDocDraw(background, surface, SVGT_RENDERING_QUALITY_BETTER);
/* draw user interface */
svgtDocDraw(ui, surface, SVGT_RENDERING_QUALITY_BETTER);

Sometime it would be useful to select just a sub-region of the whole drawing surface for the rendering, enabling in this way the possibility to draw more than one SVG document within the same surface. It is possible to select the current drawing sub-region using the svgtSurfaceViewportSet function:

/*
    Set destination viewport (i.e. a drawing surface rectangular area)
    where to map the source document viewport.

    The 'viewport' parameter must be an array of (at least)
    4 float entries, it must contain:

    - viewport[0] = top/left x
    - viewport[1] = top/left y
    - viewport[2] = width
    - viewport[3] = height

    The combined use of svgtDocViewportSet and svgtSurfaceViewportSet induces a
    transformation matrix, that will be used to draw the whole SVG document.
    The induced matrix grants that the document viewport is mapped onto the
    surface viewport (respecting the specified alignment): all SVG content will
    be drawn accordingly.

    This function returns:

    - SVGT_BAD_HANDLE_ERROR if specified surface handle is not valid

    - SVGT_ILLEGAL_ARGUMENT_ERROR if 'viewport' pointer is NULL
      or if it's not properly aligned

    - SVGT_ILLEGAL_ARGUMENT_ERROR if specified viewport width or
      height are less than or equal zero

    - SVGT_NO_ERROR if the operation was completed successfully

    NB: floating-point values of NaN are treated as 0, values of
    +Infinity and -Infinity are clamped to the largest and smallest
    available float values.
*/
SVGTErrorCode svgtSurfaceViewportSet(SVGTHandle surface,
                                     SVGTfloat* viewport);

When a drawing surface is created through the svgtSurfaceCreate function, its current target viewport is set as the entire boundary. In any case, the current viewport relative to a given surface can be retrieved using the following function:

/*
    Get current destination viewport (i.e. a drawing surface rectangular area)
    where to map the source document viewport.

    The 'viewport' parameter must be an array of (at least)
    4 float entries, it will be filled with:
    - viewport[0] = top/left x
    - viewport[1] = top/left y
    - viewport[2] = width
    - viewport[3] = height

    This function returns:

    - SVGT_BAD_HANDLE_ERROR if specified surface handle is not valid

    - SVGT_ILLEGAL_ARGUMENT_ERROR if 'viewport' pointer is NULL
      or if it's not properly aligned

    - SVGT_NO_ERROR if the operation was completed successfully
*/
SVGTErrorCode svgtSurfaceViewportGet(SVGTHandle surface,
                                     SVGTfloat* viewport);

Now suppose that we want to draw four different SVG documents within the same drawing surface (of course over 4 different non-overlapping sub-regions), the code would look as follow:

SVGTfloat srfViewport[4];
/* load SVG files */
SVGTHandle svg1 = loadSvg("car_coolant.svg");
SVGTHandle svg2 = loadSvg("car_maintenance.svg");
SVGTHandle svg3 = loadSvg("car_brake.svg");
SVGTHandle svg4 = loadSvg("car_oil.svg");
/* create a drawing surface */
SVGTHandle surface = svgtSurfaceCreate(512, 512);
/* clear the surface with an opaque white color */
svgtSurfaceClear(surface, 1.0f, 1.0f, 1.0f, 1.0f);
/* select an upper-left sub-region and draw the first SVG document */
srfViewport[0] = 0;
srfViewport[1] = 0;
srfViewport[2] = 256;
srfViewport[3] = 256;
svgtSurfaceViewportSet(surface, srfViewport);
svgtDocDraw(svg1, surface, SVGT_RENDERING_QUALITY_BETTER);
/* select an upper-right sub-region and draw the second SVG document */
srfViewport[0] = 256;
srfViewport[1] = 0;
svgtSurfaceViewportSet(surface, srfViewport);
svgtDocDraw(svg2, surface, SVGT_RENDERING_QUALITY_BETTER);
/* select the whole lower-left sub-region and draw the third SVG document */
srfViewport[0] = 0;
srfViewport[1] = 256;
svgtSurfaceViewportSet(surface, srfViewport);
svgtDocDraw(svg3, surface, SVGT_RENDERING_QUALITY_BETTER);
/* select the whole lower-right sub-region and draw the fourth SVG document */
srfViewport[0] = 256;
srfViewport[1] = 256;
svgtSurfaceViewportSet(surface, srfViewport);
svgtDocDraw(svg4, surface, SVGT_RENDERING_QUALITY_BETTER);
 
Usage of surface viewport

As for drawing surface, a viewport can be defined even for SVG documents. When an SVG document has been created through the svgtDocCreate function, its initial viewport is set equal to the viewBox XML attribute of the outermost <svg> element. SVG document viewport can be retrieved and set using the following functions:

/*
    Get the document (logical) viewport to map onto the destination (drawing
    surface) viewport. When an SVG document has been created through the
    svgtDocCreate function, the initial value of its viewport is equal to the
    'viewBox' attribute present in the outermost <svg> element.
    If such element does not contain the viewBox attribute, SVGT_NO_ERROR is
    returned and viewport array will be filled with zeros.

    The 'viewport' parameter must be an array of (at least) 4 float entries,
    it will be filled with:

    - viewport[0] = top/left x
    - viewport[1] = top/left y
    - viewport[2] = width
    - viewport[3] = height

    This function returns:

    - SVGT_BAD_HANDLE_ERROR if specified document handle is not valid

    - SVGT_ILLEGAL_ARGUMENT_ERROR if 'viewport' pointer is NULL or
      if it's not properly aligned

    - SVGT_NO_ERROR if the operation was completed successfully
*/
SVGTErrorCode svgtDocViewportGet(SVGTHandle svgDoc,
                                 SVGTfloat* viewport);
/*
    Set the document (logical) viewport to map onto the destination
    (drawing surface) viewport.

    The 'viewport' parameter must be an array of (at least)
    4 float entries, it must contain:

    - viewport[0] = top/left x
    - viewport[1] = top/left y
    - viewport[2] = width
    - viewport[3] = height

    NB: floating-point values of NaN are treated as 0, values of +Inf and -Inf
    are clamped to the largest and smallest available float values.

    This function returns:

    - SVGT_BAD_HANDLE_ERROR if specified document handle is not valid

    - SVGT_ILLEGAL_ARGUMENT_ERROR if 'viewport' pointer is NULL or
      if it's not properly aligned

    - SVGT_ILLEGAL_ARGUMENT_ERROR if specified viewport width or
      height are less than or equal zero

    - SVGT_NO_ERROR if the operation was completed successfully
*/
SVGTErrorCode svgtDocViewportSet(SVGTHandle svgDoc,
                                 SVGTfloat* viewport);

The document viewport could be though as the source (or logical) viewport, the surface viewport instead could be though as the destination (or physical) viewport. The combined use of svgtDocViewportSet and svgtSurfaceViewportSet induces a transformation matrix, that will be used (by the svgtDocDraw function) to draw the whole SVG document. The induced matrix will ensure that the document viewport will be mapped onto the surface viewport: all SVG content will be drawn accordingly.

If the two viewports do not have the same aspect ratio (i.e. width-to-height ratio), we need to specify how the svgtDocDraw function is to display the SVG document. We do so by using the following function:

/*
    Set the document alignment.
    The alignment parameter indicates whether to force uniform scaling and,
    if so, the alignment method to use in case the aspect ratio of the document
    viewport doesn't match the aspect ratio of the surface viewport.

    The 'values' parameter must be an array of (at least) 2 unsigned integers
    entries, it must contain:

    - values[0] = alignment (see SVGTAspectRatioAlign)
    - values[1] = meetOrSlice (see SVGTAspectRatioMeetOrSlice)

    This function returns:

    - SVGT_BAD_HANDLE_ERROR if specified document handle is not valid

    - SVGT_ILLEGAL_ARGUMENT_ERROR if 'viewport' pointer is NULL or
      if it's not properly aligned

    - SVGT_ILLEGAL_ARGUMENT_ERROR if specified alignment is not
      a valid SVGTAspectRatioAlign value

    - SVGT_ILLEGAL_ARGUMENT_ERROR if specified meetOrSlice is not
      a valid SVGTAspectRatioMeetOrSlice value

    - SVGT_NO_ERROR if the operation was completed successfully
*/
SVGTErrorCode svgtDocViewportAlignmentSet(SVGTHandle svgDoc,
                                          SVGTuint* values);

The function takes an array of two values as input (along with an SVG document of course): the first value tells how the document viewport is aligned within the surface viewport, the second value tells how the aspect ratio is to be preserved (if at all).

Documents alignment

Alignment is defined by the SVGTAspectRatioAlign enumeration type:

/*
    Alignment indicates whether to force uniform scaling and, if so,
    the alignment method to use in case the aspect ratio of the source
    (document) viewport doesn't match the aspect ratio of the destination
    (drawing surface) viewport.
*/
typedef enum {
    /*
        Do not force uniform scaling.
        Scale the graphic content of the given element non-uniformly if
        necessary such that the element's bounding box exactly matches the
        viewport rectangle.
        NB: in this case, the <meetOrSlice> value is ignored.
    */
    SVGT_ASPECT_RATIO_ALIGN_NONE,
    /*
        Force uniform scaling.
        Align the <min-x> of the source viewport with the smallest x value of
        the destination viewport.
        Align the <min-y> of the source viewport with the smallest y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMINYMIN,
    /*
        Force uniform scaling.
        Align the <mid-x> of the source viewport with the midpoint x value of
        the destination viewport.
        Align the <min-y> of the source viewport with the smallest y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMIDYMIN,
    /*
        Force uniform scaling.
        Align the <max-x> of the source viewport with the maximum x value of
        the destination viewport.
        Align the <min-y> of the source viewport with the smallest y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMAXYMIN,
    /*
        Force uniform scaling.
        Align the <min-x> of the source viewport with the smallest x value of
        the destination viewport.
        Align the <mid-y> of the source viewport with the midpoint y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMINYMID,
    /*
        Force uniform scaling.
        Align the <mid-x> of the source viewport with the midpoint x value of
        the destination viewport.
        Align the <mid-y> of the source viewport with the midpoint y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMIDYMID,
    /*
        Force uniform scaling.
        Align the <max-x> of the source viewport with the maximum x value of
        the destination viewport.
        Align the <mid-y> of the source viewport with the midpoint y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMAXYMID,
    /*
        Force uniform scaling.
        Align the <min-x> of the source viewport with the smallest x value of
        the destination viewport.
        Align the <max-y> of the source viewport with the maximum y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMINYMAX,
    /*
        Force uniform scaling.
        Align the <mid-x> of the source viewport with the midpoint x value of
        the destination viewport.
        Align the <max-y> of the source viewport with the maximum y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMIDYMAX,
    /*
        Force uniform scaling.
        Align the <max-x> of the source viewport with the maximum x value of
        the destination viewport.
        Align the <max-y> of the source viewport with the maximum y value of
        the destination viewport.
    */
    SVGT_ASPECT_RATIO_ALIGN_XMAXYMAX
} SVGTAspectRatioAlign;

The way in which the aspect ratio is to be preserved is defined by the SVGTAspectRatioMeetOrSlice enumeration type:

typedef enum {
    /*
        Scale the graphic such that:

        - aspect ratio is preserved

        - the entire viewBox is visible within the viewport

        - the viewBox is scaled up as much as possible,
          while still meeting the other criteria

        In this case, if the aspect ratio of the graphic does not match the
        viewport, some of the viewport will extend beyond the bounds of the
        viewBox (i.e., the area into which the viewBox will draw will be smaller
        than the viewport).
    */
    SVGT_ASPECT_RATIO_MEET,
    /*
        Scale the graphic such that:

        - aspect ratio is preserved

        - the entire viewport is covered by the viewBox

        - the viewBox is scaled down as much as possible,
          while still meeting the other criteria

        In this case, if the aspect ratio of the viewBox does not match the
        viewport, some of the viewBox will extend beyond the bounds of the
        viewport (i.e., the area into which the viewBox will draw is larger than
        the viewport).
    */
    SVGT_ASPECT_RATIO_SLICE
} SVGTAspectRatioMeetOrSlice;
 
A brief visual example of possible alignments