diff tests/test_balance_count.py @ 1:1d09e1dec1d9 upstream

ADD: PyMuPDF v1.26.4: the original sdist. It does not yet contain MuPDF. This normally will be downloaded when building PyMuPDF.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:37:51 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_balance_count.py	Mon Sep 15 11:37:51 2025 +0200
@@ -0,0 +1,52 @@
+import pymupdf
+
+
+def test_q_count():
+    """Testing graphics state balances and wrap_contents().
+
+    Take page's contents and generate various imbalanced graphics state
+    situations. Each time compare q-count with expected results.
+    Finally confirm we are out of balance using "is_wrapped", wrap the
+    contents object(s) via "wrap_contents()" and confirm success.
+    PDF commands "q" / "Q" stand for "push", respectively "pop".
+    """
+    doc = pymupdf.open()
+    page = doc.new_page()
+    # the page has no /Contents objects at all yet. Create one causing
+    # an initial imbalance (so prepended "q" is needed)
+    pymupdf.TOOLS._insert_contents(page, b"Q", True)  # append
+    assert page._count_q_balance() == (1, 0)
+    assert page.is_wrapped is False
+
+    # Prepend more data that yield a different type of imbalanced contents:
+    # Although counts of q and Q are equal now, the unshielded 'cm' before
+    # the first 'q' makes the contents unusable for insertions.
+    pymupdf.TOOLS._insert_contents(page, b"1 0 0 -1 0 0 cm q ", False)  # prepend
+    assert page.is_wrapped is False
+    if page._count_q_balance() == (0, 0):
+        print("imbalance undetected by q balance count")
+
+    text = "Hello, World!"
+    page.insert_text((100, 100), text)  # establishes balance!
+
+    # this should have produced a balanced graphics state
+    assert page._count_q_balance() == (0, 0)
+    assert page.is_wrapped
+
+    # an appended "pop" must be balanced by a prepended "push"
+    pymupdf.TOOLS._insert_contents(page, b"Q", True)  # append
+    assert page._count_q_balance() == (1, 0)
+
+    # a prepended "pop" yet needs another push
+    pymupdf.TOOLS._insert_contents(page, b"Q", False)  # prepend
+    assert page._count_q_balance() == (2, 0)
+
+    # an appended "push" needs an additional "pop"
+    pymupdf.TOOLS._insert_contents(page, b"q", True)  # append
+    assert page._count_q_balance() == (2, 1)
+
+    # wrapping the contents should yield a balanced state again
+    assert page.is_wrapped is False
+    page.wrap_contents()
+    assert page.is_wrapped is True
+    assert page._count_q_balance() == (0, 0)