Commit 3dc583fa for tesseract

commit 3dc583fa0106cb1fd6d953b5ff58816fc78b337c
Author: Stefan Weil <sw@weilnetz.de>
Date:   Thu Oct 8 14:50:25 2026 +0200

    Fix position-dependent paragraph bounding box (#4632)

    BoundingBoxInternal seeded the RIL_PARA box from the current row's
    restricted_bounding_box, which excludes upper and lower dots, before
    unioning the full bounding boxes of the paragraph's rows. When the
    current row's full box was not re-unioned, the smaller restricted seed
    leaked into the result, so the paragraph box depended on which row the
    iterator sat on.

    Build the paragraph box purely from the union of the full bounding
    boxes of its rows so it no longer depends on the iterator position.
    This makes ResultIteratorTest.RestartParagraphTest pass when the
    legacy engine is disabled.

    Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud)
    Signed-off-by: Stefan Weil <sw@weilnetz.de>

diff --git a/src/ccmain/pageiterator.cpp b/src/ccmain/pageiterator.cpp
index 0d10398c..0fb5b658 100644
--- a/src/ccmain/pageiterator.cpp
+++ b/src/ccmain/pageiterator.cpp
@@ -303,7 +303,11 @@ bool PageIterator::BoundingBoxInternal(PageIteratorLevel level, int *left,
       break;
     case RIL_PARA:
       para = it_->row()->row->para();
-      // Fall through.
+      // For a paragraph the box is the union of the full bounding boxes of
+      // all its rows. Do not seed with the current row's restricted box: the
+      // restricted box excludes upper/lower dots, so the result would depend
+      // on which row the iterator currently sits on.
+      break;
     case RIL_TEXTLINE:
       box = it_->row()->row->restricted_bounding_box(include_upper_dots_,
                                                      include_lower_dots_);