From c7afce421015f16afb9b3f265f49dc8e290dc8dd Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Sat, 28 May 2022 14:08:43 +0200 Subject: [PATCH] Support Hangul syllables when searching some text (bug 1771477) - it aims to fix https://bugzilla.mozilla.org/show_bug.cgi?id=1771477; - hangul contains some syllables which are decomposed when using NFD, hence the text must be correctly shifted in case it contains some of them. --- test/pdfs/.gitignore | 2 + test/pdfs/bug1771477.pdf | Bin 0 -> 72422 bytes test/unit/pdf_find_controller_spec.js | 29 +++++++- web/pdf_find_controller.js | 100 ++++++++++++++++++++------ 4 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 test/pdfs/bug1771477.pdf diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index f78a3384c..14b686d3c 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -524,3 +524,5 @@ !issue14627.pdf !issue14862.pdf !issue14705.pdf +!bug1771477.pdf + diff --git a/test/pdfs/bug1771477.pdf b/test/pdfs/bug1771477.pdf new file mode 100644 index 0000000000000000000000000000000000000000..adf0a44aa60a3ccb7a272f1617ec2b5f34a2b23f GIT binary patch literal 72422 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 0 && withSyllablesRegExp) { + normalizationRegex = withSyllablesRegExp; + } else { // Compile the regular expression for text normalization once. const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join(""); - normalizationRegex = new RegExp( - `([${replace}])|(\\p{M}+(?:-\\n)?)|(\\S-\\n)|(\\n)`, - "gum" - ); + const regexp = `([${replace}])|(\\p{M}+(?:-\\n)?)|(\\S-\\n)|(\\n)`; + + if (syllablePositions.length === 0) { + // Most of the syllables belong to Hangul so there are no need + // to search for them in a non-Hangul document. + // We use the \0 in order to have the same number of groups. + normalizationRegex = noSyllablesRegExp = new RegExp( + regexp + "|(\\u0000)", + "gum" + ); + } else { + normalizationRegex = withSyllablesRegExp = new RegExp( + regexp + `|(${FIRST_CHAR_SYLLABLES_REG_EXP})`, + "gum" + ); + } } // The goal of this function is to normalize the string and @@ -130,14 +173,14 @@ function normalize(text) { // Collect diacritics length and positions. const rawDiacriticsPositions = []; - let m; while ((m = DIACRITICS_REG_EXP.exec(text)) !== null) { rawDiacriticsPositions.push([m[0].length, m.index]); } let normalized = text.normalize("NFD"); const positions = [[0, 0]]; - let k = 0; + let rawDiacriticsIndex = 0; + let syllableIndex = 0; let shift = 0; let shiftOrigin = 0; let eol = 0; @@ -145,7 +188,7 @@ function normalize(text) { normalized = normalized.replace( normalizationRegex, - (match, p1, p2, p3, p4, i) => { + (match, p1, p2, p3, p4, p5, i) => { i -= shiftOrigin; if (p1) { // Maybe fractions or quotations mark... @@ -165,12 +208,12 @@ function normalize(text) { // Diacritics. hasDiacritics = true; let jj = len; - if (i + eol === rawDiacriticsPositions[k]?.[1]) { - jj -= rawDiacriticsPositions[k][0]; - ++k; + if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) { + jj -= rawDiacriticsPositions[rawDiacriticsIndex][0]; + ++rawDiacriticsIndex; } - for (let j = 1; j < jj + 1; j++) { + for (let j = 1; j <= jj; j++) { // i is the position of the first diacritic // so (i - 1) is the position for the letter before. positions.push([i - 1 - shift + j, shift - j]); @@ -204,14 +247,29 @@ function normalize(text) { return p3.charAt(0); } - // p4 - // eol is replaced by space: "foo\nbar" is likely equivalent to - // "foo bar". - positions.push([i - shift + 1, shift - 1]); - shift -= 1; - shiftOrigin += 1; - eol += 1; - return " "; + if (p4) { + // eol is replaced by space: "foo\nbar" is likely equivalent to + // "foo bar". + positions.push([i - shift + 1, shift - 1]); + shift -= 1; + shiftOrigin += 1; + eol += 1; + return " "; + } + + // p5 + if (i + eol === syllablePositions[syllableIndex]?.[1]) { + // A syllable (1 char) is replaced with several chars (n) so + // newCharsLen = n - 1. + const newCharLen = syllablePositions[syllableIndex][0] - 1; + ++syllableIndex; + for (let j = 1; j <= newCharLen; j++) { + positions.push([i - (shift - j), shift - j]); + } + shift -= newCharLen; + shiftOrigin += newCharLen; + } + return p5; } );