Files
DocumentServer-v-9.2.0/sdkjs/word/Editor/Paragraph/RunContent/Text.js
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

771 lines
24 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* (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);