/* * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ "use strict"; (function(window) { const FLAGS_MASK = 0xFFFFFFFF; // 4 байта const FLAGS_ASCII = 0x00000000; // В 0-1 битах записан const FLAGS_CS = 0x00000001; // FontSlot (не флагами, а значением const FLAGS_HANSI = 0x00000002; // от 0 до 3) const FLAGS_EASTASIA = 0x00000003; // const FLAGS_FONTKOEF_SMALLCAPS = 0x00000004; // 2 бит const FLAGS_SPACEAFTER = 0x00000008; // 3 бит const FLAGS_CAPITALS = 0x00000010; // 4 бит const FLAGS_LIGATURE = 0x00000020; // 5 бит const FLAGS_LIGATURE_CONTINUE = 0x00000040; // 6 бит const FLAGS_COMBINING_MARK = 0x00000080; // 7 бит const FLAGS_TEMPORARY = 0x00000100; // 8 бит const FLAGS_TEMPORARY_LIGATURE = 0x00000200; // 9 бит const FLAGS_TEMPORARY_LIGATURE_CONTINUE = 0x00000400; // 10 бит const FLAGS_TEMPORARY_COMBINING_MARK = 0x00000800; // 11 бит const FLAGS_VISIBLE_WIDTH = 0x00001000; // 12 бит const FLAGS_GAPS = 0x00002000; // 13 бит const FLAGS_HYPHEN_AFTER = 0x00004000; // 14 const FLAGS_TEMPORARY_HYPHEN_AFTER = 0x00008000; // 15 // Temporary const FLAGS_RTL = 0x02; // 16-31 биты зарезервированы под FontSize const FLAGS_NON_FONTKOEF_SMALLCAPS = FLAGS_MASK ^ FLAGS_FONTKOEF_SMALLCAPS; const FLAGS_NON_SPACEAFTER = FLAGS_MASK ^ FLAGS_SPACEAFTER; const FLAGS_NON_CAPITALS = FLAGS_MASK ^ FLAGS_CAPITALS; const FLAGS_NON_LIGATURE = FLAGS_MASK ^ FLAGS_LIGATURE; const FLAGS_NON_LIGATURE_CONTINUE = FLAGS_MASK ^ FLAGS_LIGATURE_CONTINUE; const FLAGS_NON_COMBINING_MARK = FLAGS_MASK ^ FLAGS_COMBINING_MARK; const FLAGS_NON_TEMPORARY = FLAGS_MASK ^ FLAGS_TEMPORARY; const FLAGS_NON_TEMPORARY_LIGATURE = FLAGS_MASK ^ FLAGS_TEMPORARY_LIGATURE; const FLAGS_NON_TEMPORARY_LIGATURE_CONTINUE = FLAGS_MASK ^ FLAGS_TEMPORARY_LIGATURE_CONTINUE; const FLAGS_NON_VISIBLE_WIDTH = FLAGS_MASK ^ FLAGS_VISIBLE_WIDTH; const FLAGS_NON_TEMPORARY_COMBINING_MARK = FLAGS_MASK ^ FLAGS_TEMPORARY_COMBINING_MARK; const FLAGS_NON_GAPS = FLAGS_MASK ^ FLAGS_GAPS; const FLAGS_NON_HYPHEN_AFTER = FLAGS_MASK ^ FLAGS_HYPHEN_AFTER; const FLAGS_NON_TEMPORARY_HYPHEN_AFTER = FLAGS_MASK ^ FLAGS_TEMPORARY_HYPHEN_AFTER; function CreateNonBreakingHyphen() { let t = new CRunText(0x002D); t.SetSpaceAfter(false); return t; } /** * Символы, которые мы в любом случае считаем комбинированными, даже если текстовый шейпер их не объединил * с предыдущим символом в один глиф * @param nCodePoint {number} * @returns {boolean} */ function isCombiningMark(nCodePoint) { return !!((0x0300 <= nCodePoint && nCodePoint <= 0x036F) || (0x0483 <= nCodePoint && nCodePoint <= 0x0487) || (0x1AB0 <= nCodePoint && nCodePoint <= 0x1ABE) || (0x1CD0 <= nCodePoint && nCodePoint <= 0x1CE0) || (0x1CE2 <= nCodePoint && nCodePoint <= 0x1CE8) || 0x1CED === nCodePoint || 0x1CF4 === nCodePoint || 0x1CF8 === nCodePoint || 0x1CF9 === nCodePoint || (0x1DC0 <= nCodePoint && nCodePoint <= 0x1DFF) || (0x20D0 <= nCodePoint && nCodePoint <= 0x20F0) || (0xFE00 <= nCodePoint && nCodePoint <= 0xFE00) || (0xFE20 <= nCodePoint && nCodePoint <= 0xFE2D) ); } /** * Класс представляющий текстовый символ * @param {Number} nCharCode - Юникодное значение символа * @constructor * @extends {AscWord.CRunElementBase} */ function CRunText(nCharCode) { AscWord.CRunElementBase.call(this); this.Value = undefined !== nCharCode ? nCharCode : 0x00; this.Width = 0x00000000 | 0; this.Flags = 0x00000000 | 0; this.Grapheme = AscFonts.NO_GRAPHEME; this.SetSpaceAfter(this.private_IsSpaceAfter()); this.updateRtlFlag(); if (AscFonts.IsCheckSymbols) AscFonts.FontPickerByCharacter.getFontBySymbol(this.Value); } CRunText.prototype = Object.create(AscWord.CRunElementBase.prototype); CRunText.prototype.constructor = CRunText; CRunText.prototype.Type = para_Text; CRunText.prototype.SetCharCode = function(CharCode) { this.Value = CharCode; this.SetSpaceAfter(this.private_IsSpaceAfter()); this.updateRtlFlag(); if (AscFonts.IsCheckSymbols) AscFonts.FontPickerByCharacter.getFontBySymbol(this.Value); }; CRunText.prototype.GetCharCode = function() { return this.Value; }; CRunText.prototype.GetCodePoint = function() { return this.Value; }; CRunText.prototype.GetScript = function() { return AscFonts.hb_get_script_by_unicode(this.GetCodePoint()); }; CRunText.prototype.SetGrapheme = function(nGrapheme) { this.Grapheme = nGrapheme; }; CRunText.prototype.SetTemporaryGrapheme = function(nGrapheme) { this.Flags |= FLAGS_TEMPORARY; this.TempGrapheme = nGrapheme; }; CRunText.prototype.GetGrapheme = function() { return (this.Flags & FLAGS_TEMPORARY ? this.TempGrapheme : this.Grapheme); }; CRunText.prototype.ResetTemporaryGrapheme = function() { this.Flags &= FLAGS_NON_TEMPORARY; }; CRunText.prototype.SetMetrics = function(nFontSize, nFontSlot, oTextPr) { let nFontCoef = 1; if (undefined !== nFontSlot) { // let nFS = FLAGS_ASCII; // if (nFontSlot & AscWord.fontslot_EastAsia) // nFS = FLAGS_EASTASIA; // else if (nFontSlot & AscWord.fontslot_HAnsi) // nFS = FLAGS_HANSI; // else if (nFontSlot & AscWord.fontslot_CS) // nFS = FLAGS_CS; // // this.Flags = (this.Flags & 0xFFFFFFFC) | nFS; if (oTextPr.Caps || oTextPr.SmallCaps) { this.Flags |= FLAGS_CAPITALS; if (!oTextPr.Caps && this.Value !== (String.fromCharCode(this.Value).toUpperCase()).charCodeAt(0)) this.Flags |= FLAGS_FONTKOEF_SMALLCAPS; else this.Flags &= FLAGS_NON_FONTKOEF_SMALLCAPS; } else { this.Flags &= FLAGS_NON_CAPITALS; this.Flags &= FLAGS_NON_FONTKOEF_SMALLCAPS; } let isCoeffScript = oTextPr.VertAlign !== AscCommon.vertalign_Baseline; if (isCoeffScript && this.Flags & FLAGS_FONTKOEF_SMALLCAPS) nFontCoef = smallcaps_and_script_koef; else if (isCoeffScript) nFontCoef = AscCommon.vaKSize; else if (this.Flags & FLAGS_FONTKOEF_SMALLCAPS) nFontCoef = smallcaps_Koef; } // Разрешенные размеры шрифта только либо целое, либо целое/2. Даже после применения FontKoef, поэтому // мы должны подкрутить коэффициент так, чтобы после домножения на него, у на получался разрешенный размер. let _nFontSize = nFontSize; if (1 !== nFontCoef) _nFontSize = (((_nFontSize * nFontCoef * 2 + 0.5) | 0) / 2); this.Flags = (this.Flags & 0xFFFF) | (((_nFontSize * 64) & 0xFFFF) << 16); }; CRunText.prototype.SetCodePointType = function(nType) { if (nType === AscWord.CODEPOINT_TYPE.LIGATURE) this.Flags |= FLAGS_LIGATURE; else this.Flags &= FLAGS_NON_LIGATURE; if (nType === AscWord.CODEPOINT_TYPE.LIGATURE_CONTINUE) this.Flags |= FLAGS_LIGATURE_CONTINUE; else this.Flags &= FLAGS_NON_LIGATURE_CONTINUE; if (nType === AscWord.CODEPOINT_TYPE.COMBINING_MARK) this.Flags |= FLAGS_COMBINING_MARK; else this.Flags &= FLAGS_NON_COMBINING_MARK; }; CRunText.prototype.SetTemporaryCodePointType = function(nType) { if (nType === AscWord.CODEPOINT_TYPE.LIGATURE) this.Flags |= FLAGS_TEMPORARY_LIGATURE; else this.Flags &= FLAGS_NON_TEMPORARY_LIGATURE; if (nType === AscWord.CODEPOINT_TYPE.LIGATURE_CONTINUE) this.Flags |= FLAGS_TEMPORARY_LIGATURE_CONTINUE; else this.Flags &= FLAGS_NON_TEMPORARY_LIGATURE_CONTINUE; if (nType === AscWord.CODEPOINT_TYPE.COMBINING_MARK) this.Flags |= FLAGS_TEMPORARY_COMBINING_MARK; else this.Flags &= FLAGS_NON_TEMPORARY_COMBINING_MARK; }; CRunText.prototype.GetCodePointType = function() { if (this.Flags & FLAGS_TEMPORARY) { if (this.Flags & FLAGS_TEMPORARY_LIGATURE) return AscWord.CODEPOINT_TYPE.LIGATURE; else if (this.Flags & FLAGS_TEMPORARY_LIGATURE_CONTINUE) return AscWord.CODEPOINT_TYPE.LIGATURE_CONTINUE; else if (this.Flags & FLAGS_TEMPORARY_COMBINING_MARK) return AscWord.CODEPOINT_TYPE.COMBINING_MARK; } else { if (this.Flags & FLAGS_LIGATURE) return AscWord.CODEPOINT_TYPE.LIGATURE; else if (this.Flags & FLAGS_LIGATURE_CONTINUE) return AscWord.CODEPOINT_TYPE.LIGATURE_CONTINUE; else if (this.Flags & FLAGS_COMBINING_MARK) return AscWord.CODEPOINT_TYPE.COMBINING_MARK; } return AscWord.CODEPOINT_TYPE.BASE; }; CRunText.prototype.IsLigature = function() { if (this.Flags & FLAGS_TEMPORARY) return !!(this.Flags & FLAGS_TEMPORARY_LIGATURE); else return !!(this.Flags & FLAGS_LIGATURE); }; CRunText.prototype.GetLigatureWidth = function() { return (AscFonts.GetGraphemeWidth(this.Flags & FLAGS_TEMPORARY ? this.TempGrapheme : this.Grapheme) * (((this.Flags >> 16) & 0xFFFF) / 64)); }; CRunText.prototype.getBidiType = function() { return AscBidi.getType(this.Value); }; CRunText.prototype.GetDirectionFlag = function() { let bidiType = AscBidi.getType(this.Value); if (bidiType & AscBidi.FLAG.STRONG) return (bidiType & AscBidi.FLAG.RTL ? AscBidi.DIRECTION_FLAG.RTL : AscBidi.DIRECTION_FLAG.LTR); else return AscBidi.DIRECTION_FLAG.Other; }; CRunText.prototype.SetWidth = function(nWidth) { this.Width = ((nWidth * (((this.Flags >> 16) & 0xFFFF) / 64)) * AscWord.TEXTWIDTH_DIVIDER) | 0; }; CRunText.prototype.SetTemporaryWidth = function(nWidth) { this.TempWidth = ((nWidth * (((this.Flags >> 16) & 0xFFFF) / 64)) * AscWord.TEXTWIDTH_DIVIDER) | 0; }; CRunText.prototype.SetWidthVisible = function(nWidth, textPr) { if (this.Flags & FLAGS_TEMPORARY_HYPHEN_AFTER) { let fontInfo = textPr.GetFontInfo(AscWord.fontslot_ASCII); nWidth += AscFonts.GetGraphemeWidth(AscCommon.g_oTextMeasurer.GetGraphemeByUnicode(0x002D, fontInfo.Name, fontInfo.Style)) * (((this.Flags >> 16) & 0xFFFF) / 64); } let nW = (nWidth * AscWord.TEXTWIDTH_DIVIDER) | 0; let isTemporary = this.IsTemporary(); if ((isTemporary && this.TempWidth !== nW) || (!isTemporary && this.Width !== nW)) { this.Flags |= FLAGS_VISIBLE_WIDTH; this.WidthVisible = nW; } else { this.Flags &= FLAGS_NON_VISIBLE_WIDTH; } }; CRunText.prototype.GetWidthVisible = function() { let width = 0; if (this.Flags & FLAGS_VISIBLE_WIDTH) width = (this.WidthVisible / AscWord.TEXTWIDTH_DIVIDER); else if (this.Flags & FLAGS_TEMPORARY) width = (this.TempWidth / AscWord.TEXTWIDTH_DIVIDER); else width = (this.Width / AscWord.TEXTWIDTH_DIVIDER); return (width > 0 ? width : 0); }; CRunText.prototype.GetWidth = function(textPr) { let nWidth = (this.Flags & FLAGS_TEMPORARY ? this.TempWidth / AscWord.TEXTWIDTH_DIVIDER : this.Width / AscWord.TEXTWIDTH_DIVIDER); if (textPr && (this.Flags & FLAGS_TEMPORARY_HYPHEN_AFTER)) { let fontInfo = textPr.GetFontInfo(AscWord.fontslot_ASCII); nWidth += AscFonts.GetGraphemeWidth(AscCommon.g_oTextMeasurer.GetGraphemeByUnicode(0x002D, fontInfo.Name, fontInfo.Style)) * (((this.Flags >> 16) & 0xFFFF) / 64); } if (this.Flags & FLAGS_GAPS) nWidth += this.LGap + this.RGap; return (nWidth > 0 ? nWidth : 0); }; CRunText.prototype.GetMeasuredWidth = function() { let nWidth = (this.Flags & FLAGS_TEMPORARY ? this.TempWidth / AscWord.TEXTWIDTH_DIVIDER : this.Width / AscWord.TEXTWIDTH_DIVIDER); return (nWidth > 0 ? nWidth / (((this.Flags >> 16) & 0xFFFF) / 64) : 0); }; CRunText.prototype.Draw = function(X, Y, Context, PDSE, oTextPr, forceGrapheme) { if (Context.m_bIsTextDrawer === true) { Context.CheckAddNewPath(X, Y, this); } if (this.Flags & FLAGS_GAPS) { Context.SaveGrState(); Context.AddClipRect(X, PDSE.LineTop, this.CellW, PDSE.LineBottom - PDSE.LineTop); this.DrawGapsBackground(X, Y, Context, PDSE, oTextPr); X += this.LGap; } let nFontSize = (((this.Flags >> 16) & 0xFFFF) / 64); if (this.IsNBSP()) { this.DrawNonBreakingSpace(Context, X, Y, nFontSize); } else if (this.Flags & FLAGS_TEMPORARY) { if (AscFonts.NO_GRAPHEME !== this.TempGrapheme) AscFonts.DrawGrapheme(this.TempGrapheme, Context, X, Y, nFontSize); } else if (AscFonts.NO_GRAPHEME !== this.Grapheme) { AscFonts.DrawGrapheme(forceGrapheme ? forceGrapheme : this.Grapheme, Context, X, Y, nFontSize); } if (this.Flags & FLAGS_TEMPORARY_HYPHEN_AFTER) this.DrawHyphenAfter(Context, X, Y, nFontSize, oTextPr); if (this.Flags & FLAGS_GAPS) Context.RestoreGrState(); }; CRunText.prototype.DrawNonBreakingSpace = function(Context, X, Y, nFontSize) { if (!editor || !editor.ShowParaMarks) return; let nbspWidth = AscFonts.GetGraphemeWidth(this.Grapheme) * nFontSize; let width = this.Width / AscWord.TEXTWIDTH_DIVIDER; let shift = (width - nbspWidth) / 2; AscFonts.DrawGrapheme(this.Grapheme, Context, X + shift, Y, nFontSize); }; CRunText.prototype.DrawHyphenAfter = function(context, X, Y, fontSize, textPr) { let fontInfo = textPr.GetFontInfo(AscWord.fontslot_ASCII); let graphemeId = AscCommon.g_oTextMeasurer.GetGraphemeByUnicode(0x002D, fontInfo.Name, fontInfo.Style); let shift = this.GetWidth(); AscFonts.DrawGrapheme(graphemeId, context, X + shift, Y, fontSize); }; CRunText.prototype.Measure = function(oMeasurer, oTextPr) { if (this.Flags & FLAGS_GAPS) { this.Flags &= FLAGS_NON_GAPS; this.LGap = 0; this.RGap = 0; this.CellW = 0; } }; CRunText.prototype.CanAddNumbering = function() { return true; }; CRunText.prototype.Copy = function() { let t = new CRunText(this.Value); t.Width = this.Width; t.Flags = this.Flags; t.Grapheme = this.Grapheme; if (this.Flags & FLAGS_TEMPORARY) { t.TempWidth = this.TempWidth; t.TempGrapheme = this.TempGrapheme; } if (this.Flags & FLAGS_VISIBLE_WIDTH) t.WidthVisible = this.WidthVisible; return t; }; CRunText.prototype.IsEqual = function(oElement) { return (oElement.Type === this.Type && this.Value === oElement.Value && this.IsSpaceAfter() === oElement.IsSpaceAfter()); }; CRunText.prototype.IsNBSP = function() { return (this.Value === nbsp_charcode); }; CRunText.prototype.IsPunctuation = function() { return !!(undefined !== AscCommon.g_aPunctuation[this.Value]); }; CRunText.prototype.IsNumber = function() { return this.IsDigit(); }; CRunText.prototype.IsSpaceAfter = function() { return !!(this.Flags & FLAGS_SPACEAFTER); }; CRunText.prototype.IsSpaceBefore = function() { return AscCommon.isEastAsianScript(this.Value); }; CRunText.prototype.isHyphenAfter = function() { return !!(this.Flags & FLAGS_HYPHEN_AFTER); }; CRunText.prototype.SetHyphenAfter = function(isHyphen) { if (isHyphen) this.Flags |= FLAGS_HYPHEN_AFTER; else this.Flags &= FLAGS_NON_HYPHEN_AFTER; }; CRunText.prototype.ResetTemporaryHyphenAfter = function() { this.Flags &= FLAGS_NON_TEMPORARY_HYPHEN_AFTER; }; CRunText.prototype.SetTemporaryHyphenAfter = function(isHyphen) { if (isHyphen) this.Flags |= FLAGS_TEMPORARY_HYPHEN_AFTER; else this.Flags &= FLAGS_NON_TEMPORARY_HYPHEN_AFTER; }; CRunText.prototype.IsTemporaryHyphenAfter = function() { return !!(this.Flags & FLAGS_TEMPORARY_HYPHEN_AFTER); }; /** * Получаем символ для проверки орфографии * @param bCaps {boolean} * @return {string} */ CRunText.prototype.GetCharForSpellCheck = function(bCaps) { // Закрывающуюся кавычку (0x2019), посылаем как апостроф if (0x2019 === this.Value) return String.fromCharCode(0x0027); else { if (true === bCaps) return (String.fromCharCode(this.Value)).toUpperCase(); else return String.fromCharCode(this.Value); } }; CRunText.prototype.SetSpaceAfter = function(bSpaceAfter) { if (bSpaceAfter) this.Flags |= FLAGS_SPACEAFTER; else this.Flags &= FLAGS_NON_SPACEAFTER; }; CRunText.prototype.updateRtlFlag = function() { let isRtl = AscFonts.isRtlScript(this.Value); if (isRtl) this.Flags |= FLAGS_RTL; else this.Flags &= ~FLAGS_RTL; }; CRunText.prototype.IsNoBreakHyphen = function() { return (false === this.IsSpaceAfter() && this.Value === 0x002D); }; CRunText.prototype.Write_ToBinary = function(Writer) { // Long : Type // Long : Value // Bool : SpaceAfter Writer.WriteLong(para_Text); Writer.WriteLong(this.Value); Writer.WriteBool(this.IsSpaceAfter()); }; CRunText.prototype.Read_FromBinary = function(Reader) { this.SetCharCode(Reader.GetLong()); this.SetSpaceAfter(Reader.GetBool()); }; CRunText.prototype.private_IsSpaceAfter = function() { // Дефисы if (0x002D === this.Value || 0x2014 === this.Value) return true; if (AscCommon.isEastAsianScript(this.Value) && this.CanBeAtEndOfLine()) return true; return false; }; CRunText.prototype.CanBeAtBeginOfLine = function() { if (this.IsNBSP()) return false; return (!(AscCommon.g_aPunctuation[this.Value] & AscCommon.PUNCTUATION_FLAG_CANT_BE_AT_BEGIN)); }; CRunText.prototype.CanBeAtEndOfLine = function() { if (this.IsNBSP()) return false; return (!(AscCommon.g_aPunctuation[this.Value] & AscCommon.PUNCTUATION_FLAG_CANT_BE_AT_END)); }; CRunText.prototype.GetAutoCorrectFlags = function() { // 33 ! // 34 " // 39 ' // 45 - // 58 : // 59 ; // 63 ? if (33 === this.Value || 34 === this.Value || 39 === this.Value || 45 === this.Value || 58 === this.Value || 59 === this.Value || 63 === this.Value) return AscWord.AUTOCORRECT_FLAGS_ALL; // /,\,@ - исключения, на них мы не должны стартовать атозамену первой буквы предложения if ((this.IsPunctuation() || this.IsNumber()) && 92 !== this.Value && 47 !== this.Value && 64 !== this.Value) return AscWord.AUTOCORRECT_FLAGS_FIRST_LETTER_SENTENCE | AscWord.AUTOCORRECT_FLAGS_HYPHEN_WITH_DASH; return AscWord.AUTOCORRECT_FLAGS_NONE; }; CRunText.prototype.IsDot = function() { return (this.Value === 0x002E); }; CRunText.prototype.IsExclamationMark = function() { return (this.Value === 0x0021); }; CRunText.prototype.IsQuestionMark = function() { return (this.Value === 0x003F); }; CRunText.prototype.IsHyphen = function() { return (this.Value === 0x002D); }; CRunText.prototype.IsLetter = function() { return (!this.IsPunctuation() && !this.IsNumber() && !this.IsNBSP()); }; CRunText.prototype.IsDigit = function() { return AscCommon.IsDigit(this.Value); }; CRunText.prototype.ToSearchElement = function(oProps) { if (0x2D === this.Value && !this.IsSpaceAfter()) return new AscCommonWord.CSearchTextSpecialNonBreakingHyphen(); if (!oProps.IsMatchCase()) return new AscCommonWord.CSearchTextItemChar(String.fromCodePoint(this.Value).toLowerCase().codePointAt(0)); return new AscCommonWord.CSearchTextItemChar(this.Value); }; CRunText.prototype.ToMathElement = function() { if (38 === this.Value) return new CMathAmp(); let oText = new CMathText(); oText.add(this.Value); return oText; }; CRunText.prototype.IsText = function() { return true; }; CRunText.prototype.GetFontSlot = function(oTextPr) { return AscWord.GetFontSlotByTextPr(this.Value, oTextPr); }; CRunText.prototype.IsCombiningMark = function() { return (!!(this.Flags & FLAGS_TEMPORARY ? this.Flags & FLAGS_TEMPORARY_COMBINING_MARK : this.Flags & FLAGS_COMBINING_MARK) || isCombiningMark(this.Value)); }; CRunText.prototype.IsLigatureContinue = function() { if (this.Flags & FLAGS_TEMPORARY) return !!(this.Flags & FLAGS_TEMPORARY_LIGATURE_CONTINUE); else return !!(this.Flags & FLAGS_LIGATURE_CONTINUE); }; CRunText.prototype.IsTemporary = function() { return !!(this.Flags & FLAGS_TEMPORARY); }; CRunText.prototype.IsNeedSaveRecalculateObject = function() { return true; }; CRunText.prototype.SaveRecalculateObject = function() { let state = [this.Flags, this.Grapheme, this.Width]; if (this.Flags & FLAGS_TEMPORARY) { state.push(this.TempGrapheme); state.push(this.TempWidth); } if (this.Flags & FLAGS_VISIBLE_WIDTH) { state.push(this.WidthVisible); } if (this.Flags & FLAGS_GAPS) { state.push(this.LGap); state.push(this.RGap); state.push(this.CellW); state.push(this.RGapCount); state.push(this.RGapCharCode); state.push(this.RGapCharWidth); state.push(this.RGapShift); state.push(this.RGapFontSlot); state.push(this.RGapFont); } return state; }; CRunText.prototype.LoadRecalculateObject = function(oState) { if (!oState || oState.length < 3) return; let nPos = 0; this.Flags = oState[nPos++]; this.Grapheme = oState[nPos++]; this.Width = oState[nPos++]; if (this.Flags & FLAGS_TEMPORARY) { this.TempGrapheme = oState[nPos++]; this.TempWidth = oState[nPos++]; } if (this.Flags & FLAGS_VISIBLE_WIDTH) { this.WidthVisible = oState[nPos++]; } if (this.Flags & FLAGS_GAPS) { this.LGap = oState[nPos++]; this.RGap = oState[nPos++]; this.CellW = oState[nPos++]; this.RGapCount = oState[nPos++]; this.RGapCharCode = oState[nPos++]; this.RGapCharWidth = oState[nPos++]; this.RGapShift = oState[nPos++]; this.RGapFontSlot = oState[nPos++]; this.RGapFont = oState[nPos++]; } }; CRunText.prototype.GetCombWidth = function() { return (AscFonts.GetGraphemeWidth(this.Grapheme) * (((this.Flags >> 16) & 0xFFFF) / 64)); }; CRunText.prototype.SetGaps = function(nLeftGap, nRightGap, nCellWidth) { this.Flags &= FLAGS_NON_TEMPORARY; this.Flags &= FLAGS_NON_VISIBLE_WIDTH; this.Flags |= FLAGS_GAPS; this.LGap = nLeftGap; this.RGap = nRightGap; this.CellW = nCellWidth; }; //--------------------------------------------------------export---------------------------------------------------- window['AscWord'] = window['AscWord'] || {}; window['AscWord'].CRunText = CRunText; window['AscWord'].CreateNonBreakingHyphen = CreateNonBreakingHyphen; window['AscWord'].isCombiningMark = isCombiningMark; })(window);