SVG

From MobileRead
Jump to: navigation, search

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>
Image of an SVG image. :)
This is how the image will display.

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.
  • M indicates movetos
  • L indicates linetos
  • Z indicates the closepath
pathLength = "<number>"
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

<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.

PreserveAspectRatio.png

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

Personal tools
Namespaces

Variants
Actions
Navigation
MobileRead Networks
Toolbox