272 lines
8.5 KiB
JavaScript
272 lines
8.5 KiB
JavaScript
/*
|
||
* (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 = 0xFF;
|
||
const FLAGS_FONTKOEF_SCRIPT = 0x01;
|
||
const FLAGS_FONTKOEF_SMALLCAPS = 0x02;
|
||
const FLAGS_GAPS = 0x04;
|
||
|
||
// 16-31 биты зарезервированы под FontSize
|
||
|
||
const FLAGS_NON_FONTKOEF_SCRIPT = FLAGS_MASK ^ FLAGS_FONTKOEF_SCRIPT;
|
||
const FLAGS_NON_FONTKOEF_SMALLCAPS = FLAGS_MASK ^ FLAGS_FONTKOEF_SMALLCAPS;
|
||
const FLAGS_NON_GAPS = FLAGS_MASK ^ FLAGS_GAPS;
|
||
|
||
/**
|
||
* Класс представляющий пробелбный символ
|
||
* @param {number} [nCharCode=0x20] - Юникодное значение символа
|
||
* @constructor
|
||
* @extends {AscWord.CRunElementBase}
|
||
*/
|
||
function CRunSpace(nCharCode)
|
||
{
|
||
AscWord.CRunElementBase.call(this);
|
||
|
||
this.Value = undefined !== nCharCode ? nCharCode : 0x20;
|
||
this.Flags = 0x00000000 | 0;
|
||
this.Width = 0x00000000 | 0;
|
||
this.WidthVisible = 0x00000000 | 0;
|
||
this.WidthOrigin = 0x00000000 | 0;
|
||
this.Grapheme = AscFonts.NO_GRAPHEME;
|
||
|
||
if (AscFonts.IsCheckSymbols)
|
||
AscFonts.FontPickerByCharacter.getFontBySymbol(this.Value);
|
||
}
|
||
CRunSpace.prototype = Object.create(AscWord.CRunElementBase.prototype);
|
||
CRunSpace.prototype.constructor = CRunSpace;
|
||
|
||
CRunSpace.prototype.Type = para_Space;
|
||
CRunSpace.prototype.IsSpace = function()
|
||
{
|
||
return true;
|
||
};
|
||
CRunSpace.prototype.SetWidth = function(width)
|
||
{
|
||
this.Width = ((width * (((this.Flags >> 16) & 0xFFFF) / 64)) * AscWord.TEXTWIDTH_DIVIDER) | 0;
|
||
};
|
||
CRunSpace.prototype.GetWidth = function()
|
||
{
|
||
let nWidth = (this.Width / AscWord.TEXTWIDTH_DIVIDER);
|
||
|
||
if (this.Flags & FLAGS_GAPS)
|
||
nWidth += this.LGap + this.RGap;
|
||
|
||
return (nWidth > 0 ? nWidth : 0);
|
||
};
|
||
CRunSpace.prototype.GetCodePoint = function()
|
||
{
|
||
return this.Value;
|
||
};
|
||
CRunSpace.prototype.getBidiType = function()
|
||
{
|
||
return AscBidi.TYPE.WS;
|
||
};
|
||
CRunSpace.prototype.SetGrapheme = function(grapheme)
|
||
{
|
||
this.Grapheme = grapheme;
|
||
};
|
||
CRunSpace.prototype.SetMetrics = function(fontSize, fontSlot, textPr)
|
||
{
|
||
this.SetScriptFlag(textPr.VertAlign !== AscCommon.vertalign_Baseline);
|
||
this.SetSmallCapsFlag(!textPr.Caps && textPr.SmallCaps);
|
||
let fontCoef = this.GetFontCoef();
|
||
// Разрешенные размеры шрифта только либо целое, либо целое/2. Даже после применения fontCoef, поэтому
|
||
// мы должны подкрутить коэффициент так, чтобы после домножения на него, у на получался разрешенный размер.
|
||
fontSize = (((fontSize * fontCoef * 2 + 0.5) | 0) / 2);
|
||
this.Flags = (this.Flags & 0xFFFF) | (((fontSize * 64) & 0xFFFF) << 16);
|
||
};
|
||
CRunSpace.prototype.Draw = function(X, Y, Context, PDSE, oTextPr)
|
||
{
|
||
if (this.Flags & FLAGS_GAPS)
|
||
{
|
||
this.DrawGapsBackground(X, Y, Context, PDSE, oTextPr);
|
||
X += this.LGap;
|
||
}
|
||
|
||
if(Context.m_bIsTextDrawer)
|
||
{
|
||
Context.CheckSpaceDraw(this);
|
||
}
|
||
|
||
if (AscFonts.NO_GRAPHEME !== this.Grapheme)
|
||
{
|
||
let fontSize = (((this.Flags >> 16) & 0xFFFF) / 64);
|
||
AscFonts.DrawGrapheme(this.Grapheme, Context, X, Y, fontSize);
|
||
}
|
||
else if (undefined !== editor && editor.ShowParaMarks)
|
||
{
|
||
Context.SetFontSlot(AscWord.fontslot_ASCII, this.GetFontCoef());
|
||
|
||
if (this.SpaceGap)
|
||
X += this.SpaceGap;
|
||
|
||
if (0x2003 === this.Value || 0x2002 === this.Value)
|
||
Context.FillText(X, Y, String.fromCharCode(0x00B0));
|
||
else if (0x2005 === this.Value)
|
||
Context.FillText(X, Y, String.fromCharCode(0x007C));
|
||
else
|
||
Context.FillText(X, Y, String.fromCharCode(0x00B7));
|
||
}
|
||
};
|
||
CRunSpace.prototype.SetWidth = function(width, textPr, enWidth)
|
||
{
|
||
let fontSize = (((this.Flags >> 16) & 0xFFFF) / 64);
|
||
let Temp = width * fontSize;
|
||
|
||
var ResultWidth = (Math.max((Temp + textPr.Spacing), 0) * AscWord.TEXTWIDTH_DIVIDER) | 0;
|
||
this.Width = ResultWidth;
|
||
this.WidthOrigin = ResultWidth;
|
||
|
||
if (Math.abs(Temp) > 0.001)
|
||
this.WidthEn = (ResultWidth * enWidth / width) | 0;
|
||
else
|
||
this.WidthEn = ResultWidth;
|
||
|
||
if (0x2003 === this.Value || 0x2002 === this.Value || 0x2005 === this.Value)
|
||
{
|
||
g_oTextMeasurer.SetTextPr(textPr);
|
||
g_oTextMeasurer.SetFontSlot(AscWord.fontslot_ASCII, this.GetFontCoef());
|
||
let code = 0x2005 === this.Value ? 0x007C : 0x00B0;
|
||
this.SpaceGap = Math.max((Temp - g_oTextMeasurer.MeasureCode(code).Width) / 2, 0);
|
||
}
|
||
else if (undefined !== this.SpaceGap)
|
||
{
|
||
this.SpaceGap = 0;
|
||
}
|
||
|
||
// Не меняем здесь WidthVisible, это значение для пробела высчитывается отдельно, и не должно меняться при пересчете
|
||
};
|
||
CRunSpace.prototype.Measure = function(Context, TextPr)
|
||
{
|
||
if (this.Flags & FLAGS_GAPS)
|
||
{
|
||
this.Flags &= FLAGS_NON_GAPS;
|
||
this.LGap = 0;
|
||
this.RGap = 0;
|
||
}
|
||
};
|
||
CRunSpace.prototype.GetFontCoef = function()
|
||
{
|
||
if (this.Flags & FLAGS_FONTKOEF_SCRIPT && this.Flags & FLAGS_FONTKOEF_SMALLCAPS)
|
||
return smallcaps_and_script_koef;
|
||
else if (this.Flags & FLAGS_FONTKOEF_SCRIPT)
|
||
return AscCommon.vaKSize;
|
||
else if (this.Flags & FLAGS_FONTKOEF_SMALLCAPS)
|
||
return smallcaps_Koef;
|
||
else
|
||
return 1;
|
||
};
|
||
CRunSpace.prototype.SetScriptFlag = function(isScript)
|
||
{
|
||
if (isScript)
|
||
this.Flags |= FLAGS_FONTKOEF_SCRIPT;
|
||
else
|
||
this.Flags &= FLAGS_NON_FONTKOEF_SCRIPT;
|
||
};
|
||
CRunSpace.prototype.SetSmallCapsFlag = function(isSmallCaps)
|
||
{
|
||
if (isSmallCaps)
|
||
this.Flags |= FLAGS_FONTKOEF_SMALLCAPS;
|
||
else
|
||
this.Flags &= FLAGS_NON_FONTKOEF_SMALLCAPS;
|
||
};
|
||
CRunSpace.prototype.CanAddNumbering = function()
|
||
{
|
||
return true;
|
||
};
|
||
CRunSpace.prototype.Copy = function()
|
||
{
|
||
return new CRunSpace(this.Value);
|
||
};
|
||
CRunSpace.prototype.Write_ToBinary = function(Writer)
|
||
{
|
||
// Long : Type
|
||
// Long : Value
|
||
|
||
Writer.WriteLong(para_Space);
|
||
Writer.WriteLong(this.Value);
|
||
};
|
||
CRunSpace.prototype.Read_FromBinary = function(Reader)
|
||
{
|
||
this.Value = Reader.GetLong();
|
||
};
|
||
CRunSpace.prototype.GetAutoCorrectFlags = function()
|
||
{
|
||
return AscWord.AUTOCORRECT_FLAGS_ALL;
|
||
};
|
||
CRunSpace.prototype.SetCondensedWidth = function(nKoef)
|
||
{
|
||
this.Width = this.WidthOrigin * nKoef;
|
||
};
|
||
CRunSpace.prototype.ResetCondensedWidth = function()
|
||
{
|
||
this.Width = this.WidthOrigin;
|
||
};
|
||
CRunSpace.prototype.BalanceSingleByteDoubleByteWidth = function()
|
||
{
|
||
// ea-space doesn't need to be balanced (bug 58483)
|
||
if (this.Value === 0x3000)
|
||
return;
|
||
|
||
this.Width = this.WidthEn;
|
||
};
|
||
CRunSpace.prototype.SetGaps = function(nLeftGap, nRightGap, nCellWidth)
|
||
{
|
||
this.Flags |= FLAGS_GAPS;
|
||
|
||
this.LGap = nLeftGap;
|
||
this.RGap = nRightGap;
|
||
};
|
||
CRunSpace.prototype.ToSearchElement = function(oProps)
|
||
{
|
||
return new AscCommonWord.CSearchTextItemChar(0x20);
|
||
};
|
||
CRunSpace.prototype.GetFontSlot = function(oTextPr)
|
||
{
|
||
return AscWord.fontslot_Unknown;
|
||
};
|
||
CRunSpace.prototype.ToMathElement = function()
|
||
{
|
||
let oSpace = new CMathText();
|
||
oSpace.add(0x0020);
|
||
return oSpace;
|
||
};
|
||
//--------------------------------------------------------export----------------------------------------------------
|
||
window['AscWord'] = window['AscWord'] || {};
|
||
window['AscWord'].CRunSpace = CRunSpace;
|
||
|
||
})(window);
|