def PDFSetFont(pdf, font_name, font_size):
    """
    Sets the font and returns the lineheight.
    """
    pdf.setFont(font_name, font_size)
    ascent, descent = getAscentDescent(font_name, font_size)
    return (ascent - descent)  # Returns line height
Beispiel #2
0
    def _draw_textarea(self, canvas: Canvas, op: OrderPosition, order: Order, o: dict):
        font = o['fontfamily']
        if o['bold']:
            font += ' B'
        if o['italic']:
            font += ' I'

        align_map = {
            'left': TA_LEFT,
            'center': TA_CENTER,
            'right': TA_RIGHT
        }
        style = ParagraphStyle(
            name=uuid.uuid4().hex,
            fontName=font,
            fontSize=float(o['fontsize']),
            leading=float(o['fontsize']),
            autoLeading="max",
            textColor=Color(o['color'][0] / 255, o['color'][1] / 255, o['color'][2] / 255),
            alignment=align_map[o['align']]
        )
        text = re.sub(
            "<br[^>]*>", "<br/>",
            bleach.clean(
                self._get_text_content(op, order, o) or "",
                tags=["br"], attributes={}, styles=[], strip=True
            )
        )
        p = Paragraph(text, style=style)
        p.wrapOn(canvas, float(o['width']) * mm, 1000 * mm)
        # p_size = p.wrap(float(o['width']) * mm, 1000 * mm)
        ad = getAscentDescent(font, float(o['fontsize']))
        p.drawOn(canvas, float(o['left']) * mm, float(o['bottom']) * mm - ad[1])
def PDFSetFont(pdf, font_name, font_size):
    """
    Sets the font and returns the lineheight.
    """
    pdf.setFont(font_name, font_size)
    ascent, descent = getAscentDescent(font_name, font_size)
    return (ascent - descent)  # Returns line height
Beispiel #4
0
    def _draw_textarea(self, canvas: Canvas, op: OrderPosition, order: Order,
                       o: dict):
        font = o['fontfamily']
        if o['bold']:
            font += ' B'
        if o['italic']:
            font += ' I'

        align_map = {'left': TA_LEFT, 'center': TA_CENTER, 'right': TA_RIGHT}
        style = ParagraphStyle(name=uuid.uuid4().hex,
                               fontName=font,
                               fontSize=float(o['fontsize']),
                               leading=float(o['fontsize']),
                               autoLeading="max",
                               textColor=Color(o['color'][0] / 255,
                                               o['color'][1] / 255,
                                               o['color'][2] / 255),
                               alignment=align_map[o['align']])
        text = re.sub(
            "<br[^>]*>", "<br/>",
            bleach.clean(self._get_text_content(op, order, o) or "",
                         tags=["br"],
                         attributes={},
                         styles=[],
                         strip=True))
        p = Paragraph(text, style=style)
        p.wrapOn(canvas, float(o['width']) * mm, 1000 * mm)
        # p_size = p.wrap(float(o['width']) * mm, 1000 * mm)
        ad = getAscentDescent(font, float(o['fontsize']))
        p.drawOn(canvas,
                 float(o['left']) * mm,
                 float(o['bottom']) * mm - ad[1])
Beispiel #5
0
    def __init__(self,
                 name: str,
                 char: str,
                 font_family: str,
                 font_fullname: str,
                 font_size: int,
                 color: str,
                 standalone: bool,
                 takes_lyric: bool,
                 lyric_offset: float,
                 keep_with_next: bool,
                 offset: [float, float] = (0.0, 0.0)):
        self.name: str = name  # The name in standard BNML
        self.char: str = char  # The character in a TTF
        self.font_family: str = font_family  # The font family name
        self.font_fullname: str = font_fullname  # The specific font file name
        self.font_size: int = font_size
        self.color: str = color
        self.width: float = pdfmetrics.stringWidth(self.char,
                                                   self.font_fullname,
                                                   self.font_size)
        ascent, descent = pdfmetrics.getAscentDescent(self.font_fullname,
                                                      self.font_size)
        self.height: float = ascent - descent
        self.standalone: bool = standalone
        self.takes_lyric: bool = takes_lyric
        self.lyric_offset: float = lyric_offset
        self.keep_with_next: bool = keep_with_next
        self.offset: [float, float] = offset

        if self.font_fullname not in pdfmetrics.getRegisteredFontNames():
            raise Exception("Neume font {} is not registered".format(
                self.font_fullname))
 def _getBaseLineRatio(self):
     if self.useAscentDescent:
         self._ascent, self._descent = getAscentDescent(
             self.fontName, self.fontSize)
         self._baselineRatio = self._ascent / (self._ascent - self._descent)
     else:
         self._baselineRatio = 1 / 1.2
Beispiel #7
0
 def wrap(self, aW, aH):
     self._ascent, self._descent = getAscentDescent(self.fontName,self.fontSize)
     needHeight = self._ascent - self._descent + self.topPad + self.bottomPad
     needWidth = stringWidth(self.text,self.fontName,self.fontSize) + self.leftPad + self.rightPad + 0.5*needHeight
     specWidth = _getLength(aW,self._specWidth)
     self.width = needWidth if needWidth>specWidth else specWidth
     self.height = needHeight
     return self.width, self.height
Beispiel #8
0
    def _draw_textarea(self, canvas: Canvas, op: OrderPosition, order: Order,
                       o: dict):
        font = o['fontfamily']
        if o['bold']:
            font += ' B'
        if o['italic']:
            font += ' I'

        align_map = {'left': TA_LEFT, 'center': TA_CENTER, 'right': TA_RIGHT}
        style = ParagraphStyle(name=uuid.uuid4().hex,
                               fontName=font,
                               fontSize=float(o['fontsize']),
                               leading=float(o['fontsize']),
                               autoLeading="max",
                               textColor=Color(o['color'][0] / 255,
                                               o['color'][1] / 255,
                                               o['color'][2] / 255),
                               alignment=align_map[o['align']])
        text = conditional_escape(
            self._get_text_content(op, order, o)
            or "", ).replace("\n", "<br/>\n")

        # reportlab does not support RTL, ligature-heavy scripts like Arabic. Therefore, we use ArabicReshaper
        # to resolve all ligatures and python-bidi to switch RTL texts.
        configuration = {
            'delete_harakat': True,
            'support_ligatures': False,
        }
        reshaper = ArabicReshaper(configuration=configuration)
        try:
            text = "<br/>".join(
                get_display(reshaper.reshape(l)) for l in text.split("<br/>"))
        except:
            logger.exception('Reshaping/Bidi fixes failed on string {}'.format(
                repr(text)))

        p = Paragraph(text, style=style)
        w, h = p.wrapOn(canvas, float(o['width']) * mm, 1000 * mm)
        # p_size = p.wrap(float(o['width']) * mm, 1000 * mm)
        ad = getAscentDescent(font, float(o['fontsize']))
        canvas.saveState()
        # The ascent/descent offsets here are not really proven to be correct, they're just empirical values to get
        # reportlab render similarly to browser canvas.
        if o.get('downward', False):
            canvas.translate(float(o['left']) * mm, float(o['bottom']) * mm)
            canvas.rotate(o.get('rotation', 0) * -1)
            p.drawOn(canvas, 0, -h - ad[1] / 2)
        else:
            canvas.translate(
                float(o['left']) * mm,
                float(o['bottom']) * mm + h)
            canvas.rotate(o.get('rotation', 0) * -1)
            p.drawOn(canvas, 0, -h - ad[1])
        canvas.restoreState()
Beispiel #9
0
 def __init__(self, text, font_family, font_size, color, top_margin):
     self.text = text
     self.font_family = font_family
     self.font_size = font_size
     self.color = color
     self.top_margin = top_margin
     self.width = pdfmetrics.stringWidth(self.text, self.font_family,
                                         self.font_size)
     ascent, descent = pdfmetrics.getAscentDescent(self.font_family,
                                                   self.font_size)
     self.height = ascent - descent
Beispiel #10
0
 def __init__(self,
              text: str = None,
              x_padding: int = 10,
              style: ParagraphStyle = ParagraphStyle('Dropcap')):
     super().__init__()
     self.text = text
     self.x_padding = x_padding
     self.style = style
     self.width = pdfmetrics.stringWidth(self.text, self.style.fontName,
                                         self.style.fontSize)
     ascent, descent = pdfmetrics.getAscentDescent(self.style.fontName,
                                                   self.style.fontSize)
     self.height = max(ascent - descent, self.style.leading)
Beispiel #11
0
 def wrap(self, w, h):
     self.width = w
     fontSize = self.maxFontSize
     aW = w - self.leftPad - self.rightPad
     sw0 = stringWidth(self.text,self.fontName,self.maxFontSize)
     if sw0 > aW:
         fontSize *= float(aW)/sw0
     self.fontSize = fontSize
     ad = getAscentDescent(self.fontName,fontSize)
     self.height = self.topPad+self.bottomPad+ad[0]-ad[1]
     self._ascent = ad[0]
     self._descent = ad[1]
     return w, self.height
Beispiel #12
0
    def computeSize(self):
        # the thing will draw in its own coordinate system
        self._lineWidths = []
        topPadding = self.topPadding
        leftPadding = self.leftPadding
        rightPadding = self.rightPadding
        bottomPadding = self.bottomPadding
        self._lines = simpleSplit(self._text, self.fontName, self.fontSize,
                                  self.maxWidth)
        if not self.width:
            self._width = leftPadding + rightPadding
            if self._lines:
                self._lineWidths = [
                    stringWidth(line, self.fontName, self.fontSize)
                    for line in self._lines
                ]
                self._width += max(self._lineWidths)
        else:
            self._width = self.width
        if self.useAscentDescent:
            self._ascent, self._descent = getAscentDescent(
                self.fontName, self.fontSize)
            self._baselineRatio = self._ascent / (self._ascent - self._descent)
        else:
            self._baselineRatio = 1 / 1.2
        if self.leading:
            self._leading = self.leading
        elif self.useAscentDescent:
            self._leading = self._ascent - self._descent
        else:
            self._leading = self.fontSize * 1.2
        self._height = self.height or (self._leading * len(self._lines) +
                                       topPadding + bottomPadding)
        self._ewidth = (self._width - leftPadding - rightPadding)
        self._eheight = (self._height - topPadding - bottomPadding)
        boxAnchor = self._getBoxAnchor()
        if boxAnchor in ['n', 'ne', 'nw']:
            self._top = -topPadding
        elif boxAnchor in ['s', 'sw', 'se']:
            self._top = self._height - topPadding
        else:
            self._top = 0.5 * self._eheight
        self._bottom = self._top - self._eheight

        if boxAnchor in ['ne', 'e', 'se']:
            self._left = leftPadding - self._width
        elif boxAnchor in ['nw', 'w', 'sw']:
            self._left = leftPadding
        else:
            self._left = -self._ewidth * 0.5
        self._right = self._left + self._ewidth
Beispiel #13
0
 def wrap(self, w, h):
     self.width = w
     from reportlab.pdfbase.pdfmetrics import getAscentDescent, stringWidth
     fontSize = self.maxFontSize
     aW = w - self.leftPad - self.rightPad
     sw0 = stringWidth(self.text,self.fontName,self.maxFontSize)
     if sw0 > aW:
         fontSize *= float(aW)/sw0
     self.fontSize = fontSize
     ad = getAscentDescent(self.fontName,fontSize)
     self.height = self.topPad+self.bottomPad+ad[0]-ad[1]
     self._ascent = ad[0]
     self._descent = ad[1]
     return w, self.height
Beispiel #14
0
    def computeSize(self):
        # the thing will draw in its own coordinate system
        self._lineWidths = []
        topPadding = self.topPadding
        leftPadding = self.leftPadding
        rightPadding = self.rightPadding
        bottomPadding = self.bottomPadding
        self._lines = simpleSplit(self._text,self.fontName,self.fontSize,self.maxWidth)
        if not self.width:
            self._width = leftPadding+rightPadding
            if self._lines:
                self._lineWidths = [stringWidth(line,self.fontName,self.fontSize) for line in self._lines]
                self._width += max(self._lineWidths)
        else:
            self._width = self.width
        if self.useAscentDescent:
            self._ascent, self._descent = getAscentDescent(self.fontName,self.fontSize)
            self._baselineRatio = self._ascent/(self._ascent-self._descent)
        else:
            self._baselineRatio = 1/1.2
        if self.leading:
            self._leading = self.leading
        elif self.useAscentDescent:
            self._leading = self._ascent - self._descent
        else:
            self._leading = self.fontSize*1.2
        self._height = self.height or (self._leading*len(self._lines) + topPadding + bottomPadding)
        self._ewidth = (self._width-leftPadding-rightPadding)
        self._eheight = (self._height-topPadding-bottomPadding)
        boxAnchor = self._getBoxAnchor()
        if boxAnchor in ['n','ne','nw']:
            self._top = -topPadding
        elif boxAnchor in ['s','sw','se']:
            self._top = self._height-topPadding
        else:
            self._top = 0.5*self._eheight
        self._bottom = self._top - self._eheight

        if boxAnchor in ['ne','e','se']:
            self._left = leftPadding - self._width
        elif boxAnchor in ['nw','w','sw']:
            self._left = leftPadding
        else:
            self._left = -self._ewidth*0.5
        self._right = self._left+self._ewidth
Beispiel #15
0
 def drawText(this,c,text,font,size,maxwidth = -1):
     # getAscentDescent doesn't take font sizes in the 
     # old version of reportlab, so we'll do the conversion
     # ourselves a la the version in svn.
     if maxwidth == -1:
         maxwidth = this.maxtextwidth
     if maxwidth != -1:
         # adjust font size to handle maximum width
         width = pdfmetrics.stringWidth(text, font, size) 
         if (width > maxwidth):
             size = float(size)*(float(maxwidth)/float(width))
     (a,d) = pdfmetrics.getAscentDescent(font)
     norm = size/1000.0
     (a,d) = (a*norm,d*norm)
     c.setFont(font,size)
     this.y = this.y - a
     if this.doDraw:
         c.drawCentredString(this.centerline,this.y,text)
     this.y = this.y - d
Beispiel #16
0
    def _draw_textarea(self, canvas: Canvas, op: OrderPosition, order: Order,
                       o: dict):
        font = o['fontfamily']
        if o['bold']:
            font += ' B'
        if o['italic']:
            font += ' I'

        align_map = {'left': TA_LEFT, 'center': TA_CENTER, 'right': TA_RIGHT}
        style = ParagraphStyle(name=uuid.uuid4().hex,
                               fontName=font,
                               fontSize=float(o['fontsize']),
                               leading=float(o['fontsize']),
                               autoLeading="max",
                               textColor=Color(o['color'][0] / 255,
                                               o['color'][1] / 255,
                                               o['color'][2] / 255),
                               alignment=align_map[o['align']])
        text = re.sub(
            "<br[^>]*>", "<br/>",
            bleach.clean(self._get_text_content(op, order, o) or "",
                         tags=["br"],
                         attributes={},
                         styles=[],
                         strip=True))

        # reportlab does not support RTL, ligature-heavy scripts like Arabic. Therefore, we use ArabicReshaper
        # to resolve all ligatures and python-bidi to switch RTL texts.
        configuration = {
            'delete_harakat': True,
            'support_ligatures': False,
        }
        reshaper = ArabicReshaper(configuration=configuration)
        text = "<br/>".join(
            get_display(reshaper.reshape(l)) for l in text.split("<br/>"))

        p = Paragraph(text, style=style)
        p.wrapOn(canvas, float(o['width']) * mm, 1000 * mm)
        # p_size = p.wrap(float(o['width']) * mm, 1000 * mm)
        ad = getAscentDescent(font, float(o['fontsize']))
        p.drawOn(canvas,
                 float(o['left']) * mm,
                 float(o['bottom']) * mm - ad[1])
Beispiel #17
0
 def drawText(this, c, text, font, size, maxwidth=-1):
     # getAscentDescent doesn't take font sizes in the
     # old version of reportlab, so we'll do the conversion
     # ourselves a la the version in svn.
     if maxwidth == -1:
         maxwidth = this.maxtextwidth
     if maxwidth != -1:
         # adjust font size to handle maximum width
         width = pdfmetrics.stringWidth(text, font, size)
         if (width > maxwidth):
             size = float(size) * (float(maxwidth) / float(width))
     (a, d) = pdfmetrics.getAscentDescent(font)
     norm = size / 1000.0
     (a, d) = (a * norm, d * norm)
     c.setFont(font, size)
     this.y = this.y - a
     if this.doDraw:
         c.drawCentredString(this.centerline, this.y, text)
     this.y = this.y - d
Beispiel #18
0
 def __init__(self,
              char: str,
              font_family: str,
              font_size: int,
              color: str,
              offset_x: int = 0,
              offset_y: int = 0):
     self.char: str = char  # The character in a TTF
     if font_family not in pdfmetrics.getRegisteredFontNames():
         raise Exception("Neume font is not registered")
     self.font_family = font_family
     self.font_size = font_size
     self.color = color
     self.offset_x = 0
     self.offset_y = 0
     self.width = pdfmetrics.stringWidth(self.char, self.font_family,
                                         self.font_size)
     ascent, descent = pdfmetrics.getAscentDescent(self.font_family,
                                                   self.font_size)
     self.height = ascent - descent
 def __init__(self, text, style, kerning):
     assert isinstance(text, unicode)
     super(StyledText, self).__init__(style)
     self.text = text
     self.width = self.str_width(text, style)
     if kerning:
         # Take kerning into account
         font = pdfmetrics.getFont(style.fontName)
         face = font.face
         kp = kerning_pairs(face, text)
         skp = sum(kp)
         #print "skp=", skp
         self.kerning_pairs = kp
         self.width += 0.001*style.fontSize*skp
         #print "Kerning!"
     else:
         self.kerning_pairs = None
     if hasattr(style, "nobr"):
         self.nobr = True
     cbDefn = getattr(style,"cbDefn", None)
     if cbDefn is not None and not self.width:
         self.width = getattr(cbDefn, "width", 0)
     self.ascent, self.descent = pdfmetrics.getAscentDescent(style.fontName, style.fontSize)
 def __init__(self, text, style, kerning):
     assert isinstance(text, unicode)
     super(StyledText, self).__init__(style)
     self.text = text
     self.width = self.str_width(text, style)
     if kerning:
         # Take kerning into account
         font = pdfmetrics.getFont(style.fontName)
         face = font.face
         kp = kerning_pairs(face, text)
         skp = sum(kp)
         #print "skp=", skp
         self.kerning_pairs = kp
         self.width += 0.001 * style.fontSize * skp
         #print "Kerning!"
     else:
         self.kerning_pairs = None
     if hasattr(style, "nobr"):
         self.nobr = True
     cbDefn = getattr(style, "cbDefn", None)
     if cbDefn is not None and not self.width:
         self.width = getattr(cbDefn, "width", 0)
     self.ascent, self.descent = pdfmetrics.getAscentDescent(
         style.fontName, style.fontSize)
Beispiel #21
0
    text = "l Guilhem Vell AV T.W. Lewis"
    cached_shape = canvas_shapeHB(pdf_canvas, text)
    drawStringHB(pdf_canvas, 1.5 * inch, 1.7 * inch, text, cached_shape)
    pdf_canvas.drawString(1.5 * inch, 2 * inch, text)

    # draw bbox
    def draw_bbox(size, pos):
        pdf_canvas.saveState()
        pdf_canvas.setStrokeColor(red)
        pdf_canvas.setLineWidth(1)
        p = pdf_canvas.beginPath()
        p.rect(*size, *pos)
        pdf_canvas.drawPath(p, stroke=True, fill=False)
        pdf_canvas.restoreState()

    asc, desc = pdfmetrics.getAscentDescent(*font)
    width = stringWidthHB(cached_shape)
    draw_bbox((1.5 * inch, 1.7 * inch + desc), (width, asc - desc))

    width = pdfmetrics.stringWidth(text, *font)
    draw_bbox((1.5 * inch, 2 * inch + desc), (width, asc - desc))

    pdf_canvas.restoreState()
    pdf_canvas.showPage()
    pdf_canvas.save()

    import freetype  # isort:skip
    from freetype.ft_enums import FT_LOAD_NO_SCALE  # isort:skip

    pdfmetrics.registerFont(TTFont("FiraCode-Regular", "tests/FiraCode-Regular.ttf"))
    face = freetype.Face("tests/FiraCode-Regular.ttf")
Beispiel #22
0
    def breakLines(self, width):
        """
        Returns a broken line structure. There are two cases

        A) For the simple case of a single formatting input fragment the output is
            A fragment specifier with
                - kind = 0
                - fontName, fontSize, leading, textColor
                - lines=  A list of lines

                        Each line has two items.

                        1. unused width in points
                        2. word list

        B) When there is more than one input formatting fragment the output is
            A fragment specifier with
               - kind = 1
               - lines=  A list of fragments each having fields
                            - extraspace (needed for justified)
                            - fontSize
                            - words=word list
                                each word is itself a fragment with
                                various settings

        This structure can be used to easily draw paragraphs with the various alignments.
        You can supply either a single width or a list of widths; the latter will have its
        last item repeated until necessary. A 2-element list is useful when there is a
        different first line indent; a longer list could be created to facilitate custom wraps
        around irregular objects."""

        if self.debug:
            print id(self), "breakLines"

        if not isinstance(width,(tuple,list)): maxWidths = [width]
        else: maxWidths = width
        lines = []
        lineno = 0
        style = self.style

        #for bullets, work out width and ensure we wrap the right amount onto line one
        _handleBulletWidth(self.bulletText,style,maxWidths)

        maxWidth = maxWidths[0]

        self.height = 0
        autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
        calcBounds = autoLeading not in ('','off')
        frags = self.frags
        nFrags= len(frags)
        if nFrags==1 and not hasattr(frags[0],'cbDefn'):
            f = frags[0]
            fontSize = f.fontSize
            fontName = f.fontName
            ascent, descent = getAscentDescent(fontName,fontSize)

            # wordsplit is here
            if hasattr(f, 'text'):
                words = split(f.text)
                if not words and hasattr(f, 'words'):
                    words = f.words
            else:
                words = f.words

            #words = hasattr(f,'text') and split(f.text, ' ') or f.words

            spaceWidth = stringWidth(' ', fontName, fontSize, self.encoding)
            cLine = []
            currentWidth = -spaceWidth   # hack to get around extra space for word 1
            for word in words:
                #this underscores my feeling that Unicode throughout would be easier!
                wordWidth = stringWidth(word, fontName, fontSize, self.encoding)
                newWidth = currentWidth + spaceWidth + wordWidth
                if newWidth <= maxWidth or not len(cLine):
                    # fit one more on this line
                    cLine.append(word)
                    currentWidth = newWidth
                else:
                    if currentWidth > self.width: self.width = currentWidth
                    #end of line
                    lines.append((maxWidth - currentWidth, cLine))
                    cLine = [word]
                    currentWidth = wordWidth
                    lineno += 1
                    try:
                        maxWidth = maxWidths[lineno]
                    except IndexError:
                        maxWidth = maxWidths[-1]  # use the last one

            #deal with any leftovers on the final line
            if cLine!=[]:
                if currentWidth>self.width: self.width = currentWidth
                lines.append((maxWidth - currentWidth, cLine))

            return f.clone(kind=0, lines=lines,ascent=ascent,descent=descent,fontSize=fontSize)
        elif nFrags<=0:
            return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName,
                            textColor=style.textColor, ascent=style.fontSize,descent=-0.2*style.fontSize,
                            lines=[])
        else:
            #if hasattr(self,'blPara') and getattr(self,'_splitpara',0):
            #    #NB this is an utter hack that awaits the proper information
            #    #preserving splitting algorithm
            #    return self.blPara
            n = 0

            # words is not a list of texts
            # it's a list of fragments, that is only ever size one or zero
            words = []
            wordfrags = []

            for fragment in frags:
                fragment_words = _getFragWords([fragment], use_bidi=self.use_bidi)
                if self.use_bidi:
                    fragment_words.reverse()
                wordfrags += fragment_words

            for w in wordfrags:
                # f is the frag
                f=w[-1][0]
                fontName = f.fontName
                fontSize = f.fontSize
                if sys.modules.has_key('PyICU'):
                    spaceWidth = 0
                else:
                    spaceWidth = stringWidth(' ',fontName, fontSize)

                # if at the beginning of a line
                if not words:
                    currentWidth = -spaceWidth   # hack to get around extra space for word 1
                    maxSize = fontSize
                    maxAscent, minDescent = getAscentDescent(fontName,fontSize)

                wordWidth = w[0]
                f = w[1][0]
                if wordWidth>0:
                    newWidth = currentWidth + spaceWidth + wordWidth
                else:
                    newWidth = currentWidth
                # newWidth is is essentially the proposed width of
                # previous width of line plus the next(current) word

                #test to see if this frag is a line break. If it is we will only act on it
                #if the current width is non-negative or the previous thing was a deliberate lineBreak
                lineBreak = hasattr(f,'lineBreak')
                endLine = (newWidth>maxWidth and n>0) or lineBreak
                # we never hit linebreak
                # so this is testing if newWidth is too large
                if not endLine:
                    if lineBreak: continue      #throw it away
                    # nText is the actual word
                    nText = w[1][1]
                    if nText: n += 1
                    fontSize = f.fontSize
                    if calcBounds:
                        #cbDefn = getattr(f,'cbDefn',None)
                        #if getattr(cbDefn,'width',0):
                        #    descent,ascent = imgVRange(cbDefn.height,cbDefn.valign,fontSize)
                        #else:
                        ascent, descent = getAscentDescent(f.fontName,fontSize)
                    else:
                        ascent, descent = getAscentDescent(f.fontName,fontSize)
                    maxSize = max(maxSize,fontSize)
                    maxAscent = max(maxAscent,ascent)
                    minDescent = min(minDescent,descent)
                    if not words:
                        g = f.clone()
                        words = [g]
                        # g.text = nText
                        g.text = [nText]
                    #elif not _sameFrag(g,f):
                    #    if currentWidth>0 and ((nText!='' and nText[0]!=' ') or hasattr(f,'cbDefn')):
                    #        #if hasattr(g,'cbDefn'):
                    #        #    i = len(words)-1
                    #        #    while i>=0:
                    #        #        wi = words[i]
                    #        #        cbDefn = getattr(wi,'cbDefn',None)
                    #        #        if cbDefn:
                    #        #            if not getattr(cbDefn,'width',0):
                    #        #                i -= 1
                    #        #                continue
                    #        #        if not wi.text.endswith(' '):
                    #        #            wi.text += ' '
                    #        #        break
                    #        #else:
                    #        if not g.text.endswith(' '):
                    #            g.text += ' '
                    #    g = f.clone()
                    #    words.append(g)
                    #    g.text = nText
                    else:
                        #if nText!='' and nText[0]!=' ':
                        if nText != '':
                            #g.text += ' ' + nText
                            g.text.append(nText)

                    #for i in w[2:]:
                    #    g = i[0].clone()
                    #    g.text=i[1]
                    #    words.append(g)
                    #    fontSize = g.fontSize
                    #    if calcBounds:
                    #        #cbDefn = getattr(g,'cbDefn',None)
                    #        #if getattr(cbDefn,'width',0):
                    #        #    descent,ascent = imgVRange(cbDefn.height,cbDefn.valign,fontSize)
                    #        #else:
                    #        ascent, descent = getAscentDescent(g.fontName,fontSize)
                    #    else:
                    #        ascent, descent = getAscentDescent(g.fontName,fontSize)
                    #    maxSize = max(maxSize,fontSize)
                    #    maxAscent = max(maxAscent,ascent)
                    #    minDescent = min(minDescent,descent)

                    currentWidth = newWidth
                else:  #either it won't fit, or it's a lineBreak tag
                    if lineBreak:
                        g = f.clone()
                        #del g.lineBreak
                        words.append(g)
                        g.text = []

                    if currentWidth>self.width: self.width = currentWidth
                    #end of line
                    if self.use_bidi:
                        words.reverse()
                    for item in words:
                        if self.use_bidi:
                            item.text.reverse()
                        if sys.modules.has_key('PyICU'):
                            item.text = ''.join(item.text)
                        else:
                            item.text = ' '.join(item.text)

                    lines.append(FragLine(extraSpace=maxWidth-currentWidth, wordCount=n,
                                          lineBreak=lineBreak, words=words, fontSize=maxSize,
                                          ascent=maxAscent, descent=minDescent))

                    #start new line
                    lineno += 1

                    # attempt to reset the maxWidth of the new line
                    try:
                        maxWidth = maxWidths[lineno]
                    except IndexError:
                        maxWidth = maxWidths[-1]  # use the last one

                    if lineBreak:
                        n = 0
                        words = []
                        continue

                    # because there was no linebreak
                    # reuse the current word as the first word of the next line
                    currentWidth = wordWidth
                    n = 1
                    g = f.clone()
                    maxSize = g.fontSize
                    if calcBounds:
                        #cbDefn = getattr(g,'cbDefn',None)
                        #if getattr(cbDefn,'width',0):
                        #    minDescent,maxAscent = imgVRange(cbDefn.height,cbDefn.valign,maxSize)
                        #else:
                        maxAscent, minDescent = getAscentDescent(g.fontName,maxSize)
                    else:
                        maxAscent, minDescent = getAscentDescent(g.fontName,maxSize)
                    words = [g]
                    #g.text = w[1][1]
                    g.text = [w[1][1]]

                    #for i in w[2:]:
                    #    g = i[0].clone()
                    #    g.text=i[1]
                    #    words.append(g)
                    #    fontSize = g.fontSize
                    #    if calcBounds:
                    #        #cbDefn = getattr(g,'cbDefn',None)
                    #        #if getattr(cbDefn,'width',0):
                    #        #    descent,ascent = imgVRange(cbDefn.height,cbDefn.valign,fontSize)
                    #        #else:
                    #        ascent, descent = getAscentDescent(g.fontName,fontSize)
                    #    else:
                    #        ascent, descent = getAscentDescent(g.fontName,fontSize)
                    #    maxSize = max(maxSize,fontSize)
                    #    maxAscent = max(maxAscent,ascent)
                    #    minDescent = min(minDescent,descent)

            # end for loop

            #deal with any leftovers on the final line
            if words != []:
                if currentWidth>self.width: self.width = currentWidth
                if self.use_bidi:
                    words.reverse()
                for item in words:
                    if self.use_bidi:
                        item.text.reverse()
                    if sys.modules.has_key('PyICU'):
                        item.text = ''.join(item.text)
                    else:
                        item.text = ' '.join(item.text)

                lines.append(ParaLines(extraSpace=(maxWidth - currentWidth),wordCount=n,
                                    words=words, fontSize=maxSize,ascent=maxAscent,descent=minDescent))

            return ParaLines(kind=1, lines=lines)

        return lines
Beispiel #23
0
 def set_height(self, neume):
     ascent, descent = pdfmetrics.getAscentDescent(neume.font_fullname,
                                                   neume.font_size)
     self.height = ascent - descent
def create_faceplate(basename, style, case, font, fontsize, reverse=True, color=None,
                     can=None, showtime=False, who=None, baffles=False, do_corner_holes=False,
                     top=None,
                     bottom=None, fpid='NA'):
    if font.title().startswith('Helvetica'):
        font = font.title()
    else:
        font = font.upper()

    if can is None:
        can = new_canvas(basename + '_W%s' % fpid)
        save_can = True
    else:
        save_can = False
    can.saveState()
    
    if save_can:
        pass ## text only
        # can.setFont('Courier', 18)
        # can.drawCentredString(WIDTH / 2 + MARGIN, HEIGHT+1.5*MARGIN, "%s %s" % (basename, __version__))
    if who:
        pass
        # can.drawCentredString(WIDTH / 2 + MARGIN, .5*MARGIN, who)
    can.setFont(font, fontsize)
    
    # can.drawString(MARGIN, MARGIN/4, "FPID: %s" % fpid)
        
    # can.drawString(MARGIN, HEIGHT + 3 * MARGIN / 2, font)
    if reverse:
        can.translate(WIDTH + 2 * MARGIN, 0)
        can.scale(-1, 1)
    else:
        can.drawCentredString(WIDTH / 2 + MARGIN, MARGIN/2, "SAMPLE ONLY, DO NOT PRINT")

    if top:
        # can.drawCentredString(WIDTH / 2 + MARGIN, HEIGHT - 1.3 * inch + MARGIN, top)
        pass 
    if bottom:
        # can.drawCentredString(WIDTH / 2 + MARGIN, .9 * inch + MARGIN, bottom)
        pass

    if color:
        can.setFillColor(color)
        can.rect(MARGIN, MARGIN, WIDTH, HEIGHT, fill=True)
        can.setFillColor(white)

    can.translate(MARGIN, MARGIN)
    outline().drawOn(can)

    
    
    x0 = (WIDTH - 2 * pcb_w)/2 + .2 * inch
    dx = 0.4 * inch
    nx = 32

    pcb = getPCB(outline=True, leds=True, buttons=True, button_holes=True)
    pcb.translate(x0 - dx/2, PCB_OFF)
    # pcb.drawOn(can)

    pcb.translate(pcb_w, 0)
    # pcb.drawOn(can)

    y0 = 2.10 * inch
    dy = 0.7 * inch
    ny = 8

    baffle_xs = arange(nx + 1) * dx + x0 - dx/2
    baffle_ys = arange(ny + 1) * dy + y0 - dy/2

    led_xs = arange(nx) * dx + x0
    led_ys = (arange(ny) * dy + y0)[::-1]
    if type(style) == type(''):
        lines = style.strip().splitlines()
    else:
        lines = style

################################################################################
    encName = 'winansi'
    decoder = codecs.lookup(encName)[1]
    def decodeFunc(txt):
        if txt is None:
            return ' '
        else:
            return case(decoder(txt, errors='replace')[0])
    # lines = [[decodeFunc(case(char)) for char in line] for line in lines]
################################################################################

    can.setFont(font, fontsize)

    asc, dsc = pdfmetrics.getAscentDescent(font,fontsize)
    if case('here') == 'HERE':
        v_off = asc/2
    else:
        v_off = asc/3
        if 'thegirlnextdoor' in font.lower():
            v_off = asc/5
    if 'italic' in font.lower():
        h_off = pdfmetrics.stringWidth('W', font, fontsize) / 8.
    else:
        h_off = 0
    
    if showtime:
        can.setFillColor((.1, .1, .1))

    xmin = min(baffle_xs)
    xmax = max(baffle_xs)
    ymin = min(baffle_ys)
    ymax = max(baffle_ys)
    if baffles: ## DRAW_GRID???
        p = MyPath()
        for x in baffle_xs:
            drawline(p, x, ymin, x, ymax)
        for y in baffle_ys:
            drawline(p, xmin, y, xmax, y)
        p.drawOn(can, linewidth=linewidth)

    for i, y in enumerate(led_ys):
        for j, x in enumerate(led_xs):
            # can.circle(x, y, 2.5 * mm, fill=False)
            if len(lines[i]) > j:
                can.drawCentredString(x - h_off, y  - v_off, case(lines[i][j]))
    if showtime:
        can.setFillColor((1, 1, 1))
        timechars = [[0, 0], [0, 1],  # it 
                [0, 3], [0, 4],  # is
                [1, 0], [1, 1], [1, 2], [1, 3], # five
                [2, 3], [2, 4], # to
                [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], # three
                [5, 10], [5, 11], [5, 13], [5, 14], [5, 15], # in the
                [6, 8], [6, 9], [6, 10], [6, 11], [6, 12], [6, 13], [6, 14], # morning
                ]
        for i, j in timechars:
            can.drawCentredString(led_xs[j], led_ys[i]  - v_off, case(lines[i][j]))
            
        
    ## reference point
    can.setStrokeColor(black)
    can.setFillColor(black)
    # can.circle(baffle_xs[-1] + .25 * inch, baffle_ys[-1] + .25 * inch, .025, fill=True)
    can.circle(WIDTH - 1 * inch, 9 * inch, .025, fill=True)
    if save_can:
        can.showPage()
        can.save()
        print 'wrote', can._filename
    try:
        can.restoreState()
    except:
        pass


    return can._filename
Beispiel #25
0
def create_faceplate(basename, style, case, font, fontsize, reverse=True, color=None,
                     can=None, showtime=False, who=None, baffles=False, do_corner_holes=True,
                     top=None,
                     bottom=None,
                     NIL=False,
                     edgecolor=red):
    if font.title().startswith('Helvetica'):
        font = font.title()
    elif font.title().startswith('Times-Roman'):
        font = font.title()
    else:
        font = font.upper()

    if can is None:
        can = new_canvas(basename)
        save_can = True
    else:
        save_can = False
    can.saveState()

    if save_can:
        can.setFont('Courier', 18)
        can.drawCentredString(W / 2 + MARGIN, HEIGHT+1.5*MARGIN, "%s %s" % (basename, __version__))
    if who:
        can.drawCentredString(W / 2 + MARGIN, .5*MARGIN, who)
    can.setFont(font, fontsize)

    if reverse:
        can.translate(W + 2 * MARGIN, 0)
        can.scale(-1, 1)
    else:
        can.drawCentredString(W / 2 + MARGIN, H - 200 * mm, "BACKWARDS!! DO NOT PRINT!!")
    #     can.drawCentredString(W / 2 + MARGIN, HEIGHT + 1.5 * MARGIN, "If you can read this, do not print!")

    if top:
        print H  / inch
        can.drawCentredString(WIDTH / 2 + MARGIN, HEIGHT - 1.3 * inch + MARGIN, top)
    if bottom:
        lines = bottom.splitlines()
        line_h = .4 * inch
        start_y = .5 * inch + MARGIN + len(lines) * line_h
        for i, l in enumerate(lines):
            can.drawCentredString(WIDTH / 2 + MARGIN, start_y - i * line_h, l)
    if color:
        can.setFillColor(color)
        can.rect(MARGIN, MARGIN, WIDTH, HEIGHT, fill=True)
        can.setFillColor(white)

    can.translate(MARGIN, MARGIN)

    if NIL:
        NIL_LED_X = (WIDTH - 3 * inch) / 2
        NIL_LED_Y = HEIGHT - .75 * inch
        NIL_DX = 16.67 * mm
        NIL_DY = 17.946 * mm
        for i in range(10):
            x = NIL_LED_X + i * NIL_DX
            for j in range(2):
                y = NIL_LED_Y + j * NIL_DY
                can.rect(x, y, .1*inch, .2 * inch, fill=False)

    print edgecolor == black
    p = outline(color=edgecolor)
    if do_corner_holes:
        for hole in corner_holes:
            p.drill(*hole)
    p.drawOn(can, linewidth)
    
    x0 = (WIDTH - pcb_w)/2 + 15 * mm / 2
    dx = 15 * mm
    nx = 14

    y0 = (HEIGHT - pcb_h)/2 + 16 * mm / 2
    dy = 16 * mm
    ny = 13

    baffle_xs = arange(nx + 1) * dx + x0 - dx/2
    baffle_ys = arange(ny + 1) * dy + y0 - dy/2

    led_xs = arange(nx) * dx + x0
    led_ys = (arange(ny) * dy + y0)[::-1]
    if type(style) == type(''):
        lines = style.strip().splitlines()
    else:
        lines = style

################################################################################
    encName = 'winansi'
    encName = 'utf-8'
    decoder = codecs.lookup(encName)[1]
    def decodeFunc(txt):
        if txt is None:
            return ' '
        else:
            return case(decoder(txt, errors='replace')[0])
    def decodeFunc(txt):
        if txt is None:
            return ' '
        else:
            return txt
    lines = [[decodeFunc(case(char)) for char in line] for line in lines]
    print '\n'.join([''.join(l) for l in lines])
################################################################################

    can.setFont(font, fontsize)

    asc, dsc = pdfmetrics.getAscentDescent(font,fontsize)
    if case('here') == 'HERE':
        v_off = asc/2
    else:
        v_off = asc/3
        if 'thegirlnextdoor' in font.lower():
            v_off = asc/5
    if 'italic' in font.lower():
        h_off = pdfmetrics.stringWidth('W', font, fontsize) / 8.
    else:
        h_off = 0
    
    if showtime:
        can.setFillColor((.1, .1, .1))
    xmin = min(baffle_xs)
    xmax = max(baffle_xs)
    ymin = min(baffle_ys)
    ymax = max(baffle_ys)
    if baffles: ## DRAW_GRID???
        p = MyPath()
        for x in baffle_xs:
            drawline(p, x, ymin, x, ymax)
        for y in baffle_ys:
            drawline(p, xmin, y, xmax, y)
        p.drawOn(can, linewidth=1 * mm)

    for i, y in enumerate(led_ys):
        for j, x in enumerate(led_xs):
            # can.circle(x, y, 2.5 * mm, fill=False)
            if len(lines[i]) > j:
                can.drawCentredString(x - h_off, y  - v_off, case(lines[i][j]))
                # can.drawCentredString(x - h_off, y  - v_off, (lines[i][j]).upper())
#########################################################
# draw an apostrophe
    can.drawCentredString(168* mm, 42 * mm, "'")            
#########################################################
    if showtime:
        can.setFillColor((1, 1, 1))
        timechars = [[0, 0], [0, 1],  # it 
                [0, 3], [0, 4],  # is
                [1, 0], [1, 1], [1, 2], [1, 3], # five
                [2, 3], [2, 4], # to
                [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], # three
                [5, 10], [5, 11], [5, 13], [5, 14], [5, 15], # in the
                [6, 8], [6, 9], [6, 10], [6, 11], [6, 12], [6, 13], [6, 14], # morning
                ]
        for i, j in timechars:
            can.drawCentredString(led_xs[j], led_ys[i]  - v_off, case(lines[i][j]))
            
        
    if save_can:
        can.showPage()
        can.save()
        print 'wrote', can._filename
    try:
        can.restoreState()
    except:
        pass
    return can._filename
def font_height(font, size):
    """글꼴의 높이를 반환한다."""
    ascent, descent = getAscentDescent(font, size)
    return (ascent - descent) * LINE_HEIGHT
Beispiel #27
0
    def draw_on_pdf(cls,
                    canvas,
                    frequencies,
                    position=None,
                    size=None,
                    colors=None,
                    fontname='Helvetica'):
        """Draw sequence logo on pdf canvas.
        canvas   : PDF canvas provided by Reportlab PDF library
        position : tuple of (X, Y) to be drawn (default is (100,300))
        size     : tuple of dimension of logo (default is (N * 10, 100), N = length)
        colors   : dictionary of base to color name
                   default  A:brown, C:navy, G:olive, T:green
        fontname : name of font (default is Helvetica)               
        """
        N = len(frequencies)
        if colors is None:
            colors = {'A': 'brown', 'C': 'navy', 'G': 'olive', 'T': 'green'}
        if position is None: position = (100, 300)
        if size is None: size = (N * 10, 100)

        from reportlab.pdfbase import pdfmetrics
        from reportlab.pdfbase.pdfdoc import PDFError, PDFDocument
        #from reportlab.pdfbase.ttfonts import TTFont

        font_ac, font_dec = pdfmetrics.getAscentDescent(fontname)

        def sort_nucleotides(nucleotides):
            nucs = {
                'A': nucleotides[0],
                'C': nucleotides[1],
                'G': nucleotides[2],
                'T': nucleotides[3]
            }
            sorted_nucs = []
            for base in sorted(nucs.keys(), key=lambda a: nucs[a]
                               ):  #lambda a, b: -(nucs[a] > nucs[b])):
                sorted_nucs.append((base, nucs[base]))
                pass
            return sorted_nucs

        canvas.saveState()
        fontsize = 1.0
        canvas.setFont('Helvetica', fontsize)
        dx = float(size[0]) / float(N)
        font_coeff = 1.0 / (font_ac * 0.001)
        scale_x = dx
        for i, nucleotides in enumerate(frequencies):
            # print(i, cls.calculate_information(nucleotides))
            height_ratio = (2.0 - cls.calculate_information(nucleotides)) / 2.0 * size[1]\
                / fontsize
            x = i * dx + position[0]
            sorted_nucs = sort_nucleotides(nucleotides)
            total_count = sum(nucleotides)
            y = position[1]
            for base, count in sorted_nucs:
                if count == 0: continue
                canvas.saveState()
                canvas.translate(x, y)
                canvas.setFont(fontname, fontsize)
                scale_y = float(count) / total_count * height_ratio
                # print('{}:{}\tyscale  = {:.2f}, {:.2f}'.format(base, count, scale_y, height_ratio))
                canvas.scale(scale_x * 1.5, scale_y * font_coeff)
                canvas.setFillColor(colors[base])
                canvas.drawString(canvas.stringWidth(base) * -0.5, 0, base)
                canvas.restoreState()
                y += scale_y * fontsize
                pass
            pass
        canvas.restoreState()
        #canvas.rect(position[0], position[1], size[0], size[1])
        pass
            return case(decoder(txt, errors='replace')[0])

    def decodeFunc(txt):
        if txt is None:
            return ' '
        else:
            return txt

    lines = [[decodeFunc(case(char)) for char in line] for line in lines]
    print 'Layout:'
    print '\n'.join([''.join(l) for l in lines])
    ################################################################################

    can.setFont(font, fontsize)

    asc, dsc = pdfmetrics.getAscentDescent(font, fontsize)
    if case('here') == 'HERE':
        v_off = asc / 2
    else:
        v_off = asc / 3
        if 'thegirlnextdoor' in font.lower():
            v_off = asc / 5
    if 'italic' in font.lower():
        h_off = pdfmetrics.stringWidth('W', font, fontsize) / 8.
    else:
        h_off = 0

    if showtime:
        can.setFillColor((.1, .1, .1))
    xmin = min(baffle_xs)
    xmax = max(baffle_xs)