[pdf] Implement the ability to specify pdfText using gid

Also fix the width of pdf text when changing the font size
This commit is contained in:
Ilya Kirillov
2025-12-10 21:12:03 +03:00
parent 5c837ad7e9
commit 76c510ac16
5 changed files with 97 additions and 26 deletions

View File

@ -597,4 +597,5 @@
window['AscCommon'].CTextMeasurer = CTextMeasurer;
window['AscCommon'].g_oTextMeasurer = g_oTextMeasurer;
window['AscCommon'].GetLoadInfoForMeasurer = GetLoadInfoForMeasurer;
window['AscCommon'].getSingleCodePointCalculator = getSingleCodePointCalculator;
})(window);

View File

@ -376,6 +376,14 @@
{
return false;
};
/**
* Является ли данный элемент специальным текстовым элементом для pdf
* @returns {boolean}
*/
CRunElementBase.prototype.IsPdfText = function()
{
return false;
};
/**
* Является ли данный элемент текстовым элементом внутри математического выражения
* @returns {boolean}

View File

@ -269,34 +269,29 @@
window['AscWord'].CRunSpace = CRunSpace;
/**
*
* @param codePoint
* @param width
* @param {number} gid
* @param {number} codePoint
* @param {number} width
* @param {number} fontSize
* @constructor
*/
function CPdfRunSpace(codePoint, width)
function CPdfRunSpace(gid, codePoint, width, fontSize)
{
CRunSpace.call(this, codePoint);
this.specWidth = width;
this.charGid = gid;
this.originWidth = width;
this.originSize = fontSize;
}
CPdfRunSpace.prototype = Object.create(CRunSpace.prototype);
CPdfRunSpace.prototype.constructor = CPdfRunSpace;
CPdfRunSpace.prototype.GetWidth = function()
{
return this.specWidth;
};
CPdfRunSpace.prototype.GetWidthVisible = function()
{
return this.specWidth;
};
CPdfRunSpace.prototype.SetWidth = function()
{
};
CPdfRunSpace.prototype.SetWidthVisible = function()
{
};
CPdfRunSpace.prototype.IsPdfText = AscWord.CPdfRunText.prototype.IsPdfText;
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;
AscWord.CPdfRunSpace = CPdfRunSpace;

View File

@ -772,27 +772,43 @@
window['AscWord'].isCombiningMark = isCombiningMark;
/**
*
* @param codePoint
* @param width
* @param {number} gid
* @param {number} codePoint
* @param {number} width
* @param {number} fontSize
* @constructor
*/
function CPdfRunText(codePoint, width)
function CPdfRunText(gid, codePoint, width, fontSize)
{
CRunText.call(this, codePoint);
this.specWidth = width;
this.charGid = gid;
this.originWidth = width;
this.originSize = (fontSize ? fontSize : 12);
this.originCoeff = 1;
}
CPdfRunText.prototype = Object.create(CRunText.prototype);
CPdfRunText.prototype.constructor = CPdfRunText;
CPdfRunText.prototype.IsPdfText = function()
{
return true;
};
CPdfRunText.prototype.GetGid = function()
{
return this.charGid;
};
CPdfRunText.prototype.GetOriginWidth = function(fontSize)
{
return this.originWidth * fontSize / this.originSize;
};
CPdfRunText.prototype.GetWidth = function()
{
return this.specWidth;
return this.originWidth * this.originCoeff;
};
CPdfRunText.prototype.GetWidthVisible = function()
{
return this.specWidth;
return this.originWidth * this.originCoeff;
};
CPdfRunText.prototype.SetWidth = function()
{
@ -800,7 +816,31 @@
CPdfRunText.prototype.SetWidthVisible = function()
{
};
CPdfRunText.prototype.SetMetrics = function(fontSize, fontSlot, textPr)
{
let fontCoeff = 1;
if (!textPr.Caps
&& textPr.SmallCaps
&& this.Value
&& this.Value !== (String.fromCharCode(this.Value).toUpperCase()).charCodeAt(0))
{
fontCoeff *= smallcaps_Koef;
}
if (textPr.VertAlign !== AscCommon.vertalign_Baseline)
fontCoeff *= AscCommon.vaKSize;
let _fontSize = fontSize * fontCoeff;
fontCoeff *= fontSize / this.originSize;
this.originCoeff = fontCoeff;
this.Flags = (this.Flags & 0xFFFF) | (((_fontSize * 64) & 0xFFFF) << 16);
};
AscWord.CPdfRunText = CPdfRunText;
})(window);

View File

@ -154,6 +154,11 @@
if (oItem.IsSpace())
this.private_HandleSpace(oItem);
}
else if (oItem.IsPdfText())
{
this.FlushWord();
this.private_HandlePdfText(oItem);
}
else if (oItem.IsNBSP())
{
this.FlushWord();
@ -246,6 +251,28 @@
let nSpace = AscCommon.g_oTextMeasurer.GetGraphemeByUnicode(0x0020, oFontInfo.Name, oFontInfo.Style);
this.private_HandleItem(oItem, nGrapheme, AscFonts.GetGraphemeWidth(nSpace), oFontInfo.Size, AscWord.fontslot_ASCII, false, false, false);
};
CParagraphTextShaper.prototype.private_HandlePdfText = function(item)
{
let fontInfo = this.TextPr.GetFontInfo(AscWord.fontslot_ASCII);
let gid = item.GetGid();
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()));
}
else
{
grapheme = AscCommon.g_oTextMeasurer.GetGraphemeByUnicode(item.GetCodePoint(), fontInfo.Name, fontInfo.Style);
}
item.SetGrapheme(grapheme);
item.SetMetrics(fontInfo.Size, AscWord.fontslot_ASCII, this.TextPr);
item.SetCodePointType(AscWord.CODEPOINT_TYPE.BASE);
};
CParagraphTextShaper.prototype.private_HandleItem = function(oItem, nGrapheme, nWidth, nFontSize, nFontSlot, nCodePointType)
{
if (this.Temporary)