Skip to content

Remove ttconv backwards-compatibility code #30145

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: text-overhaul
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
38 changes: 8 additions & 30 deletions lib/matplotlib/backends/backend_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,40 +617,18 @@ def _get_pdf_charprocs(font_path, glyph_ids):
procs = {}
for glyph_id in glyph_ids:
g = font.load_glyph(glyph_id, LoadFlags.NO_SCALE)
# NOTE: We should be using round(), but instead use
# "(x+.5).astype(int)" to keep backcompat with the old ttconv code
# (this is different for negative x's).
d1 = (np.array([g.horiAdvance, 0, *g.bbox]) * conv + .5).astype(int)
d1 = [
round(g.horiAdvance * conv), 0,
# Round bbox corners *outwards*, so that they indeed bound the glyph.
math.floor(g.bbox[0] * conv), math.floor(g.bbox[1] * conv),
math.ceil(g.bbox[2] * conv), math.ceil(g.bbox[3] * conv),
]
v, c = font.get_path()
v = (v * 64).astype(int) # Back to TrueType's internal units (1/64's).
# Backcompat with old ttconv code: control points between two quads are
# omitted if they are exactly at the midpoint between the control of
# the quad before and the quad after, but ttconv used to interpolate
# *after* conversion to PS units, causing floating point errors. Here
# we reproduce ttconv's logic, detecting these "implicit" points and
# re-interpolating them. Note that occasionally (e.g. with DejaVu Sans
# glyph "0") a point detected as "implicit" is actually explicit, and
# will thus be shifted by 1.
quads, = np.nonzero(c == 3)
quads_on = quads[1::2]
quads_mid_on = np.array(
sorted({*quads_on} & {*(quads - 1)} & {*(quads + 1)}), int)
implicit = quads_mid_on[
(v[quads_mid_on] # As above, use astype(int), not // division
== ((v[quads_mid_on - 1] + v[quads_mid_on + 1]) / 2).astype(int))
.all(axis=1)]
if (font.postscript_name, glyph_id) in [
("DejaVuSerif-Italic", 77), # j
("DejaVuSerif-Italic", 135), # \AA
]:
v[:, 0] -= 1 # Hard-coded backcompat (FreeType shifts glyph by 1).
v = (v * conv + .5).astype(int) # As above re: truncation vs rounding.
v[implicit] = (( # Fix implicit points; again, truncate.
(v[implicit - 1] + v[implicit + 1]) / 2).astype(int))
v = (v * 64 * conv).round() # Back to TrueType's internal units (1/64's).
procs[font.get_glyph_name(glyph_id)] = (
" ".join(map(str, d1)).encode("ascii") + b" d1\n"
+ _path.convert_to_string(
Path(v, c), None, None, False, None, -1,
Path(v, c), None, None, False, None, 0,
# no code for quad Beziers triggers auto-conversion to cubics.
[b"m", b"l", b"", b"c", b"h"], True)
+ b"f")
Expand Down
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_axes/imshow_clip.pdf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_ft2font/last_resort.pdf
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_legend/framealpha.pdf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_text/multiline.pdf
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_text/multiline2.pdf
Binary file not shown.
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_text/text_bboxclip.pdf
Binary file not shown.
Binary file not shown.
Binary file modified lib/matplotlib/tests/baseline_images/test_text/titles.pdf
Binary file not shown.
47 changes: 17 additions & 30 deletions src/_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -1066,38 +1066,25 @@
void __add_number(double val, char format_code, int precision,
std::string& buffer)
{
if (precision == -1) {
// Special-case for compat with old ttconv code, which *truncated*
// values with a cast to int instead of rounding them as printf
// would do. The only point where non-integer values arise is from
// quad2cubic conversion (as we already perform a first truncation
// on Python's side), which can introduce additional floating point
// error (by adding 2/3 delta-x and then 1/3 delta-x), so compensate by
// first rounding to the closest 1/3 and then truncating.
char str[255];
PyOS_snprintf(str, 255, "%d", (int)(round(val * 3)) / 3);
buffer += str;
} else {
char *str = PyOS_double_to_string(
val, format_code, precision, Py_DTSF_ADD_DOT_0, nullptr);
// Delete trailing zeros and decimal point
char *c = str + strlen(str) - 1; // Start at last character.
// Rewind through all the zeros and, if present, the trailing decimal
// point. Py_DTSF_ADD_DOT_0 ensures we won't go past the start of str.
while (*c == '0') {
--c;
}
if (*c == '.') {
--c;
}
try {
buffer.append(str, c + 1);
} catch (std::bad_alloc& e) {
PyMem_Free(str);
throw e;
}
char *str = PyOS_double_to_string(
val, format_code, precision, Py_DTSF_ADD_DOT_0, nullptr);
// Delete trailing zeros and decimal point
char *c = str + strlen(str) - 1; // Start at last character.
// Rewind through all the zeros and, if present, the trailing decimal
// point. Py_DTSF_ADD_DOT_0 ensures we won't go past the start of str.
while (*c == '0') {
--c;
}
if (*c == '.') {
--c;
}
try {
buffer.append(str, c + 1);
} catch (std::bad_alloc& e) {
PyMem_Free(str);
throw e;

Check warning on line 1085 in src/_path.h

View check run for this annotation

Codecov / codecov/patch

src/_path.h#L1085

Added line #L1085 was not covered by tests
}
PyMem_Free(str);
}


Expand Down
Loading