def test_instanceStringWidth(self): from reportlab.pdfbase.pdfmetrics import registerFont, getFont, _fonts, unicode2T1 from reportlab.pdfbase.ttfonts import TTFont ttfn = 'Vera' t1fn = 'Times-Roman' registerFont(TTFont(ttfn, "Vera.ttf")) ttf = getFont(ttfn) t1f = getFont(t1fn) testCp1252 = b'copyright \xa9 trademark \x99 registered \xae ReportLab! Ol\xe9!' enc='cp1252' senc = 'utf8' ts = b'ABCDEF\xce\x91\xce\xb2G' utext = b'ABCDEF\xce\x91\xce\xb2G'.decode(senc) fontSize = 12 defns="ttfn t1fn ttf t1f testCp1252 enc senc ts utext fontSize ttf.face ttf.face.charWidths ttf.face.defaultWidth t1f.widths t1f.encName t1f.substitutionFonts _fonts" import sys F = [] def tfunc(f,ts,fontSize,enc,funcs,i): w1 = funcs[i][0](f,ts,fontSize,enc) w2 = funcs[1][0](f,ts,fontSize,enc) #python version if abs(w1-w2)>=1e-10: F.append("stringWidth%s(%r,%r,%s,%r)-->%r != f._py_stringWidth(...)-->%r" % (fontType,f,ts,fontSize,enc,w1,w2)) for font,fontType in ((t1f,'T1'),(ttf,'TTF')): funcs = getFuncs('instanceStringWidth'+fontType) for i,kind in enumerate(('c','py')): for j in (3,2,1,0): #we run several times to allow the refcounts to stabilize if j: rcv = getrc(defns) tfunc(font,testCp1252,fontSize,enc,funcs,i) tfunc(font,ts,fontSize,senc,funcs,i) tfunc(font,utext,fontSize,senc,funcs,i) if not j: rcc = checkrc(defns,rcv) if rcc: F.append("%s %s refcount diffs (%s)" % (fontType,kind,rcc)) assert not F,"instanceStringWidth failures\n\t%s" % '\n\t'.join(F)
def testStringWidth(incFontSize): '''example from the reportlab test set''' from _rl_accel import stringWidthU from reportlab.pdfbase.pdfmetrics import _py_stringWidth, getFont, registerFont, _fonts from reportlab.pdfbase.ttfonts import TTFont ttfn = 'Luxi-Serif' t1fn = 'Times-Roman' registerFont(TTFont(ttfn, "luxiserif.ttf")) ttf = getFont(ttfn) t1f = getFont(t1fn) testCp1252 = 'copyright %s trademark %s registered %s ReportLab! Ol%s!' % (chr(169), chr(153),chr(174), chr(0xe9)) enc='cp1252' senc = 'utf8' intern(senc) ts = 'ABCDEF\xce\x91\xce\xb2G' utext = 'ABCDEF\xce\x91\xce\xb2G'.decode('utf8') fontSize = 12 defns="ttfn t1fn ttf t1f testCp1252 enc senc ts utext fontSize ttf.face ttf.face.charWidths ttf.face.defaultWidth t1f.widths t1f.encName t1f.substitutionFonts _fonts" rcv = getrc(defns) #compute initial ref def tfunc(ts,fn,fontSize,enc): w1 = stringWidthU(ts,fn,fontSize,enc) w2 = _py_stringWidth(ts,fn,fontSize,enc) assert abs(w1-w2)<1e-10,"stringWidthU(%r,%r,%s,%r)-->%r != _py_stringWidth(...)-->%r" % (ts,fn,fontSize,enc,w1,w2) tfunc(testCp1252,t1fn,fontSize,enc) tfunc(ts,t1fn,fontSize,senc) tfunc(utext,t1fn,fontSize,senc) tfunc(ts,ttfn,fontSize,senc) tfunc(testCp1252,ttfn,fontSize,enc) tfunc(utext,ttfn,fontSize,senc) if incFontSize: z = fontSize #simulate adding a reference to fontSize print checkrc(defns,rcv)
def test_instanceStringWidth(self): from reportlab.pdfbase.pdfmetrics import registerFont, getFont, _fonts, unicode2T1 from reportlab.pdfbase.ttfonts import TTFont ttfn = 'Vera' t1fn = 'Times-Roman' registerFont(TTFont(ttfn, "Vera.ttf")) ttf = getFont(ttfn) t1f = getFont(t1fn) testCp1252 = 'copyright %s trademark %s registered %s ReportLab! Ol%s!' % (chr(169), chr(153),chr(174), chr(0xe9)) enc='cp1252' senc = 'utf8' ts = 'ABCDEF\xce\x91\xce\xb2G' utext = 'ABCDEF\xce\x91\xce\xb2G'.decode(senc) fontSize = 12 defns="ttfn t1fn ttf t1f testCp1252 enc senc ts utext fontSize ttf.face ttf.face.charWidths ttf.face.defaultWidth t1f.widths t1f.encName t1f.substitutionFonts _fonts" rcv = getrc(defns) def tfunc(f,ts,fontSize,enc): w1 = f.stringWidth(ts,fontSize,enc) w2 = f._py_stringWidth(ts,fontSize,enc) assert abs(w1-w2)<1e-10,"f(%r).stringWidthU(%r,%s,%r)-->%r != f._py_stringWidth(...)-->%r" % (f,ts,fontSize,enc,w1,w2) tfunc(t1f,testCp1252,fontSize,enc) tfunc(t1f,ts,fontSize,senc) tfunc(t1f,utext,fontSize,senc) tfunc(ttf,ts,fontSize,senc) tfunc(ttf,testCp1252,fontSize,enc) tfunc(ttf,utext,fontSize,senc) rcc = checkrc(defns,rcv) assert not rcc, "rc diffs (%s)" % rcc
def registerFonts(fontlist): """ Registeres specified fonts for use in PDF. fontlist -- list of (fontname, relpath) tuples fontname -- name for font registration relpath -- path to TTF font relative to this function """ from os import path, sep from inspect import getfile, currentframe from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont for (fontname, relpath) in fontlist: # check if already registered try: pdfmetrics.getFont(fontname) continue # font already registered except KeyError: pass # font not registered selfPath = path.dirname(path.abspath(getfile(currentframe()))) ttfFile = selfPath + sep + relpath pdfmetrics.registerFont(TTFont(fontname, ttfFile))
def testStringWidth(self): from _rl_accel import stringWidthU from reportlab.pdfbase.pdfmetrics import _py_stringWidth, getFont, registerFont, _fonts from reportlab.pdfbase.ttfonts import TTFont ttfn = 'Vera' t1fn = 'Times-Roman' registerFont(TTFont(ttfn, "Vera.ttf")) ttf = getFont(ttfn) t1f = getFont(t1fn) testCp1252 = 'copyright %s trademark %s registered %s ReportLab! Ol%s!' % (chr(169), chr(153),chr(174), chr(0xe9)) enc='cp1252' senc = 'utf8' intern(senc) ts = 'ABCDEF\xce\x91\xce\xb2G' utext = 'ABCDEF\xce\x91\xce\xb2G'.decode('utf8') fontSize = 12 stringWidthU(testCp1252,t1fn,fontSize,enc) #avoid obscure startup initialization problems defns="ttfn t1fn ttf t1f testCp1252 enc senc ts utext fontSize ttf.face ttf.face.charWidths ttf.face.defaultWidth t1f.widths t1f.encName t1f.substitutionFonts _fonts" rcv = getrc(defns) #first count def tfunc(ts,fn,fontSize,enc): w1 = stringWidthU(ts,fn,fontSize,enc) w2 = _py_stringWidth(ts,fn,fontSize,enc) assert abs(w1-w2)<1e-10,"stringWidthU(%r,%r,%s,%r)-->%r != _py_stringWidth(...)-->%r" % (ts,fn,fontSize,enc,w1,w2) tfunc(testCp1252,t1fn,fontSize,enc) tfunc(ts,t1fn,fontSize,senc) tfunc(utext,t1fn,fontSize,senc) tfunc(ts,ttfn,fontSize,senc) tfunc(testCp1252,ttfn,fontSize,enc) tfunc(utext,ttfn,fontSize,senc) rcc = checkrc(defns,rcv) #second count and compare assert not rcc, "rc diffs (%s)" % rcc
def test_instanceStringWidth(self): from reportlab.pdfbase.pdfmetrics import registerFont, getFont, _fonts, unicode2T1 from reportlab.pdfbase.ttfonts import TTFont ttfn = 'Vera' t1fn = 'Times-Roman' registerFont(TTFont(ttfn, "Vera.ttf")) ttf = getFont(ttfn) t1f = getFont(t1fn) testCp1252 = 'copyright %s trademark %s registered %s ReportLab! Ol%s!' % ( chr(169), chr(153), chr(174), chr(0xe9)) enc = 'cp1252' senc = 'utf8' ts = 'ABCDEF\xce\x91\xce\xb2G' utext = 'ABCDEF\xce\x91\xce\xb2G'.decode(senc) fontSize = 12 defns = "ttfn t1fn ttf t1f testCp1252 enc senc ts utext fontSize ttf.face ttf.face.charWidths ttf.face.defaultWidth t1f.widths t1f.encName t1f.substitutionFonts _fonts" rcv = getrc(defns) def tfunc(f, ts, fontSize, enc): w1 = f.stringWidth(ts, fontSize, enc) w2 = f._py_stringWidth(ts, fontSize, enc) assert abs( w1 - w2 ) < 1e-10, "f(%r).stringWidthU(%r,%s,%r)-->%r != f._py_stringWidth(...)-->%r" % ( f, ts, fontSize, enc, w1, w2) tfunc(t1f, testCp1252, fontSize, enc) tfunc(t1f, ts, fontSize, senc) tfunc(t1f, utext, fontSize, senc) tfunc(ttf, ts, fontSize, senc) tfunc(ttf, testCp1252, fontSize, enc) tfunc(ttf, utext, fontSize, senc) rcc = checkrc(defns, rcv) assert not rcc, "rc diffs (%s)" % rcc
def setTtfFonts(familyName, font_dir, normal=(None, None), bold=(None, None), italic=(None, None), bold_italic=(None, None)): """ Sets fonts for True Type Fonts """ normalName, normalFile = normal boldName, boldFile = bold italicName, italicFile = italic bold_italicName, bold_italicFile = bold_italic pdfmetrics.registerFont( TTFont(normalName, os.path.join(font_dir, normalFile))) pdfmetrics.registerFont(TTFont(boldName, os.path.join(font_dir, boldFile))) pdfmetrics.registerFont( TTFont(italicName, os.path.join(font_dir, italicFile))) pdfmetrics.registerFont( TTFont(bold_italicName, os.path.join(font_dir, bold_italicFile))) addMapping(familyName, 0, 0, normalName) addMapping(familyName, 1, 0, boldName) addMapping(familyName, 0, 1, italicName) addMapping(familyName, 1, 1, bold_italicName) base_fonts().update({"normal": getFont(normalName).fontName}) base_fonts().update({"bold": getFont(boldName).fontName}) base_fonts().update({"italic": getFont(italicName).fontName}) base_fonts().update({"bold_italic": getFont(bold_italicName).fontName})
def define(self, name, engine, enginefontname): """Define a new font. ``name`` is the name that will be used for this font in the presentation text. ``engine`` is the font engine. MagicPoint supports several, but mgp2pdf supports only "xfont". ``enginefontname`` is the name of the font according to the font engine. For ``xfont`` it can be "family", "family-weight" or "family-weight-slant". Or it can be a fontconfig pattern. """ if engine != "xfont": raise NotImplementedError("unsupported font engine %s" % engine) if '-' in enginefontname and ':' not in enginefontname: if enginefontname.count('-') == 1: # family-weight family, weight = enginefontname.split('-') weight = self.weights.get(weight, weight) enginefontname = '%s:weight=%s' % (family, weight) elif enginefontname.count('-') == 2: # family-weight-slant family, weight, slant = enginefontname.split('-') weight = self.weights.get(weight, weight) slant = {'i': 'italic', 'r': 'roman'}[slant] enginefontname = '%s:weight=%s:slant=%s' % (family, weight, slant) filename = subprocess.Popen( ['fc-match', enginefontname, '-f', '%{file}'], stdout=subprocess.PIPE).communicate()[0].strip() if not filename: sys.exit('Could not find the font file for %s' % enginefontname) log.debug("Font %s: %s -> %s" % (name, enginefontname, filename)) pdfmetrics.registerFont(TTFont(name, filename)) pdfmetrics.getFont(name) # just see if raises
def is_registered(font_name: str) -> bool: """Checks if a font is registered.""" try: pdfmetrics.getFont(font_name) return True except KeyError: return False
def select_fontname(fontname, default_fontname): if fontname not in pdfmetrics.getRegisteredFontNames()\ or fontname not in pdfmetrics.standardFonts: # let reportlab attempt to find it try: pdfmetrics.getFont(fontname) except Exception: _logger.warning('Could not locate font %s, substituting default: %s', fontname, default_fontname) fontname = default_fontname return fontname
def setFont(self, node): fontname = node.get('name') if fontname not in pdfmetrics.getRegisteredFontNames()\ or fontname not in pdfmetrics.standardFonts: # let reportlab attempt to find it try: pdfmetrics.getFont(fontname) except Exception: _logger.debug('Could not locate font %s, substituting default: %s', fontname, self.canvas._fontname) fontname = self.canvas._fontname return self.canvas.setFont(fontname, utils.unit_get(node.get('size')))
def select_fontname(fontname, default_fontname): if fontname not in pdfmetrics.getRegisteredFontNames()\ or fontname not in pdfmetrics.standardFonts: # let reportlab attempt to find it try: pdfmetrics.getFont(fontname) except Exception: addition = "" if " " in fontname: addition = ". Your font contains spaces which is not valid in RML." _logger.warning('Could not locate font %s, substituting default: %s%s', fontname, default_fontname, addition) fontname = default_fontname return fontname
def GetStringAscDes(c, label, fontname, fontsize): # print("fontname: %s fontsize: %s" % (fontname, fontsize)) if fontsize is None or fontname is None: return (0, 0) if fontsize == 0 or fontname == "": return (0, 0) try: face = pdfmetrics.getFont(fontname).face fontname_ = fontname except: face = pdfmetrics.getFont(DEF_FONT_NAME).face fontname_ = DEF_FONT_NAME # print(face.ascent, face.descent) ascent, descent = (face.ascent / 1000.0), abs(face.descent / 1000.0) return (ascent * fontsize, descent * fontsize)
def draw_text(string, text, font, size, width, leading=None): if leading: text.setFont(font, size, leading=leading) else: text.setFont(font, size) font = pdfmetrics.getFont(font) if font.stringWidth(string, size) > width: bits = string.split(' ') while bits: did_something = False for i in range(1, len(bits) + 1): if font.stringWidth(' '.join(bits[:i]), size) > width: if i == 1: i = 2 text.textLine(' '.join(bits[:i - 1])) bits = bits[i - 1:] did_something = True break if not did_something: text.textLine(' '.join(bits)) break else: text.textLine(string)
def font_height(font_name, font_size): """Get font height details.""" from reportlab.pdfbase import pdfmetrics face = pdfmetrics.getFont(font_name).face (ascent, descent) = face.ascent, face.descent return ascent * font_size / 1000.0, descent * font_size / 1000.0, ( ascent - descent) * font_size / 1000.0
def _formatText(self, text): "Generates PDF text output operator(s)" if self._dynamicFont: #it's a truetype font and should be utf8. If an error is raised, results = [] font = pdfmetrics.getFont(self._fontname) try: #assume UTF8 stuff = font.splitString(text, self._canvas._doc) except UnicodeDecodeError: #assume latin1 as fallback from reportlab.pdfbase.ttfonts import latin1_to_utf8 from reportlab.lib.logger import warnOnce warnOnce('non-utf8 data fed to truetype font, assuming latin-1 data') text = latin1_to_utf8(text) stuff = font.splitString(text, self._canvas._doc) for subset, chunk in stuff: if subset != self._curSubset: pdffontname = font.getSubsetInternalName(subset, self._canvas._doc) results.append("%s %s Tf %s TL" % (pdffontname, fp_str(self._fontsize), fp_str(self._leading))) self._curSubset = subset chunk = self._canvas._escape(chunk) results.append("(%s) Tj" % chunk) return string.join(results, ' ') else: text = self._canvas._escape(text) return "(%s) Tj" % text
def telemetry(font, size): """ Return telemetry information about a given font. Returns a dict, with the following members: { 'm_width': float, approximated 'em square' size (rough), 'ascent': float, maximum height of text above baseline, 'descent': float, maxmim height of text below baseline, 'max_height': float, ascent+descent } """ face = getFont(font).face # +30% 'fudge' factor m_width = stringWidth('M', font, size)*1.3 ascent = float(face.ascent)*m_width/1000 descent = float(face.descent*-1)*m_width/1000 return { 'm_width': m_width, 'ascent': ascent, 'descent': descent, 'max_height': ascent+descent, }
def repl(match): out = "" prev = None fnum = 0 for c in match.group(0): while fnum < len(FONT_FALLBACK_ORDER): if ord(c) in pdfmetrics.getFont( FONT_FALLBACK_ORDER[fnum]).face.charWidths: if fnum != prev: if prev is not None: out += '</font>' out += '<font face="{}">'.format( FONT_FALLBACK_ORDER[fnum]) prev = fnum out += c break fnum += 1 else: logging.warn('No font for character {}'.format(hex(ord(c)))) out += c fnum = 0 if prev is not None: out += '</font>' logging.debug('Fallback replacement: "{}" -> "{}"'.format( match.group(0), out)) return out
def test_unicode2T1(self): from reportlab.pdfbase.pdfmetrics import getFont, _fonts t1fn = 'Times-Roman' t1f = getFont(t1fn) enc = 'cp1252' senc = 'utf8' testCp1252 = b'copyright \xa9 trademark \x99 registered \xae ReportLab! Ol\xe9!'.decode( enc) utext = b'This is the end of the \xce\x91\xce\xb2 world. This is the end of the \xce\x91\xce\xb2 world jap=\xe3\x83\x9b\xe3\x83\x86. This is the end of the \xce\x91\xce\xb2 world. This is the end of the \xce\x91\xce\xb2 world jap=\xe3\x83\x9b\xe3\x83\x86'.decode( 'utf8') FUNCS = getFuncs('unicode2T1') def tfunc(f, ts, func, kind): w1 = func(ts, [f] + f.substitutionFonts) w2 = FUNCS[1][0](ts, [f] + f.substitutionFonts) assert w1 == w2, "%s unicode2T1 %r != %r" % (kind, w1, w2) defns = "t1fn t1f testCp1252 enc senc utext t1f.widths t1f.encName t1f.substitutionFonts _fonts" F = [] for func, kind in FUNCS: rcv = getrc(defns) tfunc(t1f, testCp1252, func, kind) tfunc(t1f, utext, func, kind) rcc = checkrc(defns, rcv) if rcc: F.append("%s refcount diffs (%s)" % (kind, rcc)) assert not F, "test_unicode2T1 failures\n\t%s" % '\n\t'.join(F)
def hDraw(self, c, msg, fnt, x, y): "Helper - draws it with a box around" c.setFont(fnt, 16, 16) font = pdfmetrics.getFont(fnt) c.drawString(x, y, msg) width = font.stringWidth(msg, 16) c.rect(x,y,width,16,stroke=1,fill=0)
def getStringBBox(self, text): font = pdfmetrics.getFont(self._font) width = pdfmetrics.stringWidth(text, self._font, self.fontSize) ll = (0,0) ur = (width, (1.0 - font.face.ascent/2048.)*self.fontSize) ur = (width, (1.0 - font.face.ascent/2048.)*self.fontSize) return ll,ur
def drawString(self, x, y, s, angle=0, text_anchor='left', textRenderMode=0): needFill = textRenderMode in (0,2,4,6) needStroke = textRenderMode in (1,2,5,6) if needFill or needStroke: if text_anchor!='left': textLen = stringWidth(s, self._font,self._fontSize) if text_anchor=='end': x -= textLen elif text_anchor=='middle': x -= textLen/2. elif text_anchor=='numeric': x -= numericXShift(text_anchor,s,textLen,self._font,self._fontSize) fontObj = getFont(self._font) if not self.code[self._fontCodeLoc]: psName = asNative(fontObj.face.name) self.code[self._fontCodeLoc]='(%s) findfont %s scalefont setfont' % (psName,fp_str(self._fontSize)) if psName not in self._fontsUsed: self._fontsUsed.append(psName) if angle!=0: self.code_append('gsave %s translate %s rotate' % (fp_str(x,y),fp_str(angle))) x = y = 0 oldColor = self._color if fontObj._dynamicFont: self._textOut(x, y, s, textRenderMode=textRenderMode) else: self._issueT1String(fontObj,x,y,s, textRenderMode=textRenderMode) self.setColor(oldColor) if angle!=0: self.code_append('grestore')
def draw_candidate(c, number, family, given, party, i, tl, br, box_gap): number = str(number) font = pdfmetrics.getFont(FONT) c.rect(tl[0] + 1 * mm, tl[1] - 3 * mm - i * box_gap - (i + 1) * BOX_SIZE, BOX_SIZE, BOX_SIZE) width = font.stringWidth(number, FONT_SIZE + 1.0) c.setFont(FONT, FONT_SIZE + 1.0) c.drawCentredString( tl[0] + 1.1 * mm + BOX_SIZE / 2.0, tl[1] - 2.3 * mm - i * box_gap - (i + 1) * BOX_SIZE + 1.5 * mm, number) text = c.beginText(tl[0] + 2 * mm + BOX_SIZE, tl[1] - 3 * mm - i * box_gap - i * BOX_SIZE - 4.5) text.setFont(FONT + '-Bold', CANDIDATE_FONT_SIZE, leading=1.1 * CANDIDATE_FONT_SIZE) text.textLine(family) draw_text(given, text, FONT, CANDIDATE_FONT_SIZE, LABEL_WIDTH, leading=CANDIDATE_FONT_SIZE) if party: draw_text(party.upper(), text, FONT, PARTY_FONT_SIZE, LABEL_WIDTH) c.drawText(text) c.setFont(FONT, FONT_SIZE)
def getTextHeight(fontName, fontSize): face = pdfmetrics.getFont(fontName).face ascent = (face.ascent * fontSize) / 1000.0 descent = (face.descent * fontSize) / 1000.0 height = ascent - descent # <-- descent it's negative return height
def __call__(self,legend, g, x, xt, y, width, lWidth): from reportlab.graphics.shapes import String, Line fontSize = self.fontSize fontName = self.fontName fillColor = self.fillColor strokeColor = self.strokeColor strokeWidth = self.strokeWidth ascent=getFont(fontName).face.ascent/1000. if ascent==0: ascent=0.718 # default (from helvetica) ascent *= fontSize leading = fontSize*1.2 yt = y+self.dy-ascent*1.3 if self.lText and fillColor: g.add(String(xt,yt,self.lText, fontName=fontName, fontSize=fontSize, fillColor=fillColor, textAnchor = "start")) if self.rText: g.add(String(xt+width,yt,self.rText, fontName=fontName, fontSize=fontSize, fillColor=fillColor, textAnchor = "end")) if strokeWidth and strokeColor: yL = y+self.dly-leading g.add(Line(x+self.dlx[0],yL,x+self.dlx[1]+lWidth,yL, strokeColor=strokeColor, strokeWidth=strokeWidth, strokeDashArray=self.strokeDashArray))
def hDraw(self, c, msg, fnt, x, y): "Helper - draws it with a box around" c.setFont(fnt, 16, 16) font = pdfmetrics.getFont(fnt) c.drawString(x, y, msg) width = font.stringWidth(msg, 16) c.rect(x, y, width, 16, stroke=1, fill=0)
def _calcHeight(self): deltay = self.deltay dy = self.dy thisy = upperlefty = self.y - dy ascent=getFont(self.fontName).face.ascent/1000. if ascent==0: ascent=0.718 # default (from helvetica) leading = self.fontSize*1.2 columnCount = 0 count = 0 lowy = upperlefty for unused, name in colorNamePairs: T = string.split(name and str(name) or '','\n') S = [] # thisy+dy/2 = y+leading/2 y = thisy+(dy-ascent)*0.5-leading newy = thisy-max(deltay,len(S)*leading) lowy = min(y,newy) if count == columnMaximum-1: count = 0 thisy = upperlefty columnCount = columnCount + 1 else: thisy = newy count = count+1 return upperlefty - lowy
def _calcHeight(self): dy = self.dy yGap = self.yGap thisy = upperlefty = self.y - dy fontSize = self.fontSize ascent=getFont(self.fontName).face.ascent/1000. if ascent==0: ascent=0.718 # default (from helvetica) ascent *= fontSize leading = fontSize*1.2 deltay = self.deltay if not deltay: deltay = max(dy,leading)+self.autoYPadding columnCount = 0 count = 0 lowy = upperlefty lim = self.columnMaximum - 1 for name in self._getTexts(self.colorNamePairs): y0 = thisy+(dy-ascent)*0.5 y = y0 - _getLineCount(name)*leading leadingMove = 2*y0-y-thisy newy = thisy-max(deltay,leadingMove)-yGap lowy = min(y,newy,lowy) if count==lim: count = 0 thisy = upperlefty columnCount = columnCount + 1 else: thisy = newy count = count+1 return upperlefty - lowy
def Dessine_macaron(self, texte="", rond=False): """ Dessine un cadre arrondi et un texte dans le coin haut droit de la case """ # Dessine le rectangle de fond if self.parent.dictDonnees["case_macaron_mix_couleurs"] == False : case_macaron_bord_couleur = self.parent.dictDonnees["case_macaron_bord_couleur"] case_macaron_fond_couleur = self.parent.dictDonnees["case_macaron_fond_couleur"] else : # Mix de couleur couleur = MixCouleurs() case_macaron_bord_couleur = wx.Colour(*couleur) case_macaron_fond_couleur = wx.Colour(*couleur) self.canvas.setStrokeColor(ColorWxToPdf(case_macaron_bord_couleur, alpha=self.parent.dictDonnees["case_macaron_bord_alpha"]/100.0)) self.canvas.setFillColor(ColorWxToPdf(case_macaron_fond_couleur, alpha=self.parent.dictDonnees["case_macaron_fond_alpha"]/100.0)) if self.parent.dictDonnees["case_macaron_type"] == "rond" : self.canvas.circle(x_cen=self.largeur_case - self.parent.dictDonnees["case_macaron_largeur"] / 2.0 -5, y_cen=self.hauteur_case - self.parent.dictDonnees["case_macaron_hauteur"] / 2.0 -5, r=self.parent.dictDonnees["case_macaron_taille_police"]-3, stroke=True, fill=True) largeur, hauteur = self.parent.dictDonnees["case_macaron_largeur"] + 10, self.parent.dictDonnees["case_macaron_hauteur"] + 10 else : self.canvas.roundRect(x=self.largeur_case - self.parent.dictDonnees["case_macaron_largeur"], y=self.hauteur_case - self.parent.dictDonnees["case_macaron_hauteur"], width=self.parent.dictDonnees["case_macaron_largeur"] + self.parent.dictDonnees["case_macaron_radius"], height=self.parent.dictDonnees["case_macaron_hauteur"] + self.parent.dictDonnees["case_macaron_radius"], radius=self.parent.dictDonnees["case_macaron_radius"], stroke=True, fill=True) largeur, hauteur = self.parent.dictDonnees["case_macaron_largeur"], self.parent.dictDonnees["case_macaron_hauteur"] # Calcule la hauteur du texte face = pdfmetrics.getFont(self.parent.dictDonnees["case_macaron_nom_police"]).face hauteur_font = face.ascent * self.parent.dictDonnees["case_macaron_taille_police"] / 1000.0 # Ecrit le texte self.canvas.setFont(self.parent.dictDonnees["case_macaron_nom_police"], size=self.parent.dictDonnees["case_macaron_taille_police"]) self.canvas.setFillColor(ColorWxToPdf(self.parent.dictDonnees["case_macaron_texte_couleur"], alpha=1)) self.canvas.drawCentredString(self.largeur_case - largeur + largeur / 2.0, self.hauteur_case - (hauteur / 2.0 + hauteur_font / 2.0), texte)
def getStringBBox(self, text): font = pdfmetrics.getFont(self._font) width = pdfmetrics.stringWidth(text, self._font, self.fontSize) ll = (0, 0) ur = (width, (1.0 - font.face.ascent / 2048.) * self.fontSize) ur = (width, (1.0 - font.face.ascent / 2048.) * self.fontSize) return ll, ur
def _calcHeight(self): dy = self.dy yGap = self.yGap thisy = upperlefty = self.y - dy fontSize = self.fontSize ascent = getFont(self.fontName).face.ascent / 1000. if ascent == 0: ascent = 0.718 # default (from helvetica) ascent *= fontSize leading = fontSize * 1.2 deltay = self.deltay if not deltay: deltay = max(dy, leading) + self.autoYPadding columnCount = 0 count = 0 lowy = upperlefty lim = self.columnMaximum - 1 for name in self._getTexts(self.colorNamePairs): y0 = thisy + (dy - ascent) * 0.5 y = y0 - _getLineCount(name) * leading leadingMove = 2 * y0 - y - thisy newy = thisy - max(deltay, leadingMove) - yGap lowy = min(y, newy, lowy) if count == lim: count = 0 thisy = upperlefty columnCount = columnCount + 1 else: thisy = newy count = count + 1 return upperlefty - lowy
def GetFontWidhHeight(txt, font_name, font_size): face = pdfmetrics.getFont(font_name).face ascent = (face.ascent * font_size) / 1000.0 descent = (face.descent * font_size) / 1000.0 descent = -descent height = ascent + descent width = pdfmetrics.stringWidth(txt, font_name, font_size) return width, height
def setFont(self, node): fname = node.get('name') if fname not in pdfmetrics.getRegisteredFontNames()\ or fname not in pdfmetrics.standardFonts: # let reportlab attempt to find it try: pdfmetrics.getFont(fname) except Exception: logging.getLogger('report.fonts').\ warning('Could not locate font %s, substituting default: %s', fname, self.canvas._fontname) fname = self.canvas._fontname try: return self.canvas.setFont(fname, utils.unit_get(node.get('size'))) except KeyError: logging.getLogger('report.fonts').error("setFont failed for %s", fname) raise KeyError('Font "%s" cannot be used in the PDF engine' % fname)
def Dessine_titre(self, texte=""): """ Dessine un titre en haut de la page """ # Dessine le rectangle de fond self.canvas.setStrokeColor(ColorWxToPdf(self.parent.dictDonnees["titre_bord_couleur"], alpha=1)) self.canvas.setFillColor(ColorWxToPdf(self.parent.dictDonnees["titre_fond_couleur"], alpha=1)) self.canvas.rect(x=0, y=0, width=self.largeur, height=self.parent.dictDonnees["titre_hauteur"], stroke=True, fill=True) # Dessine le mot MENUS afficher_mot_menu = False if afficher_mot_menu == True : # Calcule la hauteur du texte taille_police = 30 face = pdfmetrics.getFont(self.parent.dictDonnees["titre_nom_police"]).face hauteur_font = face.ascent * taille_police / 1000.0 largeur_box = 200 hauteur_box = 40 x_box = 35 y_box = -10 self.canvas.rotate(2) self.canvas.setStrokeColor(ColorWxToPdf(wx.BLACK, alpha=1)) self.canvas.setFillColor(ColorWxToPdf(wx.WHITE, alpha=1)) self.canvas.rect(x=x_box, y=y_box, width=largeur_box, height=hauteur_box, stroke=True, fill=True) self.canvas.setFont(self.parent.dictDonnees["titre_nom_police"], size=taille_police) self.canvas.setFillColor(ColorWxToPdf(wx.BLACK, alpha=1)) self.canvas.drawCentredString(x_box + largeur_box / 2.0, y_box + hauteur_box / 2.0 - hauteur_font / 2.0, _(u"MENUS")) self.canvas.rotate(-2) # Ecrit la période # Calcule la hauteur du texte face = pdfmetrics.getFont(self.parent.dictDonnees["titre_nom_police"]).face hauteur_font = face.ascent * self.parent.dictDonnees["titre_taille_police"] / 1000.0 # Ecrit le texte x = self.largeur / 2.0 if afficher_mot_menu == True : x += (largeur_box + 30) / 2.0 self.canvas.setFont(self.parent.dictDonnees["titre_nom_police"], size=self.parent.dictDonnees["titre_taille_police"]) self.canvas.setFillColor(ColorWxToPdf(self.parent.dictDonnees["titre_texte_couleur"], alpha=1)) self.canvas.drawCentredString(x, self.parent.dictDonnees["titre_hauteur"] - (self.parent.dictDonnees["titre_hauteur"] / 2.0 + hauteur_font / 2.0), texte)
def drawSetNames(self, pageCards): # print sets for this page self.canvas.saveState() try: # calculate the text height, font size, and orientation maxFontsize = 12 minFontsize = 6 fontname = self.fontNameRegular font = pdfmetrics.getFont(fontname) fontHeightRelative = (font.face.ascent + abs(font.face.descent)) / 1000.0 canFit = False layouts = [{'rotation': 0, 'minMarginHeight': self.options.minVerticalMargin, 'totalMarginHeight': self.options.verticalMargin, 'width': self.options.paperwidth}, {'rotation': 90, 'minMarginHeight': self.options.minHorizontalMargin, 'totalMarginHeight': self.options.horizontalMargin, 'width': self.options.paperheight}] for layout in layouts: availableMargin = layout[ 'totalMarginHeight'] - layout['minMarginHeight'] fontsize = availableMargin / fontHeightRelative fontsize = min(maxFontsize, fontsize) if fontsize >= minFontsize: canFit = True break if not canFit: import warnings warnings.warn("Not enough space to display set names") return self.canvas.setFont(fontname, fontsize) sets = [] for c in pageCards: setTitle = c.cardset.title() if setTitle not in sets: sets.append(setTitle) # Centered on page xPos = layout['width'] / 2 # Place at the very edge of the margin yPos = layout['minMarginHeight'] if layout['rotation']: self.canvas.rotate(layout['rotation']) yPos = -yPos self.canvas.drawCentredString(xPos, yPos, '/'.join(sets)) finally: self.canvas.restoreState()
def getStringExtent(self, str, fontName = None, fontSize = None): fontName = fontName if fontName is not None else self.cFontName fontSize = fontSize if fontSize is not None else self.cFontSize face = pdfmetrics.getFont(fontName).face ascent = (face.ascent * fontSize) / 1000.0 descent = (face.descent * fontSize) / 1000.0 height = ascent - descent # <-- descent it's negative width = stringWidth(str, fontName, fontSize) return (width, height)
def __init__(self, canvas, x=0,y=0): self._code = ['BT'] #no point in [] then append RGB self._canvas = canvas #canvas sets this so it has access to size info self._fontname = self._canvas._fontname self._fontsize = self._canvas._fontsize self._leading = self._canvas._leading font = pdfmetrics.getFont(self._fontname) self._curSubset = -1 self.setTextOrigin(x, y)
def __init__(self, canvas, x=0, y=0): self._code = ['BT'] #no point in [] then append RGB self._canvas = canvas #canvas sets this so it has access to size info self._fontname = self._canvas._fontname self._fontsize = self._canvas._fontsize self._leading = self._canvas._leading font = pdfmetrics.getFont(self._fontname) self._curSubset = -1 self.setTextOrigin(x, y)
def drawString(self, x, y, text, _fontInfo=None): gs = self._gs if _fontInfo: fontName, fontSize = _fontInfo else: fontSize = gs.fontSize fontName = gs.fontName try: gfont = getFont(gs.fontName) except: gfont = None font = getFont(fontName) if font._dynamicFont: if isinstance(text, unicode): text = text.encode("utf8") gs.drawString(x, y, text) else: fc = font if not isinstance(text, unicode): try: text = text.decode("utf8") except UnicodeDecodeError, e: i, j = e.args[2:4] raise UnicodeDecodeError( *( e.args[:4] + ("%s\n%s-->%s<--%s" % (e.args[4], text[i - 10 : i], text[i:j], text[j : j + 10]),) ) ) FT = unicode2T1(text, [font] + font.substitutionFonts) n = len(FT) nm1 = n - 1 wscale = 0.001 * fontSize for i in xrange(n): f, t = FT[i] if f != fc: _setFont(gs, f.fontName, fontSize) fc = f gs.drawString(x, y, t) if i != nm1: x += wscale * sum(map(f.widths.__getitem__, map(ord, t))) if font != fc: _setFont(gs, fontName, fontSize)
def draw_post(pdf, post): pdf.setFont('HeiseiKakuGo-W5', 24) w = getFont('HeiseiKakuGo-W5').stringWidth(post[0], 24) + 0.2*cm offset = 0 for i, c in enumerate(post): if '-' in c: w /= 1.20 offset = -0.25*cm continue pdf.drawString(4.5*cm + i*w + offset, 13*cm, c)
def setFont(self,font,fontSize,leading=None): if self._font!=font or self._fontSize!=fontSize: self._font = font self._fontSize = fontSize fontObj = getFont(font) if self._ttf_embed and fontObj._dynamicFont: fontObj._assignState(self,asciiReadable=False,namePrefix='.RLF') self._curSubset = -1 self._fontCodeLoc = len(self.code) self.code_append('')
def get_word_centered_position(config, font_size): from reportlab.pdfbase import pdfmetrics face = pdfmetrics.getFont(config.font_name).face ascent = (face.ascent * font_size) / 1000.0 descent = (abs(face.descent) * font_size) / 1000.0 font_height = ascent - descent center_width = config.page_width / 2 center_height = config.page_height / 2 - font_height / 2 return center_width, center_height
def install_font(name, resource_name, user_fonts): try: pdfmetrics.getFont(name) except: regular = create_single_font(name, resource_name + "-Regular", None, user_fonts) bold = create_single_font(name + "-Bold", resource_name + "-Bold", regular, user_fonts) italic = create_single_font(name + "-Italic", resource_name + "-Italic", regular, user_fonts) bold_italic = create_single_font(name + "-BoldItalic", resource_name + "-BoldItalic", bold, user_fonts) pdfmetrics.registerFontFamily(name, normal=name, bold=bold, italic=italic, boldItalic=bold_italic)
def GetStringMetrics(c, label, fontname, fontsize, with_descent=True): # print("fontname: %s fontsize: %s" % (fontname, fontsize)) if fontsize is None or fontname is None: return (0, 0) if fontsize == 0 or fontname == "": return (0, 0) try: face = pdfmetrics.getFont(fontname).face fontname_ = fontname except: face = pdfmetrics.getFont(DEF_FONT_NAME).face fontname_ = DEF_FONT_NAME # print(face.ascent, face.descent) ascent, descent = (face.ascent / 1000.0), abs(face.descent / 1000.0) height = ascent - descent if with_descent else ascent height *= fontsize width = c.stringWidth(label, fontname_, fontsize) return (width, height)
def _t1_re_encode(self): if not self._fontsUsed: return # for each font used, reencode the vectors C = [] for fontName in self._fontsUsed: fontObj = getFont(fontName) if not fontObj._dynamicFont and fontObj.encName=='WinAnsiEncoding': C.append('WinAnsiEncoding /%s /%s RE' % (fontName, fontName)) if C: C.insert(0,PS_WinAnsiEncoding) self.code.insert(1, string.join(C, self._sep))
def _t1_re_encode(self): if not self._fontsUsed: return # for each font used, reencode the vectors C = [] for fontName in self._fontsUsed: fontObj = getFont(fontName) if not fontObj._dynamicFont and fontObj.encName == 'WinAnsiEncoding': C.append('WinAnsiEncoding /%s /%s RE' % (fontName, fontName)) if C: C.insert(0, PS_WinAnsiEncoding) self.code.insert(1, self._sep.join(C))
def drawString(self, x, y, text, _fontInfo=None, text_anchor='left'): gs = self._gs gs_fontSize = gs.fontSize gs_fontName = gs.fontName if _fontInfo and _fontInfo != (gs_fontSize, gs_fontName): fontName, fontSize = _fontInfo _setFont(gs, fontName, fontSize) else: fontName = gs_fontName fontSize = gs_fontSize try: if text_anchor in ('end', 'middle', 'end'): textLen = stringWidth(text, fontName, fontSize) if text_anchor == 'end': x -= textLen elif text_anchor == 'middle': x -= textLen / 2. elif text_anchor == 'numeric': x -= numericXShift(text_anchor, text, textLen, fontName, fontSize) if self._backend == 'rlPyCairo': gs.drawString(x, y, text) else: font = getFont(fontName) if font._dynamicFont: gs.drawString(x, y, text) else: fc = font if not isUnicode(text): try: text = text.decode('utf8') except UnicodeDecodeError as e: i, j = e.args[2:4] raise UnicodeDecodeError( *(e.args[:4] + ('%s\n%s-->%s<--%s' % (e.args[4], text[i - 10:i], text[i:j], text[j:j + 10]), ))) FT = unicode2T1(text, [font] + font.substitutionFonts) n = len(FT) nm1 = n - 1 for i in range(n): f, t = FT[i] if f != fc: _setFont(gs, f.fontName, fontSize) fc = f gs.drawString(x, y, t) if i != nm1: x += f.stringWidth(t.decode(f.encName), fontSize) finally: gs.setFont(gs_fontName, gs_fontSize)
def drawString(self, x, y, text, _fontInfo=None): gs = self._gs if _fontInfo: fontName, fontSize = _fontInfo else: fontSize = gs.fontSize fontName = gs.fontName try: gfont = getFont(gs.fontName) except: gfont = None font = getFont(fontName) if font._dynamicFont: if isinstance(text, unicode): text = text.encode('utf8') gs.drawString(x, y, text) else: fc = font if not isinstance(text, unicode): try: text = text.decode('utf8') except UnicodeDecodeError, e: i, j = e.args[2:4] raise UnicodeDecodeError( *(e.args[:4] + ('%s\n%s-->%s<--%s' % (e.args[4], text[i - 10:i], text[i:j], text[j:j + 10]), ))) FT = unicode2T1(text, [font] + font.substitutionFonts) n = len(FT) nm1 = n - 1 wscale = 0.001 * fontSize for i in xrange(n): f, t = FT[i] if f != fc: _setFont(gs, f.fontName, fontSize) fc = f gs.drawString(x, y, t) if i != nm1: x += wscale * sum(map(f.widths.__getitem__, map(ord, t))) if font != fc: _setFont(gs, fontName, fontSize)
def drawString(self, x, y, text, _fontInfo=None): gs = self._gs if _fontInfo: fontName, fontSize = _fontInfo else: fontSize = gs.fontSize fontName = gs.fontName try: gfont = getFont(gs.fontName) except: gfont = None font = getFont(fontName) if font._dynamicFont: gs.drawString(x, y, text) else: fc = font if not isUnicode(text): try: text = text.decode("utf8") except UnicodeDecodeError as e: i, j = e.args[2:4] raise UnicodeDecodeError( *( e.args[:4] + ("%s\n%s-->%s<--%s" % (e.args[4], text[i - 10 : i], text[i:j], text[j : j + 10]),) ) ) FT = unicode2T1(text, [font] + font.substitutionFonts) n = len(FT) nm1 = n - 1 for i in range(n): f, t = FT[i] if f != fc: _setFont(gs, f.fontName, fontSize) fc = f gs.drawString(x, y, t) if i != nm1: x += f.stringWidth(t.decode(f.encName), fontSize) if font != fc: _setFont(gs, fontName, fontSize)
def __init__(self, canvas, x=0,y=0): self._code = ['BT'] #no point in [] then append RGB self._canvas = canvas #canvas sets this so it has access to size info self._fontname = self._canvas._fontname self._fontsize = self._canvas._fontsize self._leading = self._canvas._leading self._doc = self._canvas._doc self._colorsUsed = self._canvas._colorsUsed self._enforceColorSpace = getattr(canvas,'_enforceColorSpace',None) font = pdfmetrics.getFont(self._fontname) self._curSubset = -1 self.setTextOrigin(x, y)
def define(self, name, engine, enginefontname): if engine != "xfont": raise NotImplementedError("unsupported font engine %s" % engine) if '-' in enginefontname and ':' not in enginefontname: if enginefontname.count('-') == 1: # family-weight family, weight = enginefontname.split('-') enginefontname = '%s:weight=%s' % (family, weight) elif enginefontname.count('-') == 2: # family-weight-slant family, weight, slant = enginefontname.split('-') slant = {'i': 'italic', 'm': 'roman'}[slant] enginefontname = '%s:weight=%s:slant=%s' % (family, weight, slant) filename = subprocess.Popen( ['fc-match', enginefontname, '-f', '%{file}'], stdout=subprocess.PIPE).communicate()[0].strip() if not filename: sys.exit('Could not find the font file for %s', enginefontname) log.debug("Font %s: %s -> %s" % (name, enginefontname, filename)) pdfmetrics.registerFont(TTFont(name, filename)) pdfmetrics.getFont(name) # just see if raises
def _setFont(gs,fontName,fontSize): try: gs.setFont(fontName,fontSize) except ValueError as e: if not e.args[0].endswith("Can't find font!"): raise #here's where we try to add a font to the canvas try: f = getFont(fontName) _renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector,open_and_read) except: s1, s2 = list(map(str,sys.exc_info()[:2])) raise RenderPMError("Can't setFont(%s) missing the T1 files?\nOriginally %s: %s" % (fontName,s1,s2)) gs.setFont(fontName,fontSize)
def _setFont(self, psfontname, size): """Sets the font and fontSize Raises a readable exception if an illegal font is supplied. Font names are case-sensitive! Keeps track of font anme and size for metrics.""" self._fontname = psfontname self._fontsize = size font = pdfmetrics.getFont(self._fontname) if font._dynamicFont: self._curSubset = -1 else: pdffontname = self._canvas._doc.getInternalFontName(psfontname) self._code.append('%s %s Tf' % (pdffontname, fp_str(size)))