diff --git a/Lib/fontTools/ttLib/tables/S_V_G_.py b/Lib/fontTools/ttLib/tables/S_V_G_.py
new file mode 100644
index 0000000..9474fcf
--- /dev/null
+++ b/Lib/fontTools/ttLib/tables/S_V_G_.py
@@ -0,0 +1,370 @@
+__doc__="""
+Compiles/decompiles version 0 and 1 SVG tables from/to XML.
+
+Version 1 is the first SVG definition, implemented in Mozilla before Aug 2013, now deprecated.
+This module will decompile this correctly, but will compile a version 1 table
+only if you add the secret element "<version1/>" to the SVG element in the TTF file.
+
+Version 0 is the joint Adobe-Mozilla proposal, which supports color palettes.
+
+The XML format is:
+  <SVG>
+    <svgDoc endGlyphID="1" startGlyphID="1">
+      <![CDATA[ <complete SVG doc> ]]
+    </svgDoc>
+...
+	<svgDoc endGlyphID="n" startGlyphID="m">
+      <![CDATA[ <complete SVG doc> ]]
+    </svgDoc>
+
+    <colorPalettes>
+    	<colorParamUINameID>n</colorParamUINameID>
+    	...
+    	<colorParamUINameID>m</colorParamUINameID>
+    	<colorPalette uiNameID="n">
+    		<colorRecord red="<int>" green="<int>" blue="<int>" alpha="<int>" />
+    		...
+    		<colorRecord red="<int>" green="<int>" blue="<int>" alpha="<int>" />
+    	</colorPalette>
+    	...
+    	<colorPalette uiNameID="m">
+    		<colorRecord red="<int> green="<int>" blue="<int>" alpha="<int>" />
+    		...
+    		<colorRecord red=<int>" green="<int>" blue="<int>" alpha="<int>" />
+    	</colorPalette>
+    </colorPalettes>
+</SVG>
+
+Color values must be less than 256. 
+
+The number of color records in each </colorPalette> must be the same as
+the number of <colorParamUINameID> elements.
+
+"""
+
+import DefaultTable
+import struct, sstruct
+from fontTools.misc.textTools import safeEval
+try:
+    import xml.etree.cElementTree as ET
+except ImportError:
+    import xml.etree.ElementTree as ET
+import string
+import types
+import re
+
+XML = ET.XML
+XMLElement = ET.Element
+xmlToString = ET.tostring
+
+SVG_format_0 = """
+	>   # big endian
+	version:                  H
+	offsetToSVGDocIndex:      L
+	offsetToColorPalettes:    L
+"""
+
+SVG_format_0Size = sstruct.calcsize(SVG_format_0)
+
+SVG_format_1 = """
+	>   # big endian
+	version:                  H
+	numIndicies:              H
+"""
+
+SVG_format_1Size = sstruct.calcsize(SVG_format_1)
+
+doc_index_entry_format_0 = """
+	>   # big endian
+	startGlyphID:             H
+	endGlyphID:               H
+	svgDocOffset:             L
+	svgDocLength:             L
+"""
+
+doc_index_entry_format_0Size = sstruct.calcsize(doc_index_entry_format_0)
+
+colorRecord_format_0 = """
+	red:                      B
+	green:                    B
+	blue:                     B
+	alpha:                    B
+"""
+
+
+class table_S_V_G_(DefaultTable.DefaultTable):
+	
+	def decompile(self, data, ttFont):
+		self.docList = None
+		self.colorPalettes = None
+		pos = 0
+		self.version = struct.unpack(">H", data[pos:pos+2])[0]
+		
+		if self.version == 1:
+			self.decompile_format_1(data, ttFont)
+		else:
+			if self.version != 0:
+				print "Unknown SVG table version '%s'. Decompiling as version 0." % (self.version)
+			self.decompile_format_0(data, ttFont)
+
+
+	def decompile_format_0(self, data, ttFont):
+		dummy, data2 = sstruct.unpack2(SVG_format_0, data, self)
+		# read in SVG Documents Index
+		pos = self.offsetToSVGDocIndex
+		self.numEntries = numEntries = struct.unpack(">H", data[pos:pos+2])[0]
+		self.decompileEntryList(data, pos+2)
+
+		# read in colorPalettes table.
+		self.colorPalettes = colorPalettes = ColorPalettes()
+		pos = self.offsetToColorPalettes
+		if pos > 0:
+			colorPalettes.numColorParams = numColorParams = struct.unpack(">H", data[pos:pos+2])[0]
+			if numColorParams > 0:
+				colorPalettes.colorParamUINameIDs = colorParamUINameIDs = []
+				pos = pos + 2
+				i = 0
+				while i < numColorParams:
+					nameID = struct.unpack(">H", data[pos:pos+2])[0]
+					colorParamUINameIDs.append(nameID)
+					pos = pos + 2
+					i += 1
+
+				colorPalettes.numColorPalettes = numColorPalettes = struct.unpack(">H", data[pos:pos+2])[0]
+				pos = pos + 2
+				if numColorPalettes > 0:
+					colorPalettes.colorPaletteList = colorPaletteList = []
+					i = 0
+					while i < numColorPalettes:
+						colorPalette = ColorPalette()
+						colorPaletteList.append(colorPalette)
+						colorPalette.uiNameID = struct.unpack(">H", data[pos:pos+2])[0]
+						pos = pos + 2
+						colorPalette.paletteColors = paletteColors = []
+						j = 0
+						while j < numColorParams:
+							colorRecord, colorPaletteData = sstruct.unpack2(colorRecord_format_0, data[pos:], ColorRecord())
+							paletteColors.append(colorRecord)
+							j += 1
+							pos += 4
+						i += 1
+
+	def decompile_format_1(self, data, ttFont):
+		pos = 2
+		self.numEntries = struct.unpack(">H", data[pos:pos+2])[0]
+		pos += 2
+		self.decompileEntryList(data, pos)
+
+	def decompileEntryList(self, data, pos):
+		# data starts with the first entry of the entry list.
+		if self.numEntries > 0:
+			data2 = data[pos:]
+			self.docList = []
+			self.entries = entries = []
+			i = 0
+			while i < self.numEntries:
+				docIndexEntry, data2 = sstruct.unpack2(doc_index_entry_format_0, data2, DocumentIndexEntry())
+				entries.append(docIndexEntry)
+				i += 1
+
+			for entry in entries:
+				start = entry.svgDocOffset
+				end = start + entry.svgDocLength
+				doc = data[start:end]
+				self.docList.append( [doc, entry.startGlyphID, entry.endGlyphID] )
+
+	def compile(self, ttFont):
+		if hasattr(self, "version1"):
+			data = self.compileFormat1(ttFont)
+		else:
+			data = self.compileFormat0(ttFont)
+		return data
+
+	def compileFormat0(self, ttFont):
+		version = 0
+		offsetToSVGDocIndex = SVG_format_0Size # I start the SVGDocIndex right after the header.
+
+		# get SGVDoc info.
+		docList = []
+		entryList = []
+		numEntries = len(self.docList)
+		datum = struct.pack(">H",numEntries)
+		entryList.append(datum)
+		curOffset = offsetToSVGDocIndex + len(datum) + doc_index_entry_format_0Size*numEntries
+		for doc, startGlyphID, endGlyphID in self.docList:
+			docOffset = curOffset
+			docLength = len(doc)
+			curOffset += docLength
+		 	entry = struct.pack(">HHLL", startGlyphID, endGlyphID, docOffset, docLength)
+		 	entryList.append(entry)
+		 	docList.append(doc)
+		entryList.extend(docList)
+		svgDocData = "".join(entryList)
+
+		# get colorpalette info.
+		if self.colorPalettes == None:
+			offsetToColorPalettes = 0
+			palettesData = ""
+		else:
+			offsetToColorPalettes = SVG_format_0Size + len(svgDocData)
+			dataList = []
+			numColorParams = len(self.colorPalettes.colorParamUINameIDs)
+			datum = struct.pack(">H", numColorParams)
+			dataList.append(datum)
+			for uiNameId in self.colorPalettes.colorParamUINameIDs:
+				datum = struct.pack(">H", uiNameId)
+				dataList.append(datum)
+			numColorPalettes = len(self.colorPalettes.colorPaletteList)
+			datum = struct.pack(">H", numColorPalettes)
+			dataList.append(datum)
+			for colorPalette in self.colorPalettes.colorPaletteList:
+				datum = struct.pack(">H", colorPalette.uiNameID)
+				dataList.append(datum)
+				for colorRecord in colorPalette.paletteColors:
+					data = struct.pack(">BBBB", colorRecord.red, colorRecord.green, colorRecord.blue, colorRecord.alpha)
+					dataList.append(data)
+			palettesData = "".join(dataList)
+
+		header = struct.pack(">HLL", version, offsetToSVGDocIndex, offsetToColorPalettes)
+		data = [header, svgDocData, palettesData]
+		data = "".join(data)
+		return data
+
+	def compileFormat1(self, ttFont):
+		version = 1
+		numEntries = len(self.docList)
+		header = struct.pack(">HH", version, numEntries)
+		dataList = [header]
+		docList = []
+		curOffset = SVG_format_1Size + doc_index_entry_format_0Size*numEntries
+		for doc, startGlyphID, endGlyphID in self.docList:
+			docOffset = curOffset
+			docLength = len(doc)
+			curOffset += docLength
+		 	entry = struct.pack(">HHLL", startGlyphID, endGlyphID, docOffset, docLength)
+		 	dataList.append(entry)
+		 	docList.append(doc)
+		dataList.extend(docList)
+		data = "".join(dataList)
+		return data
+
+	def toXML(self, writer, ttFont):
+		writer.newline()
+		for doc, startGID, endGID in self.docList:
+			writer.begintag("svgDoc", startGlyphID=startGID, endGlyphID=endGID)
+			writer.newline()
+			writer.writeraw("<![CDATA["+ doc + "]]>")
+			writer.newline()
+			writer.endtag("svgDoc")
+			writer.newline()
+
+		if self.colorPalettes.numColorParams != None:
+			writer.begintag("colorPalettes")
+			writer.newline()
+			for uiNameID in self.colorPalettes.colorParamUINameIDs:
+				writer.begintag("colorParamUINameID")
+				writer.writeraw(str(uiNameID))
+				writer.endtag("colorParamUINameID")
+				writer.newline()
+			for colorPalette in self.colorPalettes.colorPaletteList:
+				writer.begintag("colorPalette", [("uiNameID", str(colorPalette.uiNameID))])
+				writer.newline()
+				for colorRecord in colorPalette.paletteColors:
+					colorAttributes = [
+							("red", hex(colorRecord.red)),
+							("green", hex(colorRecord.green)),
+							("blue", hex(colorRecord.blue)),
+							("alpha", hex(colorRecord.alpha)),
+						]
+					writer.begintag("colorRecord", colorAttributes)
+					writer.endtag("colorRecord")
+					writer.newline()
+				writer.endtag("colorPalette")
+				writer.newline()
+
+			writer.endtag("colorPalettes")
+			writer.newline()
+		else:
+			writer.begintag("colorPalettes")
+			writer.endtag("colorPalettes")
+			writer.newline()
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		import re
+		if name == "svgDoc":
+			if not hasattr(self, "docList"):
+				self.docList = []
+			doc = "".join(content)
+			doc = doc.strip()
+			startGID = int(attrs["startGlyphID"])
+			endGID = int(attrs["endGlyphID"])
+			self.docList.append( [doc, startGID, endGID] )
+		elif  name == "colorPalettes":
+			self.colorPalettes = ColorPalettes()
+			self.colorPalettes.fromXML((name, attrs, content), ttFont)
+			if self.colorPalettes.numColorParams == 0:
+				self.colorPalettes = None
+		else:
+			print "Unknown", name, content
+
+class DocumentIndexEntry:
+	def __init__(self):
+		self.startGlyphID = None # USHORT
+		self.endGlyphID = None # USHORT
+		self.svgDocOffset = None # ULONG
+		self.svgDocLength = None # ULONG
+
+	def __repr__(self):
+		return "startGlyphID: %s, endGlyphID: %s, svgDocOffset: %s, svgDocLength: %s" % (self.startGlyphID, self.endGlyphID, self.svgDocOffset, self.svgDocLength)
+
+class ColorPalettes:
+	def __init__(self):
+		self.numColorParams = None # USHORT
+		self.colorParamUINameIDs = [] # list of name table name ID values that provide UI description of each color palette.
+		self.numColorPalettes = None # USHORT
+		self.colorPaletteList = [] # list of ColorPalette records
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		for element in content:
+			if type(element) == type(""):
+				continue
+			name, attrib, content = element
+			if name == "colorParamUINameID":
+				uiNameID = int(content[0])
+				self.colorParamUINameIDs.append(uiNameID)
+			elif name == "colorPalette":
+				colorPalette = ColorPalette()
+				self.colorPaletteList.append(colorPalette)
+				colorPalette.fromXML((name, attrib, content), ttFont)
+
+		self.numColorParams = len(self.colorParamUINameIDs)
+		self.numColorPalettes = len(self.colorPaletteList)
+		for colorPalette in self.colorPaletteList:
+			if len(colorPalette.paletteColors) != self.numColorParams:
+				raise ValueError("Number of color records in a colorPalette ('%s') does not match the number of colorParamUINameIDs elements ('%s')." % (len(colorPalette.paletteColors), self.numColorParams))
+
+class ColorPalette:
+	def __init__(self):
+		self.uiNameID = None # USHORT. name table ID that describes user interface strings associated with this color palette. 
+		self.paletteColors = [] # list of ColorRecords
+
+	def fromXML(self, (name, attrs, content), ttFont):
+		self.uiNameID = int(attrs["uiNameID"])
+		for element in content:
+			if type(element) == type(""):
+				continue
+			name, attrib, content = element
+			if name == "colorRecord":
+				colorRecord = ColorRecord()
+				self.paletteColors.append(colorRecord)
+				colorRecord.red = eval(attrib["red"])
+				colorRecord.green = eval(attrib["green"])
+				colorRecord.blue = eval(attrib["blue"])
+				colorRecord.alpha = eval(attrib["alpha"])
+
+class ColorRecord:
+	def __init__(self):
+		self.red = 255 # all are one byte values.
+		self.green = 255
+		self.blue = 255
+		self.alpha = 255
