#!/usr/bin/env python ''' This extension Create a eraser layer Copyright (C) 2012 Jabiertxo Arraiza, jabier.arraiza@marker.es Version 0.4 - Eraser TODO: Comment Better!!! CHANGE LOG 0.1 Start 30/07/2012 0.3 fix bug with borders This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' import inkex, sys, simplestyle from lxml import etree class EraserLayer(inkex.Effect): def __init__(self): inkex.Effect.__init__(self) #inserta el flltro que pasa a negro la mascara def insertFilter(self, svg): xpathStr = '//filter[@id="Decolorize_0001"]' filterElement = svg.xpath(xpathStr, namespaces=inkex.NSS) if filterElement == []: xpathStr = '//svg:defs' defs = svg.xpath(xpathStr, namespaces=inkex.NSS) flt = inkex.etree.SubElement(defs[0],inkex.addNS('filter','svg')) for k, v in [('id', 'Decolorize_0001'), ('color-interpolation-filters', 'sRGB'), ('height', '100'), ('width', '100'), ('x', '-50'), ('y', '-50')]: flt.set(k, v) fltColorMatrix = inkex.etree.SubElement(flt,inkex.addNS('feColorMatrix','svg')) for k, v in [('id', 'feColorMatrix_0001'),('values','1'), ('in', 'SourceGraphic'), ('type', 'saturate'), ('result', 'result2')]: fltColorMatrix.set(k, v) fltFlood = inkex.etree.SubElement(flt,inkex.addNS('feFlood','svg')) for k, v in [('id', 'feFlood_0001'),('flood-color','rgb(255,255,255)'), ('flood-opacity', '1'), ('result', 'result1')]: fltFlood.set(k, v) fltComposite = inkex.etree.SubElement(flt,inkex.addNS('feComposite','svg')) for k, v in [('id', 'feComposite_0001'),('operator', 'atop'),('in2', 'SourceGraphic') ,('k2', '1'),('result', 'result4')]: fltComposite.set(k, v) fltInverse = inkex.etree.SubElement(defs[0],inkex.addNS('filter','svg')) for k, v in [('id', 'Inverse_0001'), ('color-interpolation-filters', 'sRGB'), ('height', '100'), ('width', '100'), ('x', '-50'), ('y', '-50')]: fltInverse.set(k, v) fltColorMatrixInverse = inkex.etree.SubElement(fltInverse,inkex.addNS('feColorMatrix','svg')) for k, v in [('id', 'feColorMatrixInverse_0001'),('values','1'), ('type', 'saturate'), ('result', 'fbSourceGraphic')]: fltColorMatrixInverse.set(k, v) fltColorMatrixInverse = inkex.etree.SubElement(fltInverse,inkex.addNS('feColorMatrix','svg')) for k, v in [('id', 'feColorMatrixInverse_0002'),('in','fbSourceGraphic'), ('values', '-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 ')]: fltColorMatrixInverse.set(k, v) #Inserta la mascara desde el grupo eraser def insertMask(self, idLayer, svg): xpathStr = '//mask[@id="MaskEraser_' + idLayer + '"]' maskElement = svg.xpath(xpathStr, namespaces=inkex.NSS) if maskElement == []: xpathStr = '//svg:defs' defs = svg.xpath(xpathStr, namespaces=inkex.NSS) msk = inkex.etree.SubElement(defs[0],inkex.addNS('mask','svg')) for k, v in [('id', 'Eraser_' + idLayer), ('maskUnits', 'userSpaceOnUse')]: msk.set(k, v) use = inkex.etree.SubElement(msk,inkex.addNS('use','svg')) for k, v in [('id', 'Use_Eraser_' + idLayer), ('{http://www.w3.org/1999/xlink}href', "#EraserLayer_" + idLayer),('style',"filter:url(#Inverse_0001)")]: use.set(k, v) rct = inkex.etree.SubElement(msk,inkex.addNS('rect','svg')) for k, v in [('id', 'Background_' + idLayer), ('x', '-25000000'), ('y', '-25000000'), ('width', '50000000'), ('height', '50000000'), ('style', 'fill:#FFFFFF;fill-opacity:1')]: rct.set(k, v) ##crea el grupo contenedor que hara de borrador def createEraserLayer(self, layer,idLayer): container = etree.Element("g") container.set("id","ContainerEraserLayer_" + idLayer) container.set('style',"opacity:0.000000000000000000000000000000000000000000000001") container.set("{http://www.inkscape.org/namespaces/inkscape}groupmode","layer") container.set("{http://www.inkscape.org/namespaces/inkscape}label", "[container eraser] " + layer[0].get("{http://www.inkscape.org/namespaces/inkscape}label")) for position, item in enumerate(layer[0].getparent().getchildren()): if item == layer[0]: break; layer[0].getparent().insert(position+1,container) eraser = etree.Element("g") eraser.set("id","EraserLayer_" + idLayer) eraser.set('style',"filter:url(#Decolorize_0001)") eraser.set('transform',"rotate(360)") eraser.set("{http://www.inkscape.org/namespaces/inkscape}groupmode","layer") eraser.set("{http://www.inkscape.org/namespaces/inkscape}label", "[eraser] " + layer[0].get("{http://www.inkscape.org/namespaces/inkscape}label")) layer[0].set('mask',"url(#Eraser_" + idLayer + ")") selected = [] for id, node in self.selected.iteritems(): eraser.insert(1,node) container.insert(1,eraser) def effect(self): saveout = sys.stdout sys.stdout = sys.stderr svg = self.document.getroot() xpathStr = '//sodipodi:namedview' namedview = svg.xpath(xpathStr, namespaces=inkex.NSS) idLayer = namedview[0].get('{http://www.inkscape.org/namespaces/inkscape}current-layer'); if idLayer.startswith("[mask] ") == False and idLayer.startswith("[eraser] ") == False: xpathStr = '//svg:g[@id="EraserLayer_'+idLayer+'"]' filterElement = svg.xpath(xpathStr, namespaces=inkex.NSS) if filterElement == []: xpathStr = '//svg:g[@id="'+idLayer+'"]' layer = svg.xpath(xpathStr, namespaces=inkex.NSS) if layer[0] is not None and layer[0].get("{http://www.inkscape.org/namespaces/inkscape}label") is not None: self.insertFilter(svg) self.insertMask(idLayer, svg) self.createEraserLayer(layer,idLayer) else: print "Layer not found, Maybe insisde a group?" else: for id, node in self.selected.iteritems(): filterElement[0].insert(1,node) sys.stdout = saveout effect = EraserLayer() effect.affect()