[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