Skip to content

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented May 12, 2025

The old formula (*dst |= *src) works fine when either dst or src is full transparent or fully opaque, but not for compositing intermediate values. Fix that (while keeping a fast-path for the common case of writing on an empty buffer).

Example (note the more uniform gray zone between the two letters):

from matplotlib import pyplot as plt, ft2font as f, cbook
import numpy as np

font = f.FT2Font(str(cbook._get_data_path("fonts/ttf/DejaVuSans.ttf")))
font.set_size(24, 72)
im = f.FT2Image(30, 30)
ga = font.load_char(ord("A"))
gv = font.load_char(ord("V"))
font.draw_glyph_to_bitmap(im, 2, 2, ga)
font.draw_glyph_to_bitmap(im, 12, 2, gv)

(plt.figure(layout="constrained", figsize=(3, 3))
 .add_subplot(xticks=[], yticks=[])
 .imshow(np.asarray(im), cmap="gray"))
plt.show()

old/new:
old
new

Somewhat unsurprisingly, this also breaks a bunch of baseline images; maybe this could be squashed into the FreeType update (#29816)?

PR summary

PR checklist

@anntzer anntzer force-pushed the fa branch 2 times, most recently from f28745c to da6647b Compare May 13, 2025 06:48
@anntzer
Copy link
Contributor Author

anntzer commented May 16, 2025

Actually, #30059 (direct rendering into the Agg buffer) would be even more general than this, as we'd just rely on Agg's compositing.

The old formula (`*dst |= *src`) works fine when either dst or src is
full transparent or fully opaque, but not for compositing intermediate
values.  Fix that (while keeping a fast-path for the common case of
writing on an empty buffer).

Example (note the more uniform gray zone between the two letters):
```
from matplotlib import pyplot as plt, ft2font as f, cbook
import numpy as np

font = f.FT2Font(str(cbook._get_data_path("fonts/ttf/DejaVuSans.ttf")))
font.set_size(24, 72)
im = f.FT2Image(30, 30)
ga = font.load_char(ord("A"))
gv = font.load_char(ord("V"))
font.draw_glyph_to_bitmap(im, 2, 2, ga)
font.draw_glyph_to_bitmap(im, 12, 2, gv)

(plt.figure(layout="constrained", figsize=(3, 3))
 .add_subplot(xticks=[], yticks=[])
 .imshow(np.asarray(im), cmap="gray"))
plt.show()
```
@QuLogic
Copy link
Member

QuLogic commented Jun 5, 2025

Closing in favour of #30059.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants