Пример #1
0
    def draw_label(self, c: Canvas, col: int, row: int, redemption_code: str):
        x = self.left_margin + (
            col + 0.5) * self.label_width + col * self.inner_margin
        y = self.page_height - self.top_margin - (row +
                                                  0.5) * self.label_height

        # Drawing label bounds helps when adjusting layout. Not for production.
        # self.draw_label_bounds(c, x, y)

        c.setFont("Courier-Bold", 13)
        c.drawString(x - 80, y + 14, redemption_code)

        c.setFont("Helvetica", 10)

        # Space to enter redemption month and day.
        p = c.beginPath()
        p.moveTo(x + 20, y + 12)
        p.lineTo(x + 45, y + 12)
        p.moveTo(x + 55, y + 12)
        p.lineTo(x + 80, y + 12)
        p.close()
        c.drawPath(p)
        c.drawCentredString(x + 15, y + 16, 'm:')
        c.drawCentredString(x + 50, y + 16, 'd:')

        # Space to enter redeemer's email address.
        p = c.beginPath()
        p.moveTo(x - 80, y - 14)
        p.lineTo(x + 80, y - 14)
        p.close()
        c.drawPath(p)
        c.drawCentredString(x, y - 24, 'email address')
Пример #2
0
def marker_spiral(
    canvas: Canvas,
    position: Point[float],
    size: Size[float],
    repititions: int,
):
    p = canvas.beginPath()

    spacing = (size.y - size.x) / repititions
    inner_radius_x = size.x / 1.3
    inner_radius_y = size.x / 2
    p.moveTo(position.x, position.y + inner_radius_y)
    for round in range(repititions):
        multiplier = lambda frac: spacing * (round + float(frac))
        p.curveTo(
            position.x + inner_radius_x + multiplier(0),
            position.y + inner_radius_y + multiplier(0),
            position.x + inner_radius_x + multiplier(0.25),
            position.y - inner_radius_y - multiplier(0.25),
            position.x,
            position.y - inner_radius_y - multiplier(0.5),
        )
        p.curveTo(
            position.x - inner_radius_x - multiplier(0.5),
            position.y - inner_radius_y - multiplier(0.75),
            position.x - inner_radius_x - multiplier(0.75),
            position.y + inner_radius_y + multiplier(1),
            position.x,
            position.y + inner_radius_y + multiplier(1),
        )

    canvas.drawPath(p, stroke=1)
Пример #3
0
def draw_crop_mark_h(x, y, c:canvas.Canvas, color):
    c.setLineWidth(.1)
    c.setStrokeColor(color)
    p = c.beginPath()
    p.moveTo(x - CROP_MARK_LENGTH / 2, y)
    p.lineTo(x + CROP_MARK_LENGTH / 2, y)
    c.drawPath(p, stroke=1, fill=0)
Пример #4
0
def draw_bg(c:canvas.Canvas, color):
    path = c.beginPath()
    path.moveTo(0, 0)
    path.lineTo(0, 30 * cm)
    path.lineTo(25 * cm, 30 * cm)
    path.lineTo(25 * cm, 0)
    c.setFillColor(color)
    c.drawPath(path, True, True)
 def draw_tab_bounds(self, c: Canvas, x: float, y: float, tab_width: float):
     p = c.beginPath()
     p.moveTo(x, y)
     p.lineTo(x, y + self.tab_height)
     p.lineTo(x + tab_width, y + self.tab_height)
     p.lineTo(x + tab_width, y)
     p.lineTo(x, y)
     p.close()
     c.drawPath(p)
Пример #6
0
 def draw_label_bounds(self, c: Canvas, x, y):
     p = c.beginPath()
     x -= 0.5*self.label_width
     y -= 0.5*self.label_height
     p.moveTo(x, y)
     p.lineTo(x, y + self.label_height)
     p.lineTo(x + self.label_width, y + self.label_height)
     p.lineTo(x + self.label_width, y)
     p.lineTo(x, y)
     p.close()
     c.drawPath(p)
Пример #7
0
 def draw_label_bounds(self, c: Canvas, x, y):
     p = c.beginPath()
     x -= 0.5 * self.label_width
     y -= 0.5 * self.label_height
     p.moveTo(x, y)
     p.lineTo(x, y + self.label_height)
     p.lineTo(x + self.label_width, y + self.label_height)
     p.lineTo(x + self.label_width, y)
     p.lineTo(x, y)
     p.close()
     c.drawPath(p)
    def draw_tab(self, c: Canvas, tab_num: int, redemption_code: str) -> None:
        tab_width = (self.page_width - self.left_margin -
                     self.right_margin) / self.num_tabs

        # (x,y) is bottom left corner of the tab:
        x = self.left_margin + (tab_num * tab_width)
        y = self.bottom_margin

        # Drawing tab bounds helps when adjusting layout. Not for production.
        #self.draw_tab_bounds(c, x, y, tab_width)
        self.draw_tab_guides(c, x, y, tab_width)

        c.saveState()
        c.translate(x + 0.5 * tab_width, y + 0.5 * self.tab_height)
        c.rotate(90)
        c.setFont("Helvetica", 13)
        c.drawString(-0.47 * self.tab_height, 0.1 * tab_width,
                     "Free Membership!")
        c.setFont("Courier-Bold", 16)
        c.drawString(-0.47 * self.tab_height, -0.25 * tab_width,
                     redemption_code)
        c.restoreState()

        return None

        c.setFont("Helvetica", 10)

        # Space to enter redemption month and day.
        p = c.beginPath()
        p.moveTo(x + 20, y + 12)
        p.lineTo(x + 45, y + 12)
        p.moveTo(x + 55, y + 12)
        p.lineTo(x + 80, y + 12)
        p.close()
        c.drawPath(p)
        c.drawCentredString(x + 15, y + 16, 'm:')
        c.drawCentredString(x + 50, y + 16, 'd:')

        # Space to enter redeemer's email address.
        p = c.beginPath()
        p.moveTo(x - 80, y - 14)
        p.lineTo(x + 80, y - 14)
        p.close()
        c.drawPath(p)
        c.drawCentredString(x, y - 24, 'email address')
Пример #9
0
def marker_diamond(
    canvas: Canvas,
    position: Point[float],
    size: Size[float],
    repititions: int,
):
    p = canvas.beginPath()

    spacing = (size.y - size.x) / repititions
    for round in range(repititions):
        offset = size.x + spacing * round
        p.moveTo(position.x, position.y + offset)
        p.lineTo(position.x + offset, position.y)
        p.lineTo(position.x, position.y - offset)
        p.lineTo(position.x - offset, position.y)
        p.lineTo(position.x, position.y + offset)

    canvas.drawPath(p, stroke=1)
Пример #10
0
    def draw(self, work_canvas: canvas.Canvas):
        if self.text and self.font:
            work_canvas.saveState()
            work_canvas.setFillColor(COLOR_WHITE)
            work_canvas.setStrokeColor(COLOR_WHITE)
            canvas_path = work_canvas.beginPath()
            for type_op, points in self.path:
                if type_op == cairo.PATH_MOVE_TO:
                    x, y = points
                    canvas_path.moveTo(x, y)

                elif type_op == cairo.PATH_LINE_TO:
                    x, y = points
                    canvas_path.lineTo(x, y)

                elif type_op == cairo.PATH_CURVE_TO:
                    x1, y1, x2, y2, x3, y3 = points
                    canvas_path.curveTo(x1, y1, x2, y2, x3, y3)

                elif type_op == cairo.PATH_CLOSE_PATH:
                    canvas_path.close()

            work_canvas.drawPath(canvas_path, fill=1, stroke=0)
            work_canvas.restoreState()
Пример #11
0
class YearlyPdf:

    client = Address()
    provider = Address()
    items = []
    title = "Faktura"
    vs = "00000000"
    creator = ""
    sign_image = None
    payment_days = 14
    paytype = "Převodem"
 
    pdffile = None
 
    def __init__(self):
        self.p = inflect.engine()
        #self.TIN = "123121414"
        #self.CAN = "13123123123"
        self.TIN = "23102404783"
        self.CAN = "20/13/31/2009 21/14/31/2009"

        self.TOP = 260
        self.LEFT = 20
 
        pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf'))
 
        self.pdffile = NamedTemporaryFile(delete=False)
         
        self.pdf = Canvas(self.pdffile.name, pagesize = A4)
        self.pdf.setFont("DejaVu", 15)
        self.pdf.setStrokeColorRGB(0, 0, 0)
 
    def __del__(self):
        if os.path.isfile(self.pdffile.name):
            os.unlink(self.pdffile.name)
 
    #############################################################
    ## Setters
    #############################################################
     
    def setClient(self, address):
        self.client = address
 
    def setProvider(self, address):
        self.provider = address
 
    def setTitle(self, value):
        self.title = value
         
    def setVS(self, value):
        self.vs = value
 
    def setCreator(self, value):
        self.creator = value
 
    def setPaytype(self, value):
        self.paytype = value
 
    def setPaymentDays(self, value):
        self.payment_days = int(value)
 
    def addItem(self, item):
        self.items.append(item)
 
    #############################################################
    ## Getters
    #############################################################
 
    def getContent(self):
        # Texty
        self.drawMain()
        self.drawProvider(self.TOP-8,self.LEFT+3)
        #        self.drawClient(self.TOP-30,self.LEFT+91)
        #self.drawPayment(self.TOP-26,self.LEFT+3)
        self.pdf.setFont("DejaVu", 18)

        self.drawDates(self.TOP-10,self.LEFT+91)
        p = self.drawsItems(self.TOP-35,self.LEFT)

        #self.pdf.setFillColorRGB(0, 0, 0)
 
        self.pdf.showPage()
        self.pdf.save()
 
        f = open(self.pdffile.name)
        data = f.read()
        f.close()
 
        os.unlink(self.pdffile.name)
 
        return data
 
    #############################################################
    ## Draw methods
    #############################################################
 
    def drawMain(self):
        # Horní lajna
        self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title)
        self.pdf.drawString((self.LEFT+65)*mm, self.TOP*mm, "Balance Sheet")
        self.pdf.setFont("DejaVu", 8)
        self.pdf.drawString((self.LEFT+120)*mm, (self.TOP)*mm, "Dated to: %s" % self.todate)
        self.pdf.drawString((self.LEFT+120)*mm, (self.TOP+3)*mm, "Dated from: %s" % self.fromdate)

 
        # Rámečky
        #self.pdf.rect((self.LEFT)*mm, (self.TOP-38)*mm, (self.LEFT+156)*mm, 35*mm, stroke=True, fill=False)
 
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm)
        self.pdf.drawPath(path, True, True)
 
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT)*mm, (self.TOP-20)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm)
        self.pdf.drawPath(path, True, True)
 
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm)
        path.lineTo((self.LEFT+176)*mm, (self.TOP-26)*mm)
        self.pdf.drawPath(path, True, True)
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm)
        self.pdf.drawPath(path, True, True)
 
    def drawClient(self,TOP,LEFT):
        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel")
        self.pdf.setFont("DejaVu", 8)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.client.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm)
        text.textLines("\n".join(self.client.getContactLines()))
        self.pdf.drawText(text)
 
    def drawProvider(self,TOP,LEFT):
        LEFT += 90
        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Address")
        self.pdf.setFont("DejaVu", 9)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.provider.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.provider.getContactLines()))
        self.pdf.drawText(text)
        if self.provider.note:
            self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note)
 
    def drawPayment(self,TOP,LEFT):
        self.pdf.setFont("DejaVu", 11)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Patient Name")
        self.pdf.drawString((LEFT+50)*mm, (TOP)*mm, "Date")
        self.pdf.setFont("DejaVu", 9)
        text = self.pdf.beginText((LEFT+50)*mm, (TOP-6)*mm)
        text.textLines(self.date)
        self.pdf.drawText(text)
        
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.client.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm)
        text.textLines("\n".join(self.client.getContactLines()))
        self.pdf.drawText(text)
 
        self.pdf.drawText(text)
        
    def drawsItems(self,TOP,LEFT):
        LEFT += 10
        # Items
        #path = self.pdf.beginPath()
        #path.moveTo((LEFT)*mm, (TOP-4)*mm)
        #path.lineTo((LEFT+176)*mm, (TOP-4)*mm)
        #self.pdf.drawPath(path, True, True)
        
        self.pdf.setFont("DejaVu", 11)
        i=1
        self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, "Date")
        self.pdf.drawString((LEFT+40)*mm, (TOP-i)*mm, "Sale")
        self.pdf.drawString((LEFT+75)*mm, (TOP-i)*mm, "Purchase")
        self.pdf.drawString((LEFT+120)*mm, (TOP-i)*mm, "Credit")
        i+= 2
        path = self.pdf.beginPath()
        path.moveTo((LEFT)*mm, (TOP-i)*mm)
        path.lineTo((LEFT+160)*mm, (TOP-i)*mm)
        self.pdf.drawPath(path, True, True)

        i+=7
        self.pdf.setFont("DejaVu", 9)
        # List
        purchase = 0.0
        sale = 0.0
        credit = 0.0
        for x in self.sitems:
            if TOP - i < 30:
                self.pdf.showPage()
                self.pdf.setFont("DejaVu", 9)
                i = TOP - 270
            self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.date)
            i+=0
            self.pdf.drawString((LEFT+41)*mm, (TOP-i)*mm,"Rs. " + str(x.sale))
            self.pdf.drawString((LEFT+76)*mm, (TOP-i)*mm,"Rs. " + str(x.purchase))
            self.pdf.drawString((LEFT+121)*mm, (TOP-i)*mm,"Rs. " +str(x.credit))
            
            i+=5
            purchase += x.purchase
            sale += x.sale
            credit += x.credit
            
        path = self.pdf.beginPath()
        path.moveTo((LEFT)*mm, (TOP-i)*mm)
        path.lineTo((LEFT+160)*mm, (TOP-i)*mm)
        self.pdf.drawPath(path, True, True)
        i+= 10
        path = self.pdf.beginPath()
        path.moveTo((LEFT)*mm, (TOP-i)*mm)
        path.lineTo((LEFT+160)*mm, (TOP-i)*mm)
        self.pdf.drawPath(path, True, True)

        sale = round(sale,2)
        purchase = round(purchase,2)
        credit = round(credit,2)
        
        self.pdf.setFont("DejaVu", 10)
        self.pdf.setFont("DejaVu", 11)
        self.pdf.drawString((LEFT+2)*mm, (TOP-i+3)*mm, "Total Sale: ")
        self.pdf.drawString((LEFT+25)*mm, (TOP-i+3)*mm, "Rs. " + str(sale))
        self.pdf.drawString((LEFT+52)*mm, (TOP-i+3)*mm, "Purchase: ")
        self.pdf.drawString((LEFT+73)*mm, (TOP-i+3)*mm, "Rs. " + str(purchase))
        self.pdf.drawString((LEFT+97)*mm, (TOP-i+3)*mm, "Credit: ")
        self.pdf.drawString((LEFT+112)*mm, (TOP-i+3)*mm, "Rs. " + str(credit))

      
 
#        self.pdf.rect((LEFT)*mm, (TOP-i-12)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142
        
        if self.sign_image:
            self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm)
        return TOP - i
            # if self.creator: 
        #     path = self.pdf.beginPath()
        #     path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm)
        #     path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm)
        #     self.pdf.drawPath(path, True, True)
 
        #     self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Authorized Signatory")
 
#        self.pdf.rect((LEFT)*mm, (TOP-i-12)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142
 
    def drawDates(self,TOP,LEFT):
        LEFT -= 90
        today = datetime.datetime.today()
        payback = today+datetime.timedelta(self.payment_days)
        
        self.pdf.setFont("DejaVu", 10)
        self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "TIN: %s" % self.TIN)
        self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "DL: %s" % self.CAN)
Пример #12
0
class PDFWriter():
    def __init__(self):
        ## Page size ##
        self.stock = A4
        self._stockHeight = self.stock[1]
        self._stockWidth = self.stock[0]

        ## base font ##
        self.baseFontFamily = "Times-Roman"
        self.baseFontSize = 12

        self.currentFontFamily = self.baseFontFamily
        self.currentFontSize = self.baseFontSize

        ## block sizing ##
        self.c = Canvas("test.pdf", pagesize=self.stock)
        self.marginTop = mm * 20
        self.marginRight = mm * 20
        self.marginBottom = mm * 40
        self.marginLeft = mm * 20

        self.c.translate(self.marginLeft, self.marginBottom)
        self.blockHeight = self._stockHeight - self.marginTop - self.marginBottom
        self.blockWidth = self._stockWidth - self.marginLeft - self.marginRight
        self.blockXCenter = self.blockWidth / 2
        self.blockYCenter = self.blockHeight / 2

        ## font ##
        self.resetFont()

    def startVerticalTextEnvironment(self):
        self.c.saveState()
        # translate back to corner
        self.c.translate(-self.marginLeft, -self.marginBottom)
        # rotate
        self.c.rotate(270)
        # translate to bottom corner
        self.c.translate(-self._stockHeight + self.marginTop, self.marginLeft)

    def endVerticalTextEnvironment(self):
        self.c.restoreState()

    def verticalString(self, x, y, s):
        '''
    Only to be called in the vertical environment.
    Places at xy as if nothing moved.
    '''
        self.c.drawString(self.blockHeight - y, x, s)

    def setFont(self, family, size):
        self.currentFontFamily = family
        self.c.setFont(self.currentFontFamily, size)

    def setFontSize(self, size):
        self.currentFontSize = size
        self.c.setFont(self.currentFontFamily, size)

    def setFontFamily(self, family):
        self.c.setFont(family, self.currentFontSize)

    def resetFont(self):
        self.c.setFont(self.baseFontFamily, self.baseFontSize)

    def save(self):
        self.c.save()

    def vLine(self, x, y, toY):
        self.c.line(x, y, x, toY)

    def hLine(self, x, toX, y):
        self.c.line(x, y, toX, y)

    def string(self, x, y, s):
        return self.c.drawString(x, y, s)

    def centeredString(self, x, y, s):
        return self.c.drawCentredString(x, y, s)

    def stencil(self, points, close):
        self.c.setLineWidth(5)
        p = self.c.beginPath()
        xs, ys = points.pop(0)
        p.moveTo(xs, ys)
        for x1, y1 in points:
            p.lineTo(x1, y1)
        if (close):
            p.close()
        self.c.drawPath(p)

    def invertY(self, y):
        '''
    Y coorinates relative to top left corner
    '''
        return self.blockHeight - y

    def test(self):
        self.hLine(0, self.blockWidth, self.blockHeight)
        self.vLine(0, 0, self.blockHeight)
        self.hLine(0, self.blockWidth, 0)
        self.vLine(self.blockWidth, 0, self.blockHeight)
        #self.hLine(self._centerPage,  self._blockWidth, self._blockHeight/2)
        self.setFontSize(32)
        self.setFontFamily('LiberationSF')
        self.centeredString(self.blockXCenter, self.blockYCenter, 'doya?')
        self.resetFont()
        self.startVerticalTextEnvironment()
        self.verticalString(self.blockXCenter, self.invertY(0), 'hangin...')
        self.endVerticalTextEnvironment()
        self.string(self.blockXCenter, self.blockYCenter - 40, 'teh ah')
        self.stencil([(30, 30), (100, 30), (100, 25)], False)
        self.save()
Пример #13
0
class PDFBase(object):
    logo = None
    headertext = None
    sendertext = settings.ORG_NAME

    def __init__(self, recipient):
        self.pdfdata = BytesIO()
        self.canvas = Canvas(self.pdfdata)

        self.recipient = recipient
        self.preview = False

    def prepare(self):
        self.canvas.setTitle(self.title)
        self.canvas.setSubject(self.title)
        self.canvas.setAuthor(settings.ORG_NAME)
        self.canvas._doc.info.producer = "{0} Invoicing System".format(settings.ORG_NAME)

        registerFont(TTFont('DejaVu Serif', "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf"))
        registerFont(TTFont('DejaVu Serif Italic', "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Italic.ttf"))
        registerFont(TTFont('DejaVu Serif Bold', "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf"))

    def trimstring(self, s, maxlen, fontname, fontsize):
        while len(s) > 5:
            if self.canvas.stringWidth(s, fontname, fontsize) <= maxlen:
                return s
            s = s[:len(s) - 2]
        return s

    def fontheight(self, fontname, size):
        face = getFont(fontname).face
        return face.ascent * size / 1000.0 - face.descent * size / 1000.0

    def textlines(self, t, lines):
        for l in lines.splitlines():
            t.textLine(l)

    def _draw_multiline_aligned(self, txt, left, top, width, height):
        t = txt.replace("\n", "<br/>")
        style = ParagraphStyle('temp')
        style.fontName = 'DejaVu Serif'
        style.fontSize = 9
        style.leading = 9 * 1.2
        p = Paragraph(t, style)
        (actualwidth, actualheight) = p.wrap(width, height)
        p.drawOn(self.canvas, left, top - actualheight)

    def draw_header(self):
        if self.preview:
            t = self.canvas.beginText()
            t.setTextOrigin(cm(6), cm(4))
            t.setFont("DejaVu Serif Italic", 70)
            t.setFillColorRGB(0.9, 0.9, 0.9)
            t.textLine("PREVIEW PREVIEW")
            self.canvas.rotate(45)
            self.canvas.drawText(t)
            self.canvas.rotate(-45)

        if self.logo:
            im = Image(self.logo, width=cm(3), height=cm(3))
            im.drawOn(self.canvas, cm(2), cm(25))

        if self.headertext:
            t = self.canvas.beginText()
            t.setFillColor(colors.black)
            t.setFont("DejaVu Serif", 9)
            t.setTextOrigin(cm(6), cm(27.5))
            self.textlines(t, self.headertext)
            self.canvas.drawText(t)

        if self.sendertext:
            self._draw_multiline_aligned(self.sendertext,
                                         cm(2), cm(23.5), cm(9), cm(4))

        self._draw_multiline_aligned("To:\n%s" % self.recipient,
                                     cm(11), cm(23.5), cm(9), cm(4))

        p = self.canvas.beginPath()
        p.moveTo(cm(2), cm(18.9))
        p.lineTo(cm(19), cm(18.9))
        self.canvas.drawPath(p)
Пример #14
0
def make_page(c: Canvas, year_and_month: date, image: Image):
    months = [
        "January", "February", "March", "April", "May", "June", "July",
        "August", "September", "October", "November", "December"
    ]

    points, triangles = get_triangles(50, 25)
    centroids = get_centroids(points, triangles.simplices)
    dominants = get_dominant_colour(image, 12)
    seeds = numpy.random.uniform(0.0, 100000.0, [7])
    values = numpy.zeros([centroids.shape[1]])
    for p in range(centroids.shape[1]):
        values[p] = perlin_noise(seeds, centroids[0, p], centroids[1, p])
    bright_seeds = numpy.random.uniform(-16, 16, [centroids.shape[1]])
    colours = get_colour(values, dominants) + numpy.transpose(
        numpy.array([bright_seeds, bright_seeds, bright_seeds]))
    colours = numpy.clip(colours, 0, 255)

    width, height = A4
    c.translate(0.5 * inch, 0.5 * inch + height * 2 / 3)
    pw, ph = width - 1 * inch, height / 3 - 1 * inch
    for i, t in enumerate(triangles.simplices):
        vertices = points[t]
        colour = colours[i]
        c.setStrokeColorRGB(colour[0] / 255, colour[1] / 255, colour[2] / 255)
        c.setFillColorRGB(colour[0] / 255, colour[1] / 255, colour[2] / 255)
        c.setLineJoin(1)
        path = c.beginPath()
        path.moveTo(vertices[0, 0] * pw, vertices[0, 1] * ph)
        path.lineTo(vertices[1, 0] * pw, vertices[1, 1] * ph)
        path.lineTo(vertices[2, 0] * pw, vertices[2, 1] * ph)
        path.close()
        c.drawPath(path, stroke=1, fill=1)

    c.translate(0, -1 * inch)
    c.setFont("Helvetica-Bold", 24)
    c.setFillColorRGB(0, 0, 0)
    c.drawString(0, 0, months[year_and_month.month - 1])

    c.translate(0, -0.5 * inch)
    data = [(d[0], d[1], "") for d in get_days_and_dow(year_and_month)]
    if len(data) < 32:
        for _ in range(32 - len(data)):
            data.append(("", "", ""))
    data = zip_longest(data[:16], data[16:], fillvalue="")
    data = [[dt[0][0], dt[0][1], dt[0][2], dt[1][0], dt[1][1], dt[1][2]]
            for dt in data]
    table = Table(data, 2 * [0.5 * inch, 0.5 * inch, 2.63 * inch],
                  16 * [0.32 * inch])
    style = [('ALIGN', (0, 0), (-1, -1), 'CENTER'),
             ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
             ('GRID', (0, 0), (-1, -1), 1, colors.black),
             ('BOX', (0, 0), (-1, -1), 2, colors.black)]
    for row_no, row in enumerate(data):
        if row[0] == 'Sun' or row[0] == 'Sat':
            style.append(('TEXTCOLOR', (0, row_no), (2, row_no), colors.green))
        else:
            style.append(('TEXTCOLOR', (0, row_no), (2, row_no), colors.black))
        if row[3] == 'Sun' or row[3] == 'Sat':
            style.append(
                ('TEXTCOLOR', (3, row_no), (-1, row_no), colors.green))
        else:
            style.append(
                ('TEXTCOLOR', (3, row_no), (-1, row_no), colors.black))
    table.setStyle(style)
    aw, ah = width - 1 * inch, height * 2 / 3 - 1.5 * inch
    w, h = table.wrap(aw, ah)
    c.translate(0, -h)
    table.drawOn(c, 0, 0)
    c.showPage()
Пример #15
0
from reportlab.lib.colors import HexColor
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.units import cm
pdf = Canvas("bgColour.pdf")
pdf.setFillColor(HexColor("#99b0e7"))
path = pdf.beginPath()
path.moveTo(0*cm,0*cm)
path.lineTo(0*cm,30*cm)
path.lineTo(25*cm,30*cm)
path.lineTo(25*cm,0*cm)
#this creates a rectangle the size of the sheet
pdf.drawPath(path,True,True)
pdf.showPage()
pdf.save()
Пример #16
0
class PDFInvoice(object):
	def __init__(self, recipient, invoicedate, duedate, invoicenum=None, imagedir=None, currency='€', preview=False, receipt=False, bankinfo=True):
		self.pdfdata = StringIO.StringIO()
		self.canvas = Canvas(self.pdfdata)
		self.recipient = recipient
		self.invoicenum = invoicenum
		self.invoicedate = invoicedate
		self.duedate = duedate
		self.imagedir = imagedir or '.'
		self.currency = currency or '€'
		self.preview = preview
		self.receipt = receipt
		self.bankinfo = bankinfo
		self.rows = []

		if self.receipt:
			# Never include bank info on receipts
			self.bankinfo = False

		self.canvas.setTitle("PostgreSQL Europe Invoice #%s" % self.invoicenum)
		self.canvas.setSubject("PostgreSQL Europe Invoice #%s" % self.invoicenum)
		self.canvas.setAuthor("PostgreSQL Europe")
		self.canvas._doc.info.producer = "PostgreSQL Europe Invoicing System"

	def addrow(self, title, cost, count=1):
		self.rows.append((title, cost, count,))


	def trimstring(self, s, maxlen, fontname, fontsize):
		while len(s) > 5:
			if self.canvas.stringWidth(s, fontname, fontsize) <= maxlen:
				return s
			s = s[:len(s)-2]
		return s

	def _pageheader(self):
		if self.preview:
			t = self.canvas.beginText()
			t.setTextOrigin(6*cm, 4*cm)
			t.setFont("Times-Italic", 70)
			t.setFillColorRGB(0.9,0.9,0.9)
			t.textLines("PREVIEW PREVIEW")
			self.canvas.rotate(45)
			self.canvas.drawText(t)
			self.canvas.rotate(-45)

		im = Image("%s/PostgreSQL_logo.1color_blue.300x300.png" % self.imagedir, width=3*cm, height=3*cm)
		im.drawOn(self.canvas, 2*cm, 25*cm)
		t = self.canvas.beginText()
		t.setFillColorRGB(0,0,0,0)
		t.setFont("Times-Roman", 10)
		t.setTextOrigin(6*cm, 27.5*cm)
		t.textLines("""PostgreSQL Europe
Carpeaux Diem
13, rue du Square Carpeaux
75018 PARIS
France
""")
		self.canvas.drawText(t)

		t = self.canvas.beginText()
		t.setTextOrigin(2*cm, 23*cm)
		t.setFont("Times-Roman", 10)
		t.textLine("")
		t.textLines("""
Your contact: Guillaume Lelarge
Function: PostgreSQL Europe Treasurer
E-mail: [email protected]
""")
		self.canvas.drawText(t)

		t = self.canvas.beginText()
		t.setTextOrigin(11*cm, 23*cm)
		t.setFont("Times-Italic", 11)
		t.textLine("To:")
		t.setFont("Times-Roman", 11)
		t.textLines(self.recipient)
		self.canvas.drawText(t)

		p = self.canvas.beginPath()
		p.moveTo(2*cm, 18.9*cm)
		p.lineTo(19*cm, 18.9*cm)
		self.canvas.drawPath(p)


	def save(self):
		# We can fit 15 rows on one page. We might want to do something
		# cute to avoid a single row on it's own page in the future, but
		# for now, just split it evenly.
		for pagenum in range(0, (len(self.rows)-1)/15+1):
			self._pageheader()
			islastpage = (pagenum == (len(self.rows)-1)/15)

			if len(self.rows) > 15:
				suffix = " (page %s/%s)" % (pagenum+1, len(self.rows)/15+1)
			else:
				suffix = ''

			# Center between 2 and 19 is 10.5
			if self.invoicenum:
				if self.receipt:
					self.canvas.drawCentredString(10.5*cm,19*cm, "RECEIPT FOR INVOICE NUMBER %s%s" % (self.invoicenum, suffix))
				else:
					self.canvas.drawCentredString(10.5*cm,19*cm, "INVOICE NUMBER %s - %s%s" % (self.invoicenum, self.invoicedate.strftime("%B %d, %Y"),suffix))
			else:
				self.canvas.drawCentredString(10.5*cm,19*cm, "RECEIPT - %s%s" % (self.invoicedate.strftime("%B %d, %Y"), suffix))

			if pagenum == 0:
				tbldata = [["Item", "Price", "Count", "Amount"], ]
			else:
				tbldata = [["Item - continued from page %s" % pagenum, "Price", "count", "amount"], ]

			tbldata.extend([(self.trimstring(title, 10.5*cm, "Times-Roman", 10),
							 "%.2f %s" % (cost, self.currency),
							 count,
							 "%.2f %s" % ((cost * count), self.currency))
							for title,cost, count in self.rows[pagenum*15:(pagenum+1)*15]])
			style = [
					('BACKGROUND',(0,0),(3,0),colors.lightgrey),
					('ALIGN',(1,0),(3,-1),'RIGHT'),
					('LINEBELOW',(0,0),(-1,0), 2, colors.black),
					('OUTLINE', (0,0), (-1, -1), 1, colors.black),
				]
			if islastpage:
				tbldata.append(['','','Total',"%.2f %s" % (sum([cost*count for title,cost,count in self.rows]),self.currency)])
				style.append(('LINEABOVE', (-2,-1), (-1, -1), 2, colors.black))
			else:
				tbldata.append(['          Continued on page %s' % (pagenum + 2), '', '', ''])
				style.append(('ALIGN', (0, -1), (-1, -1), 'CENTER'))
				style.append(('FONT', (0, -1), (-1, -1), 'Times-Italic'))

			t = Table(tbldata, [10.5*cm, 2.5*cm, 1.5*cm, 2.5*cm])
			t.setStyle(TableStyle(style))
			w,h = t.wrapOn(self.canvas,10*cm,10*cm)
			t.drawOn(self.canvas, 2*cm, 18*cm-h)

			if self.receipt:
				self.canvas.drawCentredString(10.5*cm,17.3*cm-h, "This invoice was paid %s" % self.duedate.strftime("%B %d, %Y"))
			else:
				self.canvas.drawCentredString(10.5*cm,17.3*cm-h, "This invoice is due: %s" % self.duedate.strftime("%B %d, %Y"))


			t = self.canvas.beginText()
			t.setTextOrigin(2*cm, 5*cm)
			t.setFont("Times-Italic", 10)
			t.textLine("PostgreSQL Europe is a French non-profit under the French 1901 Law. The association is not VAT registered.")
			t.textLine("")

			if islastpage and self.bankinfo:
				t.setFont("Times-Bold", 10)
				t.textLine("Bank references / Références bancaires / Bankverbindungen / Referencias bancarias")

				t.setFont("Times-Roman", 8)
				t.textLines("""CCM PARIS 1-2 LOUVRE MONTORGUEIL
28 RUE ETIENNE MARCEL
75002 PARIS
FRANCE
IBAN: FR76 1027 8060 3100 0205 2290 114
BIC: CMCIFR2A
""")

			self.canvas.drawText(t)

			# Finish this page off, and optionally loop to another one
			self.canvas.showPage()

		# Last page is finished, flush the PDF output
		self.canvas.save()

		return self.pdfdata
Пример #17
0
class Invoice:

    client = Address()
    provider = Address()
    items = []
    title = "Faktura"
    vs = "00000000"
    creator = ""
    sign_image = None
    payment_days = 14
    paytype = "Převodem"
 
    pdffile = None
 
    def __init__(self):
        self.p = inflect.engine()
        self.TIN = "23102404783"
        self.CAN = "20/13/31/2009 21/14/31/2009"
        self.TOP = 260
        self.LEFT = 20
 
        pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf'))
 
        self.pdffile = NamedTemporaryFile(delete=False)
         
        self.pdf = Canvas(self.pdffile.name, pagesize = letter)
        self.pdf.setFont("DejaVu", 15)
        self.pdf.setStrokeColorRGB(0, 0, 0)
 
    def __del__(self):
        if os.path.isfile(self.pdffile.name):
            os.unlink(self.pdffile.name)
 
    #############################################################
    ## Setters
    #############################################################
     
    def setClient(self, address):
        self.client = address
 
    def setProvider(self, address):
        self.provider = address
 
    def setTitle(self, value):
        self.title = value
         
    def setVS(self, value):
        self.vs = value
 
    def setCreator(self, value):
        self.creator = value
 
    def setPaytype(self, value):
        self.paytype = value
 
    def setPaymentDays(self, value):
        self.payment_days = int(value)
 
    def addItem(self, item):
        self.items.append(item)
 
    #############################################################
    ## Getters
    #############################################################
 
    def getContent(self):
        # Texty
        self.drawMain()
#        barcode=code39.Extended39("inv"+str(int(self.vs)),barWidth=0.5*mm,barHeight=5*mm)
#        barcode.drawOn(self.pdf,self.TOP+45,(self.LEFT+735))
      
        #qrw =  QrCodeWidget('hello cruel world!')
        #self.pdf.add(qrw)
#        qrw = QrCodeWidget(value = "Invoice" + str(int(self.vs)), barLevel = "Q")
#        b = qrw.getBounds()
#        w=b[2]-b[0]
#        h=b[3]-b[1]
#        qr_size = 60
#        drawing = Drawing(qr_size,qr_size,transform=[float(qr_size)/w,0,0,float(qr_size)/h,0,0])
#        drawing.add(qrw)
        
#        renderPDF.draw(drawing, self.pdf, self.TOP+25, self.LEFT+710)
                        
#        qrw.drawOn(self.pdf,self.TOP+45,(self.LEFT+735))
        self.drawProvider(self.TOP-8,self.LEFT+3)
#        self.drawClient(self.TOP-30,self.LEFT+91)
        self.drawPayment(self.TOP-26,self.LEFT+3)
        self.drawItems(self.TOP-45,self.LEFT)
        self.drawDates(self.TOP-10,self.LEFT+91)
        self.drawWatermark()
        #self.pdf.setFillColorRGB(0, 0, 0)
        self.pdf.showPage()
        self.pdf.save()
 
        f = open(self.pdffile.name)
        data = f.read()
        f.close()
 
        os.unlink(self.pdffile.name)
 
        return data
 
    #############################################################
    ## Draw methods
    #############################################################
 
    def drawMain(self):
        # Horní lajna
        self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title)
        self.pdf.drawString((self.LEFT+100)*mm, self.TOP*mm, "Invoice No.: %s" % self.vs)
 
        # Rámečky
        self.pdf.rect((self.LEFT)*mm, (self.TOP-38)*mm, (self.LEFT+156)*mm, 35*mm, stroke=True, fill=False)
 
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm)
        self.pdf.drawPath(path, True, True)
 
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT)*mm, (self.TOP-20)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm)
        self.pdf.drawPath(path, True, True)
 
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm)
        path.lineTo((self.LEFT+176)*mm, (self.TOP-26)*mm)
        self.pdf.drawPath(path, True, True)
        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-26)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-20)*mm)
        self.pdf.drawPath(path, True, True)
    def drawWatermark(self):
        pass
       
    def drawClient(self,TOP,LEFT):
        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel")
        self.pdf.setFont("DejaVu", 8)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.client.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm)
        text.textLines("\n".join(self.client.getContactLines()))
        self.pdf.drawText(text)
 
    def drawProvider(self,TOP,LEFT):
        LEFT += 90
        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Address")
        self.pdf.setFont("DejaVu", 9)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.provider.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.provider.getContactLines()))
        self.pdf.drawText(text)
        if self.provider.note:
            self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note)
 
    def drawPayment(self,TOP,LEFT):
        self.pdf.setFont("DejaVu", 11)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Patient Name")
        self.pdf.drawString((LEFT+50)*mm, (TOP)*mm, "Date")
        self.pdf.setFont("DejaVu", 9)
        text = self.pdf.beginText((LEFT+50)*mm, (TOP-6)*mm)
        text.textLines(self.date)
        self.pdf.drawText(text)
        
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(self.client.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm)
        text.textLines("\n".join(self.client.getContactLines()))
        self.pdf.drawText(text)
 
        self.pdf.drawText(text)
        
    def drawItems(self,TOP,LEFT):
        # Items
        #path = self.pdf.beginPath()
        #path.moveTo((LEFT)*mm, (TOP-4)*mm)
        #path.lineTo((LEFT+176)*mm, (TOP-4)*mm)
        #self.pdf.drawPath(path, True, True)
 
        self.pdf.setFont("DejaVu", 11)
        i=1
        self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, "Description")
        self.pdf.drawString((LEFT+98)*mm, (TOP-i)*mm, "Quantity")
        self.pdf.drawString((LEFT+121)*mm, (TOP-i)*mm, "Unit Price")
        self.pdf.drawString((LEFT+149)*mm, (TOP-i)*mm, "Amount")
        i+=7
        self.pdf.setFont("DejaVu", 9)
        # List
        total=0.0

        for x in self.items:
            self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.name)
            i+=0
            self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "%d" % x.count)
            self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "Rs. %.2f" % x.price)
            self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "Rs. %.2f" % (x.total()))
            i+=5
            total += x.total()
        self.items = []
        path = self.pdf.beginPath()
        path.moveTo((LEFT)*mm, (TOP-i)*mm)
        path.lineTo((LEFT+176)*mm, (TOP-i)*mm)
        self.pdf.drawPath(path, True, True)
        total = round(total,2)
        self.pdf.setFont("DejaVu", 10)
        self.pdf.drawString((LEFT+1)*mm, (TOP-i-8)*mm, self.p.number_to_words(total).title() + " Rupees Only.")
        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT+130)*mm, (TOP-i-8)*mm, "Total: Rs. %s" % total)
        self.pdf.setFont("Helvetica-Bold", 40)
        self.pdf.setStrokeGray(0.25)
        self.pdf.setFillColorRGB(0.95, 0.95, 0.95)
        self.pdf.drawString((LEFT+60)*mm, (TOP-i)*mm, 'PAID')
        self.pdf.setFillColorRGB(0, 0, 0)
      
 
        self.pdf.rect((LEFT)*mm, (TOP-i-12)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142
 
        if self.sign_image:
            self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm)
 
        # if self.creator: 
        #     path = self.pdf.beginPath()
        #     path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm)
        #     path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm)
        #     self.pdf.drawPath(path, True, True)
 
        #     self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Authorized Signatory")
 
 
    def drawDates(self,TOP,LEFT):
        LEFT -= 90
        today = datetime.datetime.today()
        payback = today+datetime.timedelta(self.payment_days)
        
        self.pdf.setFont("DejaVu", 10)
        self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "TIN: %s" % self.TIN)
        self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "DL: %s" % self.CAN)
Пример #18
0
class PDFGenerator(object):

	canvas = None
	colorspace = None
	use_spot = True
	num_pages = 0
	page_count = 0
	prgs_msg = _('Saving in process...')

	def __init__(self, fileptr, cms, version=PDF_VERSION_DEFAULT):
		self.cms = cms
		self.canvas = Canvas(fileptr, pdfVersion=version[0])
		self.info = UC_PDFInfo(self.canvas._doc)
		self.info.pdfxversion = version[1]
		self.info.subject = '---'
		self.canvas.setPageCompression(1)

	#---PDF doc data
	def set_creator(self, name): self.info.creator = name
	def set_producer(self, name): self.info.producer = name
	def set_title(self, title): self.info.title = title
	def set_author(self, author): self.info.author = author
	def set_subject(self, subj): self.info.subject = subj
	def set_keywords(self, keywords): self.info.keywords = keywords

	#---Rendering options
	def set_compression(self, val=True):
		self.canvas.setPageCompression(int(val))

	def set_colorspace(self, cs=None):
		self.colorspace = cs

	def set_spot_usage(self, val=True):
		self.use_spot = val

	#---Page processing

	def set_num_pages(self, num=1):
		self.num_pages = num

	def set_progress_message(self, msg):
		self.prgs_msg = msg

	def start_page(self, w, h, left_margin=0.0, top_margin=0.0):
		self.canvas.translate(w / 2.0 - left_margin, h / 2.0 - top_margin)
		self.canvas.setPageSize((w, h))
		position = 0.0
		if self.num_pages:
			position = float(self.page_count) / float(self.num_pages)
		events.emit(events.FILTER_INFO, self.prgs_msg, position)

	def end_page(self):
		self.canvas.showPage()
		self.page_count += 1
		position = 1.0
		if self.num_pages:
			position = float(self.page_count) / float(self.num_pages)
		events.emit(events.FILTER_INFO, self.prgs_msg, position)


	def save(self):
		self.canvas.save()

	#--- Rendering
	def render(self, objs, toplevel=False):
		obj_count = 0
		for obj in objs:
			if obj.is_pixmap():
				self.draw_pixmap(obj)
			elif obj.is_primitive():
				curve_obj = obj.to_curve()
				if curve_obj.is_primitive():
					self.draw_curve(curve_obj)
				else:
					self.render(curve_obj.childs)
			elif obj.is_container():
				self.draw_container(obj)
			else:
				self.render(obj.childs)

			#---Progress
			obj_count += 1
			shift = 0.0
			page_size = 1.0
			if self.num_pages:
				shift = float(self.page_count) / float(self.num_pages)
				page_size = 1.0 / float(self.num_pages)
			position = shift + obj_count / len(objs) * page_size
			events.emit(events.FILTER_INFO, self.prgs_msg, position)

	def draw_curve(self, curve_obj):
		paths = libgeom.apply_trafo_to_paths(curve_obj.paths, curve_obj.trafo)
		pdfpath, closed = self.make_pdfpath(paths)
		fill_style = curve_obj.style[0]
		stroke_style = curve_obj.style[1]
		if stroke_style and stroke_style[7]:
			self.stroke_pdfpath(pdfpath, stroke_style, curve_obj.stroke_trafo)
		if fill_style and fill_style[0] & sk2_const.FILL_CLOSED_ONLY and closed:
			self.fill_pdfpath(curve_obj, pdfpath, fill_style, curve_obj.fill_trafo)
		elif fill_style and not fill_style[0] & sk2_const.FILL_CLOSED_ONLY:
			self.fill_pdfpath(curve_obj, pdfpath, fill_style, curve_obj.fill_trafo)
		if stroke_style and not stroke_style[7]:
			self.stroke_pdfpath(pdfpath, stroke_style, curve_obj.stroke_trafo)

	def draw_container(self, obj):
		container = obj.childs[0].to_curve()
		paths = libgeom.apply_trafo_to_paths(container.paths, container.trafo)
		pdfpath, closed = self.make_pdfpath(paths)
		fill_style = container.style[0]
		stroke_style = container.style[1]
		if stroke_style and stroke_style[7]:
			self.stroke_pdfpath(pdfpath, stroke_style, container.stroke_trafo)

		self.canvas.saveState()
		self.canvas.clipPath(pdfpath, 0, 0)

		if fill_style and fill_style[0] & sk2_const.FILL_CLOSED_ONLY and closed:
			self.fill_pdfpath(container, pdfpath, fill_style, container.fill_trafo)
		elif fill_style and not fill_style[0] & sk2_const.FILL_CLOSED_ONLY:
			self.fill_pdfpath(container, pdfpath, fill_style, container.fill_trafo)

		self.render(obj.childs[1:])

		self.canvas.restoreState()

		if stroke_style and not stroke_style[7]:
			self.stroke_pdfpath(pdfpath, stroke_style, container.stroke_trafo)

	def make_pdfpath(self, paths):
		closed = False
		pdfpath = self.canvas.beginPath()
		for path in paths:
			pdfpath.moveTo(*path[0])
			for point in path[1]:
				if len(point) > 2:
					pdfpath.curveTo(point[0][0], point[0][1],
								point[1][0], point[1][1],
								point[2][0], point[2][1])
				else:
					pdfpath.lineTo(*point)
			if path[2]:
				pdfpath.close()
				closed = True
		return pdfpath, closed

	def set_fill_rule(self, fillrule):
		if fillrule in (sk2_const.FILL_EVENODD,
					sk2_const.FILL_EVENODD_CLOSED_ONLY):
			fillrule = FILL_EVEN_ODD
		else:fillrule = FILL_NON_ZERO
		self.canvas._fillMode = fillrule

	def set_rgb_values(self, color, pdfcolor):
		r, g, b = self.cms.get_rgb_color(color)[1]
		density = pdfcolor.density
		if density < 1:
			r = density * (r - 1) + 1
			g = density * (g - 1) + 1
			b = density * (b - 1) + 1
		pdfcolor.red, pdfcolor.green, pdfcolor.blue = (r, g, b)

	def get_pdfcolor(self, color):
		pdfcolor = None
		alpha = color[2]
		if self.use_spot and color[0] == uc2const.COLOR_SPOT:
			c, m, y, k = self.cms.get_cmyk_color(color)[1]
			spotname = color[3]
			if spotname == uc2const.COLOR_REG: spotname = 'All'
			pdfcolor = CMYKColorSep(c, m, y, k, spotName=spotname, alpha=alpha)
		elif self.colorspace == uc2const.COLOR_CMYK:
			c, m, y, k = self.cms.get_cmyk_color(color)[1]
			pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)
		elif self.colorspace == uc2const.COLOR_RGB:
			r, g, b = self.cms.get_rgb_color(color)[1]
			return Color(r, g, b, alpha)
		elif self.colorspace == uc2const.COLOR_GRAY:
			gray = self.cms.get_grayscale_color(color)
			k = 1.0 - gray[1][0]
			c = m = y = 0.0
			pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)
		else:
			if color[0] == uc2const.COLOR_RGB:
				r, g, b = color[1]
				return Color(r, g, b, alpha)
			elif color[0] == uc2const.COLOR_GRAY:
				k = 1.0 - color[1][0]
				c = m = y = 0.0
				pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)
			else:
				c, m, y, k = self.cms.get_cmyk_color(color)[1]
				pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)

		self.set_rgb_values(color, pdfcolor)
		return pdfcolor

	def stroke_pdfpath(self, pdfpath, stroke_style, stroke_trafo=[]):
		width = stroke_style[1]

		if not stroke_style[8]:
			width = stroke_style[1]
		else:
			if not stroke_trafo:
				stroke_trafo = [] + sk2_const.NORMAL_TRAFO
			points = [[0.0, 0.0], [1.0, 0.0]]
			points = libgeom.apply_trafo_to_points(points, stroke_trafo)
			coef = libgeom.distance(*points)
			width = stroke_style[1] * coef

		self.canvas.setStrokeColor(self.get_pdfcolor(stroke_style[2]))
		dash = stroke_style[3]
		caps = stroke_style[4]
		joint = stroke_style[5]
		miter = stroke_style[6]

		self.canvas.setLineWidth(width)
		self.canvas.setLineCap(caps - 1)
		self.canvas.setLineJoin(joint)
		dashes = []
		if dash:
			dashes = list(dash)
			w = width
			if w < 1.0: w = 1.0
			for i in range(len(dashes)):
				dashes[i] = w * dashes[i]
		self.canvas.setDash(dashes)
		self.canvas.setMiterLimit(miter)
		self.canvas.drawPath(pdfpath, 1, 0)
		self.canvas.setStrokeAlpha(1.0)

	def fill_pdfpath(self, obj, pdfpath, fill_style, fill_trafo=None):
		self.set_fill_rule(fill_style[0])

		if fill_style[1] == sk2_const.FILL_SOLID:
			self.canvas.setFillColor(self.get_pdfcolor(fill_style[2]))
			self.canvas.drawPath(pdfpath, 0, 1)
		elif fill_style[1] == sk2_const.FILL_GRADIENT:
			gradient = fill_style[2]
			stops = gradient[2]
			transparency = False
			for stop in stops:
				if stop[1][2] < 1.0:
					transparency = True
					break
			if transparency:
				self.fill_tr_gradient(obj, pdfpath, fill_trafo, gradient)
			else:
				self.fill_gradient(pdfpath, fill_trafo, gradient)

		elif fill_style[1] == sk2_const.FILL_PATTERN:
			pattern = fill_style[2]
			self.fill_pattern(obj, pdfpath, fill_trafo, pattern)

	def fill_gradient(self, pdfpath, fill_trafo, gradient):
		self.canvas.saveState()
		self.canvas.clipPath(pdfpath, 0, 0)
		if fill_trafo:
			self.canvas.transform(*fill_trafo)
		grad_type = gradient[0]
		sp, ep = gradient[1]
		stops = gradient[2]
		colors = []
		positions = []
		for offset, color in stops:
			positions.append(offset)
			colors.append(self.get_pdfcolor(color))
		if grad_type == sk2_const.GRADIENT_RADIAL:
			radius = libgeom.distance(sp, ep)
			self.canvas.radialGradient(sp[0], sp[1], radius, colors,
									positions, True)
		else:
			x0, y0 = sp
			x1, y1 = ep
			self.canvas.linearGradient(x0, y0, x1, y1, colors,
									positions, True)
		self.canvas.restoreState()

	def fill_tr_gradient(self, obj, pdfpath, fill_trafo, gradient):
		grad_type = gradient[0]
		if grad_type == sk2_const.GRADIENT_RADIAL:
			self.fill_radial_tr_gradient(obj, pdfpath, fill_trafo, gradient)
		else:
			self.fill_linear_tr_gradient(obj, pdfpath, fill_trafo, gradient)

	def get_grcolor_at_point(self, stops, point=0.0):
		if not point:return self.get_pdfcolor(stops[0][1])
		if point == 1.0:return self.get_pdfcolor(stops[-1][1])
		stop0 = stops[0]
		stop1 = None
		for item in stops:
			if item[0] < point:stop0 = item
			if item[0] >= point:
				stop1 = item
				break
		size = stop1[0] - stop0[0]
		if not size:
			color = stop1[1]
		else:
			coef = (point - stop0[0]) / size
			color = self.cms.mix_colors(stop0[1], stop1[1], coef)
		return self.get_pdfcolor(color)

	def fill_linear_tr_gradient(self, obj, pdfpath, fill_trafo, gradient):
		if not fill_trafo:
			fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
		stops = gradient[2]
		sp, ep = gradient[1]
		dx, dy = sp
		l = libgeom.distance(sp, ep)
		angle = libgeom.get_point_angle(ep, sp)
		m21 = math.sin(angle)
		m11 = m22 = math.cos(angle)
		m12 = -m21
		trafo = [m11, m21, m12, m22, dx, dy]
		inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo),
										libgeom.invert_trafo(trafo))
		cv_trafo = libgeom.multiply_trafo(trafo, fill_trafo)
		paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo)
		paths = libgeom.apply_trafo_to_paths(paths, inv_trafo)
		bbox = libgeom.sum_bbox(libgeom.get_paths_bbox(paths),
							[0.0, 0.0, l, 0.0])
		bbox = libgeom.normalize_bbox(bbox)

		y = bbox[1]
		d = libgeom.distance(*libgeom.apply_trafo_to_points([[0.0, 0.0],
													[0.0, 1.0]], inv_trafo))
		height = bbox[3] - bbox[1]

		self.canvas.saveState()
		self.canvas.clipPath(pdfpath, 0, 0)
		self.canvas.transform(*cv_trafo)

		self.canvas.setFillColor(self.get_grcolor_at_point(stops, 0.0))
		self.canvas.rect(bbox[0], y, 0.0 - bbox[0], height, stroke=0, fill=1)

		x = 0.0
		while x < l:
			point = x / l
			self.canvas.setFillColor(self.get_grcolor_at_point(stops, point))
			if x + d < l: width = d
			else: width = l - x
			self.canvas.rect(x, y, width, height, stroke=0, fill=1)
			x += d

		self.canvas.setFillColor(self.get_grcolor_at_point(stops, 1.0))
		self.canvas.rect(l, y, bbox[2] - l, height, stroke=0, fill=1)

		self.canvas.restoreState()


	def fill_radial_tr_gradient(self, obj, pdfpath, fill_trafo, gradient):
		if not fill_trafo:
			fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
		stops = gradient[2]
		sp, ep = gradient[1]
		dx, dy = sp
		l = libgeom.distance(sp, ep)
		trafo = [1.0, 0.0, 0.0, 1.0, dx, dy]
		inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo),
										libgeom.invert_trafo(trafo))
		cv_trafo = libgeom.multiply_trafo(trafo, fill_trafo)
		paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo)
		paths = libgeom.apply_trafo_to_paths(paths, inv_trafo)
		bbox = libgeom.sum_bbox(libgeom.get_paths_bbox(paths),
							[0.0, 0.0, l, 0.0])
		bbox = libgeom.normalize_bbox(bbox)
		d = libgeom.distance(*libgeom.apply_trafo_to_points([[0.0, 0.0],
													[0.0, 1.0]], inv_trafo))

		circle_paths = libgeom.get_circle_paths(0.0, 0.0, sk2_const.ARC_CHORD)
		trafo = [2.0, 0.0, 0.0, 2.0, -1.0, -1.0]
		circle_paths = libgeom.apply_trafo_to_paths(circle_paths, trafo)

		inner_paths = []
		r = 0.0
		self.canvas.saveState()
		self.canvas.clipPath(pdfpath, 0, 0)
		self.canvas.transform(*cv_trafo)
		while r < l:
			point = r / l
			self.canvas.setFillColor(self.get_grcolor_at_point(stops, point))
			if r + d < l: coef = (r + d)
			else: coef = l
			trafo = [coef, 0.0, 0.0, coef, 0.0, 0.0]
			paths = libgeom.apply_trafo_to_paths(circle_paths, trafo)
			ring = self.make_pdfpath(inner_paths + paths)[0]
			inner_paths = paths
			self.canvas.drawPath(ring, stroke=0, fill=1)
			r += d

		self.canvas.setFillColor(self.get_grcolor_at_point(stops, 1.0))
		r = max(bbox[2] - bbox[0], bbox[3] - bbox[1])
		trafo = [2.0 * r, 0.0, 0.0, 2.0 * r, 0.0, 0.0]
		paths = libgeom.apply_trafo_to_paths(circle_paths, trafo)
		ring = self.make_pdfpath(inner_paths + paths)[0]
		self.canvas.drawPath(ring, stroke=0, fill=1)

		self.canvas.restoreState()

	def draw_image(self, image, alpha_channel=None):
		if not image: return
		if self.colorspace == uc2const.COLOR_CMYK:
			image = self.cms.convert_image(image, uc2const.IMAGE_CMYK)
		elif self.colorspace == uc2const.COLOR_RGB:
			image = self.cms.convert_image(image, uc2const.IMAGE_RGB)
		elif self.colorspace == uc2const.COLOR_GRAY:
			image = self.cms.convert_image(image, uc2const.IMAGE_GRAY)
		img = ImageReader(image)
		img.getRGBData()
		if alpha_channel: img._dataA = ImageReader(alpha_channel)
		self.canvas.drawImage(img, 0, 0, mask='auto')

	def draw_pixmap_obj(self, obj):
		if obj.colorspace in uc2const.DUOTONES:
			fg, bg = libimg.convert_duotone_to_image(self.cms, obj)
			self.draw_image(*bg)
			self.draw_image(*fg)
		else:
			raw_image = Image.open(StringIO(b64decode(obj.bitmap)))
			raw_image.load()
			alpha_chnl = None
			if obj.alpha_channel:
				alpha_chnl = Image.open(StringIO(b64decode(obj.alpha_channel)))
				alpha_chnl.load()
			self.draw_image(raw_image, alpha_chnl)

	def draw_pixmap(self, obj):
		self.canvas.saveState()
		self.canvas.transform(*obj.trafo)
		self.canvas.setFillColorCMYK(0, 0, 0, 1, 1)
		self.canvas.setStrokeColorCMYK(0, 0, 0, 1, 1)
		self.draw_pixmap_obj(obj)
		self.canvas.restoreState()

	def fill_pattern(self, obj, pdfpath, fill_trafo, pattern):
		if not fill_trafo:
			fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
		inv_ptrn_trafo = libgeom.invert_trafo(pattern[3])
		inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo),
										libgeom.invert_trafo(inv_ptrn_trafo))
		paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo)
		paths = libgeom.apply_trafo_to_paths(paths, inv_trafo)
		bbox = libgeom.get_paths_bbox(paths)
		cv_trafo = libgeom.multiply_trafo(pattern[3], fill_trafo)

		bmpstr = b64decode(pattern[1])
		image_obj = sk2_model.Pixmap(obj.config)
		libimg.set_image_data(self.cms, image_obj, bmpstr)
		if pattern[0] == sk2_const.PATTERN_IMG and \
		 len(pattern) > 2:
			image_obj.style[3] = deepcopy(pattern[2])
		libimg.update_image(self.cms, image_obj)

		self.canvas.saveState()
		self.canvas.clipPath(pdfpath, 0, 0)
		self.canvas.transform(*cv_trafo)

		w, h = image_obj.get_size()
		x = bbox[0]
		y = bbox[3]
		while y > bbox[1] - h:
			while x < bbox[2]:
				self.canvas.saveState()
				self.canvas.transform(1.0, 0.0, 0.0, 1.0, x, y)
				self.draw_pixmap_obj(image_obj)
				self.canvas.restoreState()
				x += w
			y -= h
			x = bbox[0]
		self.canvas.restoreState()
Пример #19
0
def render(grid, options):

    draw_with_curves = options['draw_with_curves']
    filename = options['filename']

    use_A4 = options['use_A4']
    width = options['width']
    height = options['height']

    def s_shape_00(p):
        p.moveTo(a, 0)
        if draw_with_curves:
            p.arcTo(-a, -a, a, a, 0, 90)
        else:
            p.lineTo(a, a)
        p.lineTo(0, a)

    def s_shape_01(p):
        p.moveTo(0, b)
        if draw_with_curves:
            p.arcTo(-a, b, a, s + a, 270, 90)
        else:
            p.lineTo(a, b)
        p.lineTo(a, s)

    def s_shape_10(p):
        p.moveTo(s, a)
        if draw_with_curves:
            p.arcTo(b, -a, s + a, a, 90, 90)
        else:
            p.lineTo(b, a)
        p.lineTo(b, 0)

    def s_shape_11(p):
        p.moveTo(s, b)
        if draw_with_curves:
            p.arcTo(b, b, s + a, s + a, 270, -90)
        else:
            p.lineTo(b, b)
        p.lineTo(b, s)

    buffer = StringIO()
    if filename:
        c = Canvas(filename)
    else:
        c = Canvas(buffer)

    c.setTitle('Maze')
    c.setSubject("")
    c.setAuthor("Dale O'Brien")

    if use_A4:
        page_width = 8.3 * 72
        page_height = 11.7 * 72
    else:
        page_width = 8.5 * 72
        page_height = 11.0 * 72

    c.setPageSize((page_width, page_height))

    # 0=butt,1=draw_with_curves,2=square
    c.setLineCap(1)

    left_margin = 15
    top_margin = 15

    # cells must be square, it's the math!, I'm not doing it again.
    # so scale the width if the height will go over the page

    org_width = width
    ratio = (page_height - 2 * top_margin) / (page_width - 2 * left_margin)
    if (float(height) / width > ratio):
        width = ceil(height / ratio)

    s = (page_width - 2 * left_margin) / width

    # center the maze, looks better for mazes that don't fit the page nicely
    left_margin -= (org_width - width) * s / 2.0
    top_margin -= (s * height - (page_height - 2.0 * top_margin)) / 2.0

    g = s * 0.2
    stroke = s / 7.0
    c.setLineWidth(stroke)

    k = 0.5

    n = -(g / k) + 0.5 * (s - sqrt((g *
        (4.0 * g - 3.0 * g * k + 2 * k * s)) / k))

    r = g / k
    q = n + r
    v = (g * (-1 + k)) / k

    theta = asin((2.0 * g - 2.0 * g * k + k * s) /
        (2.0 * g - g * k + k * s)) * 180 / pi

    delta = theta - 90

    for j, row in enumerate(grid):
        # upper/lower rows
        for i, cell in enumerate(row):

            x_offset = left_margin + i * s
            y_offset = top_margin + j * s

            c.translate(x_offset, y_offset)
            p = c.beginPath()

            a = g
            b = s - g

            # mark start and end
            start = False
            end = False
            if (i == 0 and j == height - 1):
                start = True

            if (i == width - 1 and j == 0):
                end = True

            if start or end:
                c.setStrokeColorRGB(0.9, 0.1, 0.1)
                c.setFillColorRGB(0.9, 0.1, 0.1)
                p.circle(s / 2.0, s / 2.0, g / 1.5)
                c.drawPath(p, fill=True)
                p = c.beginPath()
                c.setStrokeColorRGB(0.0, 0.0, 0.0)

            if cell == 3:

                '│ │'
                '│ │'

                p.moveTo(a, s)
                p.lineTo(a, 0)
                p.moveTo(b, s)
                p.lineTo(b, 0)

            if cell == 1:

                '│ │'
                '└─┘'

                p.moveTo(b, 0)
                if draw_with_curves:

                    p.lineTo(b, q)
                    x = s - v - r
                    y = n
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 180, delta)

                    p.arcTo(g / 2,
                            g / 2,
                            s - g / 2,
                            s - g / 2, theta - 90, 360 - 2 * theta)

                    x = v - r
                    p.arcTo(x, y,
                            x + 2 * r,
                            y + 2 * r, 90 - theta, delta)

                else:
                    p.lineTo(b, b)
                    p.lineTo(a, b)
                p.lineTo(g, 0)

            if cell == 2:

                '┌─┐'
                '│ │'

                p.moveTo(b, s)
                if draw_with_curves:

                    x = s - v - r
                    y = s - n - 2 * r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 180, -delta)

                    p.arcTo(g / 2,
                            g / 2,
                            s - g / 2,
                            s - g / 2, 90 - theta, -360 + 2 * theta)

                    x = v - r
                    p.arcTo(x, y,
                            x + 2 * r,
                            y + 2 * r, 270 + theta, -delta)

                else:
                    p.lineTo(b, a)
                    p.lineTo(a, a)
                p.lineTo(a, s)

            if cell == 4:

                '┌──'
                '└──'

                p.moveTo(s, b)
                if draw_with_curves:
                    x = s - n - 2 * r
                    y = s - v - r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 270, delta)

                    p.arcTo(g / 2,
                            g / 2,
                            s - g / 2,
                            s - g / 2, 90 + delta, 360 - 2 * theta)

                    y = v - r
                    p.arcTo(x, y,
                            x + 2 * r,
                            y + 2 * r, 180 - theta, delta)

                else:
                    p.lineTo(g, b)
                    p.lineTo(a, a)
                p.lineTo(s, a)

            if cell == 8:

                '──┐'
                '──┘'

                p.moveTo(0, b)
                if draw_with_curves:
                    x = n
                    y = s - v - r

                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 270, -delta)

                    p.arcTo(g / 2,
                            g / 2,
                            s - g / 2,
                            s - g / 2, 90 - delta, -360 + 2 * theta)

                    y = v - r
                    p.arcTo(x, y,
                            x + 2 * r,
                            y + 2 * r, theta, -delta)
                else:
                    p.lineTo(b, b)
                    p.lineTo(b, a)
                p.lineTo(0, a)

            if cell == 5:

                '│ └'
                '└──'

                s_shape_10(p)

                p.moveTo(s, b)
                if draw_with_curves:
                    if start:
                        p.arcTo(a, a, b, b, 90, 90)
                    else:
                        p.arcTo(a, 2 * a - b, 2 * b - a, b, 90, 90)
                else:
                    p.lineTo(a, b)
                p.lineTo(a, 0)

            if cell == 6:

                '┌──'
                '│ ┌'

                s_shape_11(p)

                p.moveTo(s, a)
                if draw_with_curves:
                    p.arcTo(a, a, 2 * b + a, 2 * b + a, 270, -90)
                else:
                    p.lineTo(a, a)
                p.lineTo(a, s)

            if cell == 7:

                '│ └'
                '│ ┌'

                p.moveTo(a, s)
                p.lineTo(a, 0)

                s_shape_10(p)
                s_shape_11(p)

            if cell == 9:

                '┘ │'
                '──┘'

                s_shape_00(p)

                p.moveTo(b, 0)
                if draw_with_curves:
                    p.arcTo(2 * a - b, 2 * a - b, b, b, 0, 90)
                else:
                    p.lineTo(b, b)
                p.lineTo(0, b)

            if cell == 10:

                '──┐'
                '┐ │'

                s_shape_01(p)

                p.moveTo(0, a)
                if draw_with_curves:
                    if end:
                        p.arcTo(a, a, b, b, 270, 90)
                    else:
                        p.arcTo(2 * a - b, a, b, 2 * b + a, 270, 90)
                else:
                    p.lineTo(b, a)
                p.lineTo(b, s)

            if cell == 11:

                '┘ │'
                '┐ │'

                p.moveTo(b, s)
                p.lineTo(b, 0)

                s_shape_00(p)
                s_shape_01(p)

            if cell == 12:

                '───'
                '───'

                p.moveTo(0, b)
                p.lineTo(s, b)
                p.moveTo(0, a)
                p.lineTo(s, a)

            if cell == 13:

                '┘ └'
                '───'

                p.moveTo(0, b)
                p.lineTo(s, b)

                s_shape_00(p)
                s_shape_10(p)

            if cell == 14:

                '───'
                '┐ ┌'

                p.moveTo(0, a)
                p.lineTo(s, a)

                s_shape_01(p)
                s_shape_11(p)

            if cell == 15:

                '┘ └'
                '┐ ┌'

                s_shape_00(p)
                s_shape_10(p)
                s_shape_01(p)
                s_shape_11(p)

            if cell == 19:

                '┤ ├'
                '┤ ├'

                p.moveTo(a, s)
                p.lineTo(a, 0)
                p.moveTo(b, s)
                p.lineTo(b, 0)

                p.moveTo(0, a)
                p.lineTo(a, a)
                p.moveTo(0, b)
                p.lineTo(a, b)

                p.moveTo(s, a)
                p.lineTo(b, a)
                p.moveTo(s, b)
                p.lineTo(b, b)

            if cell == 28:

                '┴─┴'
                '┬─┬'

                p.moveTo(0, b)
                p.lineTo(s, b)
                p.moveTo(0, a)
                p.lineTo(s, a)

                p.moveTo(a, a)
                p.lineTo(a, 0)
                p.moveTo(a, b)
                p.lineTo(a, s)

                p.moveTo(b, a)
                p.lineTo(b, 0)
                p.moveTo(b, b)
                p.lineTo(b, s)

            c.drawPath(p)
            c.translate(-x_offset, -y_offset)

    c.save()
    pdf = ""
    if not filename:
        pdf = buffer.getvalue()
        buffer.close()

    return pdf
Пример #20
0
def render(grid, options):

    draw_with_curves = options['draw_with_curves']
    filename = options['filename']

    use_A4 = options['use_A4']
    width = options['width']
    height = options['height']

    def s_shape_00(p):
        p.moveTo(a, 0)
        if draw_with_curves:
            p.arcTo(-a, -a, a, a, 0, 90)
        else:
            p.lineTo(a, a)
        p.lineTo(0, a)

    def s_shape_01(p):
        p.moveTo(0, b)
        if draw_with_curves:
            p.arcTo(-a, b, a, s + a, 270, 90)
        else:
            p.lineTo(a, b)
        p.lineTo(a, s)

    def s_shape_10(p):
        p.moveTo(s, a)
        if draw_with_curves:
            p.arcTo(b, -a, s + a, a, 90, 90)
        else:
            p.lineTo(b, a)
        p.lineTo(b, 0)

    def s_shape_11(p):
        p.moveTo(s, b)
        if draw_with_curves:
            p.arcTo(b, b, s + a, s + a, 270, -90)
        else:
            p.lineTo(b, b)
        p.lineTo(b, s)

    buffer = StringIO()
    if filename:
        c = Canvas(filename)
    else:
        c = Canvas(buffer)

    c.setTitle('Maze')
    c.setSubject("")
    c.setAuthor("Dale O'Brien")

    if use_A4:
        page_width = 8.3 * 72
        page_height = 11.7 * 72
    else:
        page_width = 8.5 * 72
        page_height = 11.0 * 72

    c.setPageSize((page_width, page_height))

    # 0=butt,1=draw_with_curves,2=square
    c.setLineCap(1)

    left_margin = 15
    top_margin = 15

    # cells must be square, it's the math!, I'm not doing it again.
    # so scale the width if the height will go over the page

    org_width = width
    ratio = (page_height - 2 * top_margin) / (page_width - 2 * left_margin)
    if (float(height) / width > ratio):
        width = ceil(height / ratio)

    s = (page_width - 2 * left_margin) / width

    # center the maze, looks better for mazes that don't fit the page nicely
    left_margin -= (org_width - width) * s / 2.0
    top_margin -= (s * height - (page_height - 2.0 * top_margin)) / 2.0

    g = s * 0.2
    stroke = s / 7.0
    c.setLineWidth(stroke)

    k = 0.5

    n = -(g / k) + 0.5 * (s - sqrt(
        (g * (4.0 * g - 3.0 * g * k + 2 * k * s)) / k))

    r = g / k
    q = n + r
    v = (g * (-1 + k)) / k

    theta = asin(
        (2.0 * g - 2.0 * g * k + k * s) / (2.0 * g - g * k + k * s)) * 180 / pi

    delta = theta - 90

    for j, row in enumerate(grid):
        # upper/lower rows
        for i, cell in enumerate(row):

            x_offset = left_margin + i * s
            y_offset = top_margin + j * s

            c.translate(x_offset, y_offset)
            p = c.beginPath()

            a = g
            b = s - g

            # mark start and end
            start = False
            end = False
            if (i == 0 and j == height - 1):
                start = True

            if (i == width - 1 and j == 0):
                end = True

            if start or end:
                c.setStrokeColorRGB(0.9, 0.1, 0.1)
                c.setFillColorRGB(0.9, 0.1, 0.1)
                p.circle(s / 2.0, s / 2.0, g / 1.5)
                c.drawPath(p, fill=True)
                p = c.beginPath()
                c.setStrokeColorRGB(0.0, 0.0, 0.0)

            if cell == 3:

                '│ │'
                '│ │'

                p.moveTo(a, s)
                p.lineTo(a, 0)
                p.moveTo(b, s)
                p.lineTo(b, 0)

            if cell == 1:

                '│ │'
                '└─┘'

                p.moveTo(b, 0)
                if draw_with_curves:

                    p.lineTo(b, q)
                    x = s - v - r
                    y = n
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 180, delta)

                    p.arcTo(g / 2, g / 2, s - g / 2, s - g / 2, theta - 90,
                            360 - 2 * theta)

                    x = v - r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 90 - theta, delta)

                else:
                    p.lineTo(b, b)
                    p.lineTo(a, b)
                p.lineTo(g, 0)

            if cell == 2:

                '┌─┐'
                '│ │'

                p.moveTo(b, s)
                if draw_with_curves:

                    x = s - v - r
                    y = s - n - 2 * r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 180, -delta)

                    p.arcTo(g / 2, g / 2, s - g / 2, s - g / 2, 90 - theta,
                            -360 + 2 * theta)

                    x = v - r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 270 + theta, -delta)

                else:
                    p.lineTo(b, a)
                    p.lineTo(a, a)
                p.lineTo(a, s)

            if cell == 4:

                '┌──'
                '└──'

                p.moveTo(s, b)
                if draw_with_curves:
                    x = s - n - 2 * r
                    y = s - v - r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 270, delta)

                    p.arcTo(g / 2, g / 2, s - g / 2, s - g / 2, 90 + delta,
                            360 - 2 * theta)

                    y = v - r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 180 - theta, delta)

                else:
                    p.lineTo(g, b)
                    p.lineTo(a, a)
                p.lineTo(s, a)

            if cell == 8:

                '──┐'
                '──┘'

                p.moveTo(0, b)
                if draw_with_curves:
                    x = n
                    y = s - v - r

                    p.arcTo(x, y, x + 2 * r, y + 2 * r, 270, -delta)

                    p.arcTo(g / 2, g / 2, s - g / 2, s - g / 2, 90 - delta,
                            -360 + 2 * theta)

                    y = v - r
                    p.arcTo(x, y, x + 2 * r, y + 2 * r, theta, -delta)
                else:
                    p.lineTo(b, b)
                    p.lineTo(b, a)
                p.lineTo(0, a)

            if cell == 5:

                '│ └'
                '└──'

                s_shape_10(p)

                p.moveTo(s, b)
                if draw_with_curves:
                    if start:
                        p.arcTo(a, a, b, b, 90, 90)
                    else:
                        p.arcTo(a, 2 * a - b, 2 * b - a, b, 90, 90)
                else:
                    p.lineTo(a, b)
                p.lineTo(a, 0)

            if cell == 6:

                '┌──'
                '│ ┌'

                s_shape_11(p)

                p.moveTo(s, a)
                if draw_with_curves:
                    p.arcTo(a, a, 2 * b + a, 2 * b + a, 270, -90)
                else:
                    p.lineTo(a, a)
                p.lineTo(a, s)

            if cell == 7:

                '│ └'
                '│ ┌'

                p.moveTo(a, s)
                p.lineTo(a, 0)

                s_shape_10(p)
                s_shape_11(p)

            if cell == 9:

                '┘ │'
                '──┘'

                s_shape_00(p)

                p.moveTo(b, 0)
                if draw_with_curves:
                    p.arcTo(2 * a - b, 2 * a - b, b, b, 0, 90)
                else:
                    p.lineTo(b, b)
                p.lineTo(0, b)

            if cell == 10:

                '──┐'
                '┐ │'

                s_shape_01(p)

                p.moveTo(0, a)
                if draw_with_curves:
                    if end:
                        p.arcTo(a, a, b, b, 270, 90)
                    else:
                        p.arcTo(2 * a - b, a, b, 2 * b + a, 270, 90)
                else:
                    p.lineTo(b, a)
                p.lineTo(b, s)

            if cell == 11:

                '┘ │'
                '┐ │'

                p.moveTo(b, s)
                p.lineTo(b, 0)

                s_shape_00(p)
                s_shape_01(p)

            if cell == 12:

                '───'
                '───'

                p.moveTo(0, b)
                p.lineTo(s, b)
                p.moveTo(0, a)
                p.lineTo(s, a)

            if cell == 13:

                '┘ └'
                '───'

                p.moveTo(0, b)
                p.lineTo(s, b)

                s_shape_00(p)
                s_shape_10(p)

            if cell == 14:

                '───'
                '┐ ┌'

                p.moveTo(0, a)
                p.lineTo(s, a)

                s_shape_01(p)
                s_shape_11(p)

            if cell == 15:

                '┘ └'
                '┐ ┌'

                s_shape_00(p)
                s_shape_10(p)
                s_shape_01(p)
                s_shape_11(p)

            if cell == 19:

                '┤ ├'
                '┤ ├'

                p.moveTo(a, s)
                p.lineTo(a, 0)
                p.moveTo(b, s)
                p.lineTo(b, 0)

                p.moveTo(0, a)
                p.lineTo(a, a)
                p.moveTo(0, b)
                p.lineTo(a, b)

                p.moveTo(s, a)
                p.lineTo(b, a)
                p.moveTo(s, b)
                p.lineTo(b, b)

            if cell == 28:

                '┴─┴'
                '┬─┬'

                p.moveTo(0, b)
                p.lineTo(s, b)
                p.moveTo(0, a)
                p.lineTo(s, a)

                p.moveTo(a, a)
                p.lineTo(a, 0)
                p.moveTo(a, b)
                p.lineTo(a, s)

                p.moveTo(b, a)
                p.lineTo(b, 0)
                p.moveTo(b, b)
                p.lineTo(b, s)

            c.drawPath(p)
            c.translate(-x_offset, -y_offset)

    c.save()
    pdf = ""
    if not filename:
        pdf = buffer.getvalue()
        buffer.close()

    return pdf
Пример #21
0
class Invoice:
    client = Address()
    provider = Address()
    items = []
    title = "Faktura"
    vs = "00000000"
    creator = ""
    sign_image = None
    payment_days = 14
    paytype = "Převodem"

    pdffile = None

    def __init__(self):
        self.TOP = 260
        self.LEFT = 20

        pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf'))

        self.pdffile = NamedTemporaryFile(delete=False)

        self.pdf = Canvas(self.pdffile.name, pagesize=letter)
        self.pdf.setFont("DejaVu", 15)
        self.pdf.setStrokeColorRGB(0, 0, 0)

    def __del__(self):
        if os.path.isfile(self.pdffile.name):
            os.unlink(self.pdffile.name)

    #############################################################
    # Setters
    #############################################################

    def setClient(self, address):
        self.client = address

    def setProvider(self, address):
        self.provider = address

    def setTitle(self, value):
        self.title = value

    def setVS(self, value):
        self.vs = value

    def setCreator(self, value):
        self.creator = value

    def setPaytype(self, value):
        self.paytype = value

    def setPaymentDays(self, value):
        self.payment_days = int(value)

    def addItem(self, item):
        self.items.append(item)

    #############################################################
    # Getters
    #############################################################

    def getContent(self):
        # Texty
        self.drawMain()
        self.drawProvider(self.TOP-10, self.LEFT+3)
        self.drawClient(self.TOP-30, self.LEFT+91)
        self.drawPayment(self.TOP-47, self.LEFT+3)
        self.drawItems(self.TOP-80, self.LEFT)
        self.drawDates(self.TOP-10, self.LEFT+91)

        # self.pdf.setFillColorRGB(0, 0, 0)

        self.pdf.showPage()
        self.pdf.save()

        f = open(self.pdffile.name)
        data = f.read()
        f.close()

        os.unlink(self.pdffile.name)

        return data

    #############################################################
    # Draw methods
    #############################################################

    def drawMain(self):
        # Horní lajna
        self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title)
        self.pdf.drawString((self.LEFT+100)*mm, self.TOP*mm, "Variabilní symbol: %s" % self.vs)

        # Rámečky
        self.pdf.rect((self.LEFT)*mm, (self.TOP-68)*mm, (self.LEFT+156)*mm, 65*mm, stroke=True, fill=False)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-68)*mm)
        self.pdf.drawPath(path)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT)*mm, (self.TOP-39)*mm)
        path.lineTo((self.LEFT+88)*mm, (self.TOP-39)*mm)
        self.pdf.drawPath(path)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT+88)*mm, (self.TOP-23)*mm)
        path.lineTo((self.LEFT+176)*mm, (self.TOP-23)*mm)
        self.pdf.drawPath(path)

    def _drawAddress(self, TOP, LEFT, header_string, address):
        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, header_string)
        self.pdf.setFont("DejaVu", 8)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines("\n".join(address.getAddressLines()))
        self.pdf.drawText(text)
        text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm)
        text.textLines("\n".join(address.getContactLines()))
        self.pdf.drawText(text)

    def drawClient(self, TOP, LEFT):
        self._drawAddress(TOP, LEFT, "Odběratel", self.client)

        # self.pdf.setFont("DejaVu", 12)
        # self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel")
        # self.pdf.setFont("DejaVu", 8)
        # text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        # text.textLines("\n".join(self.client.getAddressLines()))
        # self.pdf.drawText(text)
        # text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm)
        # text.textLines("\n".join(self.client.getContactLines()))
        # self.pdf.drawText(text)

    def drawProvider(self, TOP, LEFT):
        self._drawAddress(TOP, LEFT, "Dodavatel", self.provider)
        if self.provider.note:
            self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note)

    def drawPayment(self, TOP, LEFT):
        self.pdf.setFont("DejaVu", 11)
        self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Údaje pro platbu")
        # self.pdf.setFillColorRGB(255, 0, 0)
        text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
        text.textLines(
            """%s
Číslo účtu: %s
Variabilní symbol: %s""" % (self.provider.bank_name, self.provider.bank_account, self.vs),
        )
        self.pdf.drawText(text)

    def drawItems(self, TOP, LEFT):
        # Items
        path = self.pdf.beginPath()
        path.moveTo((LEFT)*mm, (TOP-4)*mm)
        path.lineTo((LEFT+176)*mm, (TOP-4)*mm)
        self.pdf.drawPath(path)

        self.pdf.setFont("DejaVu", 9)
        self.pdf.drawString((LEFT+1)*mm, (TOP-2)*mm, "Fakturuji vám:")

        i = 9
        self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "Množství")
        self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "Cena za jedn.")
        self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "Cena celkem")
        i += 5

        # List
        total = 0.0
        for x in self.items:
            self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.name)
            i += 5
            self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "%d ks" % x.count)
            self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "%.2f,- kč" % x.price)
            self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "%.2f,- kč" % (x.total()))
            i += 5
            total += x.total()

        path = self.pdf.beginPath()
        path.moveTo((LEFT)*mm, (TOP-i)*mm)
        path.lineTo((LEFT+176)*mm, (TOP-i)*mm)
        self.pdf.drawPath(path)

        self.pdf.setFont("DejaVu", 12)
        self.pdf.drawString((LEFT+130)*mm, (TOP-i-10)*mm, "Celkem: %d ,- kč" % total)

        self.pdf.rect((LEFT)*mm, (TOP-i-17)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False)  # 140,142

        if self.sign_image:
            self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm)

        path = self.pdf.beginPath()
        path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm)
        path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm)
        self.pdf.drawPath(path)

        self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Vystavil: %s" % self.creator)

    def drawDates(self, TOP, LEFT):
        today = datetime.datetime.today()
        payback = today+datetime.timedelta(self.payment_days)

        self.pdf.setFont("DejaVu", 10)
        self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "Datum vystavení: %s" % today.strftime("%d.%m.%Y"))
        self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "Datum splatnosti: %s" % payback.strftime("%d.%m.%Y"))
        self.pdf.drawString((LEFT)*mm, (TOP-9)*mm, "Forma úhrady: " + self.paytype)
Пример #22
0
class SimpleInvoice(BaseInvoice):

    def gen(self, filename):
        self.TOP = 260
        self.LEFT = 20
        self.filename = filename

        pdfmetrics.registerFont(TTFont('DejaVu', FONT_PATH))
        pdfmetrics.registerFont(TTFont('DejaVu-Bold', FONT_BOLD_PATH))

        self.pdf = Canvas(self.filename, pagesize = letter)
        self.addMetaInformation(self.pdf)

        self.pdf.setFont('DejaVu', 15)
        self.pdf.setStrokeColorRGB(0, 0, 0)

        # Texty
        self.drawMain()
        self.drawTitle()
        self.drawProvider(self.TOP - 10,self.LEFT + 3)
        self.drawClient(self.TOP - 35,self.LEFT + 91)
        self.drawPayment(self.TOP - 47,self.LEFT + 3)
        self.drawItems(self.TOP - 80,self.LEFT)
        self.drawDates(self.TOP - 10,self.LEFT + 91)

        #self.pdf.setFillColorRGB(0, 0, 0)

        self.pdf.showPage()
        self.pdf.save()

    #############################################################
    ## Draw methods
    #############################################################

    def addMetaInformation(self, pdf):
        pdf.setCreator(self.invoice.provider.summary)
        pdf.setTitle(self.invoice.title)
        pdf.setAuthor(self.invoice.creator.name)

    def drawTitle(self):
        # Up line
        self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.invoice.title)
        self.pdf.drawString((self.LEFT + 90) * mm,
            self.TOP*mm,
            _(u'Variable symbol: %s') %
            self.invoice.variable_symbol)

    def drawMain(self):
        # Borders
        self.pdf.rect(self.LEFT * mm, (self.TOP - 68) * mm,
                      (self.LEFT + 156) * mm, 65 * mm, stroke=True, fill=False)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT + 88) * mm, (self.TOP - 3) * mm)
        path.lineTo((self.LEFT + 88) * mm, (self.TOP - 68) * mm)
        self.pdf.drawPath(path, True, True)

        path = self.pdf.beginPath()
        path.moveTo(self.LEFT * mm, (self.TOP - 39) * mm)
        path.lineTo((self.LEFT + 88) * mm, (self.TOP - 39) * mm)
        self.pdf.drawPath(path, True, True)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT + 88) * mm, (self.TOP - 27) * mm)
        path.lineTo((self.LEFT + 176) * mm, (self.TOP - 27) * mm)
        self.pdf.drawPath(path, True, True)

    def drawClient(self,TOP,LEFT):
        self.pdf.setFont('DejaVu', 12)
        self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Customer'))
        self.pdf.setFont('DejaVu', 8)

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 4) * mm)
        text.textLines('\n'.join(self.invoice.client.get_address_lines()))
        self.pdf.drawText(text)

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm)
        text.textLines('\n'.join(self.invoice.client.get_contact_lines()))
        self.pdf.drawText(text)

        if self.invoice.client.note:
            self.pdf.setFont('DejaVu', 6)
            text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 28) * mm)
            text.textLines(self.invoice.client.note)
            self.pdf.drawText(text)


    def drawProvider(self,TOP,LEFT):
        self.pdf.setFont('DejaVu', 12)
        self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Provider'))
        self.pdf.setFont('DejaVu', 8)

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 6) * mm)
        text.textLines('\n'.join(self.invoice.provider.get_address_lines()))
        self.pdf.drawText(text)

        text = self.pdf.beginText((LEFT + 40) * mm, (TOP - 6) * mm)
        text.textLines('\n'.join(self.invoice.provider.get_contact_lines()))

        self.pdf.drawText(text)
        if self.invoice.provider.note:
            self.pdf.setFont('DejaVu', 6)
            text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm)
            text.textLines(self.invoice.provider.note)
            self.pdf.drawText(text)

    def drawPayment(self,TOP,LEFT):
        self.pdf.setFont('DejaVu-Bold', 9)
        self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Payment information'))

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 6) * mm)
        lines = [
            self.invoice.provider.bank_name,
            '%s: %s' % (_(u'Bank account'), self.invoice.provider.bank_account),
            '%s: %s' % (_(u'Variable symbol'), self.invoice.variable_symbol)
        ]
        if self.invoice.specific_symbol:
            lines.append(
                '%s: %s' % (_(u'Specific symbol'), self.invoice.specific_symbol))
        text.textLines('\n'.join(lines))
        self.pdf.drawText(text)

    def drawItems(self,TOP,LEFT):
        # Items
        path = self.pdf.beginPath()
        path.moveTo(LEFT * mm, (TOP - 4) * mm)
        path.lineTo((LEFT + 176) * mm, (TOP - 4) * mm)
        self.pdf.drawPath(path, True, True)

        self.pdf.setFont('DejaVu-Bold', 7)
        self.pdf.drawString((LEFT + 1) * mm, (TOP - 2) * mm, _(u'List of items'))

        self.pdf.drawString((LEFT + 1) * mm, (TOP - 9) * mm, _(u'Description'))
        items_are_with_tax = self.invoice.use_tax
        if items_are_with_tax:
            i=9
            self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, _(u'Units'))
            self.pdf.drawString((LEFT + 88) * mm, (TOP - i) * mm,
                                _(u'Price per one'))
            self.pdf.drawString((LEFT + 115) * mm, (TOP - i) * mm,
                                _(u'Total price'))
            self.pdf.drawString((LEFT + 137) * mm, (TOP - i) * mm,
                                _(u'Tax'))
            self.pdf.drawString((LEFT + 146) * mm, (TOP - i) * mm,
                                _(u'Total price with tax'))
            i+=5
        else:
            i=9
            self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm,
                                _(u'Units'))
            self.pdf.drawString((LEFT + 123) * mm, (TOP - i) * mm,
                                _(u'Price per one'))
            self.pdf.drawString((LEFT + 150) * mm, (TOP - i) * mm,
                                _(u'Total price'))
            i+=5

        self.pdf.setFont('DejaVu', 7)

        # List
        for item in self.invoice.items:
            self.pdf.drawString((LEFT + 1) * mm, (TOP - i) * mm, item.description)
            if item.tax or items_are_with_tax:
                items_are_with_tax = True
                if len(item.description) > 52: i+=5
                if float(int(item.count)) == item.count:
                    self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, '%d %s' % (item.count, item.unit))
                else:
                    self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, '%.1f %s' % (item.count, item.unit))
                self.pdf.drawString((LEFT + 88) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.price, self.invoice.currency))
                self.pdf.drawString((LEFT + 115) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.total, self.invoice.currency))
                self.pdf.drawString((LEFT + 137) * mm, (TOP - i) * mm, '%.0f %%' % item.tax)
                self.pdf.drawString((LEFT + 146) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.total_tax, self.invoice.currency))
                i+=5
            else:
                if len(item.description) > 75: i+=5
                if float(int(item.count)) == item.count:
                    self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm, '%d %s' % (item.count, item.unit))
                else:
                    self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm, '%.1f %s' % (item.count, item.unit))
                self.pdf.drawString((LEFT + 123) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.price, self.invoice.currency))
                self.pdf.drawString((LEFT + 150) * mm, (TOP - i) * mm, '%.2f,- %s' % (item.total, self.invoice.currency))
                i+=5

        if self.invoice.rounding_result:
            path = self.pdf.beginPath()
            path.moveTo(LEFT * mm, (TOP - i) * mm)
            path.lineTo((LEFT + 176) * mm, (TOP - i) * mm)
            i += 5
            self.pdf.drawPath(path, True, True)
            self.pdf.drawString((LEFT + 1) * mm, (TOP - i) * mm, _(u'Rounding'))
            self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, '%.2f,- %s' % (self.invoice.difference_in_rounding, self.invoice.currency))
            i += 3

        path = self.pdf.beginPath()
        path.moveTo(LEFT * mm, (TOP - i) * mm)
        path.lineTo((LEFT + 176) * mm, (TOP - i) * mm)
        self.pdf.drawPath(path, True, True)

        if not items_are_with_tax:
            self.pdf.setFont('DejaVu-Bold', 11)
            self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 7) * mm, _(u'Total')+': %.2f %s' % (self.invoice.price, self.invoice.currency))
        else:
            self.pdf.setFont('DejaVu-Bold', 6)
            self.pdf.drawString((LEFT + 1) * mm, (TOP - i - 2) * mm, _(u'Breakdown VAT'))
            vat_list, tax_list, total_list, total_tax_list = [_(u'VAT rate')], [_(u'Tax')], [_(u'Without VAT')], [_(u'With VAT')]
            for vat, items in self.invoice.generate_breakdown_vat().iteritems():
                vat_list.append('%.2f%%' % vat)
                tax_list.append('%.2f %s' % (items['tax'], self.invoice.currency))
                total_list.append('%.2f %s' % (items['total'], self.invoice.currency))
                total_tax_list.append('%.2f %s' % (items['total_tax'], self.invoice.currency))


            self.pdf.setFont('DejaVu', 6)
            text = self.pdf.beginText((LEFT + 1) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(vat_list))
            self.pdf.drawText(text)

            text = self.pdf.beginText((LEFT + 11) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(tax_list))
            self.pdf.drawText(text)

            text = self.pdf.beginText((LEFT + 27) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(total_list))
            self.pdf.drawText(text)

            text = self.pdf.beginText((LEFT + 45) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(total_tax_list))
            self.pdf.drawText(text)



            self.pdf.setFont('DejaVu-Bold', 11)
            self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 14) * mm, _(u'Total with tax')+': %.2f %s' % (self.invoice.price_tax, self.invoice.currency))

        if items_are_with_tax:
            self.pdf.rect(LEFT * mm, (TOP - i - 17) * mm, (LEFT + 156) * mm, (i + 19) * mm, stroke=True, fill=False) #140,142
        else:
            self.pdf.rect(LEFT * mm, (TOP - i - 11) * mm, (LEFT + 156) * mm, (i + 13) * mm, stroke=True, fill=False) #140,142

        if self.invoice.creator.stamp_filename:
            im = Image.open(self.invoice.creator.stamp_filename)
            height = float(im.size[1]) / (float(im.size[0])/200.0)
            self.pdf.drawImage(self.invoice.creator.stamp_filename, (LEFT + 98) * mm, (TOP - i - 72) * mm, 200, height)

        path = self.pdf.beginPath()
        path.moveTo((LEFT + 110) * mm, (TOP - i - 70) * mm)
        path.lineTo((LEFT + 164) * mm, (TOP - i - 70) * mm)
        self.pdf.drawPath(path, True, True)

        self.pdf.drawString((LEFT + 112) * mm, (TOP - i - 75) * mm, '%s: %s' % (_(u'Creator'), self.invoice.creator.name))


    def drawDates(self,TOP,LEFT):
        self.pdf.setFont('DejaVu', 10)
        top = TOP + 1
        items = [
            (LEFT * mm, '%s: %s' % (_(u'Date'), self.invoice.date)),
            (LEFT * mm, '%s: %s' % (_(u'Payback'),
                                              self.invoice.payback))

        ]
        if self.invoice.taxable_date:
            items.append((LEFT * mm, '%s: %s' % (_(u'Taxable date'),
                        self.invoice.taxable_date)))

        items.append((LEFT * mm, '%s: %s' % (_(u'Paytype'),
                                                       self.invoice.paytype)))

        for item in items:
            self.pdf.drawString(item[0], top * mm, item[1])
            top += -5
Пример #23
0
class PDFGenerator(object):
    canvas = None
    colorspace = None
    use_spot = True
    num_pages = 0
    page_count = 0
    prgs_msg = _('Saving in process...')

    def __init__(self, fileptr, cms, version=PDF_VERSION_DEFAULT):
        self.cms = cms
        self.canvas = Canvas(fileptr, pdfVersion=version[0])
        self.info = UC_PDFInfo(self.canvas._doc)
        self.info.pdfxversion = version[1]
        self.info.subject = '---'
        self.canvas.setPageCompression(1)

    # ---PDF doc data
    def set_creator(self, name):
        self.info.creator = name

    def set_producer(self, name):
        self.info.producer = name

    def set_title(self, title):
        self.info.title = title

    def set_author(self, author):
        self.info.author = author

    def set_subject(self, subj):
        self.info.subject = subj

    def set_keywords(self, keywords):
        self.info.keywords = keywords

    # ---Rendering options
    def set_compression(self, val=True):
        self.canvas.setPageCompression(int(val))

    def set_colorspace(self, cs=None):
        self.colorspace = cs

    def set_spot_usage(self, val=True):
        self.use_spot = val

    # ---Page processing

    def set_num_pages(self, num=1):
        self.num_pages = num

    def set_progress_message(self, msg):
        self.prgs_msg = msg

    def start_page(self, w, h, left_margin=0.0, top_margin=0.0):
        self.canvas.translate(w / 2.0 - left_margin, h / 2.0 - top_margin)
        self.canvas.setPageSize((w, h))
        position = 0.0
        if self.num_pages:
            position = float(self.page_count) / float(self.num_pages)
        events.emit(events.FILTER_INFO, self.prgs_msg, position)

    def end_page(self):
        self.canvas.showPage()
        self.page_count += 1
        position = 1.0
        if self.num_pages:
            position = float(self.page_count) / float(self.num_pages)
        events.emit(events.FILTER_INFO, self.prgs_msg, position)

    def save(self):
        self.canvas.save()

    # --- Rendering
    def render(self, objs, toplevel=False):
        obj_count = 0
        for obj in objs:
            if obj.is_pixmap():
                self.draw_pixmap(obj)
            elif obj.is_primitive():
                curve_obj = obj.to_curve()
                if curve_obj.is_primitive():
                    self.draw_curve(curve_obj)
                else:
                    self.render(curve_obj.childs)
            elif obj.is_container():
                self.draw_container(obj)
            else:
                self.render(obj.childs)

            # ---Progress
            obj_count += 1
            shift = 0.0
            page_size = 1.0
            if self.num_pages:
                shift = float(self.page_count) / float(self.num_pages)
                page_size = 1.0 / float(self.num_pages)
            position = shift + obj_count / len(objs) * page_size
            events.emit(events.FILTER_INFO, self.prgs_msg, position)

    def draw_curve(self, curve_obj):
        paths = libgeom.apply_trafo_to_paths(curve_obj.paths, curve_obj.trafo)
        pdfpath, closed = self.make_pdfpath(paths)
        fill_style = curve_obj.style[0]
        stroke_style = curve_obj.style[1]
        if stroke_style and stroke_style[7]:
            self.stroke_pdfpath(pdfpath, stroke_style, curve_obj.stroke_trafo)
        if fill_style and fill_style[0] & sk2const.FILL_CLOSED_ONLY and closed:
            self.fill_pdfpath(curve_obj, pdfpath, fill_style,
                              curve_obj.fill_trafo)
        elif fill_style and not fill_style[0] & sk2const.FILL_CLOSED_ONLY:
            self.fill_pdfpath(curve_obj, pdfpath, fill_style,
                              curve_obj.fill_trafo)
        if stroke_style and not stroke_style[7]:
            self.stroke_pdfpath(pdfpath, stroke_style, curve_obj.stroke_trafo)

    def draw_container(self, obj):
        container = obj.childs[0].to_curve()
        paths = libgeom.apply_trafo_to_paths(container.paths, container.trafo)
        pdfpath, closed = self.make_pdfpath(paths)
        fill_style = container.style[0]
        stroke_style = container.style[1]
        if stroke_style and stroke_style[7]:
            self.stroke_pdfpath(pdfpath, stroke_style, container.stroke_trafo)

        self.canvas.saveState()
        self.canvas.clipPath(pdfpath, 0, 0)

        if fill_style and fill_style[0] & sk2const.FILL_CLOSED_ONLY and closed:
            self.fill_pdfpath(container, pdfpath, fill_style,
                              container.fill_trafo)
        elif fill_style and not fill_style[0] & sk2const.FILL_CLOSED_ONLY:
            self.fill_pdfpath(container, pdfpath, fill_style,
                              container.fill_trafo)

        self.render(obj.childs[1:])

        self.canvas.restoreState()

        if stroke_style and not stroke_style[7]:
            self.stroke_pdfpath(pdfpath, stroke_style, container.stroke_trafo)

    def make_pdfpath(self, paths):
        closed = False
        pdfpath = self.canvas.beginPath()
        for path in paths:
            pdfpath.moveTo(*path[0])
            for point in path[1]:
                if len(point) > 2:
                    pdfpath.curveTo(point[0][0], point[0][1], point[1][0],
                                    point[1][1], point[2][0], point[2][1])
                else:
                    pdfpath.lineTo(*point)
            if path[2]:
                pdfpath.close()
                closed = True
        return pdfpath, closed

    def set_fill_rule(self, fillrule):
        if fillrule in (sk2const.FILL_EVENODD,
                        sk2const.FILL_EVENODD_CLOSED_ONLY):
            fillrule = FILL_EVEN_ODD
        else:
            fillrule = FILL_NON_ZERO
        self.canvas._fillMode = fillrule

    def set_rgb_values(self, color, pdfcolor):
        r, g, b = self.cms.get_rgb_color(color)[1]
        density = pdfcolor.density
        if density < 1:
            r = density * (r - 1) + 1
            g = density * (g - 1) + 1
            b = density * (b - 1) + 1
        pdfcolor.red, pdfcolor.green, pdfcolor.blue = (r, g, b)

    def get_pdfcolor(self, color):
        pdfcolor = None
        alpha = color[2]
        if self.use_spot and color[0] == uc2const.COLOR_SPOT:
            c, m, y, k = self.cms.get_cmyk_color(color)[1]
            spotname = color[3]
            if spotname == uc2const.COLOR_REG: spotname = 'All'
            pdfcolor = CMYKColorSep(c, m, y, k, spotName=spotname, alpha=alpha)
        elif self.colorspace == uc2const.COLOR_CMYK:
            c, m, y, k = self.cms.get_cmyk_color(color)[1]
            pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)
        elif self.colorspace == uc2const.COLOR_RGB:
            r, g, b = self.cms.get_rgb_color(color)[1]
            return Color(r, g, b, alpha)
        elif self.colorspace == uc2const.COLOR_GRAY:
            gray = self.cms.get_grayscale_color(color)
            k = 1.0 - gray[1][0]
            c = m = y = 0.0
            pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)
        else:
            if color[0] == uc2const.COLOR_RGB:
                r, g, b = color[1]
                return Color(r, g, b, alpha)
            elif color[0] == uc2const.COLOR_GRAY:
                k = 1.0 - color[1][0]
                c = m = y = 0.0
                pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)
            else:
                c, m, y, k = self.cms.get_cmyk_color(color)[1]
                pdfcolor = CMYKColor(c, m, y, k, alpha=alpha)

        self.set_rgb_values(color, pdfcolor)
        return pdfcolor

    def stroke_pdfpath(self, pdfpath, stroke_style, stroke_trafo=[]):
        width = stroke_style[1]

        if not stroke_style[8]:
            width = stroke_style[1]
        else:
            if not stroke_trafo:
                stroke_trafo = [] + sk2const.NORMAL_TRAFO
            points = [[0.0, 0.0], [1.0, 0.0]]
            points = libgeom.apply_trafo_to_points(points, stroke_trafo)
            coef = libgeom.distance(*points)
            width = stroke_style[1] * coef

        self.canvas.setStrokeColor(self.get_pdfcolor(stroke_style[2]))
        dash = stroke_style[3]
        caps = stroke_style[4]
        joint = stroke_style[5]
        miter = stroke_style[6]

        self.canvas.setLineWidth(width)
        self.canvas.setLineCap(caps - 1)
        self.canvas.setLineJoin(joint)
        dashes = []
        if dash:
            dashes = list(dash)
            w = width
            if w < 1.0: w = 1.0
            for i in range(len(dashes)):
                dashes[i] = w * dashes[i]
        self.canvas.setDash(dashes)
        self.canvas.setMiterLimit(miter)
        self.canvas.drawPath(pdfpath, 1, 0)
        self.canvas.setStrokeAlpha(1.0)

    def fill_pdfpath(self, obj, pdfpath, fill_style, fill_trafo=None):
        self.set_fill_rule(fill_style[0])

        if fill_style[1] == sk2const.FILL_SOLID:
            self.canvas.setFillColor(self.get_pdfcolor(fill_style[2]))
            self.canvas.drawPath(pdfpath, 0, 1)
        elif fill_style[1] == sk2const.FILL_GRADIENT:
            gradient = fill_style[2]
            stops = gradient[2]
            transparency = False
            for stop in stops:
                if stop[1][2] < 1.0:
                    transparency = True
                    break
            if transparency:
                self.fill_tr_gradient(obj, pdfpath, fill_trafo, gradient)
            else:
                self.fill_gradient(pdfpath, fill_trafo, gradient)

        elif fill_style[1] == sk2const.FILL_PATTERN:
            pattern = fill_style[2]
            self.fill_pattern(obj, pdfpath, fill_trafo, pattern)

    def fill_gradient(self, pdfpath, fill_trafo, gradient):
        self.canvas.saveState()
        self.canvas.clipPath(pdfpath, 0, 0)
        if fill_trafo:
            self.canvas.transform(*fill_trafo)
        grad_type = gradient[0]
        sp, ep = gradient[1]
        stops = gradient[2]
        colors = []
        positions = []
        for offset, color in stops:
            positions.append(offset)
            colors.append(self.get_pdfcolor(color))
        if grad_type == sk2const.GRADIENT_RADIAL:
            radius = libgeom.distance(sp, ep)
            self.canvas.radialGradient(sp[0], sp[1], radius, colors, positions,
                                       True)
        else:
            x0, y0 = sp
            x1, y1 = ep
            self.canvas.linearGradient(x0, y0, x1, y1, colors, positions, True)
        self.canvas.restoreState()

    def fill_tr_gradient(self, obj, pdfpath, fill_trafo, gradient):
        grad_type = gradient[0]
        if grad_type == sk2const.GRADIENT_RADIAL:
            self.fill_radial_tr_gradient(obj, pdfpath, fill_trafo, gradient)
        else:
            self.fill_linear_tr_gradient(obj, pdfpath, fill_trafo, gradient)

    def get_grcolor_at_point(self, stops, point=0.0):
        if not point: return self.get_pdfcolor(stops[0][1])
        if point == 1.0: return self.get_pdfcolor(stops[-1][1])
        stop0 = stops[0]
        stop1 = None
        for item in stops:
            if item[0] < point: stop0 = item
            if item[0] >= point:
                stop1 = item
                break
        size = stop1[0] - stop0[0]
        if not size:
            color = stop1[1]
        else:
            coef = (point - stop0[0]) / size
            color = self.cms.mix_colors(stop0[1], stop1[1], coef)
        return self.get_pdfcolor(color)

    def fill_linear_tr_gradient(self, obj, pdfpath, fill_trafo, gradient):
        if not fill_trafo:
            fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
        stops = gradient[2]
        sp, ep = gradient[1]
        dx, dy = sp
        l = libgeom.distance(sp, ep)
        angle = libgeom.get_point_angle(ep, sp)
        m21 = math.sin(angle)
        m11 = m22 = math.cos(angle)
        m12 = -m21
        trafo = [m11, m21, m12, m22, dx, dy]
        inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo),
                                           libgeom.invert_trafo(trafo))
        cv_trafo = libgeom.multiply_trafo(trafo, fill_trafo)
        paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo)
        paths = libgeom.apply_trafo_to_paths(paths, inv_trafo)
        bbox = libgeom.sum_bbox(libgeom.get_paths_bbox(paths),
                                [0.0, 0.0, l, 0.0])
        bbox = libgeom.normalize_bbox(bbox)

        y = bbox[1]
        d = libgeom.distance(*libgeom.apply_trafo_to_points(
            [[0.0, 0.0], [0.0, 1.0]], inv_trafo))
        height = bbox[3] - bbox[1]

        self.canvas.saveState()
        self.canvas.clipPath(pdfpath, 0, 0)
        self.canvas.transform(*cv_trafo)

        self.canvas.setFillColor(self.get_grcolor_at_point(stops, 0.0))
        self.canvas.rect(bbox[0], y, 0.0 - bbox[0], height, stroke=0, fill=1)

        x = 0.0
        while x < l:
            point = x / l
            self.canvas.setFillColor(self.get_grcolor_at_point(stops, point))
            if x + d < l:
                width = d
            else:
                width = l - x
            self.canvas.rect(x, y, width, height, stroke=0, fill=1)
            x += d

        self.canvas.setFillColor(self.get_grcolor_at_point(stops, 1.0))
        self.canvas.rect(l, y, bbox[2] - l, height, stroke=0, fill=1)

        self.canvas.restoreState()

    def fill_radial_tr_gradient(self, obj, pdfpath, fill_trafo, gradient):
        if not fill_trafo:
            fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
        stops = gradient[2]
        sp, ep = gradient[1]
        dx, dy = sp
        l = libgeom.distance(sp, ep)
        trafo = [1.0, 0.0, 0.0, 1.0, dx, dy]
        inv_trafo = libgeom.multiply_trafo(libgeom.invert_trafo(fill_trafo),
                                           libgeom.invert_trafo(trafo))
        cv_trafo = libgeom.multiply_trafo(trafo, fill_trafo)
        paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo)
        paths = libgeom.apply_trafo_to_paths(paths, inv_trafo)
        bbox = libgeom.sum_bbox(libgeom.get_paths_bbox(paths),
                                [0.0, 0.0, l, 0.0])
        bbox = libgeom.normalize_bbox(bbox)
        d = libgeom.distance(*libgeom.apply_trafo_to_points(
            [[0.0, 0.0], [0.0, 1.0]], inv_trafo))

        circle_paths = libgeom.get_circle_paths(0.0, 0.0, sk2const.ARC_CHORD)
        trafo = [2.0, 0.0, 0.0, 2.0, -1.0, -1.0]
        circle_paths = libgeom.apply_trafo_to_paths(circle_paths, trafo)

        inner_paths = []
        r = 0.0
        self.canvas.saveState()
        self.canvas.clipPath(pdfpath, 0, 0)
        self.canvas.transform(*cv_trafo)
        while r < l:
            point = r / l
            self.canvas.setFillColor(self.get_grcolor_at_point(stops, point))
            if r + d < l:
                coef = (r + d)
            else:
                coef = l
            trafo = [coef, 0.0, 0.0, coef, 0.0, 0.0]
            paths = libgeom.apply_trafo_to_paths(circle_paths, trafo)
            ring = self.make_pdfpath(inner_paths + paths)[0]
            inner_paths = paths
            self.canvas.drawPath(ring, stroke=0, fill=1)
            r += d

        self.canvas.setFillColor(self.get_grcolor_at_point(stops, 1.0))
        r = max(bbox[2] - bbox[0], bbox[3] - bbox[1])
        trafo = [2.0 * r, 0.0, 0.0, 2.0 * r, 0.0, 0.0]
        paths = libgeom.apply_trafo_to_paths(circle_paths, trafo)
        ring = self.make_pdfpath(inner_paths + paths)[0]
        self.canvas.drawPath(ring, stroke=0, fill=1)

        self.canvas.restoreState()

    def draw_image(self, image, alpha_channel=None):
        if not image: return
        if self.colorspace == uc2const.COLOR_CMYK:
            image = self.cms.convert_image(image, uc2const.IMAGE_CMYK)
        elif self.colorspace == uc2const.COLOR_RGB:
            image = self.cms.convert_image(image, uc2const.IMAGE_RGB)
        elif self.colorspace == uc2const.COLOR_GRAY:
            image = self.cms.convert_image(image, uc2const.IMAGE_GRAY)
        img = ImageReader(image)
        img.getRGBData()
        if alpha_channel: img._dataA = ImageReader(alpha_channel)
        self.canvas.drawImage(img, 0, 0, mask='auto')

    def draw_pixmap_obj(self, obj):
        if obj.colorspace in uc2const.DUOTONES:
            fg, bg = libimg.convert_duotone_to_image(self.cms, obj)
            self.draw_image(*bg)
            self.draw_image(*fg)
        else:
            raw_image = Image.open(StringIO(b64decode(obj.bitmap)))
            raw_image.load()
            alpha_chnl = None
            if obj.alpha_channel:
                alpha_chnl = Image.open(StringIO(b64decode(obj.alpha_channel)))
                alpha_chnl.load()
            self.draw_image(raw_image, alpha_chnl)

    def draw_pixmap(self, obj):
        self.canvas.saveState()
        self.canvas.transform(*obj.trafo)
        self.canvas.setFillColorCMYK(0, 0, 0, 1, 1)
        self.canvas.setStrokeColorCMYK(0, 0, 0, 1, 1)
        self.draw_pixmap_obj(obj)
        self.canvas.restoreState()

    def fill_pattern(self, obj, pdfpath, fill_trafo, pattern):
        if not fill_trafo:
            fill_trafo = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
        inv_ptrn_trafo = libgeom.invert_trafo(pattern[3])
        inv_trafo = libgeom.multiply_trafo(
            libgeom.invert_trafo(fill_trafo),
            libgeom.invert_trafo(inv_ptrn_trafo))
        paths = libgeom.apply_trafo_to_paths(obj.paths, obj.trafo)
        paths = libgeom.apply_trafo_to_paths(paths, inv_trafo)
        bbox = libgeom.get_paths_bbox(paths)
        cv_trafo = libgeom.multiply_trafo(pattern[3], fill_trafo)

        bmpstr = b64decode(pattern[1])
        image_obj = sk2_model.Pixmap(obj.config)
        libimg.set_image_data(self.cms, image_obj, bmpstr)
        if pattern[0] == sk2const.PATTERN_IMG and \
                        len(pattern) > 2:
            image_obj.style[3] = deepcopy(pattern[2])
        libimg.update_image(self.cms, image_obj)

        self.canvas.saveState()
        self.canvas.clipPath(pdfpath, 0, 0)
        self.canvas.transform(*cv_trafo)

        w, h = image_obj.get_size()
        x = bbox[0]
        y = bbox[3]
        while y > bbox[1] - h:
            while x < bbox[2]:
                self.canvas.saveState()
                self.canvas.transform(1.0, 0.0, 0.0, 1.0, x, y)
                self.draw_pixmap_obj(image_obj)
                self.canvas.restoreState()
                x += w
            y -= h
            x = bbox[0]
        self.canvas.restoreState()
Пример #24
0
class Invoice:
	client = Address()
	provider = Address()
	items = []
	title = "Faktura"
	vs = "00000000"
	creator = ""
	sign_image = None
	payment_days = 14
	paytype = "Převodem"

	pdffile = None

	def __init__(self):
		self.TOP = 260
		self.LEFT = 20

		pdfmetrics.registerFont(TTFont('DejaVu', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf'))

		self.pdffile = NamedTemporaryFile(delete=False)
		
		self.pdf = Canvas(self.pdffile.name, pagesize = letter)
		self.pdf.setFont("DejaVu", 15)
		self.pdf.setStrokeColorRGB(0, 0, 0)

	def __del__(self):
		if os.path.isfile(self.pdffile.name):
			os.unlink(self.pdffile.name)

	#############################################################
	## Setters
	#############################################################
	
	def setClient(self, address):
		self.client = address

	def setProvider(self, address):
		self.provider = address

	def setTitle(self, value):
		self.title = value
		
	def setVS(self, value):
		self.vs = value

	def setCreator(self, value):
		self.creator = value

	def setPaytype(self, value):
		self.paytype = value

	def setPaymentDays(self, value):
		self.payment_days = int(value)

	def addItem(self, item):
		self.items.append(item)

	#############################################################
	## Getters
	#############################################################

	def getContent(self):
		# Texty
		self.drawMain()
		self.drawProvider(self.TOP-10,self.LEFT+3)
		self.drawClient(self.TOP-30,self.LEFT+91)
		self.drawPayment(self.TOP-47,self.LEFT+3)
		self.drawItems(self.TOP-80,self.LEFT)
		self.drawDates(self.TOP-10,self.LEFT+91)

		#self.pdf.setFillColorRGB(0, 0, 0)

		self.pdf.showPage()
		self.pdf.save()

		f = open(self.pdffile.name)
		data = f.read()
		f.close()

		os.unlink(self.pdffile.name)

		return data

	#############################################################
	## Draw methods
	#############################################################

	def drawMain(self):
		# Horní lajna
		self.pdf.drawString(self.LEFT*mm, self.TOP*mm, self.title)
		self.pdf.drawString((self.LEFT+100)*mm, self.TOP*mm, "Variabilní symbol: %s" % self.vs)

		# Rámečky
		self.pdf.rect((self.LEFT)*mm, (self.TOP-68)*mm, (self.LEFT+156)*mm, 65*mm, stroke=True, fill=False)

		path = self.pdf.beginPath()
		path.moveTo((self.LEFT+88)*mm, (self.TOP-3)*mm)
		path.lineTo((self.LEFT+88)*mm, (self.TOP-68)*mm)
		self.pdf.drawPath(path, True, True)

		path = self.pdf.beginPath()
		path.moveTo((self.LEFT)*mm, (self.TOP-39)*mm)
		path.lineTo((self.LEFT+88)*mm, (self.TOP-39)*mm)
		self.pdf.drawPath(path, True, True)

		path = self.pdf.beginPath()
		path.moveTo((self.LEFT+88)*mm, (self.TOP-23)*mm)
		path.lineTo((self.LEFT+176)*mm, (self.TOP-23)*mm)
		self.pdf.drawPath(path, True, True)

	def drawClient(self,TOP,LEFT):
		self.pdf.setFont("DejaVu", 12)
		self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Odběratel")
		self.pdf.setFont("DejaVu", 8)
		text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
		text.textLines("\n".join(self.client.getAddressLines()))
		self.pdf.drawText(text)
		text = self.pdf.beginText((LEFT+2)*mm, (TOP-28)*mm)
		text.textLines("\n".join(self.client.getContactLines()))
		self.pdf.drawText(text)

	def drawProvider(self,TOP,LEFT):
		self.pdf.setFont("DejaVu", 12)
		self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Dodavatel")
		self.pdf.setFont("DejaVu", 8)
		text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
		text.textLines("\n".join(self.provider.getAddressLines()))
		self.pdf.drawText(text)
		text = self.pdf.beginText((LEFT+40)*mm, (TOP-6)*mm)
		text.textLines("\n".join(self.provider.getContactLines()))
		self.pdf.drawText(text)
		if self.provider.note:
			self.pdf.drawString((LEFT+2)*mm, (TOP-26)*mm, self.provider.note)

	def drawPayment(self,TOP,LEFT):
		self.pdf.setFont("DejaVu", 11)
		self.pdf.drawString((LEFT)*mm, (TOP)*mm, "Údaje pro platbu")
		#self.pdf.setFillColorRGB(255, 0, 0)
		text = self.pdf.beginText((LEFT+2)*mm, (TOP-6)*mm)
		text.textLines("""%s
Číslo účtu: %s
Variabilní symbol: %s"""%(self.provider.bank_name ,self.provider.bank_account, self.vs))
		self.pdf.drawText(text)

	def drawItems(self,TOP,LEFT):
		# Items
		path = self.pdf.beginPath()
		path.moveTo((LEFT)*mm, (TOP-4)*mm)
		path.lineTo((LEFT+176)*mm, (TOP-4)*mm)
		self.pdf.drawPath(path, True, True)

		self.pdf.setFont("DejaVu", 9)
		self.pdf.drawString((LEFT+1)*mm, (TOP-2)*mm, "Fakturuji vám:")

		i=9
		self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "Množství")
		self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "Cena za jedn.")
		self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "Cena celkem")
		i+=5

		# List
		total=0.0
		for x in self.items:
			self.pdf.drawString((LEFT+1)*mm, (TOP-i)*mm, x.name)
			i+=5
			self.pdf.drawString((LEFT+100)*mm, (TOP-i)*mm, "%d ks" % x.count)
			self.pdf.drawString((LEFT+122)*mm, (TOP-i)*mm, "%.2f,- kč" % x.price)
			self.pdf.drawString((LEFT+150)*mm, (TOP-i)*mm, "%.2f,- kč" % (x.total()))
			i+=5
			total += x.total()

		path = self.pdf.beginPath()
		path.moveTo((LEFT)*mm, (TOP-i)*mm)
		path.lineTo((LEFT+176)*mm, (TOP-i)*mm)
		self.pdf.drawPath(path, True, True)

		self.pdf.setFont("DejaVu", 12)
		self.pdf.drawString((LEFT+130)*mm, (TOP-i-10)*mm, "Celkem: %d ,- kč" % total)

		self.pdf.rect((LEFT)*mm, (TOP-i-17)*mm, (LEFT+156)*mm, (i+19)*mm, stroke=True, fill=False) #140,142

		if self.sign_image:
			self.pdf.drawImage(self.sign_image, (LEFT+98)*mm, (TOP-i-72)*mm)

		path = self.pdf.beginPath()
		path.moveTo((LEFT+110)*mm, (TOP-i-70)*mm)
		path.lineTo((LEFT+164)*mm, (TOP-i-70)*mm)
		self.pdf.drawPath(path, True, True)

		self.pdf.drawString((LEFT+112)*mm, (TOP-i-75)*mm, "Vystavil: %s" % self.creator)


	def drawDates(self,TOP,LEFT):
		today = datetime.datetime.today()
		payback = today+datetime.timedelta(self.payment_days)

		self.pdf.setFont("DejaVu", 10)
		self.pdf.drawString((LEFT)*mm, (TOP+1)*mm, "Datum vystavení: %s" % today.strftime("%d.%m.%Y"))
		self.pdf.drawString((LEFT)*mm, (TOP-4)*mm, "Datum splatnosti: %s" % payback.strftime("%d.%m.%Y"))
		self.pdf.drawString((LEFT)*mm, (TOP-9)*mm, "Forma úhrady: " + self.paytype)
Пример #25
0
class SimpleInvoice(BaseInvoice):
    def gen(self, filename, generate_qr_code=False):
        self.TOP = 260
        self.LEFT = 20
        self.filename = filename
        if generate_qr_code:
            qr_builder = QrCodeBuilder(self.invoice)
        else:
            qr_builder = None

        self.qr_builder = qr_builder

        pdfmetrics.registerFont(TTFont('DejaVu', FONT_PATH))
        pdfmetrics.registerFont(TTFont('DejaVu-Bold', FONT_BOLD_PATH))

        self.pdf = Canvas(self.filename, pagesize=letter)
        self.addMetaInformation(self.pdf)

        self.pdf.setFont('DejaVu', 15)
        self.pdf.setStrokeColorRGB(0, 0, 0)

        # Texty
        self.drawMain()
        self.drawTitle()
        self.drawProvider(self.TOP - 10, self.LEFT + 3)
        self.drawClient(self.TOP - 35, self.LEFT + 91)
        self.drawPayment(self.TOP - 47, self.LEFT + 3)
        self.drawItems(self.TOP - 80, self.LEFT)
        self.drawDates(self.TOP - 10, self.LEFT + 91)

        #self.pdf.setFillColorRGB(0, 0, 0)

        self.pdf.showPage()
        self.pdf.save()
        if self.qr_builder:
            self.qr_builder.destroy()

    #############################################################
    ## Draw methods
    #############################################################

    def addMetaInformation(self, pdf):
        pdf.setCreator(self.invoice.provider.summary)
        pdf.setTitle(self.invoice.title)
        pdf.setAuthor(self.invoice.creator.name)

    def drawTitle(self):
        # Up line
        self.pdf.drawString(self.LEFT * mm, self.TOP * mm, self.invoice.title)
        self.pdf.drawString(
            (self.LEFT + 90) * mm, self.TOP * mm,
            _(u'Variable symbol: %s') % self.invoice.variable_symbol)

    def drawMain(self):
        # Borders
        self.pdf.rect(self.LEFT * mm, (self.TOP - 68) * mm,
                      (self.LEFT + 156) * mm,
                      65 * mm,
                      stroke=True,
                      fill=False)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT + 88) * mm, (self.TOP - 3) * mm)
        path.lineTo((self.LEFT + 88) * mm, (self.TOP - 68) * mm)
        self.pdf.drawPath(path, True, True)

        path = self.pdf.beginPath()
        path.moveTo(self.LEFT * mm, (self.TOP - 39) * mm)
        path.lineTo((self.LEFT + 88) * mm, (self.TOP - 39) * mm)
        self.pdf.drawPath(path, True, True)

        path = self.pdf.beginPath()
        path.moveTo((self.LEFT + 88) * mm, (self.TOP - 27) * mm)
        path.lineTo((self.LEFT + 176) * mm, (self.TOP - 27) * mm)
        self.pdf.drawPath(path, True, True)

    def drawClient(self, TOP, LEFT):
        self.pdf.setFont('DejaVu', 12)
        self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Customer'))
        self.pdf.setFont('DejaVu', 8)

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 4) * mm)
        text.textLines('\n'.join(self.invoice.client.get_address_lines()))
        self.pdf.drawText(text)

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm)
        text.textLines('\n'.join(self.invoice.client.get_contact_lines()))
        self.pdf.drawText(text)

        if self.invoice.client.note:
            self.pdf.setFont('DejaVu', 6)
            text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 28) * mm)
            text.textLines(self.invoice.client.note)
            self.pdf.drawText(text)

    def drawProvider(self, TOP, LEFT):
        self.pdf.setFont('DejaVu', 12)
        self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Provider'))
        self.pdf.setFont('DejaVu', 8)

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 6) * mm)
        text.textLines('\n'.join(self.invoice.provider.get_address_lines()))
        self.pdf.drawText(text)

        text = self.pdf.beginText((LEFT + 40) * mm, (TOP - 6) * mm)
        text.textLines('\n'.join(self.invoice.provider.get_contact_lines()))

        self.pdf.drawText(text)
        if self.invoice.provider.note:
            self.pdf.setFont('DejaVu', 6)
            text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 23) * mm)
            text.textLines(self.invoice.provider.note)
            self.pdf.drawText(text)

    def drawPayment(self, TOP, LEFT):
        self.pdf.setFont('DejaVu-Bold', 9)
        self.pdf.drawString(LEFT * mm, TOP * mm, _(u'Payment information'))

        text = self.pdf.beginText((LEFT + 2) * mm, (TOP - 6) * mm)
        lines = [
            self.invoice.provider.bank_name,
            '%s: %s' %
            (_(u'Bank account'), self.invoice.provider.bank_account),
            '%s: %s' % (_(u'Variable symbol'), self.invoice.variable_symbol)
        ]
        if self.invoice.specific_symbol:
            lines.append('%s: %s' %
                         (_(u'Specific symbol'), self.invoice.specific_symbol))
        text.textLines('\n'.join(lines))
        self.pdf.drawText(text)

    def drawItems(self, TOP, LEFT):
        # Items
        path = self.pdf.beginPath()
        path.moveTo(LEFT * mm, (TOP - 4) * mm)
        path.lineTo((LEFT + 176) * mm, (TOP - 4) * mm)
        self.pdf.drawPath(path, True, True)

        self.pdf.setFont('DejaVu-Bold', 7)
        self.pdf.drawString((LEFT + 1) * mm, (TOP - 2) * mm,
                            _(u'List of items'))

        self.pdf.drawString((LEFT + 1) * mm, (TOP - 9) * mm, _(u'Description'))
        items_are_with_tax = self.invoice.use_tax
        if items_are_with_tax:
            i = 9
            self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm, _(u'Units'))
            self.pdf.drawString((LEFT + 88) * mm, (TOP - i) * mm,
                                _(u'Price per one'))
            self.pdf.drawString((LEFT + 115) * mm, (TOP - i) * mm,
                                _(u'Total price'))
            self.pdf.drawString((LEFT + 137) * mm, (TOP - i) * mm, _(u'Tax'))
            self.pdf.drawString((LEFT + 146) * mm, (TOP - i) * mm,
                                _(u'Total price with tax'))
            i += 5
        else:
            i = 9
            self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm, _(u'Units'))
            self.pdf.drawString((LEFT + 123) * mm, (TOP - i) * mm,
                                _(u'Price per one'))
            self.pdf.drawString((LEFT + 150) * mm, (TOP - i) * mm,
                                _(u'Total price'))
            i += 5

        self.pdf.setFont('DejaVu', 7)

        # List
        for item in self.invoice.items:
            self.pdf.drawString((LEFT + 1) * mm, (TOP - i) * mm,
                                item.description)
            if item.tax or items_are_with_tax:
                items_are_with_tax = True
                if len(item.description) > 52: i += 5
                if float(int(item.count)) == item.count:
                    self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm,
                                        '%.2f %s' % (item.count, item.unit))
                else:
                    self.pdf.drawString((LEFT + 68) * mm, (TOP - i) * mm,
                                        '%.2f %s' % (item.count, item.unit))
                self.pdf.drawString(
                    (LEFT + 88) * mm, (TOP - i) * mm,
                    '%.2f,- %s' % (item.price, self.invoice.currency))
                self.pdf.drawString(
                    (LEFT + 115) * mm, (TOP - i) * mm,
                    '%.2f,- %s' % (item.total, self.invoice.currency))
                self.pdf.drawString((LEFT + 137) * mm, (TOP - i) * mm,
                                    '%.0f %%' % item.tax)
                self.pdf.drawString(
                    (LEFT + 146) * mm, (TOP - i) * mm,
                    '%.2f,- %s' % (item.total_tax, self.invoice.currency))
                i += 5
            else:
                if len(item.description) > 75: i += 5
                if float(int(item.count)) == item.count:
                    self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm,
                                        '%.2f %s' % (item.count, item.unit))
                else:
                    self.pdf.drawString((LEFT + 104) * mm, (TOP - i) * mm,
                                        '%.2f %s' % (item.count, item.unit))
                self.pdf.drawString(
                    (LEFT + 123) * mm, (TOP - i) * mm,
                    '%.2f,- %s' % (item.price, self.invoice.currency))
                self.pdf.drawString(
                    (LEFT + 150) * mm, (TOP - i) * mm,
                    '%.2f,- %s' % (item.total, self.invoice.currency))
                i += 5

        if self.invoice.rounding_result:
            path = self.pdf.beginPath()
            path.moveTo(LEFT * mm, (TOP - i) * mm)
            path.lineTo((LEFT + 176) * mm, (TOP - i) * mm)
            i += 5
            self.pdf.drawPath(path, True, True)
            self.pdf.drawString((LEFT + 1) * mm, (TOP - i) * mm,
                                _(u'Rounding'))
            self.pdf.drawString(
                (LEFT + 68) * mm, (TOP - i) * mm, '%.2f,- %s' %
                (self.invoice.difference_in_rounding, self.invoice.currency))
            i += 3

        path = self.pdf.beginPath()
        path.moveTo(LEFT * mm, (TOP - i) * mm)
        path.lineTo((LEFT + 176) * mm, (TOP - i) * mm)
        self.pdf.drawPath(path, True, True)

        if not items_are_with_tax:
            self.pdf.setFont('DejaVu-Bold', 11)
            self.pdf.drawString((LEFT + 100) * mm, (TOP - i - 7) * mm,
                                _(u'Total') + ': %.2f %s' %
                                (self.invoice.price, self.invoice.currency))
        else:
            self.pdf.setFont('DejaVu-Bold', 6)
            self.pdf.drawString((LEFT + 1) * mm, (TOP - i - 2) * mm,
                                _(u'Breakdown VAT'))
            vat_list, tax_list, total_list, total_tax_list = [
                _(u'VAT rate')
            ], [_(u'Tax')], [_(u'Without VAT')], [_(u'With VAT')]
            for vat, items in self.invoice.generate_breakdown_vat().iteritems(
            ):
                vat_list.append('%.2f%%' % vat)
                tax_list.append('%.2f %s' %
                                (items['tax'], self.invoice.currency))
                total_list.append('%.2f %s' %
                                  (items['total'], self.invoice.currency))
                total_tax_list.append(
                    '%.2f %s' % (items['total_tax'], self.invoice.currency))

            self.pdf.setFont('DejaVu', 6)
            text = self.pdf.beginText((LEFT + 1) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(vat_list))
            self.pdf.drawText(text)

            text = self.pdf.beginText((LEFT + 11) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(tax_list))
            self.pdf.drawText(text)

            text = self.pdf.beginText((LEFT + 27) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(total_list))
            self.pdf.drawText(text)

            text = self.pdf.beginText((LEFT + 45) * mm, (TOP - i - 5) * mm)
            text.textLines('\n'.join(total_tax_list))
            self.pdf.drawText(text)

            self.pdf.setFont('DejaVu-Bold', 11)
            self.pdf.drawString(
                (LEFT + 100) * mm, (TOP - i - 14) * mm,
                _(u'Total with tax') + ': %.2f %s' %
                (self.invoice.price_tax, self.invoice.currency))

        if items_are_with_tax:
            self.pdf.rect(LEFT * mm, (TOP - i - 17) * mm, (LEFT + 156) * mm,
                          (i + 19) * mm,
                          stroke=True,
                          fill=False)  #140,142
        else:
            self.pdf.rect(LEFT * mm, (TOP - i - 11) * mm, (LEFT + 156) * mm,
                          (i + 13) * mm,
                          stroke=True,
                          fill=False)  #140,142

        if self.invoice.creator.stamp_filename:
            im = Image.open(self.invoice.creator.stamp_filename)
            height = float(im.size[1]) / (float(im.size[0]) / 200.0)
            self.pdf.drawImage(self.invoice.creator.stamp_filename,
                               (LEFT + 98) * mm, (TOP - i - 72) * mm, 200,
                               height)

        if self.qr_builder:
            qr_filename = self.qr_builder.filename
            im = Image.open(qr_filename)
            height = float(im.size[1]) / (float(im.size[0]) / 200.0)
            self.pdf.drawImage(qr_filename, LEFT * mm, (TOP - i - 100) * mm,
                               200, height)

        path = self.pdf.beginPath()
        path.moveTo((LEFT + 110) * mm, (TOP - i - 70) * mm)
        path.lineTo((LEFT + 164) * mm, (TOP - i - 70) * mm)
        self.pdf.drawPath(path, True, True)

        self.pdf.drawString(
            (LEFT + 112) * mm, (TOP - i - 75) * mm,
            '%s: %s' % (_(u'Creator'), self.invoice.creator.name))

    def drawDates(self, TOP, LEFT):
        self.pdf.setFont('DejaVu', 10)
        top = TOP + 1
        items = [(LEFT * mm, '%s: %s' % (_(u'Date'), self.invoice.date)),
                 (LEFT * mm, '%s: %s' % (_(u'Payback'), self.invoice.payback))]
        if self.invoice.taxable_date:
            items.append(
                (LEFT * mm,
                 '%s: %s' % (_(u'Taxable date'), self.invoice.taxable_date)))

        items.append(
            (LEFT * mm, '%s: %s' % (_(u'Paytype'), self.invoice.paytype)))

        for item in items:
            self.pdf.drawString(item[0], top * mm, item[1])
            top += -5
Пример #26
0
def draw_card(canvas: RLC.Canvas, X, Y, character):
    canvas.saveState()
    canvas.translate(X, Y)

    font_size_title = 16
    font_size_content = 8
    font_size_annotation = 5
    font_size_furigana = 6
    font_size_words = 9
    font_to_mm = 0.5 * mm
    margin_drawing = 6 * mm
    margin_left = 2 * mm
    margin_bottom = 2 * mm
    margin_text = 48 * mm
    margin_top = -font_size_furigana * font_to_mm
    len_vertical_text_bound = 12
    max_words_count = 6

    paths, hints = extract_drawings(character.char)

    canvas.translate(margin_drawing, -margin_drawing)
    canvas.setLineWidth(7)
    canvas.setLineCap(1)
    canvas.setLineJoin(1)
    for i, path in enumerate(paths):
        canvas.setStrokeColorRGB(*palette["strokes"][i])
        canvas.drawPath(convert_path(path, canvas))
    canvas.setLineWidth(1)
    canvas.setLineCap(0)
    canvas.setLineJoin(0)

    canvas.setFont('Helvetica', 5)
    canvas.setFillColorRGB(*palette["default"])
    for i, hint in enumerate(hints):
        canvas.drawString(*hint)

    canvas.translate(-margin_drawing, margin_drawing)

    canvas.setFont(font_jp, font_size_title)
    canvas.setFillColorRGB(*palette["default"])
    canvas.drawString(margin_left, -font_size_title * font_to_mm,
                      character.char)

    x_ = margin_text
    canvas.setFont(font_jp_v, font_size_annotation)
    canvas.setFillColorRGB(*palette["readings_kun"])
    canvas.drawString(x_, margin_top, "kun")
    x_ = margin_text + font_size_annotation * 0.5 * mm
    canvas.setFont(font_jp_v, font_size_content)
    canvas.setFillColorRGB(*palette["readings_kun"])
    rest = character.readings_kun
    while rest:
        if len(rest) <= len_vertical_text_bound:
            text, rest = rest.strip(), ''
        else:
            dlm = len_vertical_text_bound
            while rest[dlm] != ' ':
                dlm -= 1
            text, rest = rest[:dlm], rest[dlm:].lstrip()
        canvas.drawString(x_, margin_top, text)
        x_ += font_size_content * 0.4 * mm

    x_ += 1 * mm
    canvas.setFont(font_jp_v, font_size_annotation)
    canvas.setFillColorRGB(*palette["readings_on"])
    canvas.drawString(x_, margin_top, "on")
    x_ += font_size_annotation * font_to_mm
    canvas.setFont(font_jp_v, font_size_content)
    canvas.setFillColorRGB(*palette["readings_on"])
    canvas.drawString(x_, margin_top, character.readings_on)

    x_ += font_size_words * font_to_mm + 2 * mm
    canvas.setFont(font_jp_v, font_size_annotation)
    canvas.setFillColorRGB(*palette["default"])
    canvas.drawString(x_, margin_top, "words")
    x_ += font_size_annotation * font_to_mm
    words = character.words.split('<br/>')[:max_words_count]
    y_ = -margin_top - (font_size_words +
                        font_size_furigana * 2.5) * font_to_mm
    rightmost = 0
    for word in words:
        xl = x_
        wparts = re.split(r'[{}]', word)
        for wpart in wparts:
            if wpart and ':' in wpart:
                part, furi_part = wpart.split(':')
            else:
                part, furi_part = wpart, ''
            width_part = fontH.stringWidth(part, font_size_words)
            width_furi = fontH.stringWidth(furi_part, font_size_furigana)
            width = max(width_furi, width_part)
            canvas.setFont(font_jp, font_size_words)
            canvas.drawString(xl + width / 2 - width_part / 2, y_, part)
            canvas.setFont(font_jp, font_size_furigana)
            canvas.drawString(xl + width / 2 - width_furi / 2,
                              y_ + font_size_furigana * font_to_mm + 1 * mm,
                              furi_part)
            xl += width
            rightmost = max(rightmost, xl)
        y_ -= font_size_words * font_to_mm + font_size_furigana * font_to_mm
    x_ += rightmost

    x_ = margin_left
    canvas.setFillColorRGB(*palette["secondary"])
    canvas.setFont(font_jp, font_size_annotation)
    canvas.drawString(x_, -card_height + margin_bottom, "components")
    canvas.setFont(font_jp, font_size_content)
    canvas.drawString(
        x_, -card_height + margin_bottom + font_size_annotation * font_to_mm,
        character.parts)

    x_ += margin_left + 12 * mm + fontH.stringWidth(character.parts,
                                                    font_size_content)
    canvas.setFont(font_jp, font_size_annotation)
    canvas.drawString(x_, -card_height + margin_bottom, "radical")
    canvas.setFont(font_jp, font_size_content)
    canvas.drawString(
        x_, -card_height + margin_bottom + font_size_annotation * font_to_mm,
        character.radicals)

    canvas.setFont(font_jp, font_size_annotation)
    text = f"JLPT {character.jlpt or '-'}      #{character.frequency}"
    canvas.drawString(
        card_width - 5 * mm - fontH.stringWidth(text, font_size_annotation),
        -card_height + margin_bottom, text)

    draw_marks(canvas)

    canvas.restoreState()

    print(character.char)
Пример #27
-1
    def draw_label(self, c: Canvas, col: int, row: int, redemption_code: str):
        x = self.left_margin + (col + 0.5) * self.label_width + col * self.inner_margin
        y = self.page_height - self.top_margin - (row + 0.5) * self.label_height

        # Drawing label bounds helps when adjusting layout. Not for production.
        # self.draw_label_bounds(c, x, y)

        c.setFont("Courier-Bold", 13)
        c.drawString(x - 80, y + 14, redemption_code)

        c.setFont("Helvetica", 10)

        # Space to enter redemption month and day.
        p = c.beginPath()
        p.moveTo(x + 20, y + 12)
        p.lineTo(x + 45, y + 12)
        p.moveTo(x + 55, y + 12)
        p.lineTo(x + 80, y + 12)
        p.close()
        c.drawPath(p)
        c.drawCentredString(x + 15, y + 16, 'm:')
        c.drawCentredString(x + 50, y + 16, 'd:')

        # Space to enter redeemer's email address.
        p = c.beginPath()
        p.moveTo(x - 80, y - 14)
        p.lineTo(x + 80, y - 14)
        p.close()
        c.drawPath(p)
        c.drawCentredString(x, y - 24, 'email address')