Exemple #1
0
 def __init__(self,width=100.0,height=100.0,*args,**kw):
     Drawing.__init__(self,width,height,*args,**kw)
     self.transform = (1,0,0,1,0,0)
     v0=self._nn(Group())
     v0.transform = (1,0,0,-1,0,100)
     v0.add(Path(points=[30,1,70,1,99,30,99,70,70,99,30,99,1,70,1,30],operators=[0,1,1,1,1,1,1,1,3],isClipPath=0,autoclose='svg',fillMode=1,strokeDashArray=None,strokeWidth=1,strokeMiterLimit=0,strokeOpacity=None,strokeLineJoin=0,fillOpacity=1,strokeColor=Color(0,0,0,1),strokeLineCap=0,fillColor=Color(0,0,0,1)))
     v0.add(Path(points=[31,3,69,3,97,31,97,69,69,97,31,97,3,69,3,31],operators=[0,1,1,1,1,1,1,1,3],isClipPath=0,autoclose='svg',fillMode=1,strokeDashArray=None,strokeWidth=1,strokeMiterLimit=0,strokeOpacity=None,strokeLineJoin=0,fillOpacity=1,strokeColor=None,strokeLineCap=0,fillColor=Color(.666667,.133333,.2,1)))
     v1=v0._nn(Group())
     v1.transform = (1,0,0,-1,0,136)
     v1.add(String(50,68,u'410',textAnchor=u'middle',fontName='Helvetica',fontSize=48,fillColor=Color(1,1,1,1)))
Exemple #2
0
 def __init__(self, width=100.0, height=100.0, autoclose='', *args, **kw):
     Drawing.__init__(self, width, height, *args, **kw)
     self.transform = (1, 0, 0, 1, 0, 0)
     v0 = self._nn(Group())
     v0.transform = (1, 0, 0, -1, 0, 100)
     v1 = v0._nn(Group())
     v1.transform = (1, 0, 0, -1, 0, 100)
     v1.add(
         Path(points=[
             10, 10, 10, 90, 20, 90, 20, 10, 30, 10, 30, 90, 40, 90, 40, 10,
             50, 10, 50, 90, 60, 90, 60, 10, 70, 10, 70, 90, 80, 90, 80, 10
         ],
              operators=[
                  0, 1, 1, 1, 3, 0, 1, 1, 1, 0, 1, 1, 1, 3, 0, 1, 1, 1
              ],
              isClipPath=0,
              autoclose=autoclose,
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=2,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillOpacity=1,
              strokeColor=Color(1, 0, 0, 1),
              strokeLineCap=0,
              fillColor=Color(0, 0, 1, 1)))
Exemple #3
0
def generate_pic(glyphname, font: TTFont, size=120, scale=0.1):
    """
    生成图片 -> 预处理 -> 保存到本地
    Args:
        glyphname:
        font:
        file_suffix:
        size:
        scale:

    Returns:

    """

    gs = font.getGlyphSet()
    pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=1))
    g = gs[glyphname]
    g.draw(pen)

    w, h = size, size

    # Everything is wrapped in a group to allow transformations.
    g = Group(pen.path)
    # g.translate(10, 20)
    g.scale(scale, scale)

    d = Drawing(w, h)
    d.add(g)

    return renderPM.drawToPIL(d)
Exemple #4
0
def img_save():
    img_path = PATH.rsplit('.', 1)[0]
    font = TTFont(
        PATH)  # it would work just as well with fontTools.t1Lib.T1Font
    glyf = font['glyf']
    if not os.path.exists(img_path):
        os.makedirs(img_path)
    for glyphName in glyf.keys():
        gs = font.getGlyphSet()
        pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=1))
        g = gs[glyphName]
        g.draw(pen)
        # 调整图片大小
        w, h = 800, 800
        g = Group(pen.path)
        g.translate(10, 200)
        g.scale(0.3, 0.3)

        d = Drawing(w, h)
        d.add(g)

        image = renderPM.drawToPIL(d)
        little_image = image.resize((180, 180))
        fromImage = Image.new('RGBA', (360, 360), color=(255, 255, 255))
        fromImage.paste(little_image, (0, 0))
        # fromImage.show()
        glyphName = glyphName.replace('uni', '&#x')
        imageFile = img_path + "/%s.png" % glyphName
        fromImage.save(imageFile)
        break
Exemple #5
0
 def ttf_to_image(self):
     """
     将ttf字体文件的字体绘制在Image对象上
     :return:
     """
     glyphset = self.font.getGlyphSet()
     size = (BASE_BACKGOUND_WIDTH * FONT_NUMS_PER_LINE,
             ceil(len(self.glyphnames) / FONT_NUMS_PER_LINE) * BASE_BACKGOUND_HEIGHT)  # 背景图片尺寸
     image = Image.new("RGB", size=size, color=(255, 255, 255))  # 初始化背景图片
     name_list, image_dict = [], {}
     for index, glyphname in enumerate(self.glyphnames):
         if glyphname[0] in ['.', 'g'] or glyphname in self.ignore_names:  # 跳过'.notdef', '.null'
             continue
         g = glyphset[glyphname]
         pen = ReportLabPen(self.glyphnames, Path(fillColor=colors.black, strokeWidth=1))
         g.draw(pen)
         # w, h = g.width, g.width
         w, h = g.width if g.width > 1000 else 1000, g.width if g.width > 1000 else 1000
         g = Group(pen.path)
         g.translate(0, 200)
         d = Drawing(w, h)
         d.add(g)
         im = renderPM.drawToPIL(d, dpi=72).resize((FONT_WIDTH, FONT_HEIGHT))
         box = (
             (index % FONT_NUMS_PER_LINE) * BASE_BACKGOUND_WIDTH,
             (index // FONT_NUMS_PER_LINE) * BASE_BACKGOUND_HEIGHT)
         image.paste(im, box=box)
         name_list.append(glyphname)
         image_dict[glyphname] = im
     return image, name_list, image_dict
Exemple #6
0
 def getProperties(self, *args, **kwargs):
     # __getattribute__ wouldn't suit, as RL is directly accessing self.__dict__
     props = Path.getProperties(self, *args, **kwargs)
     if 'strokeWidth' in props:
         props['strokeWidth'] = 0
     if 'strokeColor' in props:
         props['strokeColor'] = None
     return props
Exemple #7
0
def pdfpath(pdf='', **kwds):
    if pdf:
        pdf = pdf.strip()
    if pdf:
        p = definePath(pathSegs=list(_getSegs(pdf.split())), **kwds)
    else:
        p = Path(**kwds)
    return p
Exemple #8
0
 def test_stroke(self):
     converter = svglib.Svg2RlgShapeConverter(None)
     node = etree.XML('<path d="m0,6.5h27m0,5H0" stroke="#FFF" stroke-opacity="0.5"/>')
     path = Path()
     converter.applyStyleOnShape(path, node)
     assert path.strokeColor == colors.white
     assert path.strokeOpacity == 0.5
     assert path.strokeWidth == 1
Exemple #9
0
 def getProperties(self, *args, **kwargs):
     # __getattribute__ wouldn't suit, as RL is directly accessing self.__dict__
     props = Path.getProperties(self, *args, **kwargs)
     if 'strokeWidth' in props:
         props['strokeWidth'] = 0
     if 'strokeColor' in props:
         props['strokeColor'] = None
     return props
Exemple #10
0
    def one_to_image(self, glyph_name):
        glyphset = self.font.getGlyphSet()
        try:
            glyph = glyphset[glyph_name]
        except KeyError as e:
            raise KeyError("{} dont't in {}".format(glyph_name,
                                                    self.font_file_name))

        pen = ReportLabPen(self.glyphnames,
                           Path(fillColor=colors.black, strokeWidth=1))
        glyph.draw(pen)
        w, h = glyph.width if glyph.width > 1000 else 1000, glyph.width if glyph.width > 1000 else 1000
        d = Drawing(w, h)
        g = Group(pen.path)
        g.translate(0, 150)
        d.add(g)
        im = renderPM.drawToPIL(d, dpi=72).resize((FONT_WIDTH, FONT_HEIGHT))
        return im
    def draw_one(self, unicode, font_io):
        ttf_font = TTFont(font_io)
        glyphSet = ttf_font.getGlyphSet()
        if unicode not in glyphSet:
            return None
        glyph = glyphSet[unicode]
        pen = reportLabPen.ReportLabPen(
            glyphSet, Path(fillColor=colors.black, strokeWidth=1))
        glyph.draw(pen)

        w, h = glyph.width, glyph._glyph.yMax - glyph._glyph.yMin
        yOffset = -glyph._glyph.yMin * \
                  self.font_scale + h * (1 - self.font_scale) / 2
        glyph = Group(pen.path)
        glyph.translate(w * (1 - self.font_scale) / 2, yOffset)
        glyph.scale(self.font_scale, self.font_scale)
        draw = Drawing(w, h)
        draw.add(glyph)
        PIL_image = renderPM.drawToPIL(draw)
        return PIL_image
Exemple #12
0
def ttfToImage(fontName, imagePath, fmt="png"):
    font = TTFont(fontName)
    gs = font.getGlyphSet()
    glyphNames = font.getGlyphNames()
    for i in glyphNames:
        if i[0] == '.':  #Ìø¹ý'.notdef', '.null'
            continue

        g = gs[i]
        pen = ReportLabPen(gs, Path(fillColor=colors.red, strokeWidth=5))
        g.draw(pen)
        w, h = g.width, g.width
        g = Group(pen.path)
        g.translate(0, 200)

        d = Drawing(w, h)
        d.add(g)
        imageFile = imagePath + "/" + i + ".png"
        renderPM.drawToFile(d, imageFile, fmt)

        print(i)
Exemple #13
0
    def _draw(self):
        """
        :param font_path: 下载的web 字体所在目录
        :param image_path: 转换为image后所在目录
        :return:返回font 对应的编码列表

        """
        import os
        import shutil

        shutil.rmtree(os.path.join(os.path.abspath('.'), "web_font",
                                   "image"))  # 能删除该文件夹和文件夹下所有文件
        os.mkdir(os.path.join(os.path.abspath('.'), "web_font", "image"))
        from fontTools.ttLib import TTFont
        from reportlab.lib import colors
        font = TTFont(
            os.path.join(os.path.abspath('.'), "web_font", "stonefont.woff")
        )  # it would work just as well with fontTools.t1Lib.T1Font
        gs = font.getGlyphSet()
        w, h = 40, 40
        keys = gs.keys()[2:]
        for glyphName in keys:
            pen = FontPen(gs, Path(fillColor=colors.red, strokeWidth=0.01))
            imageFile = "%s.png" % glyphName
            g = gs[glyphName]
            g.draw(pen)
            from reportlab.graphics import renderPM
            from reportlab.graphics.shapes import Group, Drawing

            g = Group(pen.path)
            g.translate(10, 13)
            g.scale(0.02, 0.02)
            d = Drawing(w, h)
            d.add(g)
            renderPM.drawToFile(d,
                                os.path.join(os.path.abspath('.'), "web_font",
                                             "image", imageFile),
                                fmt="PNG",
                                dpi=100)
        return keys
Exemple #14
0
def ttfToImage(fontName, imagePath, fmt="png"):
    font = TTFont(fontName)
    gs = font.getGlyphSet()
    glyphNames = font.getGlyphNames()

    m_dict = font.getBestCmap()

    unicode_list = []
    gs_key=[]
    for key, value in m_dict.items():
        unicode_list.append(key)
        gs_key.append(value)
    char_list = [chr(ch_unicode) for ch_unicode in unicode_list]
    #2500-29000 FZSONG_ZhongHuaSongPlane00_2021120120211201171438.ttf
    # 275 FZSONG_ZhongHuaSongPlane02_2021120120211201171459.ttf

    for i in range(len(char_list)):
        if fontName=='FZSONG_ZhongHuaSongPlane00_2021120120211201171438.ttf' and (i<2500 or i>29000):
            continue
        if fontName=='FZSONG_ZhongHuaSongPlane02_2021120120211201171459.ttf' and (i<275 or i>100000000):
            continue
        thechr=char_list[i]
        print(thechr)
        gs_ind=gs_key[i]
        if gs_ind[0] == '.':  # 跳过'.notdef', '.null'
            continue
        g = gs[gs_ind]
        pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=5))
        g.draw(pen)
        w, h = g.width, g.width
        # w = 4048
        # h = 4048
        g = Group(pen.path)
        g.translate(0, 170)

        d = Drawing(w, h)
        d.add(g)
        imageFile = imagePath + "/" + thechr + ".png"
        renderPM.drawToFile(d, imageFile, fmt)
    def draw_all(self, font_io):
        ttf_font = TTFont(font_io)
        glyphSet = ttf_font.getGlyphSet()
        font_image_dict = {}
        for glyphName in glyphSet.keys():
            if (not glyphName.startswith('uni')):
                continue
            pen = reportLabPen.ReportLabPen(
                glyphSet, Path(fillColor=colors.black, strokeWidth=1))
            glyph = glyphSet[glyphName]
            glyph.draw(pen)

            w, h = glyph.width, glyph._glyph.yMax - glyph._glyph.yMin
            yOffset = -glyph._glyph.yMin * \
                      self.font_scale + h * (1 - self.font_scale) / 2
            glyph = Group(pen.path)
            glyph.translate(w * (1 - self.font_scale) / 2, yOffset)
            glyph.scale(self.font_scale, self.font_scale)
            draw = Drawing(w, h)
            draw.add(glyph)
            PIL_image = renderPM.drawToPIL(draw)
            font_image_dict[glyphName] = PIL_image
        return font_image_dict
Exemple #16
0
    def draw(self, dx=5, dy=300, auto_width=500, auto_height=500):
        """
        绘图操作
        :param dx: 图片绘图位置
        :param dy:  图片绘图位置
        :param auto_width: 自适应图片宽度(调节字体)
        :param auto_height: 自适应图片高度(调节字体)
        :return:
        """

        def reverse_dict(data: dict):
            out = {}
            for k, v in data.items():
                out[str(v)] = str(k)

            return out

        font = TTFont(self.fontName)
        img_dict = font['cmap'].tables[2].ttFont.tables['cmap'].tables[1].cmap
        img_dict = reverse_dict(img_dict)
        gs = font.getGlyphSet()
        glyphNames = font.getGlyphNames()
        for i in glyphNames:
            name = self.key(img_dict.get(i))
            if name == None:
                continue
            g = gs[i]
            pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=10))
            g.draw(pen)
            w, h = g.width, g.width
            g = Group(pen.path)
            g.translate(dx, dy)
            d = Drawing(w + auto_width, h + auto_height)
            d.add(g)
            imageFile = self.imagePath + "/" + str(name) + "." + self.fmt
            renderPM.drawToFile(d, imageFile, self.fmt)
Exemple #17
0
    def convertPath(self, node):
        d = node.getAttribute('d')
        if not d:
            return None
        normPath = normalise_svg_path(d)
        path = Path()
        points = path.points
        # Track subpaths needing to be closed later
        unclosed_subpath_pointers = []
        subpath_start = []
        lastop = ''

        for i in range(0, len(normPath), 2):
            op, nums = normPath[i:i+2]

            if op in ('m', 'M') and i > 0 and path.operators[-1] != _CLOSEPATH:
                unclosed_subpath_pointers.append(len(path.operators))

            # moveto absolute
            if op == 'M':
                path.moveTo(*nums)
                subpath_start = points[-2:]
            # lineto absolute
            elif op == 'L':
                path.lineTo(*nums)

            # moveto relative
            elif op == 'm':
                if len(points) >= 2:
                    if lastop in ('Z', 'z'):
                        starting_point = subpath_start
                    else:
                        starting_point = points[-2:]
                    xn, yn = starting_point[0] + nums[0], starting_point[1] + nums[1]
                    path.moveTo(xn, yn)
                else:
                    path.moveTo(*nums)
                subpath_start = points[-2:]
            # lineto relative
            elif op == 'l':
                xn, yn = points[-2] + nums[0], points[-1] + nums[1]
                path.lineTo(xn, yn)

            # horizontal/vertical line absolute
            elif op == 'H':
                path.lineTo(nums[0], points[-1])
            elif op == 'V':
                path.lineTo(points[-2], nums[0])

            # horizontal/vertical line relative
            elif op == 'h':
                path.lineTo(points[-2] + nums[0], points[-1])
            elif op == 'v':
                path.lineTo(points[-2], points[-1] + nums[0])

            # cubic bezier, absolute
            elif op == 'C':
                path.curveTo(*nums)
            elif op == 'S':
                x2, y2, xn, yn = nums
                if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                path.curveTo(xi, yi, x2, y2, xn, yn)

            # cubic bezier, relative
            elif op == 'c':
                xp, yp = points[-2:]
                x1, y1, x2, y2, xn, yn = nums
                path.curveTo(xp + x1, yp + y1, xp + x2, yp + y2, xp + xn, yp + yn)
            elif op == 's':
                x2, y2, xn, yn = nums
                if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                path.curveTo(xi, yi, x0 + x2, y0 + y2, x0 + xn, y0 + yn)

            # quadratic bezier, absolute
            elif op == 'Q':
                x0, y0 = points[-2:]
                x1, y1, xn, yn = nums
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)
            elif op == 'T':
                if len(points) < 4:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                xn, yn = nums
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)

            # quadratic bezier, relative
            elif op == 'q':
                x0, y0 = points[-2:]
                x1, y1, xn, yn = nums
                x1, y1, xn, yn = x0 + x1, y0 + y1, x0 + xn, y0 + yn
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)
            elif op == 't':
                if len(points) < 4:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                x0, y0 = points[-2:]
                xn, yn = nums
                xn, yn = x0 + xn, y0 + yn
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)

            # elliptical arc
            elif op in ('A', 'a'):
                rx, ry, phi, fA, fS, x2, y2 = nums
                x1, y1 = points[-2:]
                if op == 'a':
                    x2 += x1
                    y2 += y1
                if abs(rx) <= 1e-10 or abs(ry) <= 1e-10:
                    path.lineTo(x2, y2)
                else:
                    bp = bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA, fS, x2, y2)
                    for _, _, x1, y1, x2, y2, xn, yn in bp:
                        path.curveTo(x1, y1, x2, y2, xn, yn)

            # close path
            elif op in ('Z', 'z'):
                path.closePath()

            else:
                logger.debug("Suspicious path operator: %s" % op)
            lastop = op

        gr = Group()
        self.applyStyleOnShape(path, node)

        if path.operators[-1] != _CLOSEPATH:
            unclosed_subpath_pointers.append(len(path.operators))

        if unclosed_subpath_pointers and path.fillColor is not None:
            # ReportLab doesn't fill unclosed paths, so we are creating a copy
            # of the path with all subpaths closed, but without stroke.
            # https://bitbucket.org/rptlab/reportlab/issues/99/
            closed_path = NoStrokePath(copy_from=path)
            for pointer in reversed(unclosed_subpath_pointers):
                closed_path.operators.insert(pointer, _CLOSEPATH)
            gr.add(closed_path)
            path.fillColor = None

        gr.add(path)
        return gr
Exemple #18
0
 def getProperties(self, *args, **kwargs):
     props = Path.getProperties(self, *args, **kwargs)
     if 'fillColor' in props:
         props['fillColor'] = None
     return props
Exemple #19
0
 def __init__(self, *args, **kwargs):
     copy_from = kwargs.pop('copy_from', None)
     Path.__init__(self, *args, **kwargs)
     if copy_from:
         self.__dict__.update(copy.deepcopy(copy_from.__dict__))
     self.isClipPath = 1
Exemple #20
0
 def __init__(self, ref=None):
     Path.__init__(self)
     self._ref = ref
Exemple #21
0
 def __init__(self, *args, **kwargs):
     copy_from = kwargs.pop('copy_from', None)
     Path.__init__(self, *args, **kwargs)  # we're old-style class on PY2
     if copy_from:
         self.__dict__.update(copy.deepcopy(copy_from.__dict__))
Exemple #22
0
 def getProperties(self, *args, **kwargs):
     props = Path.getProperties(self, *args, **kwargs)
     if 'fillColor' in props:
         props['fillColor'] = None
     return props
Exemple #23
0
    from fontemon_blender_addon.fontTools.ttLib import TTFont
    from reportlab.lib import colors

    path = sys.argv[1]
    glyphName = sys.argv[2]
    if (len(sys.argv) > 3):
        imageFile = sys.argv[3]
    else:
        imageFile = "%s.png" % glyphName

    font = TTFont(
        path
    )  # it would work just as well with fontemon_blender_addon.fontTools.t1Lib.T1Font
    gs = font.getGlyphSet()
    pen = ReportLabPen(gs, Path(fillColor=colors.red, strokeWidth=5))
    g = gs[glyphName]
    g.draw(pen)

    w, h = g.width, 1000
    from reportlab.graphics import renderPM
    from reportlab.graphics.shapes import Group, Drawing, scale

    # Everything is wrapped in a group to allow transformations.
    g = Group(pen.path)
    g.translate(0, 200)
    g.scale(0.3, 0.3)

    d = Drawing(w, h)
    d.add(g)
Exemple #24
0
 def __init__(self,
              width=600.0,
              height=200.0,
              fillMode='even-odd',
              *args,
              **kw):
     Drawing.__init__(self, width, height, *args, **kw)
     self.transform = (1, 0, 0, 1, 0, 0)
     v0 = self._nn(Group())
     v0.transform = (1, 0, 0, -1, 0, 200)
     v0.add(
         Rect(1,
              1,
              599,
              199,
              rx=0,
              ry=0,
              strokeDashArray=None,
              strokeWidth=2,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillOpacity=1,
              strokeColor=Color(0, 0, 1, 1),
              strokeLineCap=0,
              fillColor=None))
     v1 = v0._nn(Group())
     v1.transform = (.5, 0, 0, .5, 0, 0)
     v1.add(
         Path(points=[250, 75, 323, 301, 131, 161, 369, 161, 177, 301],
              operators=[0, 1, 1, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=fillMode,
              strokeDashArray=None,
              strokeWidth=3,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillOpacity=1,
              strokeColor=Color(0, 0, 0, 1),
              strokeLineCap=0,
              fillColor=Color(1, 0, 0, 1)))
     v2 = v1._nn(Group())
     v2.transform = (.309017, .951057, -0.951057, .309017, 306.21, 249)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (-0.809017, -0.587785, .587785, -0.809017, 175.16,
                     193.2)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (1, 0, 0, 1, 314.26, 161)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (-0.809017, .587785, -0.587785, -0.809017, 221.16,
                     268.8)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (.309017, -0.951057, .951057, .309017, 233.21, 126.98)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v1.add(
         Path(points=[
             600, 81, 659.0945, 81, 707, 128.9055, 707, 188, 707, 247.0945,
             659.0945, 295, 600, 295, 540.9055, 295, 493, 247.0945, 493,
             188, 493, 128.9055, 540.9055, 81, 600, 81, 600, 139, 627.062,
             139, 649, 160.938, 649, 188, 649, 215.062, 627.062, 237, 600,
             237, 572.938, 237, 551, 215.062, 551, 188, 551, 160.938,
             572.938, 139, 600, 139
         ],
              operators=[0, 2, 2, 2, 2, 3, 0, 2, 2, 2, 2, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=fillMode,
              strokeDashArray=None,
              strokeWidth=3,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillOpacity=1,
              strokeColor=Color(0, 0, 0, 1),
              strokeLineCap=0,
              fillColor=Color(1, 0, 0, 1)))
     v2 = v1._nn(Group())
     v2.transform = (0, 1, -1, 0, 707, 188)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (-0.866025, -0.5, .5, -0.866025, 546.5, 280.6647)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (.866025, -0.5, .5, .866025, 546.5, 95.33528)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (-0.866025, .5, -0.5, -0.866025, 624.5, 230.4352)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (0, -1, 1, 0, 551, 188)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (.866025, .5, -0.5, .866025, 624.5, 145.5648)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v1.add(
         Path(points=[
             950, 81, 1009.094, 81, 1057, 128.9055, 1057, 188, 1057,
             247.0945, 1009.094, 295, 950, 295, 890.9055, 295, 843,
             247.0945, 843, 188, 843, 128.9055, 890.9055, 81, 950, 81, 950,
             139, 922.938, 139, 901, 160.938, 901, 188, 901, 215.062,
             922.938, 237, 950, 237, 977.062, 237, 999, 215.062, 999, 188,
             999, 160.938, 977.062, 139, 950, 139
         ],
              operators=[0, 2, 2, 2, 2, 3, 0, 2, 2, 2, 2, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=fillMode,
              strokeDashArray=None,
              strokeWidth=3,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillOpacity=1,
              strokeColor=Color(0, 0, 0, 1),
              strokeLineCap=0,
              fillColor=Color(1, 0, 0, 1)))
     v2 = v1._nn(Group())
     v2.transform = (0, 1, -1, 0, 1057, 188)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (-0.866025, -0.5, .5, -0.866025, 896.5, 280.6647)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (.866025, -0.5, .5, .866025, 896.5, 95.33528)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (.866025, -0.5, .5, .866025, 974.5, 230.4352)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (0, 1, -1, 0, 901, 188)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
     v2 = v1._nn(Group())
     v2.transform = (-0.866025, -0.5, .5, -0.866025, 974.5, 145.5648)
     v2.add(
         Path(points=[16, 0, -8, 9, -8, -9],
              operators=[0, 1, 1, 3],
              isClipPath=0,
              autoclose='svg',
              fillMode=1,
              strokeDashArray=None,
              strokeWidth=1,
              strokeMiterLimit=0,
              strokeOpacity=None,
              strokeLineJoin=0,
              fillColor=Color(0, 0, 0, 1),
              strokeColor=None,
              strokeLineCap=0,
              fillOpacity=1))
Exemple #25
0
    def render(self, node, parent=None):
        if parent is None:
            parent = self.mainGroup

        # ignore if display = none
        display = node.get('display')
        if display == "none":
            return

        if node.tag == self.SVG_ROOT:
            self.level += 1

            if not self.drawing is None:
                raise SVGError('drawing already created!')

            self.root = node

            # default styles
            style = {
                'color': 'none',
                'fill': 'none',
                'stroke': 'none',
                'font-family': 'Helvetica',
                'font-size': '12'
            }

            self.styles[self.level] = style

            # iterate children
            for child in node:
                self.render(child, self.mainGroup)

            # create drawing
            width = node.get('width', '100%')
            height = node.get('height', '100%')

            if node.get("viewBox"):
                try:
                    minx, miny, width, height = node.get("viewBox").split()
                except ValueError:
                    raise SVGError("viewBox values not valid")

            if width.endswith('%') and height.endswith('%'):
                # handle relative size
                wscale = parseLength(width) / 100.
                hscale = parseLength(height) / 100.

                xL, yL, xH, yH = self.mainGroup.getBounds()
                self.drawing = Drawing(xH * wscale + xL, yH * hscale + yL)

            else:
                self.drawing = Drawing(parseLength(width), parseLength(height))

            height = self.drawing.height
            self.mainGroup.scale(1, -1)
            self.mainGroup.translate(0, -height)
            self.drawing.add(self.mainGroup)

            self.level -= 1

            return self.drawing

        elif node.tag in (self.SVG_G, self.SVG_A):
            self.level += 1

            # set this levels style
            style = self.styles[self.level - 1].copy()
            style = self.nodeStyle(node, style)
            self.styles[self.level] = style

            group = Group()

            # iterate children
            for child in node:
                self.render(child, group)

            parent.add(group)

            transforms = node.get('transform')
            if transforms:
                for op in parseTransform.iterparse(transforms):
                    self.applyTransformOnGroup(group, op)

            self.level -= 1

        elif node.tag == self.SVG_USE:
            self.level += 1

            # set this levels style
            style = self.styles[self.level - 1].copy()
            style = self.nodeStyle(node, style)
            self.styles[self.level] = style

            group = Group()

            # link id
            link_id = node.get(self.LINK).lstrip('#')

            # find linked node in defs or symbol section
            target = None
            for defs in self.root.getiterator(self.SVG_DEFS):
                for element in defs:
                    if element.get('id') == link_id:
                        target = element
                        break

            if target is None:
                for defs in self.root.getiterator(self.SVG_SYMBOL):
                    for element in defs:
                        if element.get('id') == link_id:
                            target = element
                            break

                if target is None:
                    msg = "Could not find use node '%s'" % link_id
                    raise SVGError(msg)

            self.render(target, group)

            parent.add(group)

            # apply transform
            transforms = node.get('transform')
            if transforms:
                for op in parseTransform.iterparse(transforms):
                    self.applyTransformOnGroup(group, op)

            # apply 'x' and 'y' attribute as translation of defs object
            if node.get('x') or node.get('y'):
                dx = parseLength(node.get('x', '0'))
                dy = parseLength(node.get('y', '0'))

                self.applyTransformOnGroup(group, ('translate', (dx, dy)))

            self.level -= 1

        elif node.tag == self.SVG_LINE:
            # get coordinates
            x1 = parseLength(node.get('x1', '0'))
            y1 = parseLength(node.get('y1', '0'))
            x2 = parseLength(node.get('x2', '0'))
            y2 = parseLength(node.get('y2', '0'))

            shape = Line(x1, y1, x2, y2)
            self.addShape(parent, node, shape)

        elif node.tag == self.SVG_RECT:
            # get coordinates
            x = parseLength(node.get('x', '0'))
            y = parseLength(node.get('y', '0'))
            width = parseLength(node.get('width'))
            height = parseLength(node.get('height'))

            rx = parseLength(node.get('rx', '0'))
            ry = parseLength(node.get('ry', '0'))

            shape = Rect(x, y, width, height, rx=rx, ry=ry)
            self.addShape(parent, node, shape)

        elif node.tag == self.SVG_CIRCLE:
            cx = parseLength(node.get('cx', '0'))
            cy = parseLength(node.get('cy', '0'))
            r = parseLength(node.get('r'))

            if r > 0.:
                shape = Circle(cx, cy, r)
                self.addShape(parent, node, shape)

        elif node.tag == self.SVG_ELLIPSE:
            cx = parseLength(node.get('cx', '0'))
            cy = parseLength(node.get('cy', '0'))
            rx = parseLength(node.get('rx'))
            ry = parseLength(node.get('ry'))

            if rx > 0. and ry > 0.:
                shape = Ellipse(cx, cy, rx, ry)
                self.addShape(parent, node, shape)

        elif node.tag == self.SVG_POLYLINE:
            # convert points
            points = node.get('points').strip()
            if len(points) == 0:
                return

            points = list(map(parseLength, re.split('[ ,]+', points)))

            # Need to use two shapes, because standard RLG polylines
            # do not support filling...
            group = Group()
            shape = Polygon(points)
            self.applyStyleToShape(shape, node)
            shape.strokeColor = None
            group.add(shape)

            shape = PolyLine(points)
            self.applyStyleToShape(shape, node)
            group.add(shape)

            self.addShape(parent, node, group)

        elif node.tag == self.SVG_POLYGON:
            # convert points
            points = node.get('points').strip()
            if len(points) == 0:
                return

            points = list(map(parseLength, re.split('[ ,]+', points)))

            shape = Polygon(points)
            self.addShape(parent, node, shape)

        elif node.tag == self.SVG_IMAGE:
            x = parseLength(node.get('x', '0'))
            y = parseLength(node.get('y', '0'))
            width = parseLength(node.get('width', '0'))
            height = parseLength(node.get('height', '0'))

            # link id
            link_id = node.get(self.LINK)

            filename = os.path.join(os.path.dirname(self.filename), link_id)
            shape = Image(x, y, width, height, filename)

            self.addShape(parent, node, shape)

        elif node.tag == self.SVG_TEXT:
            # Todo:
            # - rotation not handled
            # - baseshift not handled
            # - embedded span node not handled
            #
            def parsePos(node, subnode, name, default='0'):
                values = subnode.get(name)
                if values is None:
                    if node is not None:
                        values = node.get(name, default)
                    else:
                        values = default

                return list(map(parseLength, values.split()))

            def getPos(values, i, default=None):
                if i >= len(values):
                    if default is None:
                        return values[-1]
                    else:
                        return default
                else:
                    return values[i]

            def handleText(node, subnode, text):
                # get position variables
                xs = parsePos(node, subnode, 'x')
                dxs = parsePos(node, subnode, 'dx')
                ys = parsePos(node, subnode, 'y')
                dys = parsePos(node, subnode, 'dy')

                if sum(map(len, (xs, ys, dxs, dys))) == 4:
                    # single value
                    shape = String(xs[0] + dxs[0], -ys[0] - dys[0], text)
                    self.applyStyleToShape(shape, subnode)
                    group.add(shape)

                else:
                    # multiple values
                    for i, c in enumerate(text):
                        x = getPos(xs, i)
                        dx = getPos(dxs, i, 0)
                        y = getPos(ys, i)
                        dy = getPos(dys, i, 0)

                        shape = String(x + dx, -y - dy, c)
                        self.applyStyleToShape(shape, subnode)
                        group.add(shape)

            if node.text and node.text.strip():
                group = Group()

                handleText(None, node, node.text.strip())

                group.scale(1, -1)

                self.addShape(parent, node, group)

            if len(node) > 0:
                group = Group()

                self.level += 1

                # set this levels style
                style = self.styles[self.level - 1].copy()
                nodestylestyle = self.nodeStyle(node, style)
                self.styles[self.level] = nodestylestyle

                for subnode in node:
                    if subnode.tag == self.SVG_TSPAN:
                        handleText(node, subnode, subnode.text.strip())

                self.level -= 1

                group.scale(1, -1)
                self.addShape(parent, node, group)

        elif node.tag == self.SVG_PATH:

            def convertQuadratic(Q0, Q1, Q2):
                C1 = (Q0[0] + 2. / 3 * (Q1[0] - Q0[0]),
                      Q0[1] + 2. / 3 * (Q1[1] - Q0[1]))
                C2 = (C1[0] + 1. / 3 * (Q2[0] - Q0[0]),
                      C1[1] + 1. / 3 * (Q2[1] - Q0[1]))
                C3 = Q2
                return C1[0], C1[1], C2[0], C2[1], C3[0], C3[1]

            def prevCtrl(lastOp, lastArgs, currentX, currentY):
                # fetch last controll point
                if lastOp in 'CScsQqTt':
                    x, y = lastArgs[-2]

                    # mirror about current point
                    return currentX + (currentX - x), currentY + (currentY - y)

                else:
                    # defaults to current point
                    return currentX, currentY

            # store sub paths in 'paths' list
            shape = Path()

            # keep track of current point and path start point
            startX, startY = 0., 0.
            currentX, currentY = 0., 0.

            # keep track of last operation
            lastOp = None
            lastArgs = None

            # avoid empty path data
            data = node.get('d')
            if data is None or len(data) == 0:
                return

            for op, args in parsePath.iterparse(data):
                if op == 'z' or op == 'Z':
                    # close path or subpath
                    shape.closePath()

                    # next sub path starts at begining of current path
                    currentX, currentY = startX, startY

                elif op == 'M':
                    # moveto absolute
                    if lastOp is not None and lastOp not in ('z', 'Z'):
                        # close sub path
                        shape.closePath()

                    x, y = args[0]
                    shape.moveTo(x, y)

                    startX, startY = x, y

                    # multiple moveto arge result in line
                    for x, y in args[1:]:
                        shape.lineTo(x, y)

                    currentX, currentY = x, y

                elif op == 'm':
                    if lastOp is not None and lastOp not in ('z', 'Z'):
                        # close sub path
                        shape.closePath()

                    # moveto relative
                    rx, ry = args[0]
                    x, y = currentX + rx, currentY + ry
                    shape.moveTo(x, y)

                    startX, startY = x, y
                    currentX, currentY = x, y

                    # multiple moveto arge result in line
                    for rx, ry in args[1:]:
                        x, y = currentX + rx, currentY + ry
                        shape.lineTo(x, y)
                        currentX, currentY = x, y

                elif op == 'L':
                    # lineto absolute
                    for x, y in args:
                        shape.lineTo(x, y)

                    currentX, currentY = x, y

                elif op == 'l':
                    # lineto relative
                    for rx, ry in args:
                        x, y = currentX + rx, currentY + ry
                        shape.lineTo(x, y)
                        currentX, currentY = x, y

                elif op == 'V':
                    # vertical line absolute
                    for y in args:
                        shape.lineTo(currentX, y)

                    currentY = y

                elif op == 'v':
                    # vertical line relative
                    for ry in args:
                        y = currentY + ry
                        shape.lineTo(currentX, y)
                        currentY = y

                elif op == 'H':
                    # horisontal line absolute
                    for x in args:
                        shape.lineTo(x, currentY)
                    currentX = x

                elif op == 'h':
                    # horisontal line relative
                    for rx in args:
                        x = currentX + rx
                        shape.lineTo(x, currentY)
                    currentX = x

                elif op == 'C':
                    # cubic bezier absolute
                    for p1, p2, p3 in zip(*([iter(args)] * 3)):
                        shape.curveTo(*(p1 + p2 + p3))
                        currentX, currentY = p3

                elif op == 'c':
                    # cubic bezier relative
                    for pnts in zip(*([iter(args)] * 3)):
                        (x1, y1), (x2, y2), (x3, y3) = pnts
                        pnts = tuple(
                            (p[0] + currentX, p[1] + currentY) for p in pnts)
                        shape.curveTo(*(pnts[0] + pnts[1] + pnts[2]))
                        currentX, currentY = pnts[2]
                        lastOp = op
                        lastArgs = pnts
                    continue

                elif op == 'S':
                    # shorthand cubic bezier absolute
                    for p2, p3 in zip(*([iter(args)] * 2)):
                        x1, y1 = prevCtrl(lastOp, lastArgs, currentX, currentY)
                        x2, y2 = p2
                        x3, y3 = p3
                        shape.curveTo(x1, y1, x2, y2, x3, y3)
                        lastOp = op
                        lastArgs = (x2, y2), (x3, y3)
                        currentX, currentY = x3, y3
                    continue

                elif op == 's':
                    # shorthand cubic bezier relative
                    for p2, p3 in zip(*([iter(args)] * 2)):
                        x1, y1 = prevCtrl(lastOp, lastArgs, currentX, currentY)
                        x2, y2 = p2
                        x2, y2 = x2 + currentX, y2 + currentY
                        x3, y3 = p3
                        x3, y3 = x3 + currentX, y3 + currentY
                        shape.curveTo(x1, y1, x2, y2, x3, y3)
                        currentX, currentY = x3, y3
                        lastOp = op
                        lastArgs = (x1, y1), (x2, y2), (x3, y3)
                    continue

                elif op == 'Q':
                    # quadratic bezier absolute
                    for p2, p3 in zip(*([iter(args)] * 2)):
                        x1, y1 = currentX, currentY
                        x2, y2 = p2
                        x3, y3 = p3
                        ctrls = convertQuadratic((x1, y1), (x2, y2), (x3, y3))
                        shape.curveTo(*ctrls)
                        currentX, currentY = x3, y3
                    lastOp = op
                    lastArgs = (x2, y2), (x3, y3)
                    continue

                elif op == 'q':
                    # quadratic bezier relative
                    for p2, p3 in zip(*([iter(args)] * 2)):
                        x1, y1 = currentX, currentY
                        x2, y2 = p2
                        x2, y2 = x2 + currentX, y2 + currentY
                        x3, y3 = p3
                        x3, y3 = x3 + currentX, y3 + currentY
                        ctrls = convertQuadratic((x1, y1), (x2, y2), (x3, y3))
                        shape.curveTo(*ctrls)
                        currentX, currentY = x3, y3

                    lastOp = op
                    lastArgs = (x2, y2), (x3, y3)
                    continue

                elif op == 'T':
                    # shorthand quadratic bezier absolute
                    for i in range(len(args)):
                        x1, y1 = currentX, currentY
                        x2, y2 = prevCtrl(lastOp, lastArgs, currentX, currentY)
                        x3, y3 = args[i]
                        ctrls = convertQuadratic((x1, y1), (x2, y2), (x3, y3))
                        shape.curveTo(*ctrls)
                        currentX, currentY = x3, y3
                        lastOp = op
                        lastArgs = (x2, y2), (x3, y3)

                    continue

                elif op == 't':
                    # shorthand quadratic bezier relative
                    for i in range(len(args)):
                        x1, y1 = currentX, currentY
                        x2, y2 = prevCtrl(lastOp, lastArgs, currentX, currentY)
                        x3, y3 = args[i]
                        x3, y3 = x3 + currentX, y3 + currentY
                        ctrls = convertQuadratic((x1, y1), (x2, y2), (x3, y3))
                        shape.curveTo(*ctrls)
                        currentX, currentY = x3, y3
                        lastOp = op
                        lastArgs = (x2, y2), (x3, y3)

                    continue

                elif op == 'A' or op == 'a':
                    # elliptic arc missing
                    continue

                lastOp = op
                lastArgs = args

            # check if fill applies to path
            fill = None
            if node.get('fill'):
                # inline style
                fill = node.get('fill')
            else:
                # try local style
                if node.get('style'):
                    style = parseStyle.parse(node.get('style'))

                    if 'fill' in style:
                        fill = style['fill']

                # try global style
                if fill is None:
                    style = self.styles[self.level]

                    if 'fill' in style:
                        fill = style['fill']
                    else:
                        fill = 'none'

            # hack because RLG has no "semi-closed" paths...
            if lastOp == 'z' or lastOp == 'Z' or fill == 'none':
                self.addShape(parent, node, shape)

            else:
                group = Group()
                strokeshape = shape.copy()
                self.addShape(group, node, strokeshape, fill='none')
                shape.closePath()
                self.addShape(group, node, shape, stroke='none')
                self.addShape(parent, node, group)

        elif node.tag == self.SVG_TITLE or node.tag == self.SVG_DESC:
            # Skip non-graphics elements
            return
Exemple #26
0
	def __init__(self, glyphSet, path=None):
		BasePen.__init__(self, glyphSet)
		if path is None:
			from reportlab.graphics.shapes import Path
			path = Path()
		self.path = path
Exemple #27
0
 def __init__(self, *args, **kwargs):
     copy_from = kwargs.pop('copy_from', None)
     Path.__init__(self, *args, **kwargs)  # we're old-style class on PY2
     if copy_from:
         self.__dict__.update(copy.deepcopy(copy_from.__dict__))
Exemple #28
0
    def convertPath(self, node):
        d = node.getAttribute('d')
        normPath = normalise_svg_path(d)
        path = Path()
        points = path.points
        # Track subpaths needing to be closed later
        unclosed_subpath_pointers = []
        subpath_start = []
        lastop = ''

        for i in xrange(0, len(normPath), 2):
            op, nums = normPath[i:i+2]

            if op in ('m', 'M') and i > 0 and path.operators[-1] != _CLOSEPATH:
                unclosed_subpath_pointers.append(len(path.operators))

            # moveto absolute
            if op == 'M':
                path.moveTo(*nums)
                subpath_start = points[-2:]
            # lineto absolute
            elif op == 'L':
                path.lineTo(*nums)

            # moveto relative
            elif op == 'm':
                if len(points) >= 2:
                    if lastop in ('Z', 'z'):
                        starting_point = subpath_start
                    else:
                        starting_point = points[-2:]
                    xn, yn = starting_point[0] + nums[0], starting_point[1] + nums[1]
                    path.moveTo(xn, yn)
                else:
                    path.moveTo(*nums)
                subpath_start = points[-2:]
            # lineto relative
            elif op == 'l':
                xn, yn = points[-2] + nums[0], points[-1] + nums[1]
                path.lineTo(xn, yn)

            # horizontal/vertical line absolute
            elif op == 'H':
                path.lineTo(nums[0], points[-1])
            elif op == 'V':
                path.lineTo(points[-2], nums[0])

            # horizontal/vertical line relative
            elif op == 'h':
                path.lineTo(points[-2] + nums[0], points[-1])
            elif op == 'v':
                path.lineTo(points[-2], points[-1] + nums[0])

            # cubic bezier, absolute
            elif op == 'C':
                path.curveTo(*nums)
            elif op == 'S':
                x2, y2, xn, yn = nums
                if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                path.curveTo(xi, yi, x2, y2, xn, yn)

            # cubic bezier, relative
            elif op == 'c':
                xp, yp = points[-2:]
                x1, y1, x2, y2, xn, yn = nums
                path.curveTo(xp + x1, yp + y1, xp + x2, yp + y2, xp + xn, yp + yn)
            elif op == 's':
                x2, y2, xn, yn = nums
                if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                path.curveTo(xi, yi, x0 + x2, y0 + y2, x0 + xn, y0 + yn)

            # quadratic bezier, absolute
            elif op == 'Q':
                x0, y0 = points[-2:]
                x1, y1, xn, yn = nums
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)
            elif op == 'T':
                if len(points) < 4:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                xn, yn = nums
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)

            # quadratic bezier, relative
            elif op == 'q':
                x0, y0 = points[-2:]
                x1, y1, xn, yn = nums
                x1, y1, xn, yn = x0 + x1, y0 + y1, x0 + xn, y0 + yn
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)
            elif op == 't':
                if len(points) < 4:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                x0, y0 = points[-2:]
                xn, yn = nums
                xn, yn = x0 + xn, y0 + yn
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)

            # elliptical arc
            elif op in ('A', 'a'):
                rx, ry, phi, fA, fS, x2, y2 = nums
                x1, y1 = points[-2:]
                if op == 'a':
                    x2 += x1
                    y2 += y1
                if abs(rx) <= 1e-10 or abs(ry) <= 1e-10:
                    path.lineTo(x2, y2)
                else:
                    bp = bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA, fS, x2, y2)
                    for _, _, x1, y1, x2, y2, xn, yn in bp:
                        path.curveTo(x1, y1, x2, y2, xn, yn)

            # close path
            elif op in ('Z', 'z'):
                path.closePath()

            else:
                logger.debug("Suspicious path operator: %s" % op)
            lastop = op

        gr = Group()
        self.applyStyleOnShape(path, node)

        if path.operators[-1] != _CLOSEPATH:
            unclosed_subpath_pointers.append(len(path.operators))

        if unclosed_subpath_pointers and path.fillColor is not None:
            # ReportLab doesn't fill unclosed paths, so we are creating a copy
            # of the path with all subpaths closed, but without stroke.
            # https://bitbucket.org/rptlab/reportlab/issues/99/
            closed_path = NoStrokePath(copy_from=path)
            for pointer in reversed(unclosed_subpath_pointers):
                closed_path.operators.insert(pointer, _CLOSEPATH)
            gr.add(closed_path)
            path.fillColor = None

        gr.add(path)
        return gr
Exemple #29
0
    def convertPath(self, node):
        d = node.getAttribute('d')
        if not d:
            return None
        normPath = normalise_svg_path(d)
        path = Path(autoclose='svg')
        points = path.points
        # Track subpaths needing to be closed later
        subpath_start = []
        lastop = ''

        for i in xrange(0, len(normPath), 2):
            op, nums = normPath[i:i + 2]

            # moveto absolute
            if op == 'M':
                path.moveTo(*nums)
                subpath_start = points[-2:]
            # lineto absolute
            elif op == 'L':
                path.lineTo(*nums)

            # moveto relative
            elif op == 'm':
                if len(points) >= 2:
                    if lastop in ('Z', 'z'):
                        starting_point = subpath_start
                    else:
                        starting_point = points[-2:]
                    xn, yn = starting_point[0] + nums[0], starting_point[
                        1] + nums[1]
                    path.moveTo(xn, yn)
                else:
                    path.moveTo(*nums)
                subpath_start = points[-2:]
            # lineto relative
            elif op == 'l':
                xn, yn = points[-2] + nums[0], points[-1] + nums[1]
                path.lineTo(xn, yn)

            # horizontal/vertical line absolute
            elif op == 'H':
                path.lineTo(nums[0], points[-1])
            elif op == 'V':
                path.lineTo(points[-2], nums[0])

            # horizontal/vertical line relative
            elif op == 'h':
                path.lineTo(points[-2] + nums[0], points[-1])
            elif op == 'v':
                path.lineTo(points[-2], points[-1] + nums[0])

            # cubic bezier, absolute
            elif op == 'C':
                path.curveTo(*nums)
            elif op == 'S':
                x2, y2, xn, yn = nums
                if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                path.curveTo(xi, yi, x2, y2, xn, yn)

            # cubic bezier, relative
            elif op == 'c':
                xp, yp = points[-2:]
                x1, y1, x2, y2, xn, yn = nums
                path.curveTo(xp + x1, yp + y1, xp + x2, yp + y2, xp + xn,
                             yp + yn)
            elif op == 's':
                x2, y2, xn, yn = nums
                if len(points) < 4 or lastop not in {'c', 'C', 's', 'S'}:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                path.curveTo(xi, yi, x0 + x2, y0 + y2, x0 + xn, y0 + yn)

            # quadratic bezier, absolute
            elif op == 'Q':
                x0, y0 = points[-2:]
                x1, y1, xn, yn = nums
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)
            elif op == 'T':
                if len(points) < 4:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                xn, yn = nums
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)

            # quadratic bezier, relative
            elif op == 'q':
                x0, y0 = points[-2:]
                x1, y1, xn, yn = nums
                x1, y1, xn, yn = x0 + x1, y0 + y1, x0 + xn, y0 + yn
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (x1, y1), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)
            elif op == 't':
                if len(points) < 4:
                    xp, yp, x0, y0 = points[-2:] * 2
                else:
                    xp, yp, x0, y0 = points[-4:]
                x0, y0 = points[-2:]
                xn, yn = nums
                xn, yn = x0 + xn, y0 + yn
                xi, yi = x0 + (x0 - xp), y0 + (y0 - yp)
                (x0, y0), (x1, y1), (x2, y2), (xn, yn) = \
                    convert_quadratic_to_cubic_path((x0, y0), (xi, yi), (xn, yn))
                path.curveTo(x1, y1, x2, y2, xn, yn)

            # elliptical arc
            elif op in ('A', 'a'):
                rx, ry, phi, fA, fS, x2, y2 = nums
                x1, y1 = points[-2:]
                if op == 'a':
                    x2 += x1
                    y2 += y1
                if abs(rx) <= 1e-10 or abs(ry) <= 1e-10:
                    path.lineTo(x2, y2)
                else:
                    bp = bezier_arc_from_end_points(x1, y1, rx, ry, phi, fA,
                                                    fS, x2, y2)
                    for _, _, x1, y1, x2, y2, xn, yn in bp:
                        path.curveTo(x1, y1, x2, y2, xn, yn)

            # close path
            elif op in ('Z', 'z'):
                path.closePath()

            else:
                logger.debug("Suspicious path operator: %s" % op)
            lastop = op

        gr = Group()
        self.applyStyleOnShape(path, node)

        gr.add(path)
        return gr
Exemple #30
0
		print("  (The file format will be PNG, regardless of the image file name supplied)")
		sys.exit(0)

	from fontTools.ttLib import TTFont
	from reportlab.lib import colors

	path = sys.argv[1]
	glyphName = sys.argv[2]
	if (len(sys.argv) > 3):
		imageFile = sys.argv[3]
	else:
		imageFile = "%s.png" % glyphName

	font = TTFont(path)  # it would work just as well with fontTools.t1Lib.T1Font
	gs = font.getGlyphSet()
	pen = ReportLabPen(gs, Path(fillColor=colors.black, strokeWidth=0))
	#pen = ReportLabPen(gs, Path(fillColor=colors.red, strokeWidth=5))
	g = gs[glyphName]
	g.draw(pen)

	w, h = g.width, 1000
	from reportlab.graphics import renderPM
	from reportlab.graphics.shapes import Group, Drawing, scale

	# Everything is wrapped in a group to allow transformations.
	g = Group(pen.path)
	g.translate(10, 10)
	#g.scale(0.9, 0.9)
	#g.scale(0.3, 0.3)
	g.scale(0.8, 0.8)
Exemple #31
0
    def draw(self):
        self.qr.make()

        g = Group()

        color = self.barFillColor
        border = self.barBorder
        width = self.barWidth
        height = self.barHeight
        x = self.x
        y = self.y

        g.add(SRect(x, y, width, height, fillColor=None))

        path = Path(fillColor=colors.black, strokeColor=None)

        moduleCount = self.qr.getModuleCount()
        minwh = float(min(width, height))
        boxsize = minwh / (moduleCount + border * 2)
        offsetX = (width - minwh) / 2
        offsetY = (minwh - height) / 2

        for r, row in enumerate(self.qr.modules):
            c = 0
            for t, tt in itertools.groupby(row):
                isDark = t
                count = len(list(tt))
                if isDark:
                    x = (c + border) * boxsize
                    y = (r + border + 1) * boxsize
                    path.moveTo(offsetX + x, offsetY + height - y)
                    path.lineTo(offsetX + x + count * boxsize,
                                offsetY + height - y)
                    path.lineTo(offsetX + x + count * boxsize,
                                offsetY + height - y + boxsize)
                    path.lineTo(offsetX + x, offsetY + height - y + boxsize)
                    path.closePath()

                c += count

        g.add(path)

        return g
Exemple #32
0
 def __init__(self, glyphSet, path=None):
     BasePen.__init__(self, glyphSet)
     if path is None:
         path = Path()
     self.path = path
Exemple #33
0
 def __init__(self, *args, **kwargs):
     copy_from = kwargs.pop('copy_from', None)
     Path.__init__(self, *args, **kwargs)
     if copy_from:
         self.__dict__.update(copy.deepcopy(copy_from.__dict__))
     self.isClipPath = 1