Ejemplo n.º 1
0
    def fixUses(self, node, index):
        '''
    Fix <use> objects after transformation the objects their refer to
    '''

        # Go deep first
        for i in node:
            self.fixUses(i, index)

        # Is it a <use> tag?
        if node.tag == inkex.addNS("use", "svg"):
            # Get reference
            href = node.get(inkex.addNS('href', 'xlink'))
            if href[0] == "#":
                # Did we apply any transforms to the referred node?
                if href[1:] in index:
                    # Yes!
                    thatTr = index[href[1:]]
                    thisTr = SpeleoTransform.getTransform(node)
                    invThatTr = SpeleoTransform.invertTransform(thatTr)

                    # So, first transform of this <use> should be *reverting* that transform!
                    node.set(
                        "transform",
                        simpletransform.formatTransform(
                            simpletransform.composeTransform(
                                thisTr, invThatTr)))
Ejemplo n.º 2
0
    def effect(self):
        # Initialize symbol knowledge
        self.initSymbols()

        if self.options.replace:
            self.ensureSymbol(self.options.replace)

        symbol_ids = []
        # Go through all selected ...
        for id, obj in self.selected.iteritems():
            # Get unique symbol IDs
            symbol_ids.append(obj.get(inkex.addNS("href", "xlink")))

        # For all found distinct symbol IDs ...
        for link in set(symbol_ids):
            # Perhaps not a symbol?
            if link == None: continue

            if self.options.group:
                # Create a group
                group = inkex.etree.SubElement(
                    self.currentLayer(), "g",
                    {"style": "stroke:black; stroke-width: 0.28mm;"})

                # Compute corrective transform
                correctiveTransform = SpeleoTransform.invertTransform(
                    SpeleoTransform.getTotalTransform(group))
            else:
                # No group, no transform!
                group = None
                correctiveTransform = None

            # Look for our symbols!
            self.scanTree(self.document.getroot(), link, group,
                          correctiveTransform)
Ejemplo n.º 3
0
  def processTree(self, node):
    '''
    Recursively walk the SVG tree and randomize all rock/pebble symbols on the way
    '''
    
    # Is this a symbol reference?
    if node.tag == inkex.addNS('use', 'svg'):
      # Is this one of our rock/pebble symbols?
      m = re.match('#(gr|un|)?([ra])b([0-9]+)[a-z]', str(node.get(inkex.addNS("href", "xlink"))))
      if m:
        # Add translation, if present
        x = float(node.get("x"))
        y = float(node.get("y"))
        
        if x <> 0 or y <> 0:
          node.set("x", "0")
          node.set("y", "0")
          currentTr = node.get("transform")
          if currentTr == None: currentTr = ""
          node.set("transform", currentTr + (" translate(%.6f, %.6f) " % (x, y)))

        # Get current symbol transform
        tr = SpeleoTransform.getTotalTransform(node)
        
        # Move it back to 0,0 for rotation
        simpletransform.applyTransformToNode(SpeleoTransform.invertTransform(tr), node)

        # Select a new, random symbol ID (matching the symbol family)
        new_id = m.group(1) + m.group(2) + "b" + m.group(3) + random.choice("abcdefghij")
        
        # Make sure the new symbol type is with us
        if self.ensureSymbol(new_id):
          node.set(inkex.addNS("href", "xlink"), "#" + new_id)
          # If not, we just leave the type as it is.

        # Apply random rotation
        simpletransform.applyTransformToNode(simpletransform.parseTransform("rotate(" + str(random.randint(0, 359)) + ")"), node)
        
        # Return the symbol to where it was
        simpletransform.applyTransformToNode(tr, node)


    # For compatibility with old maps, using speleoUIS3
    if (node.tag == inkex.addNS('tspan', 'svg') or node.tag == inkex.addNS('text', 'svg')) and node.text:
      if len(node.text) == 1:
        if node.text in string.ascii_lowercase:
          node.text = random.choice(string.ascii_lowercase)
        elif node.text in string.ascii_uppercase:
          node.text = random.choice(string.ascii_uppercase)
        if (node.text in string.ascii_letters):
          node.set("rotate",  str(random.randint(0, 359)))

    # Recurse!
    for child in node:
      self.processTree(child);
Ejemplo n.º 4
0
    def makeLine(self, node, grp=None):
        if node.tag != inkex.addNS("path", "svg"):
            return False

        t = self.options.linetype

        if self.options.method == "patheffect":
            return self.makeLinePE(node)

        tr = SpeleoTransform.getTotalTransform(node.getparent())
        parent_scale = (tr[0][0] + tr[1][1]) / 2.0

        tr = SpeleoTransform.getTotalTransform(node)
        this_scale = (tr[0][0] + tr[1][1]) / 2.0

        docscale = self.getDocScale()
        fontsize = self.options.fontsize / parent_scale * 0.352778 * docscale
        linewidth = self.options.linewidth / this_scale * docscale
        fontstroke = self.options.fontstroke / parent_scale * docscale

        if t == 1:
            line_style = 'stroke:#000000;stroke-width:%.3fpx;fill:none' % linewidth
            text_style = 'font-size:%.3fpt' % fontsize
            text = self.char * 100
        elif t == 2:
            line_style = 'stroke:#000000;fill:none;stroke-width:0.5px;stroke-opacity:0.005'
            text_style = 'font-size:%.3fpx;stroke:#000000;stroke-width:%.3fpx' % (
                fontsize, fontstroke)
            text = self.char * 100

        node.set('style', line_style)
        tx = inkex.etree.Element('text', {"class": "speleoLine"})
        tp = inkex.etree.Element('textPath')
        tspan = inkex.etree.Element('tspan')

        tp.set(inkex.addNS('href', 'xlink'), '#' + node.get("id"))
        tspan.set(
            'style',
            'font-family:Speleo3;-inkscape-font-specification:Speleo3;' +
            text_style)
        tspan.text = text

        tp.append(tspan)
        tx.append(tp)

        if grp == None: grp = inkex.etree.SubElement(node.getparent(), "g")
        tx.set(inkex.addNS('insensitive', 'sodipodi'), 'true')
        grp.append(node)
        grp.append(tx)
        return True
Ejemplo n.º 5
0
    def effect(self):
        if self.options.mode == "unpack":
            # Unpack layers from a group

            # Get current layer
            root = self.currentLayer()

            # Are we in the root layer?
            invertedTransform = SpeleoTransform.invertTransform(
                SpeleoTransform.getTotalTransform(root))

            # Go through all selected layer containers
            for id, node in self.selected.iteritems():
                if node.tag != inkex.addNS('g', 'svg'): continue

                # Index of all applied transforms
                idIndex = {}

                # Transform the group
                self.processLayerContainer(node, root, invertedTransform,
                                           idIndex)

                # Fix references
                self.fixUses(root, idIndex)
        else:
            # Pack layers into group

            # What to pack?
            if self.options.pack == "root":
                root = self.getRoot()
            else:
                root = self.currentLayer()

            # Create a containter to pack the layers into
            self.box = inkex.etree.SubElement(self.document.getroot(), "g")

            # Pack all the layers!
            for child in root:
                self.packLayers(child, True)

        # Unmark any current layer setting
        view = self.xpathSingle('//sodipodi:namedview')
        if view <> None:
            current_layer = inkex.addNS('current-layer', 'inkscape')
            if current_layer in view.attrib:
                view.attrib.pop(current_layer)
Ejemplo n.º 6
0
    def getBox(self, obj):
        x = y = w = h = 0
        try:
            x = float(obj.get("x"))
            y = float(obj.get("y"))
        except:
            pass
        tr = SpeleoTransform.getTotalTransform(obj)
        (x, y) = SpeleoTransform.transformCoords((x, y), tr)

        if obj.tag == inkex.addNS("rect", "svg"):
            try:
                x2 = float(obj.get("x")) + float(obj.get("width"))
                y2 = float(obj.get("y")) + float(obj.get("height"))
                (x2, y2) = SpeleoTransform.transformCoords((x2, y2), tr)
                w = abs(x2 - x)
                h = abs(y2 - y)
            except:
                pass

        return (x, y, w, h)
Ejemplo n.º 7
0
    def getTransformed(self, x, y, src, dst, t, node=None):
        '''
    Transform local coordinates into new local coordinates
    '''
        # Compute absolute coordinates
        (gx, gy) = SpeleoTransform.transformCoords((x, y), t)

        # Compute new coordinates using transformation method of choice
        (nx, ny, angle) = self.transformCoordinates(gx, gy, src, dst)

        # If nothing changed, return old local coordinates
        if nx == gx and ny == gy and angle == 0: return (x, y)

        # ... so that we do not waste time on inverting transforms

        # See if we need to rotate a symbol...
        if angle <> 0 and node <> None:
            # Maybe it needs rotation!
            if node.tag == inkex.addNS("use", "svg") and self.options.rotate:
                name = node.get(inkex.addNS("href", "xlink"))[1:]
                if name in [
                        "gradient", "mini-gradient", "source", "sink", "water",
                        "draft", "paleoflow", "scallops", "gradarr",
                        "mini-gradarr"
                        "grgradient", "grmini-gradient", "grsource", "grsink",
                        "grwater", "grdraft", "grpaleoflow", "grscallops",
                        "gradarr", "mini-gradarr"
                ]:

                    #          simpletransform.applyTransformToNode(simpletransform.parseTransform("rotate(" + str(angle) + ")"), node)
                    node.set(
                        "transform",
                        node.get("transform") + " rotate(" + str(angle) + ")")
                    t = SpeleoTransform.getTotalTransform(node)

        # Invert transform
        it = SpeleoTransform.invertTransform(t)

        # Go back to local coordinate system
        return SpeleoTransform.transformCoords((nx, ny), it)
Ejemplo n.º 8
0
    def saveStation(self, marker, caption):
        '''
    Retrieve station data from SVG elements and store it
    '''

        # Get station name from the caption object
        name = self.getText(caption)

        # Perhaps it's not a station, but rather a prefix indication
        if name[:3] == "***":
            self.prefix = name[3:]
            return 1

        # Get absolute marker coordinates
        coords = SpeleoTransform.transformCoords(
            (float(marker.get("x")), float(marker.get("y"))),
            SpeleoTransform.getTotalTransform(marker))
        self.log("Station %s has coordinates %.2f, %.2f" %
                 (name, coords[0], coords[1]))

        # Save the station
        self.dict[name] = coords
        return True
Ejemplo n.º 9
0
    def scanTree(self, node, sel, group, correctiveTransform):
        '''
    Recursively look for <use>s referring to symbol sel
    
    Adds all these symbols to group 'group', applying transforms accordingly
    '''

        # Avoid too much recursion
        if node == group: return

        # Do not go into invisible layers
        if self.isLayer(node):
            if self.hasDisplayNone(node):
                return

        # Recurse first
        for i in node:
            self.scanTree(i, sel, group, correctiveTransform)

        # See if it's the symbol we need
        href = node.get(inkex.addNS('href', 'xlink'))

        # Perhaps not a reference at all...
        if href == None: return

        # Is this the right symbol?
        if href == sel:
            # Move to our group
            if group <> None:
                # Get total transform of this symbol
                transform = SpeleoTransform.getTotalTransform(node)

                # Group it together with others
                group.append(node)

                # Reset this node transform
                node.set(
                    "transform",
                    simpletransform.formatTransform(
                        simpletransform.composeTransform(
                            correctiveTransform, transform)))

            # Did anyone order a replace?
            if self.options.replace:
                node.set(inkex.addNS('href', 'xlink'),
                         '#' + self.options.replace)
Ejemplo n.º 10
0
    def makeLinePE(self, node):
        if node.tag != inkex.addNS("path", "svg"):
            return False

        docscale = self.getDocScale()

        if len(node.get(inkex.addNS("original-d", "inkscape"), "")) == 0:
            node.set(inkex.addNS("original-d", "inkscape"), node.get("d"))
            self.removeAttrib(node, inkex.addNS("d", "svg"))

        node.set(
            inkex.addNS("path-effect", "inkscape"), "#caveink-step-effect"
            if self.options.char < 4 else "#caveink-drip-effect")

        tr = SpeleoTransform.getTotalTransform(node)
        this_scale = (tr[0][0] + tr[1][1]) / 2.0
        linewidth = self.options.linewidth / this_scale * docscale
        line_style = 'stroke:#000000;stroke-width:%.3fpx;fill:none' % linewidth
        node.set('style', line_style)
Ejemplo n.º 11
0
    def processLayerContainer(self, node, root, invertedRootTransform,
                              idIndex):
        '''
    Unpack layers contained in a layer container.
    
    Does some preparations, and then recursively calls unpackLayers()
    '''

        # The group might have been transformed
        thisTransform = SpeleoTransform.getTotalTransform(node)

        # Account for any transforms our target layer can possibly have
        thisTransform = simpletransform.composeTransform(
            invertedRootTransform, thisTransform)

        # Process children - should all be layers in fact!
        for child in node:
            # Apply transforms and change groupping mode
            self.unpackLayers(child, thisTransform, idIndex)
            # Move to our root
            root.append(child)

        # Delete the container
        node.getparent().remove(node)
Ejemplo n.º 12
0
    def drawGrid(self, x_center, y_center, doc_w, doc_h, pos_x=0, pos_y=0):

        if self.options.coords == "rotate":
            rot = " rotate(270)"
        else:
            rot = ""

        x_center -= pos_x
        y_center -= pos_y

        uufactor = self.getDocScale()

        uu_spacing = self.options.spacing / self.options.scale * 1000.0 * uufactor

        x_start = x_center - math.floor(x_center / uu_spacing) * uu_spacing
        y_start = y_center - math.floor(y_center / uu_spacing) * uu_spacing
        num_x = int(math.ceil(doc_w / uu_spacing))
        num_y = int(math.ceil(doc_h / uu_spacing))

        layer = self.currentLayer()

        g = inkex.etree.SubElement(layer, 'g')

        # Invert any sub-transforms of layer
        simpletransform.applyTransformToNode(
            SpeleoTransform.invertTransform(
                SpeleoTransform.getTotalTransform(g)), g)

        # Add translation
        simpletransform.applyTransformToNode(
            simpletransform.parseTransform("translate(%.6f, %.6f)" %
                                           (pos_x, pos_y)), g)

        if self.options.coords != "none":
            g.set(
                'style', 'stroke:#888;fill:#888;stroke-width:' +
                str(uufactor * 0.2) + 'px;font-size:' +
                str(self.options.fontsize * uufactor * 0.352778) +
                'px;text-anchor:end;text-align:end')

            cg = inkex.etree.SubElement(g, "g")
            g = inkex.etree.SubElement(g, "g")

            g.set('style', 'fill:none;')
            cg.set('style', 'stroke:none;stroke-width:0')
        else:
            g.set('style',
                  'stroke:#888;fill:none;stroke-width:' + str(uufactor * 0.2))

        # Vertical lines and coordinates
        for x in range(0, num_x):
            x = x_start + x * uu_spacing
            if x > doc_w: break

            if self.options.type == "line":
                l = inkex.etree.SubElement(g, 'path')
                l.set('d', 'M ' + str(x) + ",0 L " + str(x) + "," + str(doc_h))

            if self.options.coords != "none":
                l = inkex.etree.SubElement(cg, 'text')
                l.text = str(
                    int(
                        round((x - x_center) / uu_spacing *
                              self.options.spacing) +
                        self.options.origin_x)) + self.options.units
                l.set("style", "text-anchor:end;text-align:end")
                l.set("transform", ("translate(%.2f,%.2f)" + rot) %
                      (x - 1.4 * uufactor, 4.2 * uufactor))

        # Horizontal lines and coordinates
        for y in range(0, num_y):
            y = y_start + y * uu_spacing
            if y > doc_h: break

            if self.options.type == "line":
                l = inkex.etree.SubElement(g, 'path')
                l.set('d', 'M 0,' + str(y) + " L " + str(doc_w) + "," + str(y))

            if self.options.coords != "none":
                l = inkex.etree.SubElement(cg, 'text')
                l.text = str(
                    int(-round(
                        (y - y_center) / uu_spacing * self.options.spacing) +
                        self.options.origin_y)) + self.options.units
                l.set("style", "text-anchor:end;text-align:end")
                l.set(
                    "transform", "translate(%.2f,%.2f)" %
                    (12.7 * uufactor, y - 1.4 * uufactor))

        # Crosses, if requested
        if self.options.type == "cross":
            l = inkex.etree.SubElement(g, 'path')
            path_id = self.uniqueId("gridCross", True)
            l.set('d', "M -10,0 10,0 M 0,-10 0,10")
            l.set("transform", "translate(%.2f, %.2f)" % (x_center, y_center))
            l.set("id", path_id)

            for x in range(0, num_x):
                x_doc = x_start + x * uu_spacing - x_center
                if x_doc > doc_w: break

                for y in range(0, num_y):
                    if x == 0 and y == 0: continue

                    y_doc = y_start + y * uu_spacing - y_center
                    if y_doc > doc_h: break

                    l = inkex.etree.SubElement(g, 'use')
                    l.set(inkex.addNS('href', 'xlink'), '#' + str(path_id))
                    l.set("transform", "translate(%.2f,%.2f)" % (x_doc, y_doc))
Ejemplo n.º 13
0
    def rectify(self, src, dst, node, centerline):
        '''
    Recursively transform objects from old to new centerline
    '''
        # Skip invisible layers
        if self.hasDisplayNone(node): return

        # Skip layers with centerlines and the defs object
        if node == centerline: return
        if node == self.dst: return
        if node.tag == inkex.addNS('defs', 'svg'): return

        # If it's a path ...
        if node.tag == inkex.addNS('path', 'svg'):
            # Parse path data
            path = simplepath.parsePath(node.get("d"))

            # Get absolute transform
            tr = SpeleoTransform.getTotalTransform(node)

            # Rectify the path
            self.rectifyPath(path, src, dst, tr)

            # Re-set path data
            node.set("d", simplepath.formatPath(path))

            # Remove attributes that break our efforts
            # TODO not really compatible now with our modern dripline / step generating code
            self.removeAttrib(node, inkex.addNS("path-effect", "inkscape"))
            self.removeAttrib(node, inkex.addNS("original-d", "inkscape"))
            self.removeAttrib(node, inkex.addNS("type", "sodipodi"))

            return
        elif node.get("x") <> None and node.tag == inkex.addNS("use", "svg"):

            # Convert use coordinates to a transform
            #      node.set("transform", node.get("transform") + " translate(" + node.get('x') + "," + node.get('y') + ")")
            #simpletransform.applyTransformToNode(simpletransform.parseTransform("translate(" + node.get('x') + "," + node.get('y') + ")"), node)

            # Handle symbols
            tr = SpeleoTransform.getTotalTransform(node)

            # Convert and set new coordinates
            (x, y) = self.getTransformed(float(node.get("x")),
                                         float(node.get("y")), src, dst, tr,
                                         node)

            node.set("x", str(x))
            node.set("y", str(y))
        elif node.get("x") <> None:
            # Generic handler for nodes having x & y coordinates
            tr = SpeleoTransform.getTotalTransform(node)

            # Convert and set new coordinates
            (x, y) = self.getTransformed(float(node.get("x")),
                                         float(node.get("y")), src, dst, tr,
                                         node)

            node.set("x", str(x))
            node.set("y", str(y))
        elif node.get("cx") <> None:
            # Generic handler for nodes having x & y coordinates as cx/cy
            tr = SpeleoTransform.getTotalTransform(node)

            # Convert and set new coordinates
            (x, y) = self.getTransformed(float(node.get("cx")),
                                         float(node.get("cy")), src, dst, tr)
            node.set("cx", str(x))
            node.set("cy", str(y))

        # Go deeper
        for child in node.getchildren():
            self.rectify(src, dst, child, centerline)