Files
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

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);