[cairo-commit] svgslides/src svgslides-4suite,1.2,1.3

Carl Worth commit at pdx.freedesktop.org
Sat Feb 12 19:41:50 PST 2005


Committed by: cworth

Update of /cvs/cairo/svgslides/src
In directory gabe:/tmp/cvs-serv2895/src

Modified Files:
	svgslides-4suite 
Log Message:

       * test/test.xml: Add tests for indentation and img tag.

        * src/svgslides-4suite (get_attr, get_attr_float): Add some much
        needed convenience functions for getting attributes (of the right
        type and with default values).
        (prev_sib, find_position_content_node)
        (find_position_content_nodes, find_height_content_node)
        (find_height_content_nodes, layout_content_nodes): Fix layout of
        bulleted lists. Now supports multiple levels of indentation.
        (transform_li): Add bullet to <li> results.
        (transform_img): Add support for <img> tag.


Index: svgslides-4suite
===================================================================
RCS file: /cvs/cairo/svgslides/src/svgslides-4suite,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- svgslides-4suite	12 Feb 2005 21:45:23 -0000	1.2
+++ svgslides-4suite	13 Feb 2005 03:41:48 -0000	1.3
@@ -33,10 +33,26 @@
 def slide_file_name (slide_num):
     return basename+'-'+str(slide_num+1).zfill(3)+'.svg'
 
+# Some convenience functions to make this DOM stuff a touch less painful
+
 def do_xpath (context_node, expr):
     ctx = Context (context_node, processorNss = NSS)
     return XPath.Evaluate (expr, ctx)
 
+def get_attr (node, attr, default=''):
+    value = node.getAttributeNS (None, attr)
+    if value:
+        return value
+    else:
+        return default
+
+def get_attr_float (node, attr, default=1.0):
+    value = node.getAttributeNS (None, attr)
+    if value:
+        return float(value)
+    else:
+        return default
+
 ###
 ### Main program
 ###
@@ -82,56 +98,137 @@
 
     def substitute_region (region):
 
-	def line_height ():
-	    return font_size * 1.8
-
-	# XXX: Need to finish the layout functions
-	def layout_ul (ul):
-	    ul.x = 10
-	    ul.y = 10
+	# Find previous sibling, ignoring all text nodes
+	def prev_sib (node):
+	    sib = node.previousSibling
+	    while sib and sib.nodeName == '#text':
+		sib = sib.previousSibling
+	    return sib
 
-	def layout_li (li):
-	    sibs = do_xpath (li, "preceding-sibling::ss:li[1]")
-	    if len(sibs):
-		sib = sibs[0]
-		li.x = sib.x
-		li.y = sib.y + line_height ()
+	def find_position_content_node (node):
+	    sib = prev_sib (node)
+	    if sib:
+		node.y = sib.y + sib.height
 	    else:
-		li.x = 0
-		li.y = line_height ()
+                node.y = 0
+	    if node.nodeName == u'ul':
+		parent = node.parentNode
+		if parent.nodeName == u'ul':
+		    node.x = 50
+		else:
+		    node.x = 0
+	    else:
+		node.x = 0
 
-	def layout_content_node (node):
+	def find_position_content_nodes (nodes):
+	    for node in nodes:
+		if node.nodeName != '#text':
+		    find_position_content_node (node)
+		    if node.hasChildNodes ():
+			find_position_content_nodes (node.childNodes)
+
+	def find_height_content_node (node):
 	    if node.nodeName == u'ul':
-		layout_ul (node)
+		height = 0
 	    elif node.nodeName == u'li':
-		layout_li (node)
+		height = font_size * 1.8
+	    else:
+		height = 0
+	    if node.hasChildNodes ():
+		height += find_height_content_nodes (node.childNodes)
+	    node.height = height
+	    return height
 
-	def layout_content_nodes (nodes):
+	def find_height_content_nodes (nodes):
+	    height = 0
 	    for node in nodes:
-		layout_content_node (node)
-		if (node.hasChildNodes ()):
-		    layout_content_nodes (node.childNodes)
+		height += find_height_content_node (node)
+	    return height
+
+	def layout_content_nodes (nodes):
+	    find_height_content_nodes (content)
+	    find_position_content_nodes (content)
 
 	def transform_ul (ul, root):
-	    group = doc.createElementNS (SVG, 'g')
-	    root.appendChild (group)
-	    return group
+	    if ul.x or ul.y:
+		group = doc.createElementNS (SVG, 'g')
+		group.setAttributeNS (None, u'transform', 'translate('+`ul.x`+','+`ul.y`+')')
+		root.appendChild (group)
+		return group
+	    else:
+		return root
 
 	def transform_li (li, root):
+            # XXX: Theme designer should be able to draw a custom bullet
+            bullet_radius = font_size / 6
+
+            bullet = get_attr (li, 'bullet')
+            if bullet != 'off':
+                circle = doc.createElementNS (SVG, 'circle')
+                root.appendChild (circle)
+                circle.setAttributeNS (None, u'cx', `li.x + bullet_radius`)
+                circle.setAttributeNS (None, u'cy', `li.y + font_size / 1.5`)
+                circle.setAttributeNS (None, u'r',  `bullet_radius`)
+            
 	    values = do_xpath (li, u'text()')
 	    text = doc.createElementNS (SVG, 'text')
 	    root.appendChild (text)
 	    for v in values:
 		text.appendChild (doc.createTextNode (v.nodeValue))
-	    text.setAttributeNS (None, u'x', `li.x`)
-	    text.setAttributeNS (None, u'y', `li.y`)
+	    text.setAttributeNS (None, u'x', `li.x + 3 * bullet_radius`)
+	    text.setAttributeNS (None, u'y', `li.y + font_size`)
 	    return root
 
+        def transform_img (img, root):
+            img_file = img.getAttributeNS (None, 'src')
+            img_uri = Uri.OsPathToUri (img_file, attemptAbsolute=1)
+            img_doc = Dom.NonvalidatingReader.parseUri (img_uri)
+
+            svg_root = do_xpath (img_doc, "svg:svg[1]")[0]
+
+            svg_width = get_attr_float (svg_root, 'width')
+            svg_height = get_attr_float (svg_root, 'height')
+
+            img_x = get_attr_float (img, 'x', 0.0)
+            img_y = get_attr_float (img, 'y', 0.0)
+            # XXX: width/height are currently not working
+            img_width = get_attr_float (img, 'width', 1.0)
+            img_height = get_attr_float (img, 'height', 1.0)
+
+            width = img_width * svg_width
+            height = img_height * svg_height
+
+            x_offset = img_x * region_width
+
+            x_align = get_attr (img, 'x-align', 'left')
+            if x_align == 'right':
+                x_offset -= width
+            elif x_align == 'center':
+                x_offset -= width / 2
+
+            y_offset = img_y * region_height
+
+            y_align = get_attr (img, 'y-align', 'top')
+            if y_align == 'bottom':
+                y_offset -= height
+            elif y_align == 'center':
+                y_offset -= height / 2
+
+            group = doc.createElementNS (SVG, 'g')
+            group.setAttributeNS (None, u'transform', 'translate('+`x_offset`+','+`y_offset`+')')
+            root.appendChild (group)
+
+            group.appendChild (doc.importNode (svg_root, 1))
+
+            return root
+
 	def transform_content_node (node, root):
 	    if node.nodeName == u'ul':
 		return transform_ul (node, root)
 	    if node.nodeName == u'li':
 		return transform_li (node, root)
+            if node.nodeName == u'img':
+		return transform_img (node, root)
 	    return root
 
 	def transform_content_nodes (nodes, root):
@@ -150,10 +247,10 @@
 
 	# Get bounds information from a mandatory rect within the region
 	rect = do_xpath (region, u'svg:rect[1]')[0]
-	region_x = rect.getAttributeNS (None, 'x')
-	region_y = rect.getAttributeNS (None, 'y')
-	region_width = rect.getAttributeNS (None, 'width')
-	region_height = rect.getAttributeNS (None, 'height')
+	region_x = get_attr_float (rect, 'x')
+	region_y = get_attr_float (rect, 'y')
+	region_width = get_attr_float (rect, 'width')
+	region_height = get_attr_float (rect, 'height')
 
 	# Remove sample content from region
 	while len(region.childNodes):
@@ -162,7 +259,7 @@
 	# Add a new group with a transform based on the rect
 	g = doc.createElementNS (SVG, 'g')
 	region.appendChild (g)
-	g.setAttributeNS (None, 'transform', 'translate('+region_x+','+region_y+')')
+	g.setAttributeNS (None, 'transform', 'translate('+`region_x`+','+`region_y`+')')
 
 	if (region_name == 'default'):
 	    content = do_xpath (slide, u'*[local-name() != "region"]')




More information about the cairo-commit mailing list