Esempio n. 1
0
    def set_stroke(self, dc, svg_stroke, line_width=1.0, linecap='butt', dasharray=None):
        #Patch to avoid to have too dim lines for staff, bar, note stems
        if line_width < 1:
            line_width = 1.0
        #End Patch
        if dasharray:
            # convert from something like "5,5" to (5,5)
            dasharray = tuple([int(x.strip()) for x in dasharray.split(',')])
        # 1.3.6.3 [JWDJ] 2015-3 search cache once instead of twice
        key = (svg_stroke, line_width, dasharray)
        pen = self.stroke_cache.get(key)
        if pen is None:
            if svg_stroke == 'none':
                if WX41:
                    pen = self.renderer.CreatePen(wx.GraphicsPenInfo(style=wx.PENSTYLE_TRANSPARENT))
                else:
                    pen = self.renderer.CreatePen(wx.NullPen)
            else:
                if WX41:
                    wxpen = wx.GraphicsPenInfo(wx_colour(svg_stroke)).Width(line_width)
                    if linecap == 'butt':
                        wxpen.Cap(wx.CAP_BUTT)
                    elif linecap == 'round':
                        wxpen.Cap(wx.CAP_ROUND)
                    else:
                        raise Exception('linecap %s not supported yet' % linecap)
                    # if dasharray:
                    #     # 1.3.6.3 [JWDJ] 2015-3 dasharray is always a tuple, never a str or unicode
                    #     #if type(dasharray) in (str, unicode):
                    #     #    dasharray = [int(x.strip()) for x in dasharray.split(',')]
                    #     wxpen.Dashes(list(dasharray))
                    #     wxpen.Style(wx.USER_DASH)
                    wxpen.Join(wx.JOIN_MITER)
                else:
                    wxpen = wx.Pen(wx_colour(svg_stroke), line_width)
                    if linecap == 'butt':
                        wxpen.SetCap(wx.CAP_BUTT)
                    elif linecap == 'round':
                        wxpen.SetCap(wx.CAP_ROUND)
                    else:
                        raise Exception('linecap %s not supported yet' % linecap)
                    if dasharray:
                        # 1.3.6.3 [JWDJ] 2015-3 dasharray is always a tuple, never a str or unicode
                        #if type(dasharray) in (str, unicode):
                        #    dasharray = [int(x.strip()) for x in dasharray.split(',')]
                        wxpen.SetDashes(list(dasharray))
                        wxpen.SetStyle(wx.USER_DASH)
                    wxpen.SetJoin(wx.JOIN_MITER)

                pen = self.renderer.CreatePen(wxpen)
            self.stroke_cache[key] = pen
        dc.SetPen(pen)
Esempio n. 2
0
 def draw_drag_rect(self, dc):
     if self.drag_rect:
         dc = wx.GraphicsContext.Create(dc)
         #z = self.renderer.zoom
         #dc.Scale(z, z)
         x, y, width, height = self.drag_rect
         dc.SetPen( dc.CreatePen(wx.Pen(wx_colour('black'), 1.0, style=wx.DOT )) )
         dc.SetBrush(dc.CreateBrush(wx.Brush(wx_colour('#fffbc6'), wx.SOLID)))
         path = dc.CreatePath()
         path.MoveToPoint(x, y)
         path.AddLineToPoint(x+width, y)
         path.AddLineToPoint(x+width, y+height)
         path.AddLineToPoint(x, y+height)
         path.AddLineToPoint(x, y)
         dc.DrawPath(path)
Esempio n. 3
0
 def set_stroke(self, dc, svg_stroke, line_width=1.0, linecap='butt', dasharray=None):
     #Patch to avoid to have too dim lines for staff, bar, note stems
     if line_width < 1:
         line_width = 1.0
     #End Patch
     if dasharray:
         # convert from something like "5,5" to (5,5)
         dasharray = tuple([int(x.strip()) for x in dasharray.split(',')])
     # 1.3.6.3 [JWDJ] 2015-3 search cache once instead of twice
     key = (svg_stroke, line_width, dasharray)
     pen = self.stroke_cache.get(key)
     if pen is None:
         if svg_stroke == 'none':
             pen = self.renderer.CreatePen(wx.NullPen)
         else:
             wxpen = wx.Pen(wx_colour(svg_stroke), line_width)
             if linecap == 'butt':
                 wxpen.SetCap(wx.CAP_BUTT)
             elif linecap == 'round':
                 wxpen.SetCap(wx.CAP_ROUND)
             else:
                 raise Exception('linecap %s not supported yet' % linecap)
             if dasharray:
                 # 1.3.6.3 [JWDJ] 2015-3 dasharray is always a tuple, never a str or unicode
                 #if type(dasharray) in (str, unicode):
                 #    dasharray = [int(x.strip()) for x in dasharray.split(',')]
                 wxpen.SetDashes(list(dasharray))
                 wxpen.SetStyle(wx.USER_DASH)
             wxpen.SetJoin(wx.JOIN_MITER)
             pen = self.renderer.CreatePen(wxpen)
         self.stroke_cache[key] = pen
     dc.SetPen(pen)
Esempio n. 4
0
 def draw_drag_rect(self, dc):
     if self.drag_rect:
         dc = wx.GraphicsContext.Create(dc)
         #z = self.renderer.zoom
         #dc.Scale(z, z)
         x, y, width, height = self.drag_rect
         dc.SetPen(
             dc.CreatePen(wx.Pen(wx_colour('black'), 1.0, style=wx.DOT)))
         dc.SetBrush(
             dc.CreateBrush(wx.Brush(wx_colour('#fffbc6'), wx.SOLID)))
         path = dc.CreatePath()
         path.MoveToPoint(x, y)
         path.AddLineToPoint(x + width, y)
         path.AddLineToPoint(x + width, y + height)
         path.AddLineToPoint(x, y + height)
         path.AddLineToPoint(x, y)
         dc.DrawPath(path)
Esempio n. 5
0
 def set_fill(self, dc, svg_fill):
     # 1.3.6.3 [JWDJ] 2015-3 search cache once instead of twice
     brush = self.fill_cache.get(svg_fill)
     if brush is None:
         if svg_fill == 'none':
             brush = self.renderer.CreateBrush(wx.NullBrush)
         elif svg_fill == 'white':
             brush = self.renderer.CreateBrush(wx.WHITE_BRUSH)
         elif svg_fill == 'black':
             brush = self.renderer.CreateBrush(wx.BLACK_BRUSH)
         elif svg_fill.startswith('#'): # 1.3.6.2 [JWdJ] 2015-02-12 Added voicecolor
             brush = self.renderer.CreateBrush(wx.Brush(svg_fill, wx.SOLID))
         else:
             brush = self.renderer.CreateBrush(wx.Brush(wx_colour(svg_fill), wx.SOLID))
         self.fill_cache[svg_fill] = brush
     dc.SetBrush(brush)
Esempio n. 6
0
 def set_fill(self, dc, svg_fill):
     # 1.3.6.3 [JWDJ] 2015-3 search cache once instead of twice
     brush = self.fill_cache.get(svg_fill)
     if brush is None:
         if svg_fill == 'none':
             brush = self.renderer.CreateBrush(wx.NullBrush)
         elif svg_fill == 'white':
             brush = self.renderer.CreateBrush(wx.WHITE_BRUSH)
         elif svg_fill == 'black':
             brush = self.renderer.CreateBrush(wx.BLACK_BRUSH)
         elif svg_fill.startswith('#'): # 1.3.6.2 [JWdJ] 2015-02-12 Added voicecolor
             brush = self.renderer.CreateBrush(wx.Brush(svg_fill, wx.SOLID))
         else:
             brush = self.renderer.CreateBrush(wx.Brush(wx_colour(svg_fill), wx.SOLID))
         self.fill_cache[svg_fill] = brush
     dc.SetBrush(brush)
Esempio n. 7
0
    def draw_svg_element(self, page, dc, svg_element, highlight,
                         current_color):
        ''' This is the main engine for converting the svg items in the svg file into graphics
        displayed in the music pane. The book SVG Essentials by J. David
        Eisenberg describes all the elements used (eg. g, use, ellipse, ...)
        In addition there is an item <abc> which contains annotation and
        information for matching the graphics element with the note in the
        abc file. The <abc> element id indicates the type of object.
        (N - notes, R - rest, B - bar line, b - beam joining notes, e - note flag,
         M - time signature, K - key signature, 'c' octave shift in clef)
        '''

        name = svg_element.name
        if name == 'defs':
            return

        attr = svg_element.attributes
        transform = attr.get('transform')
        if transform:
            dc.PushState()
            self.do_transform(dc, transform)

        # 1.3.6.2 [JWdJ] 2015-02-12 Added voicecolor
        if name == 'g':
            style = attr.get('style')
            if style:
                m = self.color_re.match(style)
                if m:
                    current_color = m.group(1).upper()

            # 1.3.6.2 [JWdJ] 2015-02-14 Only 'g' and 'defs' have children
            for child in svg_element.children:
                self.draw_svg_element(page, dc, child, highlight,
                                      current_color)

        # if something is going to be drawn, prepare
        else:
            # 1.3.6.3 [JWDJ] 2015-3 Only set fill if fill is specified (where 'none' is not the same as None)
            fill = attr.get('fill')
            if fill is None and name == 'circle':
                fill = current_color  # 1.3.6.4 To draw the two dots in !segno!
            if fill is not None:
                if fill == 'currentColor':
                    fill = current_color

                if highlight and fill != 'none':
                    fill = self.highlight_color

                self.set_fill(dc, fill)

            stroke = attr.get('stroke', 'none')
            if stroke == 'currentColor':
                stroke = current_color

            if highlight and stroke != 'none':
                stroke = self.highlight_color

            self.set_stroke(dc, stroke, float(attr.get('stroke-width', 1.0)),
                            attr.get('stroke-linecap', 'butt'),
                            attr.get('stroke-dasharray', None))

        #print 'setmatrix', matrix.Get(), '[%s]' % attr.get('transform', '')

        # 1.3.6.2 [JWdJ] 2015-02-14 Process most common names first (path, ellipse, use)
        if name == 'path':
            path = self.parse_path(attr['d'])
            #Patch from Seymour regarding Debian 7.0 to be tested on other platform
            #if wx.Platform != "__WXMAC__": #At least the SetPen has some side effect on Mac didn't tried on other. So do not apply Seymour Patch if under Mac
            #    dc.SetPen(wx.Pen('#000000', 1, wx.SOLID))
            #End of patch
            dc.DrawPath(path, wx.WINDING_RULE)
        elif name == 'use':
            x, y = float(attr.get('x', 0)), float(attr.get('y', 0))
            element_id = attr[href_tag][1:]
            # abcm2ps specific:
            desc = attr.get('desc')
            if desc:
                user_x, user_y = self.transform_point(dc, x, y)
                abc_row, abc_col = desc[1], desc[2]
                page.notes.append((user_x, user_y, abc_row, abc_col, desc))
                note_index = len(page.notes) - 1
                if note_index in page.selected_indices:
                    highlight = True

            dc.PushState()
            dc.Translate(x, y)
            self.draw_svg_element(page, dc, page.id_to_element[element_id],
                                  highlight, current_color)
            if desc:
                page.note_draw_info.append(
                    (element_id, current_color, dc.GetTransform().Get()))
            dc.PopState()
        elif name == 'ellipse':
            cx, cy, rx, ry = attr.get('cx',
                                      0), attr.get('cy',
                                                   0), attr['rx'], attr['ry']
            cx, cy, rx, ry = map(float, (cx, cy, rx, ry))
            path = dc.CreatePath()
            path.AddEllipse(cx - rx, cy - ry, rx + rx, ry + ry)
            dc.DrawPath(path)
        elif name == 'circle':
            cx, cy, r = map(float,
                            (attr.get('cx', 0), attr.get('cy', 0), attr['r']))
            path = dc.CreatePath()
            path.AddCircle(cx, cy, r)
            dc.DrawPath(path)
        elif name == 'text':
            text = attr['text']
            if not self.can_draw_sharps_and_flats:
                text = text.replace(u'\u266d',
                                    'b').replace(u'\u266f',
                                                 '#').replace(u'\u266e', '=')
            x, y = float(attr.get('x', 0)), float(attr.get('y', 0))
            if attr.get('font-style') == 'italic':
                style = wx.FONTSTYLE_ITALIC
            else:
                style = wx.FONTSTYLE_NORMAL
            if attr.get('font-weight') == 'bold':
                weight = wx.FONTWEIGHT_BOLD
            else:
                weight = wx.FONTWEIGHT_NORMAL
            font_size = int(round(float(attr.get('font-size', 12)) * 1))
            # 1.3.6.3 [JWDJ] 2015-3 bugfix: use correct font family
            font_face = ''
            svg_to_wx_font_family = {
                'serif': wx.FONTFAMILY_ROMAN,
                'sans-serif': wx.FONTFAMILY_SWISS,
                'monospace': wx.FONTFAMILY_MODERN,
                'bookman': wx.FONTFAMILY_ROMAN,
                'sans':
                wx.FONTFAMILY_SWISS,  # should be 'sans-serif' (abcm2ps bug?)
            }

            svg_font_family = attr.get('font-family', 'serif').lower()
            font_family = svg_to_wx_font_family.get(svg_font_family)
            if font_family is None:
                font_family = wx.FONTFAMILY_DEFAULT
                font_face = svg_font_family  # 1.3.6.4 [JWDJ] if font family is not known then assume it is a font face

            ##print repr(text), font_face, attr.get('font-size'), attr.get('font-weight')
            wxfont = wx.Font(font_size, font_family, style, weight, False,
                             font_face, wx.FONTENCODING_DEFAULT)
            if '__WXMSW__' in wx.PlatformInfo:
                wxfont.SetPixelSize((font_size, font_size))
                y += 1
            else:
                wxfont.SetPointSize(font_size)
            font = dc.CreateFont(wxfont, wx_colour(attr.get('fill', 'black')))
            dc.SetFont(font)
            (width, height, descent,
             externalLeading) = dc.GetFullTextExtent(text)
            if attr.get('text-anchor') == 'middle':
                x -= width / 2
            elif attr.get('text-anchor') == 'end':
                x -= width
            try:
                dc.DrawText(text, x, y - height + descent)
            except wx.PyAssertionError:
                raise Exception(
                    u'Could not draw text, text=%s, font=%s (%s / %s), size=%s, fill=%s, weight=%s, style=%s, x=%s, y=%s, height=%s, descent=%s, transform=%s'
                    % (repr(text), font_face, wxfont.GetFaceName(),
                       wxfont.GetDefaultEncoding(), font_size,
                       attr.get('fill',
                                'black'), attr.get('font-weight', '<none>'),
                       attr.get('font-style', '<none>'), x, y, height, descent,
                       dc.GetTransform().Get()))
        elif name == 'rect':
            x, y, width, height = attr.get('x', 0), attr.get(
                'y', 0), attr['width'], attr['height']
            if '%' in width:
                # 1.3.6.2 [JWdJ] 2015-02-12 Added for %%bgcolor
                if width == height == '100%':
                    x, y, width, height = map(float,
                                              (0, 0, self.buffer.GetWidth(),
                                               self.buffer.GetHeight()))
                else:
                    return
            else:
                x, y, width, height = map(float, (x, y, width, height))
            path = dc.CreatePath()
            path.MoveToPoint(x, y)
            path.AddLineToPoint(x + width, y)
            path.AddLineToPoint(x + width, y + height)
            path.AddLineToPoint(x, y + height)
            path.AddLineToPoint(x, y)
            dc.DrawPath(path)
        elif name == 'line':
            x1, y1, x2, y2 = map(
                float, (attr['x1'], attr['y1'], attr['x2'], attr['y2']))
            # 1.3.6.3 [JWDJ] 2015-3 Fill and stroke already have been set
            # self.set_fill(dc, 'none')
            # self.set_stroke(dc, stroke, float(attr.get('stroke-width', 1.0)), attr.get('stroke-linecap', 'butt'), attr.get('stroke-dasharray', None))
            # 1.3.6.3 [JWDJ] 2015-3 Fixes line in !segno!
            dc.DrawLines([(x1, y1), (x2, y2)])

        if transform:
            dc.PopState()
Esempio n. 8
0
    def draw_svg_element(self, page, dc, svg_element, highlight, current_color):
        ''' This is the main engine for converting the svg items in the svg file into graphics
        displayed in the music pane. The book SVG Essentials by J. David
        Eisenberg describes all the elements used (eg. g, use, ellipse, ...)
        In addition there is an item <abc> which contains annotation and
        information for matching the graphics element with the note in the
        abc file. The <abc> element id indicates the type of object.
        (N - notes, R - rest, B - bar line, b - beam joining notes, e - note flag,
         M - time signature, K - key signature, 'c' octave shift in clef)
        '''

        name = svg_element.name
        if name == 'defs':
            return

        attr = svg_element.attributes
        transform = attr.get('transform')
        if transform:
            dc.PushState()
            self.do_transform(dc, transform)

        # 1.3.6.2 [JWdJ] 2015-02-12 Added voicecolor
        if name == 'g':
            style = attr.get('style')
            if style:
                m = self.color_re.match(style)
                if m:
                    current_color = m.group(1).upper()

            # 1.3.6.2 [JWdJ] 2015-02-14 Only 'g' and 'defs' have children
            for child in svg_element.children:
                self.draw_svg_element(page, dc, child, highlight, current_color)

        # if something is going to be drawn, prepare
        else:
            # 1.3.6.3 [JWDJ] 2015-3 Only set fill if fill is specified (where 'none' is not the same as None)
            fill = attr.get('fill')
            if fill is None and name == 'circle':
                fill = current_color # 1.3.6.4 To draw the two dots in !segno!
            if fill is not None:
                if fill == 'currentColor':
                    fill = current_color

                if highlight and fill != 'none':
                    fill = self.highlight_color

                self.set_fill(dc, fill)

            stroke = attr.get('stroke', 'none')
            if stroke == 'currentColor':
                stroke = current_color

            if highlight and stroke != 'none':
                stroke = self.highlight_color

            self.set_stroke(dc, stroke, float(attr.get('stroke-width', 1.0)), attr.get('stroke-linecap', 'butt'), attr.get('stroke-dasharray', None))

        #print 'setmatrix', matrix.Get(), '[%s]' % attr.get('transform', '')

        # 1.3.6.2 [JWdJ] 2015-02-14 Process most common names first (path, ellipse, use)
        if name == 'path':
            path = self.parse_path(attr['d'])
            #Patch from Seymour regarding Debian 7.0 to be tested on other platform
            #if wx.Platform != "__WXMAC__": #At least the SetPen has some side effect on Mac didn't tried on other. So do not apply Seymour Patch if under Mac
            #    dc.SetPen(wx.Pen('#000000', 1, wx.SOLID))
            #End of patch
            dc.DrawPath(path, wx.WINDING_RULE)
        elif name == 'use':
            x, y = float(attr.get('x', 0)), float(attr.get('y', 0))
            element_id = attr[href_tag][1:]
            # abcm2ps specific:
            desc = attr.get('desc')
            if desc:
                user_x, user_y = self.transform_point(dc, x, y)
                abc_row, abc_col = desc[1], desc[2]
                page.notes.append((user_x, user_y, abc_row, abc_col, desc))
                note_index = len(page.notes)-1
                if note_index in page.selected_indices:
                    highlight = True

            dc.PushState()
            dc.Translate(x, y)
            self.draw_svg_element(page, dc, page.id_to_element[element_id], highlight, current_color)
            if desc:
                page.note_draw_info.append((element_id, current_color, dc.GetTransform().Get()))
            dc.PopState()
        elif name == 'ellipse':
            cx, cy, rx, ry = attr.get('cx', 0), attr.get('cy', 0), attr['rx'], attr['ry']
            cx, cy, rx, ry = map(float, (cx, cy, rx, ry))
            path = dc.CreatePath()
            path.AddEllipse(cx-rx, cy-ry, rx+rx, ry+ry)
            dc.DrawPath(path)
        elif name == 'circle':
            cx, cy, r = map(float, (attr.get('cx', 0), attr.get('cy', 0), attr['r']))
            path = dc.CreatePath()
            path.AddCircle(cx, cy, r)
            dc.DrawPath(path)
        elif name == 'text':
            text = attr['text']
            if not self.can_draw_sharps_and_flats:
                text = text.replace(u'\u266d', 'b').replace(u'\u266f', '#').replace(u'\u266e', '=')
            x, y = float(attr.get('x', 0)), float(attr.get('y', 0))
            if attr.get('font-style') == 'italic':
                style = wx.FONTSTYLE_ITALIC
            else:
                style = wx.FONTSTYLE_NORMAL
            if attr.get('font-weight') == 'bold':
                weight = wx.FONTWEIGHT_BOLD
            else:
                weight = wx.FONTWEIGHT_NORMAL
            font_size = int(round(float(attr.get('font-size', 12))*1))
            # 1.3.6.3 [JWDJ] 2015-3 bugfix: use correct font family
            font_face = ''
            svg_to_wx_font_family = {
                'serif': wx.FONTFAMILY_ROMAN,
                'sans-serif': wx.FONTFAMILY_SWISS,
                'monospace': wx.FONTFAMILY_MODERN,
                'bookman': wx.FONTFAMILY_ROMAN,
                'sans': wx.FONTFAMILY_SWISS, # should be 'sans-serif' (abcm2ps bug?)
            }

            svg_font_family = attr.get('font-family', 'serif').lower()
            font_family = svg_to_wx_font_family.get(svg_font_family)
            if font_family is None:
                font_family = wx.FONTFAMILY_DEFAULT
                font_face = svg_font_family # 1.3.6.4 [JWDJ] if font family is not known then assume it is a font face

            ##print repr(text), font_face, attr.get('font-size'), attr.get('font-weight')
            wxfont = wx.Font(font_size, font_family, style, weight, False, font_face, wx.FONTENCODING_DEFAULT)
            if wx.VERSION >= (3, 0) or '__WXMSW__' in wx.PlatformInfo:
                wxfont.SetPixelSize((font_size, font_size))
                y += 1
            else:
                wxfont.SetPointSize(font_size)

            font = dc.CreateFont(wxfont, wx_colour(attr.get('fill', 'black')))
            dc.SetFont(font)
            (width, height, descent, externalLeading) = dc.GetFullTextExtent(text)
            if attr.get('text-anchor') == 'middle':
                x -= width / 2
            elif attr.get('text-anchor') == 'end':
                x -= width
            try:
                dc.DrawText(text, x, y-height+descent)
            except wx.PyAssertionError:
                raise Exception(u'Could not draw text, text=%s, font=%s (%s / %s), size=%s, fill=%s, weight=%s, style=%s, x=%s, y=%s, height=%s, descent=%s, transform=%s' %
                                (repr(text), font_face, wxfont.GetFaceName(), wxfont.GetDefaultEncoding(), font_size,
                                attr.get('fill', 'black'),
                                attr.get('font-weight', '<none>'),
                                attr.get('font-style', '<none>'),
                                x, y, height, descent, dc.GetTransform().Get()))
        elif name == 'rect':
            x, y, width, height = attr.get('x', 0), attr.get('y', 0), attr['width'], attr['height']
            if '%' in width:
                # 1.3.6.2 [JWdJ] 2015-02-12 Added for %%bgcolor
                if width == height == '100%':
                    x, y, width, height = map(float, (0, 0, self.buffer.GetWidth(), self.buffer.GetHeight()))
                else:
                    return
            else:
                x, y, width, height = map(float, (x, y, width, height))
            path = dc.CreatePath()
            path.MoveToPoint(x, y)
            path.AddLineToPoint(x+width, y)
            path.AddLineToPoint(x+width, y+height)
            path.AddLineToPoint(x, y+height)
            path.AddLineToPoint(x, y)
            dc.DrawPath(path)
        elif name == 'line':
            x1, y1, x2, y2 = map(float, (attr['x1'], attr['y1'], attr['x2'], attr['y2']))
            # 1.3.6.3 [JWDJ] 2015-3 Fill and stroke already have been set
            # self.set_fill(dc, 'none')
            # self.set_stroke(dc, stroke, float(attr.get('stroke-width', 1.0)), attr.get('stroke-linecap', 'butt'), attr.get('stroke-dasharray', None))
            # 1.3.6.3 [JWDJ] 2015-3 Fixes line in !segno!
            dc.DrawLines([(x1, y1), (x2, y2)])

        if transform:
            dc.PopState()