SVG
ePUB OPS Reading Systems must support SVG (Scalable Vector Graphics) as an OPS Core Media Type.
Contents |
[edit] Overview
Many images, such as maps, charts, graphs, etc., originate from vector graphics systems, not photographs. Such images can be represented in a vector (as opposed to raster) format that describes the image in terms of lines, curves and absolutely positioned blocks of text (as opposed to an array of pixels). Replacing raster images with vector ones makes documents more accessible and searchable. This additional effort on the part of Reading Systems provides a framework that authors can use to improve accessibility significantly. Vector images also improve the visual quality of documents (since vector images are inherently scalable) and tend to decrease document sizes.
Scalable Vector Graphics (SVG) is a text-based graphics language that describes images with vector shapes, text, and embedded raster graphics. SVG is an XML markup language for describing two-dimensional vector graphics. It is a W3C standard. Basically SVG is to vector graphics what XHTML is to text. It is explicitly designed to work with other W3C standards such as CSS, DOM and SMIL. SVG has support for CSS which can be used like CSS in a standard ePub or HTML document.
Note that an SVG element can be placed inside the XHTML itself and this is generally the preferred method. It is also possible to place an IMG element in the XHTML file and then reference the SVG as a separate file (with an SVG extension) although some reading devices or apps my not support this.
[edit] The Canvas
At the start of an SVG image a canvas must be created. The width and height of this canvas is often determined by the parent element. The SVG defined sizes may therefore be scaled to fit. In general the SVG statement itself may be used to define the canvas size. Real dimensions or relative dimensions can be used but are either specified or converted to pixels. Supported units include em, ex, px, pt, pc, cm, mm, in, and percentages. Think of the canvas as a scalable piece of graph paper where the values define the grid points.
Inside the canvas is a viewport which may be implied. The initial viewport uses an arbitrary x,y coordinate system and this is scaled to fit inside the canvas. The origin is the upper left corner. X points right and Y points down.
<svg width="300px" height="200px" version="1.1" viewBox="0 0 1500 1000" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
New viewports can also be defined when needed either with a viewBox or a Transform. A transform can offset the starting point, rotate or scale (via a multiplier) the coordinates. The specifications provides more complex examples illustrating these features.
[edit] Examples
Here is an example of an SVG file. An SVG file will normally have a .SVG extension.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg id="svg2" version="1.0" width="400" height="400" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"> <g id="layerOne"> <rect id="myRect" width="50" height="50" x="100" y="25" style="fill:blue;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> <circle id="myCirc" cx="200" cy="200" r="50" style="fill:green;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> <path id="myPath" d="M 238 49 L 350 145 L 327 172 L 215 76 Z" style="fill:red;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> </g> </svg>
Note that the path in this example could have been defined as a rectangle and then the "transform" attribute could be used to rotate it. But, of course, a path can be a much more complex shape.
[edit] Shapes
SVG markup is relatively simple. You can follow the basic idea of pixels and layout shapes as such. Just understand that what you specify as 100px may scale up to 150px along with the rest of the image scaling up 150%.
[edit] Rectangles
<g id="layerOne"> <rect id="myRect" width="50" height="50" x="100" y="25" style="fill:blue;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> <circle id="myCirc" cx="200" cy="200" r="50" style="fill:green;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" />
Attributes:
x = "<coordinate>"
The x-axis coordinate of the side of the rectangle which has the smaller x-axis coordinate value in the current user coordinate system. If the attribute is not specified, the effect is as if a value of "0" were specified.
y = "<coordinate>"
The y-axis coordinate of the side of the rectangle which has the smaller y-axis coordinate value in the current user coordinate system. If the attribute is not specified, the effect is as if a value of "0" were specified.
width = "<length>"
The width of the rectangle. A negative value is an error (see Error processing). A value of zero disables rendering of the element.
height = "<length>"
The height of the rectangle. A negative value is an error (see Error processing). A value of zero disables rendering of the element.
rx = "<length>"
For rounded rectangles, the x-axis radius of the ellipse used to round off the corners of the rectangle. A negative value is an error.
ry = "<length>"
For rounded rectangles, the y-axis radius of the ellipse used to round off the corners of the rectangle. A negative value is an error.
[edit] Circles
<rect id="myRect" width="50" height="50" x="100" y="25" style="fill:blue;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> <circle id="myCirc" cx="200" cy="200" r="50" style="fill:green;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> <path id="myPath" d="M 238 49 L 350 145 L 327 172 L 215 76 Z" style="fill:red;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" />
Attributes:
cx = "<coordinate>"
The x-axis coordinate of the center of the circle. If the attribute is not specified, the effect is as if a value of "0" were specified.
cy = "<coordinate>"
The y-axis coordinate of the center of the circle. If the attribute is not specified, the effect is as if a value of "0" were specified.
r = "<length>"
The radius of the circle. A negative value is an error (see Error processing). A value of zero disables rendering of the element.
[edit] Paths
<circle id="myCirc" cx="200" cy="200" r="50" style="fill:green;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> <path id="myPath" d="M 238 49 L 350 145 L 327 172 L 215 76 Z" style="fill:red;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> </g> </svg>
Attributes:
d = "path data"
The definition of the outline of a shape.pathLength = "<number>"
- M indicates movetos
- L indicates linetos
- Z indicates the closepath
The author's computation of the total length of the path, in user units. This value is used to calibrate the user agent's own distance-along-a-path calculations with that of the author. The user agent will scale all distance-along-a-path computations by the ratio of ‘pathLength’ to the user agent's own computed value for total path length. ‘pathLength’ potentially affects calculations for text on a path, motion animation and various stroke operations. A negative value is an error.
[edit] xLinks
You can draw shapes and make them clickable by putting them inside of an anchor element like you would in normal xHTML. Take our first example. If you wanted to take the square and link it to a web page you could do the following:
<g id="layerOne"> <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.eprdctn.org"> <rect id="myRect" width="50" height="50" x="100" y="25" style="fill:blue;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" /> </a> <circle id="myCirc" cx="200" cy="200" r="50" style="fill:green;opacity:1;fill-opacity:0.5;stroke:black;stroke-opacity:1;" />
[edit] Embedding Images
There are a few times where you will want to embed another image inside of your SVG. One example I often use for embedding images in SVG is creating image maps. You can embed an image and later add opac elements that link to different parts of your xHTML. This is great for graphs and maps.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg2" version="1.0" width="768" height="923"> <g id="layerOne"> <image xlink:href="19_img01.jpg" width="768" height="923" /> </g> </svg>
Here is another for scalable covers in an eBook. This is inside an HTML page. The width and height should be the actual size of the image.
<div> <svg xmlns="http://www.w3.org/2000/svg" height="100%" preserveAspectRatio="xMidYMid meet" version="1.1" viewBox="0 0 482 775" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink"> <image height="775" width="482" xlink:href="../Images/cover.jpeg"></image> </svg> </div>
It is also possible to add a caption to the figure using SVG text element. Make the viewBox taller than the image size to make room for the text. This will keep the caption on the same page with the text.
[edit] Text
The example below contains the text string "Hello, out there" which will be rendered onto the canvas using the Verdana font family with the glyphs filled with the color blue. To be less specific on the font family you could use sans-serif or serif.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="10cm" height="3cm" viewBox="0 0 1000 300" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example text01 - 'Hello, out there' in blue</desc> <text x="250" y="150" font-family="Verdana" font-size="55" fill="blue" > Hello, out there </text> <!-- Show outline of canvas using 'rect' element --> <rect x="1" y="1" width="998" height="298" fill="none" stroke="blue" stroke-width="2" /> </svg>
The text-anchor property can be used to specify left, middle, right position of a line of text. The textlength property will allow specifying the length of the line into which the text itself will attempt to be placed evenly. It is also possible to specify comma separated x and y coordinates which will be used to specify the locations of individual characters. There is also a rotation capability using the rotate property.
[edit] Text with an embedded image
The simple case is to add text under and image. To do this just increase the size of the viewBox Y value to accommodate text and then enter the text after the image description. To place the text above the image requires only a few more changes. Take a look at this example text:
<text text-anchor="middle" font-family="serif"> <tspan x="242" y="30" font-size="25" font-style="italic">CHAPTER</tspan> <tspan x="242" y="80" font-size="45" font-style="normal" font-weight="bold">Two</tspan> </text>
The example shows two lines of text with different font sizes. The total height of the two lines is 125 pixels which is dictated by the y location and height of the second line. The picture starting location, which is generally 0, would have to be changed to 125 to make room for the text. And, of course, the viewBox would also need to be increased by 125 pixels. The text entries themselves would be entered before the image entry to aid in understanding when you look at the code, but the software does not require that.
Another use for text with an embedded image is to place the text over the top of the image. In this case you would not increase the viewBox nor the starting location for the image. The order is important in this case to see the text which should come after the image.
[edit] Use element
The use element can be used with a defined object and use it multiple times if you wish. Thus you could define a shape or a path or other object and re-use it without having to enter the definition again. Here is an example:
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <desc>Example Use02 - 'use' on a 'symbol'</desc> <defs> <symbol id="MySymbol" viewBox="0 0 20 20"> <desc>MySymbol - four rectangles in a grid</desc> <rect x="1" y="1" width="8" height="8"/> <rect x="11" y="1" width="8" height="8"/> <rect x="1" y="11" width="8" height="8"/> <rect x="11" y="11" width="8" height="8"/> </symbol> </defs> <rect x=".1" y=".1" width="99.8" height="29.8" fill="none" stroke="blue" stroke-width=".2" /> <use x="45" y="10" width="10" height="10" xlink:href="#MySymbol" /> </svg>
Note the "defs" section define an object with 4 boxes as a symbol and then the "use" element is able to use that symbol as a named element but can adjust some of the values as needed.
[edit] Other Examples
- Breakfast in Bridgetown by Paul Gerald - This works best on iPad but shows off SVGs being used as image maps. Also uses nonlinear content.
- Floral heart - a fleuron
- An Apple logo in black
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="101" height="121"> <g> <path d="m 28.709,28.63 c 3.516,0 7.758,0.726 12.727,2.179 5.015,1.454 8.343,2.18 9.984,2.18 2.109,0 5.555,-0.82 10.336,-2.461 4.781,-1.64 8.93,-2.461 12.445,-2.461 5.766,0 10.899,1.547 15.399,4.641 2.531,1.781 5.039,4.195 7.523,7.242 -3.75,3.188 -6.492,6.024 -8.226,8.508 -3.141,4.5 -4.711,9.469 -4.711,14.906 0,5.953 1.664,11.32 4.992,16.102 3.328,4.781 7.125,7.804 11.392,9.07 -1.783,5.766 -4.736,11.794 -8.861,18.074 -6.234,9.42 -12.422,14.13 -18.562,14.13 -2.438,0 -5.813,-0.77 -10.125,-2.32 -4.266,-1.55 -7.875,-2.32 -10.828,-2.32 -2.954,0 -6.399,0.8 -10.336,2.39 -3.891,1.64 -7.055,2.46 -9.493,2.46 -7.359,0 -14.578,-6.23 -21.656,-18.7 C 3.631,89.919 0.092,77.825 0.092,65.966 0.09199,54.95 2.7873,45.974 8.1779,39.036 13.615,32.098 20.4589,28.63 28.7089,28.63 M 73.0059,0.927 c 0.187,0.60946 0.305,1.1486 0.352,1.6172 0.046,0.4689 0.07,0.9376 0.07,1.4063 0,3.0001 -0.703,6.281 -2.109,9.844 -1.407,3.562 -3.633,6.867 -6.68,9.914 -2.625,2.578 -5.227,4.312 -7.805,5.203 -1.64,0.516 -4.125,0.914 -7.453,1.195 0.094,-7.125 1.945,-13.289 5.555,-18.492 3.656,-5.203 9.679,-8.7655 18.07,-10.687" /> </g> </svg>
Taken from https://commons.wikimedia.org/wiki/File:Apple_logo_black.svg
[edit] ViewBox & AspectRatio
Please study the use of the ViewBox attribute on the W3C site. It can be adjust the graphics to fit the display size.
The value of the ‘viewBox’ attribute is a list of four numbers <min-x>, <min-y>, <width> and <height>
Please study the use of the PreserveAspectRatio attribute on the W3C site. This attribute can force the aspect ratio of the graphics to a best fit with the aspect ratio of the device screen. The image below is explained on the web site. It is especially useful for a image element (raster image) in a particular graphic.
The aspect ratio can be turned off by setting its value to 'none'.
[edit] General Notes on SVG Usage in ePUB
OPS supports the full SVG 1.1 Recommendation. The only exception is that, since OPS is not targeting interactive content, SVG animation and scripting features are not supported. These features must not be used by publication authors; a Reading System should not render such content. CSS styling of SVG must be fully supported.
Text in SVG images should be selectable and searchable. SVG images may contain links (a elements) and thus may be used for navigation. If a Reading System supports "tabbing" through links, SVG links must be included.
For ePub version 2, inline SVG is only supported within documents using the XHTML Preferred Vocabulary. It must not be used within DTBook documents. For ePub 3 SVG can be either inside an XHTML or as a standalone entity with an SVG file extension.
[edit] Creating SVG
- Inkscape - create and edit fully compliant SVG
- A text editor such as Notepad++
- LaTeX to SVG converter - LaTeX has many devotees but is not recognized in ePUB. This converter helps overcome these problems for complex layouts like math equations.
- Inkscape - A free open source vector graphics editor, with capabilities similar to Illustrator, CorelDraw, or Xara X, using the W3C standard Scalable Vector Graphics (SVG) file format.
- Affinity Designer Vector graphics application.
- Adobe Illustrator - can create SVG.
- SVG-edit - "A complete vector graphics editor in the browser," open-source project hosted on Google.
- svgEpub - A free open source epub authoring tool, which can create SVG files from raster image files.
- MobileRead forum - A tutorial on creating an SVG image from a raster file. Focuses on turning rasterized text into SVG so it will scale well.
- Export Excel charts to SVG files - requirements: Excel 2007 or later to make the PDF required, Inkscape. See also MobileRead discussion.
[edit] For more information
- The W3.org specification - for SVG 1.1
- The IDPF.org ePub 2.0.1 specification - SVG
- The IDPF.org ePub 3.0 Draft - SVG Content Documents
- The IDPF.org ePub 2.0.1 to 3.0 New Changes - SVG
- Ebook Covers illustrates using SVG to scale a cover image.
- SVG Tutorial Nice tutorial on some of the shapes and lines you can draw in SVG.
- SVG Essentials - wiki page from O'Reilly.com
- SVG Tutorials.jenkov full tutorials