Skip to content

Commit fa10cc3

Browse files
committed
Match paragraph breaks with Read Aloud branch in Reader
1 parent f058571 commit fa10cc3

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

src/core/module/structure.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ function split(chars, reflowRTL) {
823823
let MAX_LINE_SPACING = 5;
824824
let MIN_LINE_SPACING = -2;
825825
let MAX_LINE_SPACING_CHANGE = 2;
826+
let INDENT_EPS = 10;
826827

827828
let isGapValid = (gap) => gap >= MIN_LINE_SPACING && gap <= MAX_LINE_SPACING;
828829

@@ -831,6 +832,7 @@ function split(chars, reflowRTL) {
831832

832833

833834
let paragraphBreaks = [];
835+
let indentedBreaks = new Set();
834836
for (let i = 1; i < lineBreaks.length - 1; i++) {
835837
let currentLine = { start: lineBreaks[i - 1], end: lineBreaks[i] - 1 };
836838
let nextLine = { start: lineBreaks[i] || 0, end: lineBreaks[i + 1] - 1 };
@@ -861,18 +863,61 @@ function split(chars, reflowRTL) {
861863
let currentLineFontName = mostCommonFontName(chars.slice(currentLine.start, currentLine.end));
862864
let nextLineFontName = mostCommonFontName(chars.slice(nextLine.start, nextLine.end));
863865

866+
let rotation = chars[currentLine.start].rotation;
867+
let isIndented = (
868+
rotation === 0 && nextRect[0] > currentRect[0] + INDENT_EPS
869+
|| rotation === 90 && nextRect[1] > currentRect[1] + INDENT_EPS
870+
|| rotation === 180 && currentRect[2] > nextRect[2] + INDENT_EPS
871+
|| rotation === 270 && currentRect[3] > nextRect[3] + INDENT_EPS
872+
);
873+
864874
if (
865875
// The lines shouldn't be in the same row
866876
!allowGap
867877
|| !(currentRect[1] > nextRect[3])
868878
|| currentLineFontName !== nextLineFontName && currentRect[2] < nextRect[2] - 10
869-
|| Math.abs(currentLineHeight - nextLineHeight) > 2) {
879+
|| Math.abs(currentLineHeight - nextLineHeight) > 2
880+
// Next line is indented relative to the current line
881+
|| isIndented) {
870882
paragraphBreaks.push(lineBreaks[i]);
883+
if (isIndented) {
884+
indentedBreaks.add(lineBreaks[i]);
885+
}
871886
}
872887
}
873888

874889
paragraphBreaks.push(chars.length);
875890

891+
// Merge single-line paragraphs back into the previous paragraph
892+
// when they share the same font, to prevent over-splitting.
893+
// Skip breaks triggered by indentation, as those are intentional.
894+
let paragraphStarts = [0];
895+
for (let pb of paragraphBreaks) {
896+
if (pb < chars.length) {
897+
paragraphStarts.push(pb);
898+
}
899+
}
900+
let removedBreaks = new Set();
901+
for (let p = 1; p < paragraphStarts.length; p++) {
902+
let currentStart = paragraphStarts[p];
903+
if (indentedBreaks.has(currentStart)) {
904+
continue;
905+
}
906+
let currentEnd = (p + 1 < paragraphStarts.length) ? paragraphStarts[p + 1] : chars.length;
907+
// Count lines in this paragraph
908+
let lineCount = 0;
909+
for (let lb of lineBreaks) {
910+
if (lb >= currentStart && lb < currentEnd) {
911+
lineCount++;
912+
}
913+
}
914+
if (lineCount === 1
915+
&& chars[currentStart].fontName === chars[paragraphStarts[p - 1]].fontName) {
916+
removedBreaks.add(currentStart);
917+
}
918+
}
919+
paragraphBreaks = paragraphBreaks.filter(pb => !removedBreaks.has(pb));
920+
876921
for (let paragraphBreak of paragraphBreaks) {
877922
chars[paragraphBreak - 1].paragraphBreakAfter = true;
878923
}

0 commit comments

Comments
 (0)