home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Inkscape / Inkscape-0.48.2-1-win32.exe / share / extensions / gimp_xcf.py < prev    next >
Encoding:
Python Source  |  2011-07-08  |  7.8 KB  |  224 lines

  1. #!/usr/bin/env python 
  2. '''
  3. Copyright (C) 2006 Aaron Spike, aaron@ekips.org
  4. Copyright (C) 2010 Nicolas Dufour, nicoduf@yahoo.fr (Windows support and various fixes)
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. '''
  20. import inkex
  21. import sys, os, tempfile, shutil
  22. import gettext
  23.  
  24. try:
  25.     from subprocess import Popen, PIPE
  26.     bsubprocess = True
  27. except:
  28.     bsubprocess = False
  29.  
  30. class MyEffect(inkex.Effect):
  31.     def __init__(self):
  32.         inkex.Effect.__init__(self)
  33.         self.OptionParser.add_option("-d", "--guides",
  34.                                          action="store", type="inkbool",
  35.                                          dest="saveGuides", default=False,
  36.                                          help="Save the Guides with the .XCF")
  37.         self.OptionParser.add_option("-r", "--grid",
  38.                                          action="store", type="inkbool",
  39.                                          dest="saveGrid", default=False,
  40.                                          help="Save the Grid with the .XCF")
  41.  
  42.     def output(self):
  43.         pass
  44.  
  45.     def clear_tmp(self):
  46.         shutil.rmtree(self.tmp_dir)
  47.  
  48.     def effect(self):
  49.         svg_file = self.args[-1]
  50.         ttmp_orig = self.document.getroot()
  51.         docname = ttmp_orig.get(inkex.addNS('docname',u'sodipodi'))
  52.         if docname is None: docname = self.args[-1]
  53.  
  54.         pageHeight = int(inkex.unittouu(self.xpathSingle('/svg:svg/@height').split('.')[0]))
  55.         pageWidth = int(inkex.unittouu(self.xpathSingle('/svg:svg/@width').split('.')[0]))
  56.  
  57.         #create os temp dir
  58.         self.tmp_dir = tempfile.mkdtemp()
  59.  
  60.         # Guides
  61.         hGuides = []
  62.         vGuides = []
  63.         valid = 0
  64.         if self.options.saveGuides:
  65.             guideXpath = "sodipodi:namedview/sodipodi:guide" #grab all guide tags in the namedview tag
  66.             for guideNode in self.document.xpath(guideXpath, namespaces=inkex.NSS):
  67.                 ori = guideNode.get('orientation')
  68.                 if  ori == '0,1':
  69.                     #this is a horizontal guide
  70.                     pos = int(guideNode.get('position').split(',')[1].split('.')[0])
  71.                     #GIMP doesn't like guides that are outside of the image
  72.                     if pos > 0 and pos < pageHeight:
  73.                         #the origin is at the top in GIMP land
  74.                         hGuides.append(str(pageHeight - pos))
  75.                 elif ori == '1,0':
  76.                     #this is a vertical guide
  77.                     pos = int(guideNode.get('position').split(',')[0].split('.')[0])
  78.                     #GIMP doesn't like guides that are outside of the image
  79.                     if pos > 0 and pos < pageWidth:
  80.                         vGuides.append(str(pos))
  81.  
  82.         hGList = ' '.join(hGuides)
  83.         vGList = ' '.join(vGuides)
  84.  
  85.         # Grid
  86.         gridSpacingFunc = ''
  87.         gridOriginFunc = '' 
  88.         #GIMP only allows one rectangular grid
  89.         gridXpath = "sodipodi:namedview/inkscape:grid[@type='xygrid' and (not(@units) or @units='px')]"
  90.         if (self.options.saveGrid and self.document.xpath(gridXpath, namespaces=inkex.NSS)):
  91.             gridNode = self.xpathSingle(gridXpath)
  92.             if gridNode != None:
  93.                 #these attributes could be nonexistant
  94.                 spacingX = gridNode.get('spacingx')
  95.                 if spacingX == None: spacingX = '1  '
  96.  
  97.                 spacingY = gridNode.get('spacingy')
  98.                 if spacingY == None: spacingY = '1  '
  99.  
  100.                 originX = gridNode.get('originx')
  101.                 if originX == None: originX = '0  '
  102.  
  103.                 originY = gridNode.get('originy')
  104.                 if originY == None: originY = '0  '
  105.  
  106.                 gridSpacingFunc = '(gimp-image-grid-set-spacing img %s %s)' % (spacingX[:-2], spacingY[:-2])
  107.                 gridOriginFunc = '(gimp-image-grid-set-offset img %s %s)'% (originX[:-2], originY[:-2])
  108.  
  109.         # Layers
  110.         area = '--export-area-page'
  111.         pngs = []
  112.         names = []
  113.         path = "/svg:svg/*[name()='g' or @style][@id]"
  114.         for node in self.document.xpath(path, namespaces=inkex.NSS):
  115.             if len(node) > 0: # Get rid of empty layers
  116.                 valid=1
  117.                 id = node.get('id')
  118.                 if node.get("{" + inkex.NSS["inkscape"] + "}label"):
  119.                     name = node.get("{" + inkex.NSS["inkscape"] + "}label")
  120.                 else:
  121.                     name = id
  122.                 filename = os.path.join(self.tmp_dir, "%s.png" % id)
  123.                 command = "inkscape -i %s -j %s -e %s %s " % (id, area, filename, svg_file)
  124.                 if bsubprocess:
  125.                     p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
  126.                     return_code = p.wait()
  127.                     f = p.stdout
  128.                     err = p.stderr
  129.                 else:
  130.                     _,f,err = os.popen3(command,'r')
  131.                 f.read()
  132.                 f.close()
  133.                 err.close()
  134.                 if os.name == 'nt':
  135.                     filename = filename.replace("\\", "/")
  136.                 pngs.append(filename)
  137.                 names.append(name.encode('utf-8'))
  138.  
  139.         if (valid==0):
  140.             inkex.errormsg(gettext.gettext('This extension requires at least one non empty layer.'))
  141.             self.clear_tmp()
  142.             sys.exit(0)
  143.  
  144.         filelist = '"%s"' % '" "'.join(pngs)
  145.         namelist = '"%s"' % '" "'.join(names)
  146.         xcf = os.path.join(self.tmp_dir, "%s.xcf" % docname)
  147.         if os.name == 'nt':
  148.             xcf = xcf.replace("\\", "/")
  149.         script_fu = """
  150. (tracing 1)
  151. (define
  152.   (png-to-layer img png_filename layer_name)
  153.   (let*
  154.     (
  155.       (png (car (file-png-load RUN-NONINTERACTIVE png_filename png_filename)))
  156.       (png_layer (car (gimp-image-get-active-layer png)))
  157.       (xcf_layer (car (gimp-layer-new-from-drawable png_layer img)))
  158.     )
  159.     (gimp-image-add-layer img xcf_layer -1)
  160.     (gimp-drawable-set-name xcf_layer layer_name)
  161.   )
  162. )
  163. (let*
  164.   (
  165.     (img (car (gimp-image-new 200 200 RGB)))
  166.   )
  167.   (gimp-image-undo-disable img)
  168.   (for-each
  169.     (lambda (names)
  170.       (png-to-layer img (car names) (cdr names))
  171.     )
  172.     (map cons '(%s) '(%s))
  173.   )
  174.  
  175.   (gimp-image-resize-to-layers img)
  176.  
  177.   (for-each
  178.     (lambda (hGuide)
  179.       (gimp-image-add-hguide img hGuide)
  180.     )
  181.     '(%s)
  182.   )
  183.  
  184.   (for-each
  185.     (lambda (vGuide)
  186.       (gimp-image-add-vguide img vGuide)
  187.     )
  188.     '(%s)
  189.   )
  190.  
  191.   %s
  192.   %s
  193.  
  194.   (gimp-image-undo-enable img)
  195.   (gimp-file-save RUN-NONINTERACTIVE img (car (gimp-image-get-active-layer img)) "%s" "%s"))
  196. (gimp-quit 0)
  197.         """ % (filelist, namelist, hGList, vGList, gridSpacingFunc, gridOriginFunc, xcf, xcf)
  198.  
  199.         junk = os.path.join(self.tmp_dir, 'junk_from_gimp.txt')
  200.         f = os.popen('gimp -i --batch-interpreter plug-in-script-fu-eval -b - > %s 2>&1' % junk,'w')
  201.         f.write(script_fu)
  202.         f.close()
  203.         # uncomment these lines to see the output from gimp
  204.         #err = open(junk, 'r')
  205.         #inkex.debug(err.read())
  206.         #err.close()
  207.  
  208.         x = open(xcf, 'rb')
  209.         if os.name == 'nt':
  210.             try:
  211.                 import msvcrt
  212.                 msvcrt.setmode(1, os.O_BINARY)
  213.             except:
  214.                 pass
  215.         sys.stdout.write(x.read())
  216.         x.close()
  217.         self.clear_tmp()
  218.  
  219.  
  220. if __name__ == '__main__':
  221.     e = MyEffect()
  222.     e.affect()
  223.  
  224.