Guest User

Inkscape margins calculations

a guest
May 24th, 2016
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.72 KB | None | 0 0
  1.  
  2. from xml.dom.minidom import parse
  3. import re
  4. import subprocess as sp
  5.  
  6. source = "./ink-bug.svg"
  7. tmp_svg = "./tmp4738233729506.svg"
  8. output_path =  "./output/"
  9.  
  10.  
  11.  
  12. special_name_re = re.compile("\s*\$exp\s*:\s*(.+)")
  13.  
  14.  
  15. def generate_svg (filename, node, vbs):
  16.     b1 = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  17. <svg
  18.   xmlns:dc="http://purl.org/dc/elements/1.1/"
  19.   xmlns:cc="http://creativecommons.org/ns#"
  20.   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  21.   xmlns:svg="http://www.w3.org/2000/svg"
  22.   xmlns="http://www.w3.org/2000/svg"
  23.   version="1.1"
  24.   id="svg2"
  25.   viewBox="""
  26.     b2 = """>
  27.  <defs
  28.     id="defs4" />
  29.  <metadata
  30.     id="metadata7">
  31.    <rdf:RDF>
  32.      <cc:Work
  33.         rdf:about="">
  34.        <dc:format>image/svg+xml</dc:format>
  35.        <dc:type
  36.           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  37.        <dc:title></dc:title>
  38.      </cc:Work>
  39.    </rdf:RDF>
  40.  </metadata>
  41.  <g
  42.     id="layer1">"""
  43.     e = """  </g>
  44. </svg>
  45. """
  46.     f = open(filename, "w")
  47.     f.write(b1 + '"' + vbs + '"' + b2 + node.toxml() + e)
  48.     return f.close()
  49.  
  50.  
  51.  
  52.  
  53. def find_figure_node (nodes):
  54.     return next(node for node in nodes
  55.                 if not(node.nodeName in ["text", "#text"]))
  56.  
  57.  
  58. class InkComm:
  59.     def __init__(self):
  60.         "Open unbuffered pipe to Inkscape shell in text mode"
  61.         self.p = sp.Popen(['inkscape', '--shell'],
  62.                           bufsize=0, universal_newlines=True,
  63.                           stdin=sp.PIPE, stdout=sp.PIPE)
  64.         self.read()
  65.  
  66.     def read(self):
  67.         "Read from open Inkscape shell till '>' occur"
  68.         rv = ''
  69.         while True:
  70.             r = self.p.stdout.read(1)
  71.             if r == '>':
  72.                 break
  73.             rv += r
  74.         return rv
  75.  
  76.     def write(self, words_of_wisdom):
  77.         "Write data and newline char"
  78.         return self.p.stdin.write(words_of_wisdom + '\n')
  79.    
  80.     def close(self):
  81.         "Guess what this method does"
  82.         stdout, stderr = self.p.communicate('quit\n')
  83.         return self.p.returncode, stdout, stderr
  84.  
  85.     def get_svg_geometry (self, svgfile):
  86.         "Returns list contains [x, y, width, height] of svg"
  87.         self.write("-S " + svgfile)
  88.         s = self.read().splitlines()[0]
  89.         return map(float,s.split(',')[1:])
  90.  
  91.     def export_svg_area_in_png (self, svg, pngout, svgarea,
  92.                                 width=None, height=None):
  93.         com = svg
  94.         com += " --export-png={0}".format(pngout)
  95.         # com += " --export-area-snap"
  96.         com += " --export-area={0}".format(':'.join(map(str,svgarea)))
  97.         com += " --export-background='#ffffff'"
  98.         if height: com += " --export-height={0}".format(height)
  99.         if width: com += " --export-width={0}".format(width)
  100.        
  101.         self.write(com)
  102.         self.read()
  103.         return(pngout)
  104.  
  105.  
  106. fig_table = {"star-01":{'y':590},
  107.              "star-02":{'y':368},
  108.              "star-03":{'y':210},
  109.              "star-04":{'y':0},
  110.              "star-05":{'y':-212},
  111.              "star-06":{'y':-445},
  112.              "star-07":{'y':-664},
  113.              "star-08":{'y':-865},
  114.              "star-09":{'y':-1110},
  115.              "star-10":{'y':-1325},
  116. }
  117.  
  118. def expand_area (x,y,w,h):
  119.     rd = .3
  120.     dx = w*rd
  121.     x1 =  x - dx
  122.     x2 =  x + w + dx
  123.     y1 =  y + 0.5*h
  124.     y2 =  y - 1.0*h
  125.     return x1,y1,x2,y2
  126.  
  127.            
  128. ink_proc = InkComm()
  129.  
  130. def test_raster(svg, yopts, of, vy):
  131.     x, y, w, h = ink_proc.get_svg_geometry(tmp_svg)
  132.     # real_y = yopts['y']
  133.     real_y = vy - y
  134.     print "{:s}  {:f}  {:f}".format(of, y, real_y)
  135.     real_h = yopts.get('h') or h
  136.     ink_proc.export_svg_area_in_png(svg, of,
  137.                                     expand_area(x, real_y, w, real_h),
  138.                                     width = 450)
  139.  
  140. vb_re = re.compile("\s+")
  141.  
  142. # def get_vy(svg):
  143. #     s = svg.firstChild.getAttribute("viewBox")
  144. #     return float(vb_re.split(s)[3])
  145.    
  146.  
  147. def gen_rfiles (xmlfile):
  148.     svg = parse(xmlfile)
  149.     vbs = svg.firstChild.getAttribute("viewBox")
  150.     vy = float(vb_re.split(vbs)[3])
  151.     text_elements = svg.getElementsByTagName("text")
  152.     for text_element in text_elements:
  153.         x = text_element.firstChild
  154.         if x.hasChildNodes():
  155.             t = x.firstChild.nodeValue
  156.             m = special_name_re.match(t)
  157.             if m:
  158.                 nam = m.group(1).strip()
  159.                 yopts = fig_table.get(nam)
  160.                 if yopts:
  161.                     figure = find_figure_node(text_element.parentNode.childNodes)
  162.                     generate_svg(tmp_svg, figure, vbs)
  163.                     test_raster(tmp_svg, yopts, output_path + nam + '.png', vy)
  164.  
  165.  
  166.  
  167.    
  168.  
  169. gen_rfiles(source)
  170.  
  171. ink_proc.close()
Advertisement
Add Comment
Please, Sign In to add comment