From 695475a036130545d13745f416debe72546d5ff1 Mon Sep 17 00:00:00 2001 From: oneweek-lee Date: Thu, 16 Apr 2026 19:44:14 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[react-pdf]=20text=20layer=EC=99=80=20canva?= =?UTF-8?q?s=20=EC=9C=84=EC=B9=98=20=EB=B6=88=EC=9D=BC=EC=B9=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CSS: line-height: 1, text-size-adjust: none 추가 (pdfjs-dist 공식 구현 기준) - CSS: transform-origin을 0% 0%로 변경 - merge: text item 간 gap을 width에 포함하여 visual span 정확도 개선 - tokenize: 매직 넘버(+5, +3.5, 4.5) 제거, 비례 분할 방식으로 변경 Closes common-fe/pie/discussions/3483 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/components/layer/Text.module.scss | 6 ++- packages/react-pdf/src/utils/text.ts | 37 ++++++++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/packages/react-pdf/src/components/layer/Text.module.scss b/packages/react-pdf/src/components/layer/Text.module.scss index 563e9135..4c33a5ba 100644 --- a/packages/react-pdf/src/components/layer/Text.module.scss +++ b/packages/react-pdf/src/components/layer/Text.module.scss @@ -1,12 +1,16 @@ .text-layer { pointer-events: none; + line-height: 1; + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + text-size-adjust: none; } .text-layer-item { height: 1em; font-family: sans-serif; position: absolute; - transform-origin: left bottom; + transform-origin: 0% 0%; white-space: pre; pointer-events: all; } diff --git a/packages/react-pdf/src/utils/text.ts b/packages/react-pdf/src/utils/text.ts index f7cc237e..5bd9c255 100644 --- a/packages/react-pdf/src/utils/text.ts +++ b/packages/react-pdf/src/utils/text.ts @@ -3,19 +3,27 @@ import type {TextItem, TextMarkedContent} from 'pdfjs-dist/types/src/display/api function tokenizeTextItems(texts: TextItem[]) { return texts.reduce((result, textItem) => { const {str, width, transform, ...rest} = textItem - const splittedStr = str.split(' ') - const strLength = str.length - const tokenizedStr = splittedStr.reduce((calculatedStr, s) => { - const currentStrWidth = s.trim().length === 0 ? 4.5 : Math.ceil((width / strLength) * s.length) + 5 - const reducedStrsLength = calculatedStr.length - const {width: lastWidth, transform: lastTransform} = - reducedStrsLength === 0 ? {width: 0, transform: [...transform]} : calculatedStr[reducedStrsLength - 1] - const newTransform = [...lastTransform] - newTransform[4] += lastWidth + (reducedStrsLength === 0 ? 0 : 3.5) - calculatedStr.push({str: s, width: currentStrWidth, transform: newTransform, ...rest}) - return calculatedStr + const words = str.split(' ') + const totalChars = str.length + + if (totalChars === 0) { + return result + } + + const charWidth = width / totalChars + let charOffset = 0 + + const tokenized = words.reduce((acc, word, wordIndex) => { + if (word.length > 0) { + const newTransform = [...transform] + newTransform[4] += charWidth * charOffset + acc.push({str: word, width: charWidth * word.length, transform: newTransform, ...rest}) + } + charOffset += word.length + (wordIndex < words.length - 1 ? 1 : 0) + return acc }, [] as TextItem[]) - return [...result, ...tokenizedStr] + + return [...result, ...tokenized] }, [] as TextItem[]) } @@ -31,8 +39,11 @@ export function mergeTextItems(texts: (TextItem | TextMarkedContent)[], options? const prev = result[result.length - 1] // y 값을 비교하여, 같은 줄인지 확인 if (prev.transform[5] === token.transform[5]) { + // item 간 gap을 포함한 전체 visual span 계산 + const prevEndX = prev.transform[4] + prev.width + const gap = token.transform[4] - prevEndX prev.str = prev.str + token.str - prev.width = prev.width + token.width + prev.width = prev.width + Math.max(0, gap) + token.width } else { result.push(token) } From 08036d11d332895ded9960f00a9c13ad564e73f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=9C=EC=A3=BC?= Date: Thu, 16 Apr 2026 19:48:07 +0900 Subject: [PATCH 2/2] Fix text layer and canvas position mismatch in react-pdf Fixes the mismatch between the text layer and canvas in react-pdf. --- .changeset/purple-clowns-wash.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/purple-clowns-wash.md diff --git a/.changeset/purple-clowns-wash.md b/.changeset/purple-clowns-wash.md new file mode 100644 index 00000000..73e80b5d --- /dev/null +++ b/.changeset/purple-clowns-wash.md @@ -0,0 +1,7 @@ +--- +"@naverpay/react-pdf": patch +--- + +[react-pdf] text layer와 canvas 위치 불일치 수정 + +PR: [[react-pdf] text layer와 canvas 위치 불일치 수정](https://github.com/NaverPayDev/pie/pull/221)