Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8b2257d
Parse fallback_list through wrapper
aitikgupta Jul 25, 2021
8114a54
Define new/modify previous FT2Font functions
aitikgupta Jul 25, 2021
a4b78c8
Implement new/modify previous FT2Font functions
aitikgupta Jul 25, 2021
67dbcf8
Parse multiple fonts for a single FT2Font object
aitikgupta Jul 25, 2021
69cf28b
Trigger font fallback for Agg backend
aitikgupta Jul 25, 2021
d5aef82
Remove prints
aitikgupta Aug 7, 2021
aa82ecd
Cleanup wrapper
aitikgupta Aug 7, 2021
bea7a2d
Remove stale prints
aitikgupta Aug 7, 2021
5117398
Do not warn for get_char_index
aitikgupta Aug 7, 2021
fc413dc
Left != Right kerning comment
aitikgupta Aug 7, 2021
3f42cbd
Windows compiler fix
aitikgupta Aug 7, 2021
9c062cd
Add fallback test for Agg backend
aitikgupta Aug 13, 2021
cf4f743
Debug fontNames
aitikgupta Jul 28, 2021
9950a3e
Segfaults on exit
aitikgupta Jul 29, 2021
ab2f95a
More work on PDF backend
aitikgupta Jul 31, 2021
41e247d
Implement another approach
aitikgupta Aug 1, 2021
e5b4dae
Revisit the approach
aitikgupta Aug 3, 2021
3af91d8
Type3 PDF Backend works!
aitikgupta Aug 6, 2021
7ee77f2
Type42 PDF fallback works!
aitikgupta Aug 6, 2021
3cacd45
Create a fill_glyphs method
aitikgupta Aug 7, 2021
8719e2e
Use fill_glyphs instead of set_text
aitikgupta Aug 7, 2021
e6c7998
Cleanup wrapper
aitikgupta Aug 7, 2021
f86ec41
Few cleanups
aitikgupta Aug 7, 2021
a6d21cd
Rebase from Agg backend
aitikgupta Aug 7, 2021
ecf0556
Use multi-font output for PS backend
aitikgupta Aug 13, 2021
b55f011
Add multi-font tests for PS backend
aitikgupta Aug 13, 2021
83b227d
Add baseline images
aitikgupta Aug 13, 2021
913ad4c
Specify font number for TTC fonts
aitikgupta Aug 13, 2021
6fe8f44
Flake8 fixes
aitikgupta Aug 13, 2021
a3e7f03
Fix memory leak and render tofu
aitikgupta Aug 18, 2021
986ecfe
Check if fallback font is available
aitikgupta Aug 18, 2021
1c85f46
Check for Agg as well
aitikgupta Aug 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Revisit the approach
  • Loading branch information
aitikgupta committed Aug 13, 2021
commit e5b4daed15fa6d83ec746692c88cfcc12579ec56
7 changes: 4 additions & 3 deletions lib/matplotlib/_text_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


LayoutItem = dataclasses.make_dataclass(
"LayoutItem", ["char", "glyph_idx", "x", "prev_kern"])
"LayoutItem", ["ft_object", "char", "glyph_idx", "x", "prev_kern"])


def warn_on_missing_glyph(codepoint):
Expand Down Expand Up @@ -60,12 +60,13 @@ def layout(string, font, *, kern_mode=KERNING_DEFAULT):
print("Inside _text_helpers.py")
# breakpoint()
for char in string:
print("\nchecking:", char, "\n")
# print("\nchecking:", char, "\n")
glyph_idx = font.get_char_index(ord(char))
kern = (font.get_kerning(prev_glyph_idx, glyph_idx, kern_mode) / 64
if prev_glyph_idx is not None else 0.)
x += kern
glyph = font.load_glyph(glyph_idx, flags=LOAD_NO_HINTING)
yield LayoutItem(char, glyph_idx, x, kern)
ft_object = font.get_glyph_to_font().get(glyph_idx)
yield LayoutItem(ft_object, char, glyph_idx, x, kern)
x += glyph.linearHoriAdvance / 65536
prev_glyph_idx = glyph_idx
73 changes: 33 additions & 40 deletions lib/matplotlib/backends/backend_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,25 +862,21 @@ def fontName(self, fontprop):
"""

if isinstance(fontprop, str):
filename = [fontprop]
filename = fontprop
elif mpl.rcParams['pdf.use14corefonts']:
filename = find_fontsprop(
filename = findfont(
fontprop, fontext='afm', directory=RendererPdf._afm_font_dir
).values()
)
else:
filename = find_fontsprop(fontprop).values()
filename = findfont(fontprop)

Fxs = []
for fname in filename:
Fx = self.fontNames.get(fname)
if Fx is None:
Fx = next(self._internal_font_seq)
self.fontNames[fname] = Fx
_log.debug('Assigning font %s = %r', Fx, fname)
Fxs.append(Fx)
Fx = self.fontNames.get(filename)
if Fx is None:
Fx = next(self._internal_font_seq)
self.fontNames[filename] = Fx
_log.debug('Assigning font %s = %r', Fx, filename)

# return only the first for Op.selectfont to work
return Fxs[0]
return Fx

def dviFontName(self, dvifont):
"""
Expand Down Expand Up @@ -1072,7 +1068,6 @@ def createType1Descriptor(self, t1font, fontfile):
return fontdescObject

def _get_xobject_symbol_name(self, filename, symbol_name):
# since filename is a string
Fx = self.fontName(filename)
x = "-".join([
Fx.name.decode(),
Expand Down Expand Up @@ -1924,6 +1919,8 @@ class RendererPdf(_backend_pdf_ps.RendererPDFPSBase):
def __init__(self, file, image_dpi, height, width):
super().__init__(width, height)
self.file = file
self.char_to_font = {}
self.glyph_to_font = {}
self.gc = self.new_gc()
self.image_dpi = image_dpi

Expand Down Expand Up @@ -2343,8 +2340,11 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
else:
font = self._get_font_ttf(prop)
font.set_text(s)
char_to_font = font.get_char_to_font()
for char, font in char_to_font.items():
self.char_to_font = font.get_char_to_font()
self.glyph_to_font = font.get_glyph_to_font()
# populate self.fontNames with all fonts
_ = [self.file.fontName(ft_object.fname) for ft_object in self.glyph_to_font.values()]
for char, font in self.char_to_font.items():
print(chr(char), "to:", font.fname)
self.file._character_tracker.track(font, chr(char))
print("\nFONT_TO_CHAR:", self.file._character_tracker.used)
Expand Down Expand Up @@ -2387,22 +2387,22 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
# the regular text show command (TJ) with appropriate kerning between
# chunks, whereas multibyte characters use the XObject command (Do).
else:
# List of (start_x, [prev_kern, char, char, ...]), w/o zero kerns.
# List of (ft_object, start_x, [prev_kern, char, char, ...]), w/o zero kerns.
singlebyte_chunks = []
# List of (start_x, glyph_index).
# List of (ft_object, start_x, glyph_index).
multibyte_glyphs = []
prev_was_multibyte = True
for item in _text_helpers.layout(
s, font, kern_mode=KERNING_UNFITTED):
if _font_supports_glyph(fonttype, ord(item.char)):
if prev_was_multibyte:
singlebyte_chunks.append((item.x, []))
singlebyte_chunks.append((item.ft_object, item.x, []))
if item.prev_kern:
singlebyte_chunks[-1][1].append(item.prev_kern)
singlebyte_chunks[-1][1].append(item.char)
singlebyte_chunks[-1][2].append(item.prev_kern)
singlebyte_chunks[-1][2].append(item.char)
prev_was_multibyte = False
else:
multibyte_glyphs.append((item.x, item.glyph_idx))
multibyte_glyphs.append((item.ft_object, item.x, item.glyph_idx))
prev_was_multibyte = True
# Do the rotation and global translation as a single matrix
# concatenation up front
Expand All @@ -2413,14 +2413,12 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
x, y, Op.concat_matrix)
# Emit all the 1-byte characters in a BT/ET group.

x = self.file.fontName(prop)
print(x)
# breakpoint()

self.file.output(Op.begin_text,
self.file.fontName(prop), fontsize, Op.selectfont)
self.file.output(Op.begin_text)
# ft, fontsize, Op.selectfont
prev_start_x = 0
for start_x, kerns_or_chars in singlebyte_chunks:
for ft_object, start_x, kerns_or_chars in singlebyte_chunks:
ft_name = self.file.fontName(ft_object.fname)
self.file.output(ft_name, fontsize, Op.selectfont)
self._setup_textpos(start_x, 0, 0, prev_start_x, 0, 0)
self.file.output(
# See pdf spec "Text space details" for the 1000/fontsize
Expand All @@ -2432,20 +2430,15 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
prev_start_x = start_x
self.file.output(Op.end_text)
# Then emit all the multibyte characters, one at a time.
glyph_to_font = font.get_glyph_to_font()
for start_x, glyph_idx in multibyte_glyphs:
self._draw_xobject_glyph(glyph_to_font, fontsize, glyph_idx, start_x, 0)
for ft_object, start_x, glyph_idx in multibyte_glyphs:
self._draw_xobject_glyph(ft_object, fontsize, glyph_idx, start_x, 0)
self.file.output(Op.grestore)
# print("fine here")

def _draw_xobject_glyph(self, glyph_to_font, fontsize, glyph_idx, x, y):
def _draw_xobject_glyph(self, ft_object, fontsize, glyph_idx, x, y):
"""Draw a multibyte character from a Type 3 font as an XObject."""
if glyph_idx not in glyph_to_font:
# ideally raise.
pass
font = glyph_to_font[glyph_idx]
symbol_name = font.get_glyph_name(glyph_idx)
name = self.file._get_xobject_symbol_name(font.fname, symbol_name)
symbol_name = ft_object.get_glyph_name(glyph_idx)
name = self.file._get_xobject_symbol_name(ft_object.fname, symbol_name)
self.file.output(
Op.gsave,
0.001 * fontsize, 0, 0, 0.001 * fontsize, x, y, Op.concat_matrix,
Expand Down
2 changes: 1 addition & 1 deletion src/ft2font_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ static PyObject *PyFT2Font_load_char(PyFT2Font *self, PyObject *args, PyObject *

FT2Font *ft_object = NULL;
CALL_CPP("load_char", (self->x->load_char(charcode, flags, ft_object, (bool)fallback)));
printf("Char %ld loaded to: %lu\n", charcode, ft_object->get_face()->num_glyphs);
// printf("Char %ld loaded to: %lu\n", charcode, ft_object->get_face()->num_glyphs);

FT2Font *ft_object = NULL;
CALL_CPP("load_char", (self->x->load_char(charcode, flags, ft_object, (bool)fallback)));
Expand Down