Exemplo n.º 1
0
    def simplifyNodes(self, nodes):
        '''remove v, V, h, and H command'''
        point = []
        for node in nodes:
            node.showCommand = True
            characterCount = Node.getCharacterCount(node.command)
            if characterCount > 1:
                point = node.getTarget()
            elif characterCount == 1:
                if node.command == "v":
                    point[0] = "0"
                    point[1] = node.attrib[0]
                elif node.command == "V":
                    point[1] = node.attrib[0]
                elif node.command == "h":
                    point[0] = node.attrib[0]
                    point[1] = "0"
                elif node.command == "H":
                    point[0] = node.attrib[0]
                    
                if node.command == "v" or node.command == "h":
                    node.command = "l"
                elif node.command == "V" or node.command == "H":
                    node.command = "L"
                    
#                node.showCommand = True
                node.attrib = [ point[0],  point[1] ]
Exemplo n.º 2
0
    def build_path(self, svg, camera, entity, options):
        '''Special progressive drawing of a path element.
        The path will be included one bezier element at a time until whole.'''
        if not 'd' in entity.attrib: return
        id = entity.attrib['id']
        name = id
        print '%05d - Building up <%s id="%s"> (%s)...' % (camera.time, entity.tag, id, name)
        # replace style with our own style
        style = ''
        if 'style' in entity.attrib:
            style = entity.attrib['style']
        width = (camera.area[3]-camera.area[1]) / float(camera.height)
        if self.options['page']:
            page_width = float(svg.root.attrib['width'])
            page_height = float(svg.root.attrib['height'])
            if page_width > page_height:
                width = page_width / page_height
            else:
                width = page_height / page_width
        
        style_dict = {}
        style_list = style.split(';')
        for s in style_list:
            w = s.split(':')
            if len(w) > 1:
                style_dict[w[0]] = w[1]
        
#        print ';'.join("%s:%r" % (key,val) for (key,val) in style_dict.iteritems())
        
        hl = {
              'opacity': '1', 
              'overflow': 'visible', 
              'fill-opacity': '0',
              'fill-rule': 'nonzero',
              'stroke-linecap': 'round',
              'stroke-linejoin': 'round',
              'marker': 'none',
              'marker-start': 'none',
              'marker-mid': 'none',
              'marker-end': 'none',
              'stroke-miterlimit': '4',
              'stroke-dasharray': 'none',
              'stroke-dashoffset': '0',
              'stroke-opacity': '1',
              'visibility': 'visible',
              'display': 'inline',
              'enable-background': 'accumulate', 
              'stroke-width': '%f' % width
              }
              
        if self.options['objectline']:
            if 'line' in style_dict:
                hl['stroke'] = style_dict['line']
            else:
#                hl['stroke'] = '#000000'
                hl['stroke'] = self.options['line']
        else:
            hl['stroke'] = self.options['line']

        if self.options['fullpath']:
#            hl.append('marker-end:url(#%s)' % self.marker)
            hl['marker-end'] = 'url(#%s)' % self.marker
            #~ hl.append('marker-start:url(#Arrow1Lstart)')
            #~ hl[12] = 'marker-end:url(#SquareL)'
#        else:
#            hl.append('marker-end:none')
            #~ hl.append('marker-start:none')
            
        if self.options['fillpath']:
#            hl.append('marker-end:url(#%s)' % self.marker)
            hl['fill-opacity'] = '1'
            
        '''hl = [
        'opacity:1', 'overflow:visible',
        'fill:none',
        'fill-opacity:0.',
        'fill-rule:nonzero',
        'stroke:%s' % self.options['line'],
        'stroke-width:%f' % width,
        'stroke-linecap:round', 'stroke-linejoin:round',
        'marker:none',
        'marker-start:none',
        'marker-mid:none',
        #~ 'marker-end:none',
        'stroke-miterlimit:4', 'stroke-dasharray:none',
        'stroke-dashoffset:0', 'stroke-opacity:1',
        'visibility:visible', 'display:inline',
        'enable-background:accumulate' 
        ]'''
        
        
#        hairline = ';'.join(hl)
        hairline = ';'.join("%s:%s" % (key,val) for (key,val) in hl.iteritems())
        #~ print hairline

        entity.attrib['style'] = hairline
        # scan the control points
        points = entity.attrib['d'].split(' ')
        
        d = entity.attrib['d'].strip()
        d = d.replace('z',  'Z').replace(',',  ' ')
        d = re.sub(r'([a-zA-Z])([0-9])', r'\1 ', d)
        
        paths = re.findall('[^Z]+Z', d)
        if len(paths) == 0:
            paths = d.split('Z')
        
        built = [ ]
        tempBuilt = [ ]
        pathLastNode = None
        
        # each control point is a letter, followed by some floating-point pairs
        for pathIndex, path in enumerate(paths):
            if len(path) == 0:
                continue
                
            nodes = []
            command = ""
            point = ""
            characterCount = 0
            showCommand = False
            
            points = path.strip().split(' ')
            pointsCount = len(points)

            node = None
            while points:
                if not self.isRunning: return
                
                point = points[0]
                
                node = Node()
                attrib = []
                if re.match(r'^[a-zA-Z]$', point):
                    command = point
                    showCommand = True
                    characterCount = Node.getCharacterCount(command)
                    points.pop(0)
                else:
                    '''avoid sequential M or m command'''
                    if command == "M":
                        command = "L"
                    elif command == "m":
                        command = "l"
                    showCommand = False
            
                for j in range(0, characterCount):
                    if len(points) > 0:
                        attrib.append(points.pop(0))

                node.command = command
                node.attrib = attrib
                node.showCommand = showCommand
                
                nodes.append(node)
            
            #self.simplifyNodes(nodes)
            leftPath = []
            rightPath = []
            
            closedPath = False
            node = nodes[-1]
            lastNode = None
            if node.command == "Z":
                closedPath = True
                
                firstNode = nodes[0]
                n = Node()
                
                '''force first node of each path to absolute command'''
                if pathIndex > 0 and firstNode.command.islower():
                        firstNode.command = firstNode.command.upper()
                        lastCoordinate = pathLastNode.getTarget()
                        firstNode.attrib = [ str(float(lastCoordinate[0]) + float(firstNode.attrib[0])),  str(float(lastCoordinate[1]) + float(firstNode.attrib[1])) ]
                
                n.attrib = firstNode.getTarget()
                n.showCommand = True
                n.command = "L"
                    
                nodes.insert(-1,  n)
                pathLastNode = n
                lastNode = nodes.pop()
            
            if self.options['circlepath']:
                tempBuilt = built[:]
                
            index = 0
            while nodes:
                if not self.isRunning: return
                
                if not self.options['fullpath']:
#                    node = nodes.pop(0)
#                    built.append(node.getValue())
#                        built.append( points.pop(0) )
#                    while nodes and not re.match(r'^[a-zA-Z]$', nodes[0].showCommand):
                    command = nodes[0].command
                    while nodes:
                        node = nodes.pop(0)
#                        print node.getValue()
                        built.append(node.getValue())
                        
                        if node.command.lower() != command.lower():
                            break
                        
                else:
                    if self.options['circlepath'] and closedPath:
                        if len(nodes) > 0:
                            node = nodes.pop(0)
                            leftPath.append(node)
                        if len(nodes) > 0:
                            node = nodes.pop()
                            rightPath.insert(0, node)
                        
                        cleanPath = []
                        for node in nodes:
                            n = Node()
                            if node.command.islower():
                                n.command = "m"
                            else:
                                n.command = "M"
                            
                            n.showCommand = True
                            n.attrib = node.attrib[-2:]
                            cleanPath.append(n)
                            
                        if self.options['closepath']:
                            currentPoint = ["0", "0"]
                            absolutePath = False
                            for node in cleanPath:
                                if node.command.islower():
                                    currentPoint[0] = str(float(currentPoint[0]) + float(node.attrib[0]))
                                    currentPoint[1] = str(float(currentPoint[1]) + float(node.attrib[1]))
                                else:
                                    absolutePath = True
                                    currentPoint[0] = node.attrib[0]
                                    currentPoint[1] = node.attrib[1]
                                    
                            node = Node()
                            node.showCommand = True
                            node.command = "L" if absolutePath else "l"
                            node.attrib = currentPoint
                            
                            cleanPath = []
                            cleanPath.append(node)
                            
                        buildNodes = leftPath + cleanPath + rightPath
                        
                        built = []
                        for node in buildNodes:
                            built.append(node.getValue())
#                        print ' '.join(built)
                        built = tempBuilt + built
                    else:
                        node = nodes.pop(0)
                        built.append(node.getValue())
                        
                entity.attrib['d'] = ' '.join(built)
                camera.shoot(svg)
            
            '''if closedPath:
                built.append(lastNode.getValue())
                entity.attrib['d'] = ' '.join(built)
                camera.shoot(svg)'''
                
        # put the original style back
        entity.attrib['style'] = style
        camera.shoot(svg)