Skip to content

fix(layout): move objects past the page foot to the next page's top as Hancom does - #383

Merged
airmang merged 3 commits into
mainfrom
fix/page-estimate-square-object-moved-to-the-next-page
Oct 2, 2026
Merged

airmang merged 3 commits into
mainfrom
fix/page-estimate-square-object-moved-to-the-next-page

Conversation

@airmang

@airmang airmang commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

바뀐 점

쪽 수 추정(실험, estimate_pages)이 본문 바닥을 넘는 개체 가운데, 한/글이 통째로 다음 쪽 맨 위로 옮기는 개체를 따르게 한다.

  • 글과 함께 움직이는 어울림(SQUARE) 그림·도형이 바닥을 넘으면, 한/글은 띄움과 상관없이 다음 쪽 본문 맨 위로 옮긴다.
    • 개체가 있던 쪽의 줄은 개체 문단까지 모두 전체 폭이다.
    • 다음 쪽에서 줄 위가 개체 아래 끝보다 위인 줄은 개체 곁으로 간다. 양옆에 글이 가면 두 조각, 한쪽이면 한 조각이다. 같거나 아래인 줄은 전체 폭이다.
    • 개체 문단이나 뒤 문단이 쪽을 넘으면, 넘어간 줄부터 개체 곁에서 다시 나뉜다.
    • 나누지 않게 둔 어울림 표(pageBreak="NONE")도 그렇게 옮겨 간다.
    • 전에는 줄 캐시가 없으면 지원 밖(a square-wrapped or offset top-and-bottom object past the page foot)이었다.
  • 빈 문단 줄 아래로 띄워 위아래로 둔 그림·도형도, 문단이 놓인 자리에서 개체 발이 바닥을 넘으면 다음 쪽 맨 위로 옮겨 간다.
    • 문단 줄은 제자리에 남고, 다음 쪽에서 개체에 닿는 줄은 그 아래로 간다.
    • 전에는 캐시가 있을 때도 문단째 다음 쪽으로 보냈다.
  • 나뉠 수 있는 어울림 표는 옮겨 가지 않고 쪽 끝에서 나뉜다(다음 쪽 맨 위에 남은 행 높이만큼 띠가 이어진다). 그래서 전처럼 캐시가 있을 때만 따른다. 위아래로 둔 표도 이 PR에서는 바꾸지 않는다.
  • 코드
    • 처음 놓을 때 그런 개체를 만나면 구역을 한 번 더 놓는다(_BandMoves). 그 문단은 개체 없이 다시 만든다.
      • 어울림 개체는 바닥을 넘는지 줄을 놓은 뒤에 본다.
      • 위아래 개체는 줄을 놓기 전에, 문단이 놓일 자리에서 본다(_Para.wrap_push, _Para.moves).
    • 쪽 나누기(_Paginator)는 개체 문단의 첫 줄을 놓을 때 다음 쪽 맨 위에 개체의 띠를 둔다(_move_band). 그 쪽은 줄이 없어도 쓰인 쪽으로 센다.
      • 위아래 개체의 띠는 종이 기준 개체의 띠처럼 줄이 피해 간다.
      • 어울림 개체의 띠에 닿는 줄은 캐시 없는 글 문단이면 띠 곁에서 다시 나눈다(_at_band, _Reflow.banded). 여러 단의 너비가 다를 때 쓰던 다시 나누기(_Reflow)를 넓혔다.
    • 그 자리에 개체·각주가 든 문단, 캐시를 지키는 문단, 표가 오면 지원 밖이다.
  • 양옆에 글이 가는 개체 곁의 줄은 글이 첫 조각에서 끝나도 두 조각이다. 글이 없는 줄도 두 조각이다. 둘째 조각은 빈 조각(hp:lineseg@flags 16번 비트)이다.
    • 캐시 없는 추정도 이제 빈 둘째 조각을 센다(_at_one_height, _in_two_pieces).
    • 바닥을 넘지 않는 띠에서도 같다.
  • 문단 첫 줄을 그림 아래로 밀어낸 위아래 그림은 띠 발을 밀리기 전 줄 자리에서 잰다(_Para.wrap_shift). 전에는 밀린 줄 자리에 그림 높이를 한 번 더 더해, 바닥 위에서 끝나는 그림도 바닥을 넘는다고 보아 지원 밖으로 두었다.
  • 모듈 설명과 변경 로그를 고친다.

테스트

  • tests/test_layout_page_estimate.py의 HANCOM_PAGES에 한/글 저장본 열을 더한다(캐시 있음·없음). 그림은 20000×27112이고, 10pt 글에 줄 간격 160%다.
    • 가운데 그림이 바닥을 5000 넘는다. 뒤 글은 모두 앞 쪽에 들어가고, 둘째 쪽의 짧은 곁 줄은 둘째 조각이 비어 있다.
    • 뒤 문단이 둘째 쪽으로 넘어가 그림 곁에서 두 조각으로 이어진다(3쪽).
    • 그림을 단 왼쪽에 두면 곁 줄이 오른쪽 한 조각이다(3쪽).
    • 그림 문단 자체의 글이 둘째 쪽 그림 곁으로 이어진다.
    • 문단에서 8000 아래로 띄운 그림도 다음 쪽 맨 위에 선다(3쪽).
    • 나누지 않게 둔 6행 표(단 왼쪽)도 그렇다(3쪽).
    • 빈 문단 줄 1319 아래로 띄워 위아래로 둔 그림(높이 8000)은 다음 쪽 맨 위로 가고, 문단 줄은 남는다(3쪽).
    • 14pt 글 문단에서 1319 아래로 띄운 30000 높이 그림이 첫 줄을 그림 아래로 민다. 그림은 바닥 위에서 끝난다(2쪽).
    • 띠가 바닥 위에서 끝날 때도 짧은 곁 줄은 두 조각이다.
    • 글과 함께 움직이지 않는 그림이 제 쪽에 남을 때, 글 없는 그림 문단의 줄과 짧은 곁 줄이 두 조각이다.
  • 기존 시험 test_a_square_object_past_the_page_foot_goes_on_at_the_next_page(이름을 바꿈)
    • 그림 저장본 둘은 이제 캐시가 없어도 한/글과 같다.
    • 나뉘는 어울림 표 저장본은 전처럼 캐시 없이는 지원 밖이다.
  • 고치기 전 코드에서는 새 저장본 열의 캐시 없는 시험이 실패한다. 위아래 그림 저장본 둘은 캐시가 있는 시험도 실패한다.

🤖 Generated with Claude Code

airmang and others added 3 commits October 2, 2026 23:33
…s Hancom does

A picture or drawing wrapped square and flowing with the text whose band
passed the body's foot was followed only through the layout caches.
Hancom sets it at the next page's body top whatever its offset: the lines
of its own page are the whole width, and the lines on the next page whose
top is above its foot go beside it. The section is now laid out again
with the object there: its paragraph and the ones after it the whole
width, and the lines reaching it on the next page broken again beside it.
A table wrapped square and set not to split moves the same way; one that
may split is split over the page end instead and is still followed only
through the caches.

A picture or drawing placed top and bottom below its empty paragraph's
line, flowing with the text, whose foot would pass the body's foot from
where the paragraph stands, goes on alone to the next page's top too: the
paragraph's line stays, and the lines on the next page reaching it go
below it. The estimate sent the paragraph to the next page with it, with
the layout caches as well.

A line beside an object with text on both sides is two pieces even when
its text ends in the first piece or it holds no text; the estimate now
counts the empty second piece too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… stood

A top-and-bottom object offset from a paragraph of text pushes the
paragraph's first line below it. Its band's foot is measured from where
that line stood before it was pushed, but both checks of whether the band
passes the body's foot added it to the line's new top, so an object
ending well above the foot was taken past it: refused before, and sent
to the next page by the previous commit. The push is now taken off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…are-object-moved-to-the-next-page

# Conflicts:
#	CHANGELOG.md
@airmang

airmang commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

커밋 둘을 더했습니다.

  • d062561e: 문단 첫 줄을 그림 아래로 밀어낸 위아래 그림의 띠 발을, 밀리기 전 줄 자리에서 잽니다.
    • 전에는 밀린 줄 자리에 그림 높이를 한 번 더 더했습니다. 그래서 바닥 위에서 끝나는 그림도 바닥을 넘는다고 보았습니다. main은 지원 밖으로 두었고, 이 PR의 첫 커밋은 다음 쪽으로 옮겼습니다.
    • 한/글 저장본 pages_picture_pushing_its_first_line_above_the_foot을 더했습니다(캐시 있음·없음).
  • 14f21b27: main(006eb94b, fix(layout): keep rows with vertical text as declared and their tables whole #382 병합)을 합쳤습니다. 충돌은 CHANGELOG.md뿐이었고, 두 항목을 모두 두었습니다.

전체 테스트, 쪽 수 추정·FormFit 테스트, 게이트를 다시 통과했고, coverage ledger도 main과 같습니다. 본문의 바뀐 점과 테스트 항목도 고쳤습니다.

@airmang
airmang merged commit 582c64d into main Oct 2, 2026
13 checks passed
@airmang
airmang deleted the fix/page-estimate-square-object-moved-to-the-next-page branch October 2, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant