Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Improve usability of dviread.Text by third parties.#22609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
oscargus merged 1 commit intomatplotlib:mainfromanntzer:dvifonthelpers
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
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
63 changes: 62 additions & 1 deletionlib/matplotlib/dviread.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,10 +58,71 @@

# The marks on a page consist of text and boxes. A page also has dimensions.
Page = namedtuple('Page', 'text boxes height width descent')
Text = namedtuple('Text', 'x y font glyph width')
Box = namedtuple('Box', 'x y height width')


# Also a namedtuple, for backcompat.
class Text(namedtuple('Text', 'x y font glyph width')):
"""
A glyph in the dvi file.

The *x* and *y* attributes directly position the glyph. The *font*,
*glyph*, and *width* attributes are kept public for back-compatibility,
but users wanting to draw the glyph themselves are encouraged to instead
load the font specified by `font_path` at `font_size`, warp it with the
effects specified by `font_effects`, and load the glyph specified by
`glyph_name_or_index`.
"""

def _get_pdftexmap_entry(self):
return PsfontsMap(find_tex_file("pdftex.map"))[self.font.texname]

@property
def font_path(self):
"""The `~pathlib.Path` to the font for this glyph."""
psfont = self._get_pdftexmap_entry()
if psfont.filename is None:
raise ValueError("No usable font file found for {} ({}); "
"the font may lack a Type-1 version"
.format(psfont.psname.decode("ascii"),
psfont.texname.decode("ascii")))
return Path(psfont.filename)

@property
def font_size(self):
"""The font size."""
return self.font.size

@property
def font_effects(self):
"""
The "font effects" dict for this glyph.

This dict contains the values for this glyph of SlantFont and
ExtendFont (if any), read off :file:`pdftex.map`.
"""
return self._get_pdftexmap_entry().effects

@property
def glyph_name_or_index(self):
"""
Either the glyph name or the native charmap glyph index.

If :file:`pdftex.map` specifies an encoding for this glyph's font, that
is a mapping of glyph indices to Adobe glyph names; use it to convert
dvi indices to glyph names. Callers can then convert glyph names to
glyph indices (with FT_Get_Name_Index/get_name_index), and load the
glyph using FT_Load_Glyph/load_glyph.

If :file:`pdftex.map` specifies no encoding, the indices directly map
to the font's "native" charmap; glyphs should directly loaded using
FT_Load_Char/load_char after selecting the native charmap.
"""
entry = self._get_pdftexmap_entry()
return (_parse_enc(entry.encoding)[self.glyph]
if entry.encoding is not None else self.glyph)


# Opcode argument parsing
#
# Each of the following functions takes a Dvi object and delta,
Expand Down
2 changes: 1 addition & 1 deletionlib/matplotlib/tests/test_usetex.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -131,7 +131,7 @@ def test_missing_psfont(fmt, monkeypatch):
monkeypatch.setattr(
dviread.PsfontsMap, '__getitem__',
lambda self, k: dviread.PsFont(
texname='texfont', psname='Some Font',
texname=b'texfont', psname=b'Some Font',
effects=None, encoding=None, filename=None))
mpl.rcParams['text.usetex'] = True
fig, ax = plt.subplots()
Expand Down
84 changes: 30 additions & 54 deletionslib/matplotlib/textpath.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
from collections import OrderedDict
import functools
import logging
import urllib.parse

Expand DownExpand Up@@ -243,25 +242,29 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,

# Gather font information and do some setup for combining
# characters into strings.
for x1, y1, dvifont, glyph, width in page.text:
font, enc = self._get_ps_font_and_encoding(dvifont.texname)
char_id = self._get_char_id(font, glyph)

for text in page.text:
font = get_font(text.font_path)
char_id = self._get_char_id(font, text.glyph)
if char_id not in glyph_map:
font.clear()
font.set_size(self.FONT_SCALE, self.DPI)
# See comments in _get_ps_font_and_encoding.
ifenc is not None:
index = font.get_name_index(enc[glyph])
glyph_name_or_index = text.glyph_name_or_index
ifisinstance(glyph_name_or_index, str):
index = font.get_name_index(glyph_name_or_index)
font.load_glyph(index, flags=LOAD_TARGET_LIGHT)
else:
font.load_char(glyph, flags=LOAD_TARGET_LIGHT)
elif isinstance(glyph_name_or_index, int):
self._select_native_charmap(font)
font.load_char(
glyph_name_or_index, flags=LOAD_TARGET_LIGHT)
else: # Should not occur.
raise TypeError(f"Glyph spec of unexpected type: "
f"{glyph_name_or_index!r}")
glyph_map_new[char_id] = font.get_path()

glyph_ids.append(char_id)
xpositions.append(x1)
ypositions.append(y1)
sizes.append(dvifont.size / self.FONT_SCALE)
xpositions.append(text.x)
ypositions.append(text.y)
sizes.append(text.font_size / self.FONT_SCALE)

myrects = []

Expand All@@ -277,48 +280,21 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
glyph_map_new, myrects)

@staticmethod
@functools.lru_cache(50)
def _get_ps_font_and_encoding(texname):
tex_font_map = dviread.PsfontsMap(dviread._find_tex_file('pdftex.map'))
psfont = tex_font_map[texname]
if psfont.filename is None:
raise ValueError(
f"No usable font file found for {psfont.psname} ({texname}). "
f"The font may lack a Type-1 version.")

font = get_font(psfont.filename)

if psfont.encoding:
# If psfonts.map specifies an encoding, use it: it gives us a
# mapping of glyph indices to Adobe glyph names; use it to convert
# dvi indices to glyph names and use the FreeType-synthesized
# Unicode charmap to convert glyph names to glyph indices (with
# FT_Get_Name_Index/get_name_index), and load the glyph using
# FT_Load_Glyph/load_glyph. (That charmap has a coverage at least
# as good as, and possibly better than, the native charmaps.)
enc = dviread._parse_enc(psfont.encoding)
else:
# If psfonts.map specifies no encoding, the indices directly
# map to the font's "native" charmap; so don't use the
# FreeType-synthesized charmap but the native ones (we can't
# directly identify it but it's typically an Adobe charmap), and
# directly load the dvi glyph indices using FT_Load_Char/load_char.
for charmap_code in [
1094992451, # ADOBE_CUSTOM.
1094995778, # ADOBE_STANDARD.
]:
try:
font.select_charmap(charmap_code)
except (ValueError, RuntimeError):
pass
else:
break
def _select_native_charmap(font):
# Select the native charmap. (we can't directly identify it but it's
# typically an Adobe charmap).
for charmap_code in [
1094992451, # ADOBE_CUSTOM.
1094995778, # ADOBE_STANDARD.
]:
try:
font.select_charmap(charmap_code)
except (ValueError, RuntimeError):
pass
else:
_log.warning("No supported encoding in font (%s).",
psfont.filename)
enc = None

return font, enc
break
else:
_log.warning("No supported encoding in font (%s).", font.fname)


text_to_path = TextToPath()
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp