From 31262cf58ddb02522eb61fe3fbc8024f365ce4f0 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 11 Dec 2025 15:02:04 +0300 Subject: [PATCH] [pdf] Use font metrics for pdf text if the width isn't specified --- common/libfont/textmeasurer.js | 32 ++++++++++++++++++++++- word/Editor/Paragraph/RunContent/Space.js | 8 ++++-- word/Editor/Paragraph/RunContent/Text.js | 15 ++++++----- word/Editor/Paragraph/TextShaper.js | 28 +++++++++----------- 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/common/libfont/textmeasurer.js b/common/libfont/textmeasurer.js index c20980a5f7..9e415e64e6 100644 --- a/common/libfont/textmeasurer.js +++ b/common/libfont/textmeasurer.js @@ -178,6 +178,37 @@ AscFonts.AddGlyphToGrapheme(nGID, oGlyph.fAdvanceX * 64, 0, 0, 0); return AscFonts.GetGrapheme(getSingleCodePointCalculator(codePoint)); }, + + GetGraphemeByGid : function(gid, fontName, fontStyle, codePoint) + { + this.SetFontInternal(fontName, AscFonts.MEASURE_FONTSIZE, fontStyle); + + let font = this.m_oManager.m_oFont; + if (!font) + { + font = this.GetFontBySymbol(gid).Font; + //return AscFonts.NO_GRAPHEME; + } + + let stringGid = true; + if (!font.GetStringGID()) + { + font.SetStringGID(true); + stringGid = false; + } + + let glyph = font.GetChar(gid); + + if (!stringGid) + font.SetStringGID(false); + + if (!glyph) + return AscFonts.NO_GRAPHEME; + + AscFonts.InitGrapheme(AscCommon.FontNameMap.GetId(fontName), fontStyle); + AscFonts.AddGlyphToGrapheme(gid, glyph.fAdvanceX * 64, 0, 0, 0); + return AscFonts.GetGrapheme(getSingleCodePointCalculator(codePoint)); + }, SetTextPr : function(textPr, theme) { @@ -597,5 +628,4 @@ window['AscCommon'].CTextMeasurer = CTextMeasurer; window['AscCommon'].g_oTextMeasurer = g_oTextMeasurer; window['AscCommon'].GetLoadInfoForMeasurer = GetLoadInfoForMeasurer; - window['AscCommon'].getSingleCodePointCalculator = getSingleCodePointCalculator; })(window); diff --git a/word/Editor/Paragraph/RunContent/Space.js b/word/Editor/Paragraph/RunContent/Space.js index 47d66c68a8..ad9af5eb56 100644 --- a/word/Editor/Paragraph/RunContent/Space.js +++ b/word/Editor/Paragraph/RunContent/Space.js @@ -287,11 +287,15 @@ CPdfRunSpace.prototype.constructor = CPdfRunSpace; CPdfRunSpace.prototype.IsPdfText = AscWord.CPdfRunText.prototype.IsPdfText; + CPdfRunSpace.prototype.GetGid = AscWord.CPdfRunText.prototype.GetGid; + CPdfRunSpace.prototype.GetOriginWidth = AscWord.CPdfRunText.prototype.GetOriginWidth; CPdfRunSpace.prototype.GetWidth = AscWord.CPdfRunText.prototype.GetWidth; CPdfRunSpace.prototype.GetWidthVisible = AscWord.CPdfRunText.prototype.GetWidthVisible; - CPdfRunSpace.prototype.SetWidth = AscWord.CPdfRunText.prototype.SetWidth; - CPdfRunSpace.prototype.SetWidthVisible = AscWord.CPdfRunText.prototype.SetWidthVisible; CPdfRunSpace.prototype.SetMetrics = AscWord.CPdfRunText.prototype.SetMetrics; + CPdfRunSpace.prototype.SetGrapheme = function() + { + this.Grapheme = AscFonts.NO_GRAPHEME; + }; AscWord.CPdfRunSpace = CPdfRunSpace; diff --git a/word/Editor/Paragraph/RunContent/Text.js b/word/Editor/Paragraph/RunContent/Text.js index 000bf6cb23..5c9d62e744 100644 --- a/word/Editor/Paragraph/RunContent/Text.js +++ b/word/Editor/Paragraph/RunContent/Text.js @@ -783,9 +783,10 @@ CRunText.call(this, codePoint); this.charGid = gid; - this.originWidth = width; - this.originSize = (fontSize ? fontSize : 12); + this.originWidth = width ? width : 0; + this.originSize = fontSize ? fontSize : 0; this.originCoeff = 1; + this.fontSize = this.originSize; } CPdfRunText.prototype = Object.create(CRunText.prototype); CPdfRunText.prototype.constructor = CPdfRunText; @@ -804,17 +805,15 @@ }; CPdfRunText.prototype.GetWidth = function() { - return this.originWidth * this.originCoeff; + return this.originSize ? this.originWidth * this.originCoeff : this.Width / AscWord.TEXTWIDTH_DIVIDER; }; CPdfRunText.prototype.GetWidthVisible = function() { - return this.originWidth * this.originCoeff; - }; - CPdfRunText.prototype.SetWidth = function() - { + return this.originSize ? this.originWidth * this.originCoeff : this.Width / AscWord.TEXTWIDTH_DIVIDER; }; CPdfRunText.prototype.SetWidthVisible = function() { + }; CPdfRunText.prototype.SetMetrics = function(fontSize, fontSlot, textPr) { @@ -833,6 +832,8 @@ let _fontSize = fontSize * fontCoeff; + this.fontSize = _fontSize; + fontCoeff *= fontSize / this.originSize; this.originCoeff = fontCoeff; diff --git a/word/Editor/Paragraph/TextShaper.js b/word/Editor/Paragraph/TextShaper.js index 2f98246829..e2de26e512 100644 --- a/word/Editor/Paragraph/TextShaper.js +++ b/word/Editor/Paragraph/TextShaper.js @@ -148,17 +148,17 @@ for (let nPos = nStartPos; nPos < nEndPos; ++nPos) { let oItem = oRun.GetElement(nPos); - if (!oItem.IsText()) + if (oItem.IsPdfText()) + { + this.FlushWord(); + this.private_HandlePdfText(oItem); + } + else if (!oItem.IsText()) { this.FlushWord(); if (oItem.IsSpace()) this.private_HandleSpace(oItem); } - else if (oItem.IsPdfText()) - { - this.FlushWord(); - this.private_HandlePdfText(oItem); - } else if (oItem.IsNBSP()) { this.FlushWord(); @@ -258,20 +258,18 @@ let grapheme; if (gid) - { - let originWidth = item.GetOriginWidth(AscFonts.MEASURE_FONTSIZE); - AscFonts.InitGrapheme(AscCommon.FontNameMap.GetId(fontInfo.Name), fontInfo.Style); - AscFonts.AddGlyphToGrapheme(gid, originWidth * 64, 0, 0, 0); - grapheme = AscFonts.GetGrapheme(AscCommon.getSingleCodePointCalculator(item.GetCodePoint())); - } + grapheme = AscCommon.g_oTextMeasurer.GetGraphemeByGid(gid, fontInfo.Name, fontInfo.Style, item.GetCodePoint()); else - { grapheme = AscCommon.g_oTextMeasurer.GetGraphemeByUnicode(item.GetCodePoint(), fontInfo.Name, fontInfo.Style); - } + + let width = AscFonts.GetGraphemeWidth(grapheme); item.SetGrapheme(grapheme); item.SetMetrics(fontInfo.Size, AscWord.fontslot_ASCII, this.TextPr); - item.SetCodePointType(AscWord.CODEPOINT_TYPE.BASE); + item.SetWidth(width, this.TextPr, width); + + if (item.IsText()) + item.SetCodePointType(AscWord.CODEPOINT_TYPE.BASE); }; CParagraphTextShaper.prototype.private_HandleItem = function(oItem, nGrapheme, nWidth, nFontSize, nFontSlot, nCodePointType) {