Skip to content

Commit 230ab6e

Browse files
committed
add test script
Also improve miter description in shape.rst.
1 parent 2a2a24a commit 230ab6e

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed

docs/shape.rst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -620,15 +620,23 @@ Common Parameters
620620

621621
**miter_limit** (*float*)
622622

623-
A float specifying the maximum acceptable value of the quotient `(miter length) / (border line width)`. Used in text output methods, this is only relevant for non-zero render mode values -- then characters are written with border lines (i.e. "stroked"). If two lines stroking a character meet at a sharp (<= 90°) angle and the border line width is large enough, then "spikes" may become visible -- causing an ugly appearance. For visualization of this see page 126 of the :ref:`AdobeManual`. For instance, when joined lines meet at an angle of 90°, then the miter length is ``sqrt(2) * (border line width)``, so their miter quotient is ``sqrt(2)``. If ``miter_limit`` is exceeded, then all line joins meeting at a sharper angle will be appear as beveled ("butt" appearance). The default value 1 will ensure that line joins always appear as beveled. A value of ``None`` will cause a PDF default value.
623+
A float specifying the maximum acceptable value of the quotient `miter-length / line-width` ("miter quotient"). Used in text output methods. This is only relevant for non-zero render mode values -- then, characters are written with border lines (i.e. "stroked").
624+
625+
If two lines stroking some character meet at a sharp (<= 90°) angle and the line width is large enough, then "spikes" may become visible -- causing an ugly appearance as shown below. For more background, see page 126 of the :ref:`AdobeManual`.
626+
627+
For instance, when joins meet at 90°, then the miter length is ``sqrt(2) * line-width``, so the miter quotient is ``sqrt(2)``.
628+
629+
If ``miter_limit`` is exceeded, then all joins with a larger qotient will appear as beveled ("butt" appearance).
630+
631+
The default value 1 (and any smaller value) will ensure that all joins are rendered as a butt. A value of ``None`` will use the PDF default value.
624632

625633
Example text showing spikes (``miter_limit=None``):
626634

627-
.. image:: images/img-rendermode.*
635+
.. image:: images/spikes-yes.*
628636

629-
Example text suppressing spikes (``miter_limit=1``):
637+
Example text suppressing spikes (``miter_limit=1``):
630638

631-
.. image:: images/img-rendermode.*
639+
.. image:: images/spikes-no.*
632640

633641
----
634642

tests/resources/spikes-no.png

-3.25 KB
Binary file not shown.

tests/resources/spikes-yes.png

-3.29 KB
Binary file not shown.

tests/test_spikes.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import pymupdf
2+
import pathlib
3+
import os
4+
5+
6+
def test_spikes():
7+
"""Check suppression of text spikes caused by long miters."""
8+
root = os.path.abspath(f"{__file__}/../..")
9+
spikes_yes = pathlib.Path(f"{root}/docs/images/spikes-yes.png")
10+
spikes_no = pathlib.Path(f"{root}/docs/images/spikes-no.png")
11+
doc = pymupdf.open()
12+
text = "NATO MEMBERS" # some text provoking spikes ("N", "M")
13+
point = (10, 35) # insert point
14+
15+
# make text provoking spikes
16+
page = doc.new_page(width=200, height=50) # small page
17+
page.insert_text(
18+
point,
19+
text,
20+
fontsize=20,
21+
render_mode=1, # stroke text only
22+
border_width=0.3, # causes thick border lines
23+
miter_limit=None, # do not care about miter spikes
24+
)
25+
# write same text in white over the previous for better demo purpose
26+
page.insert_text(point, text, fontsize=20, color=(1, 1, 1))
27+
pix1 = page.get_pixmap()
28+
assert pix1.tobytes() == spikes_yes.read_bytes()
29+
30+
# make text suppressing spikes
31+
page = doc.new_page(width=200, height=50)
32+
page.insert_text(
33+
point,
34+
text,
35+
fontsize=20,
36+
render_mode=1,
37+
border_width=0.3,
38+
miter_limit=1, # suppress each and every miter spike
39+
)
40+
page.insert_text(point, text, fontsize=20, color=(1, 1, 1))
41+
pix2 = page.get_pixmap()
42+
assert pix2.tobytes() == spikes_no.read_bytes()

0 commit comments

Comments
 (0)