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.

Java binding

The Java binding of AmanithSVG API consists in two different layers:

Here’s a list of classes exposed by the high level Java layer:


SVGTError

The SVGTError enumeration wraps the native SVGTErrorCode enum type, and it represents all possible error codes signaled dy AmanithSVG functions.


SVGTAlign

The SVGTAlign enumeration wraps the native SVGTAspectRatioAlign enum type, and it defines 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.


SVGTMeetOrSlice

The SVGTMeetOrSlice enumeration wraps the native SVGTAspectRatioMeetOrSlice enum type, and it defines the scaling 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.


SVGTRenderingQuality

The SVGTRenderingQuality enumeration wraps the native SVGTRenderingQuality enum type, and it defines the quality (and speed) of SVG drawings.


SVGTLogLevel

The SVGTLogLevel enumeration wraps the native SVGTLogLevel enum type, and it defines the possible logging levels (e.g. errors, warnings or just informational messages).


SVGTResourceType

The SVGTResourceType enumeration wraps the native SVGTResourceType enum type, and it defines the type of each external resource provided to AmanithSVG.


SVGTResourceHint

The SVGTResourceHint enumeration wraps the native SVGTResourceHint enum type, and it defines all the possible hints for tagging external resources provided to AmanithSVG.


SVGColor

SVGColor is a simple class that exposes four (float) color components (red, green, blue, alpha), within the [0.0f; 1.0f] range. The class is so simple that it does not require further explanation.


SVGPoint

SVGPoint is a simple class representing a 2D point, the class exposes two (float) properties: abscissa (x) and ordinate (y). The class is so simple that it does not require further explanation.


SVGViewport

SVGViewport represents a rectangular area, specified by its top/left corner, a width and an height. The positive x-axis points towards the right, the positive y-axis points down. The class exposes four (float) properties: x, y, width, height. The class is so simple that it does not require further explanation.


SVGAlignment

The SVGAlignment class represents a couple of values, one taken from the SVGTAlign enum type and the other taken from the SVGTMeetOrSlice enum type. Alignment indicates whether to force uniform scaling and, if so, the alignment method to use in case the aspect ratio of the source viewport doesn’t match the aspect ratio of the destination viewport. For detailed explanation of SVGTAlign and SVGTMeetOrSlice enum type, please refer to the low level API documentation.

 
A brief visual example of possible alignments

SVGDocument

In order to render SVG contents, AmanithSVG must create an optimized in-memory representation of SVG files: a such representation is called SVG Document. An SVG document can be created through SVGAssets’s createDocument function, specifying the xml text. The document will be parsed immediately, and the internal drawing tree will be created. Once the document has been created, it can be drawn several times onto one (or more) drawing surface. In order to draw a document, we must:

  1. create a drawing surface using SVGAssets’s createSurface function
  2. call SVGSurface’s draw method, specifying the document to draw

Example:

SVGAssets svg = < instantiate AmanithSVG >;
String xml = new String(Files.readAllBytes(Paths.get("animals.svg")));
SVGDocument doc = svg.createDocument(xml);

< do something with document >

/* release AmanithSVG */
svg.dispose();

SVGDocument class exposes four main properties: handle, width, height, viewport, aspectRatio, accessible through their respective “get” methods getHandle(), getWidth(), getHeight(), getViewport(), getAspectRatio(). Handle, width and height are read-only values, all other properties can also be set through their respective “set” methods setAspectRatio, setViewport.

/* 
    AmanithSVG document handle (read only); it's the handle created by the low level
    svgtDocCreate function.
*/
SVGTHandle getHandle();

/*
    SVG content itself optionally can provide information about the appropriate
    viewport region for the content via the 'width' and 'height' XML attributes
    on the outermost <svg> element.
    Use this method to get the suggested viewport width, in pixels.

    It returns a negative number (i.e. an invalid width) in the following cases:
    - outermost element is not an <svg> element
    - outermost <svg> element doesn't have a 'width' attribute specified
    - outermost <svg> element has a negative 'width' attribute specified
      (e.g. width="-50")
    - outermost <svg> element has a 'width' attribute specified in relative measure
      units (i.e. em, ex, % percentage)
*/
float getWidth();

/*
    SVG content itself optionally can provide information about the appropriate
    viewport region for the content via the 'width' and 'height' XML attributes
    on the outermost <svg> element.
    Use this method to get the suggested viewport height, in pixels.

    It returns a negative number (i.e. an invalid height) in the following cases:
    - outermost element is not an <svg> element
    - outermost <svg> element doesn't have a 'height' attribute specified
    - outermost <svg> element has a negative 'height' attribute specified
      (e.g. height="-30")
    - outermost <svg> element has a 'height' attribute specified in relative measure
      units (i.e. em, ex, % percentage)
*/
float getHeight();

/*
    The document (logical) viewport to map onto the destination (drawing surface)
    viewport.
    When an SVG document has been created through the SVGAssets.createDocument
    function, the initial value of its viewport is equal to the 'viewBox' attribute
    present in the outermost <svg> element.
*/
SVGViewport getViewport();

/*
    Viewport aspect ratio.
    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.
*/
SVGAlignment getAspectRatio();

/* Set a new alignment for the document viewport. */
void setAspectRatio(SVGAlignment aspectRatio);

/* Set a new viewport for the document. */
void setViewport(SVGViewport viewport);

SVGSurface

SVGSurface class represents a drawing surface.

A drawing surface is just a rectangular area made of pixels, where each pixel is represented internally by a 32bit unsigned integer. A pixel is made of four 8-bit components: red, green, blue, alpha. Coordinate system is the same of SVG specifications: top/left pixel has coordinate (0, 0), with the positive x-axis pointing towards the right and the positive y-axis pointing down.

An SVGSurface can be created by using the SVGAssets.createSurface function, specifying its dimensions in pixels.

SVGSurface class exposes four main properties: handle, width, height, viewport, accessible through their respective “get” methods getHandle(), getWidth(), getHeight(), getViewport().

/*
    AmanithSVG surface handle (read only); it's the handle created by the low level
    svgtSurfaceCreate function.
*/
SVGTHandle getHandle();

/* Get current surface width, in pixels. */
int getWidth();

/* Get current surface height, in pixels. */
int getHeight();

/*
    The surface viewport (i.e. a drawing surface rectangular area), where to map
    the source document viewport.
    The combined use of surface and document viewport, 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.
*/
SVGViewport getViewport();

A drawing surface can be resized by calling the resize method:

/*
    Resize the surface, specifying new dimensions in pixels; it returns
    SVGTError.None if the operation was completed successfully, else an error code.
    After resizing, the surface viewport will be reset to the whole surface.
*/
SVGTError resize(int newWidth,
                 int newHeight);

Once that an SVGDocument has been created, it can be rendered over a drawing surface using the following SVGSurface method:

/*
    Draw an SVG document, on this drawing surface.
    First the drawing surface is cleared if a valid (i.e. not null) clear color
    is provided. Then the specified document, if valid, is drawn.
    It returns SVGTError.None if the operation was completed successfully, else
    an error code.
*/
SVGTError draw(SVGDocument document,
               SVGColor clearColor,
               SVGTRenderingQuality renderingQuality);

Here’s a complete example:

SVGAssets svg = < instantiate AmanithSVG >;
/* load an SVG file */
String xml = new String(Files.readAllBytes(Paths.get("animals.svg")));
SVGDocument doc = svg.createDocument(xml);

/* create a 512x512 drawing surface */
SVGSurface srf = svg.createSurface(512, 512);

/* draw the SVG */
srf.draw(doc, SVGColor.White, SVGTRenderingQuality.Better);
< do something with surface pixels (e.g. upload pixels to a GPU texture) >

/* destroy surface and document */
doc.dispose();
srf.dispose();
/* release AmanithSVG */
svg.dispose();
 
Rendering result

By modifying the drawing surface viewport, it’s possible to draw more than one SVG document on it. For example, 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:

SVGAssets svg = < instantiate AmanithSVG >;
/* load SVG files */
SVGDocument doc1 = svg.createDocument(new String(Files.readAllBytes(Paths.get("car_coolant.svg"))));
SVGDocument doc2 = svg.createDocument(new String(Files.readAllBytes(Paths.get("car_maintenance.svg"))));
SVGDocument doc3 = svg.createDocument(new String(Files.readAllBytes(Paths.get("car_brake.svg"))));
SVGDocument doc4 = svg.createDocument(new String(Files.readAllBytes(Paths.get("car_oil.svg"))));

/* create a drawing surface */
SVGSurface srf = svg.createSurface(512, 512);

/* select an upper-left sub-region and draw the first SVG document */
srf.setViewport(new SVGViewport(0, 0, 256, 256));
srf.draw(doc1, SVGColor.White, SVGTRenderingQuality.Better);

/* select an upper-right sub-region and draw the second SVG document */
srf.setViewport(new SVGViewport(256, 0, 256, 256));
srf.draw(doc2, null, SVGTRenderingQuality.Better);

/* select the whole lower-left sub-region and draw the third SVG document */
srf.setViewport(new SVGViewport(0, 256, 256, 256));
srf.draw(doc3, null, SVGTRenderingQuality.Better);

/* select the whole lower-right sub-region and draw the fourth SVG document */
srf.setViewport(new SVGViewport(256, 256, 256, 256));
srf.draw(doc4, null, SVGTRenderingQuality.Better);

< do something with surface pixels (e.g. upload pixels to a GPU texture) >

/* destroy surface and documents */
doc1.dispose();
doc2.dispose();
doc3.dispose();
doc4.dispose();
srf.dispose();
/* release AmanithSVG */
svg.dispose();
 
Usage of surface viewport

SVGPacker

Besides rendering single SVG documents over drawing surfaces, AmanithSVG can pack the rendering of one or more SVG documents within one or more drawing surfaces, automatically. For each given SVG, you can choose to pack the whole document or instead to pack each first-level element separately.

The whole process consists of some steps that must be followed in this order:

Here is a complete example code:

SVGAssets svg = < instantiate AmanithSVG >;

/* create an SVG document */
SVGDocument doc = svg.createDocument(new String(Files.readAllBytes(Paths.get("orc.svg"))));

/* initialize the packing process: generate atlases with a maximum 512 pixels dimension and no additional scale */
SVGPacker packer = svg.createPacker(1.0f, 512, 1, false);

if (packer.begin()) {

    int[] info = new int[2];
    // add the document to the packer, and get back the actual number of packed bounding boxes
    packer.add(doc, true, 1.0f, info);

    // info[0] = number of collected bounding boxes
    // info[1] = the actual number of packed bounding boxes
    if ((info == null) || (info[1] != info[0])) {
        System.out.println("Some SVG elements cannot be packed!");
        System.out.println("Specified maximum texture dimensions do not allow to pack all SVG elements");
        // close the packing process without doing anything
        packer.end(false);
    }
    else {
        // finalize the packing process and get back generated bins
        SVGPacker.SVGPackedBin[] bins = packer.end(true);

        for (int i = 0; i < bins.length; ++i) {
            // extract the bin (i.e. get atlas width, height and the number of packed documents/elements)
            SVGPacker.SVGPackedBin bin = bins[i];
            /* create a drawing surface with the same atlas dimension */
            SVGSurface srf = svg.createSurface(bin.Width, bin.Height);
            /* draw all documents/elements over the drawing surface */
            srf.draw(bin, SVGColor.Clear, SVGTRenderingQuality.Better);
            /* if needed, process the drawing surface (e.g. upload its pixels on a GPU texture) and then destroy it */
            < do something with surface pixels (e.g. upload pixels to a GPU texture) >
            /* destroy the surface */
            srf.dispose();
        }
    }
}

/* destroy the document */
doc.dispose();
/* release AmanithSVG */
svg.dispose();

If we run the example code using this orc.svg file, it will produce a single 452 x 108 bin, with the following packed rectangles:

 elemNameoriginalXoriginalYxywidthheightzOrder
rects[0]head59001331059
rects[1]body2680133093977
rects[2]sx_leg_down75191226048612
rects[3]dx_leg_down41191274038634
rects[4]sx_arm_up95102312038545
rects[5]dx_arm_up1998350038546
rects[6]dx_arm_down19141388032688
rects[7]sx_arm_down99139420032680
rects[8]dx_leg_up431473125438543
rects[9]sx_leg_up701463505438541
 
orc.svg
 
orc atlas

It is important to note that the whole packing process, as well as the SVGSurface.draw(SVGPacker.SVGPackedBin, SVGColor, SVGTRenderingQuality) method, is not affected by SVG documents viewports nor by drawing surfaces viewports. In other words, the viewport values set through SVGDocument.setViewport and SVGSurface.setViewport methods do not affect the behavior of packing processes and atlas generation.

For a more detailed explanation on the packing process, please refer to the relative low level api.


SVGResource

This class represents an external (binary) resource, available for rendering SVG documents. Each resource is defined by a unique string identifier (typically the file name, without the path), a type (font or image), and a set of hints; all such properties must be specified in SVGResource constructor. SVGResource class cannot be instantiated directly, because it has an abstract getStream method that must be implemented according to the target platform (or development tool/environment): such method must return an in-memory representation of the underlying binary TTF / OTF / WOFF / JPEG / PNG file.

/* Constructor. */
abstract SVGResource(String id,
                     SVGTResourceType type,
                     final EnumSet<SVGTResourceHint> hints);

/* Get input/read stream for the resource. */
abstract InputStream getStream();

/* Resource identifier. */
String _id;

/* Resource type. */
SVGTResourceType _type;

/* Resource hints. */
EnumSet<SVGTResourceHint> _hints;

Resources are provided to SVGAssets through an instance of a class derived from SVGAssetsConfig.


SVGAssetsConfig

The SVGAssetsConfig class provides configuration parameters, along with font resources, to an SVGAssets instance. Configuration parameters can be divided in two sub-sets:

The class is abstract so it cannot be instantiated directly; it must be extended by implementing the mechanism to access resource files (defined by the SVGResource class). In particular, each class that extends SVGAssetsConfig must implement the resourcesCount and getResource methods. See details:

/*
    Constructor, device screen properties must be supplied
    (with/height in pixels and dpi).
*/
SVGAssetsConfig(int screenWidth,
                int screenHeight,
                float screenDpi);

/* Get screen resolution width, in pixels. */
int getScreenWidth();

/* Get screen resolution height, in pixels. */
int getScreenHeight();

/* Get screen dpi. */
float getScreenDpi();

/*
    Get curves quality, used by AmanithSVG geometric kernel to approximate curves
    with straight line segments (flattening). Valid range is [1; 100], where 100
    represents the best quality.

    A zero or negative value means "keep the default one".
*/
float getCurvesQuality();

/*
    Set curves quality, used by AmanithSVG geometric kernel to approximate curves
    with straight line segments (flattening). Valid range is [1; 100], where 100
    represents the best quality.

    A zero or negative value means "keep the default one".
*/
void setCurvesQuality(float quality);

/* Get user-agent language. */
String getLanguage();

/*
    Set the user-agent language.

    Specify the system/user-agent language; this setting will affect the
    conditional rendering of <switch> elements and elements with
    'systemLanguage' attribute specified. The given argument must be a
    non-empty list of languages separated by semicolon
    (e.g. "en-US;en-GB;it;es")
*/
void setLanguage(String languages);

/* Get log level. */
EnumSet<SVGTLogLevel> getLogLevel();

/* Get log capacity, in characters. */
int getLogCapacity();

/*
    Set log parameters (log level and log capacity).

    If the specified log level is empty, logging is disabled.
    If the specified log capacity (in characters) is less than or equal
    zero, logging is disabled.
*/
void setLogParameters(EnumSet<SVGTLogLevel> logLevel,
                      int logCapacity);

/*
    Get the number of (external) resources provided by this configuration.
    It must be implemented by all derived classes.
*/
abstract int resourcesCount();

/*
    Get a resource given an index.
    If the given index is less than zero or greater or equal to the value
    returned by 'resourcesCount', a null resource is returned.

    It must be implemented by all derived classes.
*/
abstract SVGResource getResource(int index);

SVGAssets

SVGAssets is the class through which you can create SVGDocument, SVGSurface and SVGPacker instances; here are the main methods:

/*
    Create a drawing surface, specifying its dimensions in pixels.

    Supplied dimensions should be positive numbers greater than zero, else
    a null instance will be returned.
*/
SVGSurface createSurface(int width,
                         int height);

/*
    Create and load an SVG document, specifying the whole XML string.
    If supplied XML string is null or empty, a null instance will be returned.
*/
SVGDocument createDocument(String xmlText);

/*
    Create an SVG packer, specifying a scale factor.
    
    Every collected SVG document/element will be packed into rectangular bins,
    whose dimensions won't exceed the specified 'maxTexturesDimension' in pixels.

    If true, 'pow2Textures' will force bins to have power-of-two dimensions.
    Each rectangle will be separated from the others by the specified 'border' in pixels.

    The specified 'scale' factor will be applied to all collected SVG documents/elements,
    in order to realize resolution-independent atlases.
*/
SVGPacker createPacker(float scale,
                       int maxTexturesDimension,
                       int border,
                       boolean pow2Textures);

/* Get library version. */
static String getVersion();

AmanithSVG can provide detailed information about error situations that can occur when parsing and rendering SVG content. For example AmanithSVG can report if a closing tag did not match the opening one (or if some tag was not closed at all) when parsing an SVG document; or if a font needed for rendering has not been set. In case of error, it is possible to receive additional information on the conditions (which caused the error) in the form of text messages that AmanithSVG can append to a given memory buffer. Log level and the capacity (in characters) of the internal log buffer can be configured through the SVGAssetsConfig class, provided to SVGAssets initialization mechanism.

/* Get AmanithSVG log content as a string. */
String getLog();

/*
    Clear the AmanithSVG log buffer set for the current thread.

    If specified, make sure AmanithSVG no longer uses a log buffer for
    the current thread. In this case, logging can be reactivated (for
    the calling thread) by calling this method with a 'false' parameter.
*/
SVGTError logClear(boolean stopLogging);

From an application point of view, it could be useful to apppend some custom messages to the AmanithSVG log buffer. One of the main purposes can be to insert debug messages, to better understand the interactions between the application and the AmanithSVG library. In this way the application can keep track of all SVG-related activities, and the whole log buffer can be analyzed later (if needed).

/*
    Append an informational message to the AmanithSVG log buffer
    set for the current thread.
*/
boolean logInfo(String message);

/*
    Append a warning message to the AmanithSVG log buffer
    set for the current thread.
*/
boolean logWarning(String message);

/*
    Append an error message to the AmanithSVG log buffer
    set for the current thread.
*/
boolean logError(String message);

Here’s an example:

SVGAssets svg = < instantiate AmanithSVG >;

/* clear AmanithSVG log */
svg.logClear(false);

< load SVG, draw it >

/* print AmanithSVG log content, in order to get details on possible warnings/errors */
System.out.println(svg.getLog());

/* make sure AmanithSVG no longer uses a log buffer (i.e. disable logging) */
svg.logClear(true);

/* release AmanithSVG */
svg.dispose();