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

Drop the FT2Font intermediate buffer.#30059

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
anntzer wants to merge1 commit intomatplotlib:main
base:main
Choose a base branch
Loading
fromanntzer:ft-direct-render
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
77 changes: 49 additions & 28 deletionslib/matplotlib/backends/backend_agg.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,7 +70,7 @@
self._filter_renderers = []

self._update_methods()
self.mathtext_parser = MathTextParser('agg')
self.mathtext_parser = MathTextParser('path')

self.bbox = Bbox.from_bounds(0, 0, self.width, self.height)

Expand DownExpand Up@@ -172,36 +172,58 @@

def draw_mathtext(self, gc, x, y, s, prop, angle):
"""Draw mathtext using :mod:`matplotlib.mathtext`."""
ox, oy, width, height, descent, font_image = \
self.mathtext_parser.parse(s, self.dpi, prop,
antialiased=gc.get_antialiased())

xd = descent * sin(radians(angle))
yd = descent * cos(radians(angle))
x = round(x + ox + xd)
y = round(y - oy + yd)
self._renderer.draw_text_image(font_image, x, y + 1, angle, gc)
# y is downwards.
parse = self.mathtext_parser.parse(
s, self.dpi, prop, antialiased=gc.get_antialiased())
c = cos(radians(angle))
s = sin(radians(angle))
for font, size, char, dx, dy in parse.glyphs: # dy is upwards.
font.set_size(size, self.dpi)
bitmap = font._render_glyph(
font.get_char_index(char),
# The "y" parameter is upwards (per FreeType).
x + dx * c - dy * s, self.height - y + dx * s + dy * c, angle,
get_hinting_flag())
# draw_text_image's y is downwards & the bitmap bottom side.
self._renderer.draw_text_image(
bitmap["buffer"],
bitmap["left"],
int(self.height) - bitmap["top"] + bitmap["buffer"].shape[0],
0, gc)
if not angle:
for dx, dy, w, h in parse.rects: # dy is upwards & the rect top side.
self._renderer.draw_text_image(
np.full((round(h), round(w)), np.uint8(0xff)),
round(x + dx), round(y - dy - h),
0, gc)
else:
rgba = gc.get_rgb()

Check warning on line 200 in lib/matplotlib/backends/backend_agg.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/backends/backend_agg.py#L200

Added line #L200 was not covered by tests
if len(rgba) == 3 or gc.get_forced_alpha():
rgba = rgba[:3] + (gc.get_alpha(),)
gc1 = self.new_gc()
gc1.set_linewidth(0)

Check warning on line 204 in lib/matplotlib/backends/backend_agg.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/backends/backend_agg.py#L202-L204

Added lines #L202 - L204 were not covered by tests
for dx, dy, w, h in parse.rects: # dy is upwards & the rect top side.
path = Path._create_closed(

Check warning on line 206 in lib/matplotlib/backends/backend_agg.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/backends/backend_agg.py#L206

Added line #L206 was not covered by tests
[(dx, dy), (dx + w, dy), (dx + w, dy + h), (dx, dy + h)])
self._renderer.draw_path(

Check warning on line 208 in lib/matplotlib/backends/backend_agg.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/backends/backend_agg.py#L208

Added line #L208 was not covered by tests
gc1, path,
mpl.transforms.Affine2D()
.rotate_deg(angle).translate(x, self.height - y),
rgba)
gc1.restore()

Check warning on line 213 in lib/matplotlib/backends/backend_agg.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/backends/backend_agg.py#L213

Added line #L213 was not covered by tests

def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
# docstring inherited
if ismath:
return self.draw_mathtext(gc, x, y, s, prop, angle)
font = self._prepare_font(prop)
# We pass '0' for angle here, since it will be rotated (in raster
# space) in the following call to draw_text_image).
font.set_text(s, 0, flags=get_hinting_flag())
font.draw_glyphs_to_bitmap(
antialiased=gc.get_antialiased())
d = font.get_descent() / 64.0
# The descent needs to be adjusted for the angle.
xo, yo = font.get_bitmap_offset()
xo /= 64.0
yo /= 64.0
xd = d * sin(radians(angle))
yd = d * cos(radians(angle))
x = round(x + xo + xd)
y = round(y + yo + yd)
self._renderer.draw_text_image(font, x, y + 1, angle, gc)
font.set_text(s, angle, flags=get_hinting_flag())
for bitmap in font._render_glyphs(x, self.height - y):
self._renderer.draw_text_image(
bitmap["buffer"],
bitmap["left"],
int(self.height) - bitmap["top"] + bitmap["buffer"].shape[0],
0, gc)

def get_text_width_height_descent(self, s, prop, ismath):
# docstring inherited
Expand All@@ -211,9 +233,8 @@
return super().get_text_width_height_descent(s, prop, ismath)

if ismath:
ox, oy, width, height, descent, font_image = \
self.mathtext_parser.parse(s, self.dpi, prop)
return width, height, descent
parse = self.mathtext_parser.parse(s, self.dpi, prop)
return parse.width, parse.height, parse.depth

font = self._prepare_font(prop)
font.set_text(s, 0.0, flags=get_hinting_flag())
Expand Down
2 changes: 2 additions & 0 deletionssrc/ft2font.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,7 +174,9 @@ class FT2Font
py::array_t<uint8_t, py::array::c_style> image;
FT_Face face;
FT_Vector pen; /* untransformed origin */
public:
std::vector<FT_Glyph> glyphs;
private:
std::vector<FT2Font *> fallbacks;
std::unordered_map<FT_UInt, FT2Font *> glyph_to_font;
std::unordered_map<long, FT2Font *> char_to_font;
Expand Down
48 changes: 47 additions & 1 deletionsrc/ft2font_wrapper.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1772,7 +1772,53 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())

.def_buffer([](PyFT2Font &self) -> py::buffer_info {
return self.x->get_image().request();
});
})

// TODO: Return a nicer structure than dicts.
// NOTE: The lifetime of the buffers is limited and could get invalidated...
// TODO: Real antialiasing flag.
// TODO: throw_ft_error.
// x, y are upwards here
.def("_render_glyph", [](PyFT2Font *self, FT_UInt idx,
double x, double y, double angle,
LoadFlags flags) {
auto face = self->x->get_face();
auto hf = self->x->get_hinting_factor();
auto c = std::cos(angle * M_PI / 180) * 0x10000L,
s = std::sin(angle * M_PI / 180) * 0x10000L;
auto matrix = FT_Matrix{
std::lround(c / hf), std::lround(-s), std::lround(s / hf), std::lround(c)};
auto delta = FT_Vector{std::lround(x * 64), std::lround(y * 64)};
FT_Set_Transform(face, &matrix, &delta);
FT_CHECK(FT_Load_Glyph, face, idx, static_cast<FT_Int32>(flags));
FT_CHECK(FT_Render_Glyph, face->glyph, FT_RENDER_MODE_NORMAL);
py::dict d;
d["left"] = face->glyph->bitmap_left;
d["top"] = face->glyph->bitmap_top;
d["buffer"] = py::array_t<uint8_t>{
{face->glyph->bitmap.rows, face->glyph->bitmap.width},
{face->glyph->bitmap.pitch, 1},
face->glyph->bitmap.buffer};
return d;
})
.def("_render_glyphs", [](PyFT2Font *self, double x, double y) {
auto origin = FT_Vector{std::lround(x * 64), std::lround(y * 64)};
py::list gs;
for (auto &g: self->x->glyphs) {
FT_CHECK(FT_Glyph_To_Bitmap, &g, FT_RENDER_MODE_NORMAL, &origin, 1);
auto bg = reinterpret_cast<FT_BitmapGlyph>(g);
py::dict d;
d["left"] = bg->left;
d["top"] = bg->top;
d["buffer"] = py::array_t<uint8_t>{
{bg->bitmap.rows, bg->bitmap.width},
{bg->bitmap.pitch, 1},
bg->bitmap.buffer};
gs.append(d);
}
return gs;
})
;

m.attr("__freetype_version__") = version_string;
m.attr("__freetype_build_type__") = FREETYPE_BUILD_TYPE;
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp