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

Implement libraqm for vector outputs#30607

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

Open
QuLogic wants to merge3 commits intomatplotlib:text-overhaul
base:text-overhaul
Choose a base branch
Loading
fromQuLogic:libraqm-vector
Open
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
1 change: 1 addition & 0 deletionsci/mypy-stubtest-allowlist.txt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ matplotlib\._.*
matplotlib\.rcsetup\._listify_validator
matplotlib\.rcsetup\._validate_linestyle
matplotlib\.ft2font\.Glyph
matplotlib\.ft2font\.LayoutItem
matplotlib\.testing\.jpl_units\..*
matplotlib\.sphinxext(\..*)?

Expand Down
44 changes: 12 additions & 32 deletionslib/matplotlib/_text_helpers.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,29 +4,23 @@

from __future__ import annotations

importdataclasses
from collections.abcimportIterator

from . import _api
from .ft2font import FT2Font,GlyphIndexType, Kerning, LoadFlags
from .ft2font import FT2Font,CharacterCodeType, LayoutItem, LoadFlags


@dataclasses.dataclass(frozen=True)
class LayoutItem:
ft_object: FT2Font
char: str
glyph_index: GlyphIndexType
x: float
prev_kern: float


def warn_on_missing_glyph(codepoint, fontnames):
def warn_on_missing_glyph(codepoint: CharacterCodeType, fontnames: str):
_api.warn_external(
f"Glyph {codepoint} "
f"({chr(codepoint).encode('ascii', 'namereplace').decode('ascii')}) "
f"missing from font(s) {fontnames}.")


def layout(string, font, *, features=None, kern_mode=Kerning.DEFAULT, language=None):
def layout(string: str, font: FT2Font, *,
features: tuple[str] | None = None,
language: str | tuple[tuple[str, int, int], ...] | None = None
) -> Iterator[LayoutItem]:
"""
Render *string* with *font*.

Expand All@@ -41,8 +35,6 @@ def layout(string, font, *, features=None, kern_mode=Kerning.DEFAULT, language=N
The font.
features : tuple of str, optional
The font features to apply to the text.
kern_mode : Kerning
A FreeType kerning mode.
language : str, optional
The language of the text in a format accepted by libraqm, namely `a BCP47
language code <https://www.w3.org/International/articles/language-tags/>`_.
Expand All@@ -51,20 +43,8 @@ def layout(string, font, *, features=None, kern_mode=Kerning.DEFAULT, language=N
------
LayoutItem
"""
x = 0
prev_glyph_index = None
char_to_font = font._get_fontmap(string) # TODO: Pass in features and language.
base_font = font
for char in string:
# This has done the fallback logic
font = char_to_font.get(char, base_font)
glyph_index = font.get_char_index(ord(char))
kern = (
base_font.get_kerning(prev_glyph_index, glyph_index, kern_mode) / 64
if prev_glyph_index is not None else 0.
)
x += kern
glyph = font.load_glyph(glyph_index, flags=LoadFlags.NO_HINTING)
yield LayoutItem(font, char, glyph_index, x, kern)
x += glyph.linearHoriAdvance / 65536
prev_glyph_index = glyph_index
for raqm_item in font._layout(string, LoadFlags.NO_HINTING,
features=features, language=language):
raqm_item.ft_object.load_glyph(raqm_item.glyph_index,
flags=LoadFlags.NO_HINTING)
yield raqm_item
4 changes: 2 additions & 2 deletionslib/matplotlib/backends/_backend_pdf_ps.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -220,8 +220,8 @@ def track(self, font: FT2Font, s: str) -> list[tuple[int, CharacterCodeType]]:
and the character codes will be returned from the string unchanged.
"""
return [
self.track_glyph(f, ord(c), f.get_char_index(ord(c)))
forc, fin font._get_fontmap(s).items()
self.track_glyph(raqm_item.ft_object, raqm_item.char, raqm_item.glyph_index)
forraqm_itemin font._layout(s, ft2font.LoadFlags.NO_HINTING)
]

def track_glyph(self, font: FT2Font, chars: str | CharacterCodeType,
Expand Down
22 changes: 15 additions & 7 deletionslib/matplotlib/backends/backend_pdf.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,7 +34,7 @@
from matplotlib.figure import Figure
from matplotlib.font_manager import get_font, fontManager as _fontManager
from matplotlib._afm import AFM
from matplotlib.ft2font import FT2Font, FaceFlags,Kerning,LoadFlags, StyleFlags
from matplotlib.ft2font import FT2Font, FaceFlags, LoadFlags, StyleFlags
from matplotlib.transforms import Affine2D, BboxBase
from matplotlib.path import Path
from matplotlib.dates import UTC
Expand DownExpand Up@@ -469,6 +469,7 @@ class Op(Enum):
textpos = b'Td'
selectfont = b'Tf'
textmatrix = b'Tm'
textrise = b'Ts'
show = b'Tj'
showkern = b'TJ'
setlinewidth = b'w'
Expand DownExpand Up@@ -2285,6 +2286,8 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
# If fonttype is neither 3 nor 42, emit the whole string at once
# without manual kerning.
if fonttype not in [3, 42]:
if not mpl.rcParams['pdf.use14corefonts']:
self.file._character_tracker.track(font, s)
self.file.output(Op.begin_text,
self.file.fontName(prop), fontsize, Op.selectfont)
self._setup_textpos(x, y, angle)
Expand All@@ -2305,13 +2308,16 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
# kerning between chunks.
else:
def output_singlebyte_chunk(kerns_or_chars):
if not kerns_or_chars:
return
self.file.output(
# See pdf spec "Text space details" for the 1000/fontsize
# (aka. 1000/T_fs) factor.
[(-1000 * next(group) / fontsize) if tp == float # a kern
else self._encode_glyphs(group, fonttype)
for tp, group in itertools.groupby(kerns_or_chars, type)],
Op.showkern)
kerns_or_chars.clear()
# Do the rotation and global translation as a single matrix
# concatenation up front
self.file.output(Op.gsave)
Expand All@@ -2326,24 +2332,26 @@ def output_singlebyte_chunk(kerns_or_chars):
# Emit all the characters in a BT/ET group.
self.file.output(Op.begin_text)
for item in _text_helpers.layout(s, font, features=features,
kern_mode=Kerning.UNFITTED,
language=language):
subset, charcode = self.file._character_tracker.track_glyph(
item.ft_object, item.char, item.glyph_index)
if (item.ft_object, subset) != prev_font:
if singlebyte_chunk:
output_singlebyte_chunk(singlebyte_chunk)
output_singlebyte_chunk(singlebyte_chunk)
ft_name = self.file.fontName(item.ft_object.fname, subset)
self.file.output(ft_name, fontsize, Op.selectfont)
self._setup_textpos(item.x, 0, 0, prev_start_x, 0, 0)
singlebyte_chunk = []
prev_font = (item.ft_object, subset)
prev_start_x = item.x
if item.y:
output_singlebyte_chunk(singlebyte_chunk)
self.file.output(item.y, Op.textrise)
if item.prev_kern:
singlebyte_chunk.append(item.prev_kern)
singlebyte_chunk.append(charcode)
if singlebyte_chunk:
output_singlebyte_chunk(singlebyte_chunk)
if item.y:
output_singlebyte_chunk(singlebyte_chunk)
self.file.output(0, Op.textrise)
output_singlebyte_chunk(singlebyte_chunk)
self.file.output(Op.end_text)
self.file.output(Op.grestore)

Expand Down
13 changes: 6 additions & 7 deletionslib/matplotlib/backends/backend_ps.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -776,7 +776,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
if ismath:
return self.draw_mathtext(gc, x, y, s, prop, angle)

stream = [] # list of (ps_name, x, char_name)
stream = [] # list of (ps_name, x,y,char_name)

if mpl.rcParams['ps.useafm']:
font = self._get_font_afm(prop)
Expand All@@ -794,7 +794,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
kern = font.get_kern_dist_from_name(last_name, name)
last_name = name
thisx += kern * scale
stream.append((ps_name, thisx, name))
stream.append((ps_name, thisx,0,name))
thisx += width * scale

else:
Expand All@@ -814,14 +814,13 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
ps_name = (item.ft_object.postscript_name
.encode("ascii", "replace").decode("ascii"))
glyph_name = item.ft_object.get_glyph_name(item.glyph_index)
stream.append((f'{ps_name}-{subset}', item.x, glyph_name))
stream.append((f'{ps_name}-{subset}', item.x,item.y,glyph_name))
self.set_color(*gc.get_rgb())

for ps_name, group in itertools. \
groupby(stream, lambda entry: entry[0]):
for ps_name, group in itertools.groupby(stream, lambda entry: entry[0]):
self.set_font(ps_name, prop.get_size_in_points(), False)
thetext = "\n".join(f"{x:g}0 m /{name:s} glyphshow"
for _, x, name in group)
thetext = "\n".join(f"{x:g}{y:g} m /{name:s} glyphshow"
for _, x,y,name in group)
self._pswriter.write(f"""\
gsave
{self._get_clip_cmd(gc)}
Expand Down
8 changes: 7 additions & 1 deletionlib/matplotlib/backends/backend_svg.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1048,6 +1048,11 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
text2path = self._text2path
color = rgb2hex(gc.get_rgb())
fontsize = prop.get_size_in_points()
if mtext is not None:
features = mtext.get_fontfeatures()
language = mtext.get_language()
else:
features = language = None

style = {}
if color != '#000000':
Expand All@@ -1068,7 +1073,8 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
if not ismath:
font = text2path._get_font(prop)
glyph_info, glyph_map_new, rects = text2path.get_glyphs_with_font(
font, s, glyph_map=glyph_map, return_new_glyphs_only=True)
font, s, features=features, language=language,
glyph_map=glyph_map, return_new_glyphs_only=True)
self._update_glyph_map_defs(glyph_map_new)

for glyph_repr, xposition, yposition, scale in glyph_info:
Expand Down
24 changes: 23 additions & 1 deletionlib/matplotlib/ft2font.pyi
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -191,6 +191,22 @@ class _SfntPcltDict(TypedDict):
widthType: int
serifStyle: int

@final
class LayoutItem:
@property
def ft_object(self) -> FT2Font: ...
@property
def char(self) -> str: ...
@property
def glyph_index(self) -> GlyphIndexType: ...
@property
def x(self) -> float: ...
@property
def y(self) -> float: ...
@property
def prev_kern(self) -> float: ...
def __str__(self) -> str: ...

@final
class FT2Font(Buffer):
def __init__(
Expand All@@ -203,7 +219,13 @@ class FT2Font(Buffer):
) -> None: ...
if sys.version_info[:2] >= (3, 12):
def __buffer__(self, flags: int) -> memoryview: ...
def _get_fontmap(self, string: str) -> dict[str, FT2Font]: ...
def _layout(
self,
text: str,
flags: LoadFlags,
features: tuple[str, ...] | None = ...,
language: str | tuple[tuple[str, int, int], ...] | None = ...,
) -> list[LayoutItem]: ...
def clear(self) -> None: ...
def draw_glyph_to_bitmap(
self, image: NDArray[np.uint8], x: int, y: int, glyph: Glyph, antialiased: bool = ...
Expand Down
Binary file modifiedlib/matplotlib/tests/baseline_images/test_axes/canonical.pdf
View file
Open in desktop
Binary file not shown.
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp