From 47568c248cc496ef98d9368cfb1b146c415c5c7e Mon Sep 17 00:00:00 2001 From: Arie Bovenberg Date: Mon, 22 May 2023 22:08:32 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20regression=20in=20drawn=20?= =?UTF-8?q?text=20leading?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.rst | 1 + src/pdfje/draw.py | 6 ++- src/pdfje/text.py | 0 src/pdfje/typeset/common.py | 10 ++++ src/pdfje/typeset/lines.py | 14 +---- tests/test_document.py | 100 ------------------------------------ 6 files changed, 17 insertions(+), 114 deletions(-) delete mode 100644 src/pdfje/text.py diff --git a/README.rst b/README.rst index e479194..689d94f 100644 --- a/README.rst +++ b/README.rst @@ -109,6 +109,7 @@ Features: - 🚧 Avoiding orphaned/widowed lines - 🚧 Tex-style line breaking - 🚧 Broader unicode support in text wrapping + - 🚧 Headings (which stick to their paragraphs) - Drawing operations - ✅ Lines - ✅ Rectangles diff --git a/src/pdfje/draw.py b/src/pdfje/draw.py index f71d5f4..d71f35e 100644 --- a/src/pdfje/draw.py +++ b/src/pdfje/draw.py @@ -18,7 +18,7 @@ ) from .fonts.registry import Registry from .style import Span, Style, StyledMixin, StyleFull, StyleLike -from .typeset.common import Command, State, Stretch, splitlines +from .typeset.common import Command, State, Stretch, max_lead, splitlines from .typeset.lines import Line as TextLine from .typeset.words import parse as parse_words @@ -367,8 +367,10 @@ def render(self, r: Registry, s: StyleFull, /) -> Streamable: state = s.as_state(r) yield b"BT\n%g %g Td\n" % self.loc.astuple() yield from state + stretches = list(self.flatten(r, s)) + lead = max_lead(stretches, state) yield from _pick_renderer(self.align)( - into_lines(splitlines(self.flatten(r, s)), state), state.lead, 0 + into_lines(splitlines(stretches), state), lead, 0 ) yield b"ET\n" diff --git a/src/pdfje/text.py b/src/pdfje/text.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/pdfje/typeset/common.py b/src/pdfje/typeset/common.py index d6826db..a57b862 100644 --- a/src/pdfje/typeset/common.py +++ b/src/pdfje/typeset/common.py @@ -190,6 +190,16 @@ class Stretch(NamedTuple): txt: str +def max_lead(s: Iterable[Stretch], state: State) -> Pt: + # FUTURE: we apply commands elsewhere, so doing it also here + # is perhaps a bit wasteful + lead = state.lead + for cmd, _ in s: + state = cmd.apply(state) + lead = max(lead, state.lead) + return lead + + def _encode_kerning( txt: str, kerning: Sequence[Kern], diff --git a/src/pdfje/typeset/lines.py b/src/pdfje/typeset/lines.py index 8d31017..87c7f34 100644 --- a/src/pdfje/typeset/lines.py +++ b/src/pdfje/typeset/lines.py @@ -5,7 +5,7 @@ from ..atoms import LiteralStr, Real from ..common import BranchableIterator, Pt, Streamable, add_slots -from .common import State, Stretch +from .common import State, Stretch, max_lead from .words import WithCmd, Word from .words import parse as parse_words from .words import render_kerned @@ -61,16 +61,6 @@ def _indent_first( yield from it -def _max_lead(s: Iterable[Stretch], state: State) -> Pt: - # TODO: we apply commands elsewhere, so doing it also here - # is perhaps a bit wasteful - lead = state.lead - for cmd, _ in s: - state = cmd.apply(state) - lead = max(lead, state.lead) - return lead - - @add_slots @dataclass(frozen=True) class Wrapper: @@ -94,7 +84,7 @@ def start( return Wrapper( BranchableIterator(_indent_first(words, indent)), cmd.apply(state), - _max_lead(it, state), + max_lead(it, state), ) def line(self, width: Pt) -> tuple[Line, Wrapper | WrapDone]: diff --git a/tests/test_document.py b/tests/test_document.py index 4944a47..e2eebbf 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -271,106 +271,6 @@ def test_draw(outfile): [ Page([Text((250, 400), "First!", Style(size=50))]), Page([Text((50, 720), ZEN_OF_PYTHON)]), - Page( - [ - Rect((50, 720), 72, -800), - Text( - (50, 720), - """\ -In olden times -when wishing -still helped -one, there -lived a king -whose daugh- -ters were all -beautiful, but -the young- -est was so -beautiful that -the sun itself, -which has -seen so much, -was astonished -whenever it -shone in her -face. Close by -the king’s cas- -tle lay a -great dark for- -est, and under -an old lime- -tree in the -forest was a -well, and when -the day was -very warm, the -king’s child -went out into -the forest and -sat down by -the side of the -cool fountain, -and when she -was bored she -took a golden -ball, and threw -it up on high -and caught it, -and this ball -was her favo- -rite plaything.""", - style=times_roman, - ), - Rect((150, 720), 72, -800), - Text( - (150, 720), - """\ -In olden times -when wishing -still helped -one, there lived -a king whose -daughters were -all beautiful, -but the young- -est was so -beautiful that -the sun itself, -which has -seen so much, -was astonished -whenever it -shone in her -face. Close by -the king’s cas- -tle lay a great -dark forest, and -under an old -lime-tree in the -forest was a -well, and when -the day was -very warm, the -king’s child -went out into -the forest and -sat down by -the side of the -cool fountain, -and when she -was bored she -took a golden -ball, and threw -it up on high -and caught it, -and this ball -was her favo- -rite plaything.""", - style=times_roman, - ), - ] - ), Page( [ Polyline(