Comments (9)
PHP font files, by converting the truetype font files via this site
from fpdf2.
I'm waiting for the clean-up in this PR to be merged: #22
After that I'll give a look at this.
A good start would be to make our CharmapTest.test_first_999_chars
test (in test/end_to_end_legacy/charmap/charmap_test.py
) pass.
from fpdf2.
Hello, i somewhat bypassed this by taking the php files and parsing them myself. I implemented the new code concerning the truetype font files, it "dies" over the version of the ttf file. If i remove it , it says there is no attribute "name" in the extracted information. If you want i could drop the code of the php parsing here somewhere. I also modified the add_font function to accomodate this.
from fpdf2.
I'm curious about reading your code, so yes! :)
I'm not sure about what are the PHP files you are refering to though.
from fpdf2.
Sorry, posting the code went a bit wrong...
from fpdf2.
import re
import regex
def parse_php(fontfile):
font_dict = {}
for item in php_chunks(fontfile):
key, attr = item.split(" = ")
attr = attr.replace("\t","").strip()
attr = re.sub("^(.*);",r"\1",attr)
# re.split("[,](?!'=>)",data["cw"])
if re.match("'(.*)'",attr):
attr = re.sub("'(.*)'",r"\1",attr)
try:
attr = eval(attr)
font_dict[key.replace("$","").strip()] = attr
except:
if "array" in attr:
if re.match("^array\(",attr):
attr_dict = {}
attr = re.sub("array\((.*)\)",r"\1",attr)
attr = regex.split("(?<!array\(\d*)[,](?!'=>)",attr)
for row in attr:
dict_key, dict_item = row.strip().split("=>")
try:
attr_dict[str(eval(dict_key))] = eval(dict_item)
except:
attr_dict[str(eval(dict_key))] = dict_item
font_dict[key.replace("$","").strip()] = attr_dict
else:
font_dict[key.replace("$","").strip()] = attr
return font_dict
def php_chunks(raw):
raw = raw.read()
chunk = ""
for idx, line in enumerate(raw.splitlines()):
if line.startswith("$"):
if idx != 1:
yield chunk
chunk = ""
chunk = "".join(line)
else:
chunk = "".join([chunk,line])
if __name__ == "__main__":
fontfile = open("calibrib.php","r")
data = parse_php(fontfile)
from fpdf2.
def add_font(self, family, style = '', fname = None, file_type = "uni"):
"Add a TrueType or Type1 font"
family = family.lower()
if not fname:
fname = family.replace(' ', '') + style.lower() + '.pkl'
if (family == 'arial'): family = 'helvetica'
style = style.upper()
if (style == 'IB'): style = 'BI'
fontkey = family + style
# Font already added
if fontkey in self.fonts: return
if file_type=="uni":
global SYSTEM_TTFONTS, FPDF_CACHE_MODE, FPDF_CACHE_DIR
if os.path.exists(fname):
ttffilename = fname
elif (FPDF_FONT_DIR and
os.path.exists(os.path.join(FPDF_FONT_DIR, fname))):
ttffilename = os.path.join(FPDF_FONT_DIR, fname)
elif (SYSTEM_TTFONTS and
os.path.exists(os.path.join(SYSTEM_TTFONTS, fname))):
ttffilename = os.path.join(SYSTEM_TTFONTS, fname)
else:
raise RuntimeError("TTF Font file not found: %s" % fname)
name = '' # noqa: F841
if FPDF_CACHE_MODE == 0:
unifilename = os.path.splitext(ttffilename)[0] + '.pkl'
elif FPDF_CACHE_MODE == 2:
unifilename = os.path.join(FPDF_CACHE_DIR,
_hashpath(ttffilename) + ".pkl")
else:
unifilename = None
font_dict = load_cache(unifilename)
if font_dict is None:
ttf = TTFontFile()
ttf.getMetrics(ttffilename)
desc = {
'Ascent' : int(round(ttf.ascent, 0)),
'Descent' : int(round(ttf.descent, 0)),
'CapHeight' : int(round(ttf.capHeight, 0)),
'Flags' : ttf.flags,
'FontBBox' : "[%s %s %s %s]" % (
int(round(ttf.bbox[0], 0)),
int(round(ttf.bbox[1], 0)),
int(round(ttf.bbox[2], 0)),
int(round(ttf.bbox[3], 0))),
'ItalicAngle' : int(ttf.italicAngle),
'StemV' : int(round(ttf.stemV, 0)),
'MissingWidth' : int(round(ttf.defaultWidth, 0)),
}
# Generate metrics .pkl file
font_dict = {
'name' : re.sub('[ ()]', '', ttf.fullName),
'type' : 'TTF',
'desc' : desc,
'up' : round(ttf.underlinePosition),
'ut' : round(ttf.underlineThickness),
'ttffile' : ttffilename,
'fontkey' : fontkey,
'originalsize' : os.stat(ttffilename).st_size,
'cw' : ttf.charWidths,
}
if unifilename:
try:
with open(unifilename, "wb") as fh:
pickle.dump(font_dict, fh)
except IOError as e:
if not e.errno == errno.EACCES:
raise # Not a permission error.
del ttf
# include numbers in the subset! (if alias present)
have_page_alias = lambda: hasattr(self, 'str_alias_nb_pages')
sbarr = list(range(0, 57 if have_page_alias() else 32))
self.fonts[fontkey] = {
'i' : len(self.fonts) + 1,
'type' : font_dict['type'],
'name' : font_dict['name'],
'desc' : font_dict['desc'],
'up' : font_dict['up'],
'ut' : font_dict['ut'],
'cw' : font_dict['cw'],
'ttffile' : font_dict['ttffile'],
'fontkey' : fontkey,
'subset' : sbarr,
'unifilename' : unifilename
}
self.font_files[fontkey] = {'length1': font_dict['originalsize'],
'type': "TTF", 'ttffile': ttffilename}
self.font_files[fname] = {'type': "TTF"}
elif file_type=="pickled":
with open(fname, 'rb') as fontfile:
font_dict = pickle.load(fontfile)
self.fonts[fontkey] = {'i': len(self.fonts) + 1}
self.fonts[fontkey].update(font_dict)
diff = font_dict.get('diff')
if (diff):
# Search existing encodings
d = 0
nb = len(self.diffs)
for i in range(1, nb + 1):
if (self.diffs[i] == diff):
d = i
break
if (d == 0):
d = nb + 1
self.diffs[d] = diff
self.fonts[fontkey]['diff'] = d
filename = font_dict.get('filename')
if (filename):
if (font_dict['type'] == 'TrueType'):
originalsize = font_dict['originalsize']
self.font_files[filename] = {'length1': originalsize}
else:
self.font_files[filename] = {'length1': font_dict['size1'],
'length2': font_dict['size2']}
elif file_type=="php":
if os.path.exists(os.path.join(FPDF_FONT_DIR,fname)):
phpfilename = os.path.join(FPDF_FONT_DIR,fname)
elif os.path.exists(fname):
phpfilename = fname
if not os.path.exists(os.path.join(FPDF_FONT_DIR,os.path.basename(fname))):
shutil.copy2(fname,os.path.join(FPDF_FONT_DIR,os.path.basename(fname)))
z_file = re.sub(".php",".z",fname)
shutil.copy2(z_file,os.path.join(FPDF_FONT_DIR,os.path.basename(z_file)))
else:
raise RuntimeError("PHP Font file not found: %s" % fname)
with open(phpfilename,'r') as fontfile:
font_dict = parse_php(fontfile)
self.fonts[fontkey] = {'i': len(self.fonts) + 1}
self.fonts[fontkey].update(font_dict)
filename = font_dict.get('file')
if (filename):
if (font_dict['type'] == 'TrueType'):
self.font_files[filename] = {'length1': font_dict['originalsize'],
'type': font_dict["type"],
'file': font_dict["file"]}
else:
self.font_files[filename] = {'length1': font_dict['size1'],
'length2': font_dict['size2']}
from fpdf2.
It is not pretty, but it does allow me to use other fonts.
from fpdf2.
Thank you @bwdalmijn Interesting, and I was able to find the source code behind this /makefont/
web page.
I think I found a simpler fix for this issue though: #26
from fpdf2.
Related Issues (20)
- `write_html` skips one line when the line wraps inside a word (no spaces available for wrapping) HOT 1
- Possible to create a new release? HOT 6
- The example for column span in tables does not work as documented.
- svg exported from matplotlib not inserted correctly - add support for clip-path & clipPath HOT 4
- Support for subscript/superscript in cell/multicell using markdown HOT 9
- Format imports with isort HOT 7
- PDF metadata not encrypted HOT 7
- Can not use the _out method of fpdf due to semgrep error in github workfloat HOT 2
- 4 unit tests are currently failing in the GitHub Actions pipeline HOT 1
- Calling `pdf.image()` might closes passed BytesIO object HOT 6
- New feature: Handle bidirectional text
- Unexpected edge case behavior when using text shaping HOT 2
- Bug: dataclasses.FrozenInstanceError: cannot assign to field 'glyph_id', deepcopy issue, section_title_styles, add_font HOT 3
- Image in table overlaps with border HOT 1
- Inconsistent vertical alignment for text in tables HOT 5
- Please add automatic black formatting to workflow HOT 4
- Differences of PDF output for OTF files HOT 3
- How does one set the color for h1, h2 ... etc. html tags? HOT 2
- RTL multi-line text gets bottom-up HOT 1
- Mixed scripts with text shaping failure
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fpdf2.