Adds transformation support for OT-SVG glyphs.

* include/freetype/ftglyph.h: Adds `transform' and `delta' fields
to `FT_SvgGlyphRed'.

* include/freetype/otsvg.h: Adds `transform' and `delta' fields to
`FT_SVG_Document'.

* src/base/ftglyph.c: Creates method `ft_svg_glyph_transform' and
modifies existing functions for the new fields.

* src/sfnt/ttsvg.c: (tt_face_load_svg_doc) Set `transform' to unity
and `delta' to zero by default.

* src/svg/ftsvg.c: Adds `ft_svg_transform'.
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index b29751e..e346444 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -268,6 +268,12 @@
    *   end_glyph_id ::
    *     The ending glyph ID for the glyph range that this document has.
    *
+   *   transform ::
+   *     Transformation matrix to apply on the glyph while rendering.
+   *
+   *   delta ::
+   *     Translation to apply on the glyph while rendering.
+   *
    * @note:
    *   `metrics` and `units_per_EM` might look like repetitions since both
    *   fields are stored in face objects.  However, the Glyph Management API
@@ -289,7 +295,8 @@
     FT_UShort           units_per_EM;
     FT_UShort           start_glyph_id;
     FT_UShort           end_glyph_id;
-    /* TODO: (OT-SVG) Maybe put a transformation matrix here */
+    FT_Matrix           transform;
+    FT_Vector           delta;
   } FT_SvgGlyphRec;
 
 
diff --git a/include/freetype/otsvg.h b/include/freetype/otsvg.h
index b7b9af8..55969e5 100644
--- a/include/freetype/otsvg.h
+++ b/include/freetype/otsvg.h
@@ -147,6 +147,12 @@
    *   end_glyph_id ::
    *     The ending glyph ID for the glyph range that this document has.
    *
+   *   transform ::
+   *     Transformation matrix to apply on the glyph while rendering.
+   *
+   *   delta ::
+   *     Translation to apply on the glyph while rendering.
+   *
    * @note:
    *   `metrics` and `units_per_EM` might look like repetitions since both
    *   fields are stored in face object, but they are not; When the slot is
@@ -165,6 +171,8 @@
     FT_UShort        units_per_EM;
     FT_UShort        start_glyph_id;
     FT_UShort        end_glyph_id;
+    FT_Matrix        transform;
+    FT_Vector        delta;
   } FT_SVG_DocumentRec;
 
   /**************************************************************************
diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index fa60ea1..17fe8b8 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -326,6 +326,8 @@
     glyph->units_per_EM        = document->units_per_EM;
     glyph->start_glyph_id      = document->start_glyph_id;
     glyph->end_glyph_id        = document->end_glyph_id;
+    glyph->transform           = document->transform;
+    glyph->delta               = document->delta;
     /* copy the document into glyph */
     FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
 
@@ -372,6 +374,8 @@
     target->units_per_EM        = source->units_per_EM;
     target->start_glyph_id      = source->start_glyph_id;
     target->end_glyph_id        = source->end_glyph_id;
+    target->transform           = source->transform;
+    target->delta               = source->delta;
 
     /* allocate space for the svg document */
     target->svg_document = memory->alloc( memory,
@@ -385,6 +389,55 @@
     return error;
   }
 
+  FT_CALLBACK_DEF( void )
+  ft_svg_glyph_transform( FT_Glyph          svg_glyph,
+                          const FT_Matrix*  _matrix,
+                          const FT_Vector*  _delta )
+  {
+    FT_SvgGlyph  glyph = (FT_SvgGlyph)svg_glyph;
+
+    FT_Matrix*  matrix = _matrix;
+    FT_Vector*  delta  = _delta;
+
+    FT_Matrix  tmp_matrix;
+    FT_Vector  tmp_delta;
+    FT_Matrix  a, b;
+    FT_Pos     x, y;
+
+    if ( !matrix )
+    {
+      tmp_matrix.xx = 0x10000;
+      tmp_matrix.xy = 0;
+      tmp_matrix.yx = 0;
+      tmp_matrix.yy = 0x10000;
+      matrix = &tmp_matrix;
+    }
+
+    if ( !delta )
+    {
+      tmp_delta.x = 0;
+      tmp_delta.y = 0;
+      delta = &tmp_delta;
+    }
+
+    a = glyph->transform;
+    b = *matrix;
+    FT_Matrix_Multiply( &b, &a );
+
+    x = ADD_LONG(ADD_LONG(
+        FT_MulFix(matrix->xx, glyph->delta.x),
+        FT_MulFix(matrix->xy, glyph->delta.y)),
+        delta->x);
+    y = ADD_LONG(ADD_LONG(
+        FT_MulFix(matrix->yx, glyph->delta.x),
+        FT_MulFix(matrix->yy, glyph->delta.y)),
+        delta->y);
+    glyph->delta.x = x;
+    glyph->delta.y = y;
+
+    glyph->transform = a;
+  }
+
   FT_CALLBACK_DEF( FT_Error )
   ft_svg_glyph_prepare( FT_Glyph     svg_glyph,
                         FT_GlyphSlot slot )
@@ -404,6 +457,8 @@
     document->units_per_EM        = glyph->units_per_EM;
     document->start_glyph_id      = glyph->start_glyph_id;
     document->end_glyph_id        = glyph->end_glyph_id;
+    document->transform           = glyph->transform;
+    document->delta               = glyph->delta;
 
     slot->format      = FT_GLYPH_FORMAT_SVG;
     slot->glyph_index = glyph->glyph_index;
@@ -421,7 +476,7 @@
     ft_svg_glyph_init,      /* FT_Glyph_InitFunc       glyph_init      */
     ft_svg_glyph_done,      /* FT_Glyph_DoneFunc       glyph_done      */
     ft_svg_glyph_copy,      /* FT_Glyph_CopyFunc       glyph_copy      */
-    NULL,                   /* FT_Glyph_TransformFunc  glyph_transform */
+    ft_svg_glyph_transform, /* FT_Glyph_TransformFunc  glyph_transform */
     NULL,                   /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
     ft_svg_glyph_prepare    /* FT_Glyph_PrepareFunc    glyph_prepare   */
   )
diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
index 211a639..fced193 100644
--- a/src/sfnt/ttsvg.c
+++ b/src/sfnt/ttsvg.c
@@ -318,6 +318,13 @@
     svg_document->start_glyph_id      = start_glyph_id;
     svg_document->end_glyph_id        = end_glyph_id;
 
+    svg_document->transform.xx = 0x10000;
+    svg_document->transform.xy = 0;
+    svg_document->transform.yx = 0;
+    svg_document->transform.yy = 0x10000;
+    svg_document->delta.x      = 0;
+    svg_document->delta.y      = 0;
+
     FT_TRACE5(( "start_glyph_id: %d\n", start_glyph_id ));
     FT_TRACE5(( "end_glyph_id:   %d\n", end_glyph_id ));
     FT_TRACE5(( "svg_document:\n%.*s\n", doc_length, doc_list ));
diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c
index 901f3e8..298ce65 100644
--- a/src/svg/ftsvg.c
+++ b/src/svg/ftsvg.c
@@ -175,6 +175,57 @@
     return 0;
   }
 
+  static FT_Error
+  ft_svg_transform( FT_Renderer       renderer,
+                    FT_GlyphSlot      slot,
+                    const FT_Matrix*  _matrix,
+                    const FT_Vector*  _delta )
+  {
+    FT_SVG_Document  doc = (FT_SVG_Document)slot->other;
+
+    FT_Matrix*  matrix = _matrix;
+    FT_Vector*  delta  = _delta;
+    FT_Matrix   tmp_matrix;
+    FT_Vector   tmp_delta;
+    FT_Matrix   a, b;
+    FT_Pos      x, y;
+
+    if ( !matrix )
+    {
+      tmp_matrix.xx = 0x10000;
+      tmp_matrix.xy = 0;
+      tmp_matrix.yx = 0;
+      tmp_matrix.yy = 0x10000;
+      matrix = &tmp_matrix;
+    }
+
+    if ( !delta )
+    {
+      tmp_delta.x = 0;
+      tmp_delta.y = 0;
+    }
+
+    a = doc->transform;
+    b = *matrix;
+    FT_Matrix_Multiply( &b, &a );
+
+
+    x = ADD_LONG(ADD_LONG(
+        FT_MulFix(matrix->xx, doc->delta.x),
+        FT_MulFix(matrix->xy, doc->delta.y)),
+        delta->x);
+    y = ADD_LONG(ADD_LONG(
+        FT_MulFix(matrix->yx, doc->delta.x),
+        FT_MulFix(matrix->yy, doc->delta.y)),
+        delta->y);
+    doc->delta.x = x;
+    doc->delta.y = y;
+
+    doc->transform = a;
+
+    return FT_Err_Ok;
+  }
+
 #endif
 
 #ifdef FT_CONFIG_OPTION_SVG
@@ -201,7 +252,7 @@
       PUT_SVG_MODULE( ft_svg_get_interface ),                /* get_interface */
       SVG_GLYPH_FORMAT,
       (FT_Renderer_RenderFunc)PUT_SVG_MODULE( ft_svg_render ),
-      NULL,
+      (FT_Renderer_TransformFunc)PUT_SVG_MODULE( ft_svg_transform ),
       NULL,
       NULL,
       NULL