256 lines
9.9 KiB
Python
256 lines
9.9 KiB
Python
#Copyright ReportLab Europe Ltd. 2000-2017
|
|
#see license.txt for license details
|
|
#history https://hg.reportlab.com/hg-public/reportlab/log/tip/src/reportlab/pdfbase/_fontdata.py
|
|
#$Header $
|
|
__version__='3.3.0'
|
|
__doc__="""Database of font related things
|
|
|
|
- standardFonts - tuple of the 14 standard string font names
|
|
- standardEncodings - tuple of the known standard font names
|
|
- encodings - a mapping object from standard encoding names (and minor variants)
|
|
to the encoding vectors ie the tuple of string glyph names
|
|
- widthsByFontGlyph - fontname x glyphname --> width of glyph
|
|
- widthVectorsByFont - fontName -> vector of widths
|
|
|
|
This module defines a static, large data structure. At the request
|
|
of the Jython project, we have split this off into separate modules
|
|
as Jython cannot handle more than 64k of bytecode in the 'top level'
|
|
code of a Python module.
|
|
"""
|
|
import os, sys
|
|
|
|
# mapping of name to width vector, starts empty until fonts are added
|
|
# e.g. widths['Courier'] = [...600,600,600,...]
|
|
widthVectorsByFont = {}
|
|
fontsByName = {}
|
|
fontsByBaseEnc = {}
|
|
# this is a list of the standard 14 font names in Acrobat Reader
|
|
standardFonts = (
|
|
'Courier', 'Courier-Bold', 'Courier-Oblique', 'Courier-BoldOblique',
|
|
'Helvetica', 'Helvetica-Bold', 'Helvetica-Oblique', 'Helvetica-BoldOblique',
|
|
'Times-Roman', 'Times-Bold', 'Times-Italic', 'Times-BoldItalic',
|
|
'Symbol','ZapfDingbats')
|
|
|
|
standardFontAttributes = {
|
|
#family, bold, italic defined for basic ones
|
|
'Courier':('Courier',0,0),
|
|
'Courier-Bold':('Courier',1,0),
|
|
'Courier-Oblique':('Courier',0,1),
|
|
'Courier-BoldOblique':('Courier',1,1),
|
|
|
|
'Helvetica':('Helvetica',0,0),
|
|
'Helvetica-Bold':('Helvetica',1,0),
|
|
'Helvetica-Oblique':('Helvetica',0,1),
|
|
'Helvetica-BoldOblique':('Helvetica',1,1),
|
|
|
|
'Times-Roman':('Times-Roman',0,0),
|
|
'Times-Bold':('Times-Roman',1,0),
|
|
'Times-Italic':('Times-Roman',0,1),
|
|
'Times-BoldItalic':('Times-Roman',1,1),
|
|
|
|
'Symbol':('Symbol',0,0),
|
|
'ZapfDingbats':('ZapfDingbats',0,0)
|
|
|
|
}
|
|
|
|
#this maps fontnames to the equivalent filename root.
|
|
_font2fnrMapWin32 = {
|
|
'symbol': 'sy______',
|
|
'zapfdingbats': 'zd______',
|
|
'helvetica': '_a______',
|
|
'helvetica-bold': '_ab_____',
|
|
'helvetica-boldoblique': '_abi____',
|
|
'helvetica-oblique': '_ai_____',
|
|
'times-bold': '_eb_____',
|
|
'times-bolditalic': '_ebi____',
|
|
'times-italic': '_ei_____',
|
|
'times-roman': '_er_____',
|
|
'courier-bold': 'cob_____',
|
|
'courier-boldoblique': 'cobo____',
|
|
'courier': 'com_____',
|
|
'courier-oblique': 'coo_____',
|
|
}
|
|
if sys.platform in ('linux2',):
|
|
_font2fnrMapLinux2 ={
|
|
'symbol': 'Symbol',
|
|
'zapfdingbats': 'ZapfDingbats',
|
|
'helvetica': 'Arial',
|
|
'helvetica-bold': 'Arial-Bold',
|
|
'helvetica-boldoblique': 'Arial-BoldItalic',
|
|
'helvetica-oblique': 'Arial-Italic',
|
|
'times-bold': 'TimesNewRoman-Bold',
|
|
'times-bolditalic':'TimesNewRoman-BoldItalic',
|
|
'times-italic': 'TimesNewRoman-Italic',
|
|
'times-roman': 'TimesNewRoman',
|
|
'courier-bold': 'Courier-Bold',
|
|
'courier-boldoblique': 'Courier-BoldOblique',
|
|
'courier': 'Courier',
|
|
'courier-oblique': 'Courier-Oblique',
|
|
}
|
|
_font2fnrMap = _font2fnrMapLinux2
|
|
for k, v in _font2fnrMap.items():
|
|
if k in _font2fnrMapWin32.keys():
|
|
_font2fnrMapWin32[v.lower()] = _font2fnrMapWin32[k]
|
|
del k, v
|
|
else:
|
|
_font2fnrMap = _font2fnrMapWin32
|
|
|
|
def _findFNR(fontName):
|
|
return _font2fnrMap[fontName.lower()]
|
|
|
|
from reportlab.rl_config import T1SearchPath
|
|
from reportlab.lib.utils import rl_isfile
|
|
def _searchT1Dirs(n,rl_isfile=rl_isfile,T1SearchPath=T1SearchPath):
|
|
assert T1SearchPath!=[], "No Type-1 font search path"
|
|
for d in T1SearchPath:
|
|
f = os.path.join(d,n)
|
|
if rl_isfile(f): return f
|
|
return None
|
|
del T1SearchPath, rl_isfile
|
|
|
|
def findT1File(fontName,ext='.pfb'):
|
|
if sys.platform in ('linux2',) and ext=='.pfb':
|
|
try:
|
|
f = _searchT1Dirs(_findFNR(fontName))
|
|
if f: return f
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
f = _searchT1Dirs(_font2fnrMapWin32[fontName.lower()]+ext)
|
|
if f: return f
|
|
except:
|
|
pass
|
|
|
|
return _searchT1Dirs(_findFNR(fontName)+ext)
|
|
|
|
# this lists the predefined font encodings - WinAnsi and MacRoman. We have
|
|
# not added MacExpert - it's possible, but would complicate life and nobody
|
|
# is asking. StandardEncoding means something special.
|
|
standardEncodings = ('WinAnsiEncoding','MacRomanEncoding','StandardEncoding','SymbolEncoding','ZapfDingbatsEncoding','PDFDocEncoding', 'MacExpertEncoding')
|
|
|
|
#this is the global mapping of standard encodings to name vectors
|
|
class _Name2StandardEncodingMap(dict):
|
|
'''Trivial fake dictionary with some [] magic'''
|
|
_XMap = {'winansi':'WinAnsiEncoding','macroman': 'MacRomanEncoding','standard':'StandardEncoding','symbol':'SymbolEncoding', 'zapfdingbats':'ZapfDingbatsEncoding','pdfdoc':'PDFDocEncoding', 'macexpert':'MacExpertEncoding'}
|
|
def __setitem__(self,x,v):
|
|
y = x.lower()
|
|
if y[-8:]=='encoding': y = y[:-8]
|
|
y = self._XMap[y]
|
|
if y in self: raise IndexError('Encoding %s is already set' % y)
|
|
dict.__setitem__(self,y,v)
|
|
|
|
def __getitem__(self,x):
|
|
y = x.lower()
|
|
if y[-8:]=='encoding': y = y[:-8]
|
|
y = self._XMap[y]
|
|
return dict.__getitem__(self,y)
|
|
|
|
encodings = _Name2StandardEncodingMap()
|
|
|
|
#due to compiled method size limits in Jython,
|
|
#we pull these in from separate modules to keep this module
|
|
#well under 64k. We might well be able to ditch many of
|
|
#these anyway now we run on Unicode.
|
|
|
|
from reportlab.pdfbase._fontdata_enc_winansi import WinAnsiEncoding
|
|
from reportlab.pdfbase._fontdata_enc_macroman import MacRomanEncoding
|
|
from reportlab.pdfbase._fontdata_enc_standard import StandardEncoding
|
|
from reportlab.pdfbase._fontdata_enc_symbol import SymbolEncoding
|
|
from reportlab.pdfbase._fontdata_enc_zapfdingbats import ZapfDingbatsEncoding
|
|
from reportlab.pdfbase._fontdata_enc_pdfdoc import PDFDocEncoding
|
|
from reportlab.pdfbase._fontdata_enc_macexpert import MacExpertEncoding
|
|
encodings.update({
|
|
'WinAnsiEncoding': WinAnsiEncoding,
|
|
'MacRomanEncoding': MacRomanEncoding,
|
|
'StandardEncoding': StandardEncoding,
|
|
'SymbolEncoding': SymbolEncoding,
|
|
'ZapfDingbatsEncoding': ZapfDingbatsEncoding,
|
|
'PDFDocEncoding': PDFDocEncoding,
|
|
'MacExpertEncoding': MacExpertEncoding,
|
|
})
|
|
|
|
ascent_descent = {
|
|
'Courier': (629, -157),
|
|
'Courier-Bold': (626, -142),
|
|
'Courier-BoldOblique': (626, -142),
|
|
'Courier-Oblique': (629, -157),
|
|
'Helvetica': (718, -207),
|
|
'Helvetica-Bold': (718, -207),
|
|
'Helvetica-BoldOblique': (718, -207),
|
|
'Helvetica-Oblique': (718, -207),
|
|
'Times-Roman': (683, -217),
|
|
'Times-Bold': (676, -205),
|
|
'Times-BoldItalic': (699, -205),
|
|
'Times-Italic': (683, -205),
|
|
'Symbol': (0, 0),
|
|
'ZapfDingbats': (0, 0)
|
|
}
|
|
|
|
# ditto about 64k limit - profusion of external files
|
|
import reportlab.pdfbase._fontdata_widths_courier
|
|
import reportlab.pdfbase._fontdata_widths_courierbold
|
|
import reportlab.pdfbase._fontdata_widths_courieroblique
|
|
import reportlab.pdfbase._fontdata_widths_courierboldoblique
|
|
import reportlab.pdfbase._fontdata_widths_helvetica
|
|
import reportlab.pdfbase._fontdata_widths_helveticabold
|
|
import reportlab.pdfbase._fontdata_widths_helveticaoblique
|
|
import reportlab.pdfbase._fontdata_widths_helveticaboldoblique
|
|
import reportlab.pdfbase._fontdata_widths_timesroman
|
|
import reportlab.pdfbase._fontdata_widths_timesbold
|
|
import reportlab.pdfbase._fontdata_widths_timesitalic
|
|
import reportlab.pdfbase._fontdata_widths_timesbolditalic
|
|
import reportlab.pdfbase._fontdata_widths_symbol
|
|
import reportlab.pdfbase._fontdata_widths_zapfdingbats
|
|
widthsByFontGlyph = {
|
|
'Courier':
|
|
reportlab.pdfbase._fontdata_widths_courier.widths,
|
|
'Courier-Bold':
|
|
reportlab.pdfbase._fontdata_widths_courierbold.widths,
|
|
'Courier-Oblique':
|
|
reportlab.pdfbase._fontdata_widths_courieroblique.widths,
|
|
'Courier-BoldOblique':
|
|
reportlab.pdfbase._fontdata_widths_courierboldoblique.widths,
|
|
'Helvetica':
|
|
reportlab.pdfbase._fontdata_widths_helvetica.widths,
|
|
'Helvetica-Bold':
|
|
reportlab.pdfbase._fontdata_widths_helveticabold.widths,
|
|
'Helvetica-Oblique':
|
|
reportlab.pdfbase._fontdata_widths_helveticaoblique.widths,
|
|
'Helvetica-BoldOblique':
|
|
reportlab.pdfbase._fontdata_widths_helveticaboldoblique.widths,
|
|
'Times-Roman':
|
|
reportlab.pdfbase._fontdata_widths_timesroman.widths,
|
|
'Times-Bold':
|
|
reportlab.pdfbase._fontdata_widths_timesbold.widths,
|
|
'Times-Italic':
|
|
reportlab.pdfbase._fontdata_widths_timesitalic.widths,
|
|
'Times-BoldItalic':
|
|
reportlab.pdfbase._fontdata_widths_timesbolditalic.widths,
|
|
'Symbol':
|
|
reportlab.pdfbase._fontdata_widths_symbol.widths,
|
|
'ZapfDingbats':
|
|
reportlab.pdfbase._fontdata_widths_zapfdingbats.widths,
|
|
}
|
|
|
|
|
|
#preserve the initial values here
|
|
def _reset(
|
|
initial_dicts=dict(
|
|
ascent_descent=ascent_descent.copy(),
|
|
fontsByBaseEnc=fontsByBaseEnc.copy(),
|
|
fontsByName=fontsByName.copy(),
|
|
standardFontAttributes=standardFontAttributes.copy(),
|
|
widthVectorsByFont=widthVectorsByFont.copy(),
|
|
widthsByFontGlyph=widthsByFontGlyph.copy(),
|
|
)
|
|
):
|
|
for k,v in initial_dicts.items():
|
|
d=globals()[k]
|
|
d.clear()
|
|
d.update(v)
|
|
|
|
from reportlab.rl_config import register_reset
|
|
register_reset(_reset)
|
|
del register_reset
|