550 lines
15 KiB
JavaScript
550 lines
15 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 CMathLimitPr(ctrPr)
|
||
{
|
||
this.type = LIMIT_LOW;
|
||
this.ctrPr = new CMathCtrlPr(ctrPr);
|
||
}
|
||
|
||
CMathLimitPr.prototype.GetRPr = function ()
|
||
{
|
||
return this.ctrPr.GetRPr();
|
||
}
|
||
|
||
CMathLimitPr.prototype.Set_FromObject = function(Obj)
|
||
{
|
||
if (undefined !== Obj.type && null !== Obj.type)
|
||
this.type = Obj.type;
|
||
|
||
this.ctrPr.SetRPr(Obj.ctrPrp);
|
||
};
|
||
|
||
CMathLimitPr.prototype.Copy = function()
|
||
{
|
||
var NewPr = new CMathLimitPr();
|
||
NewPr.type = this.type;
|
||
NewPr.ctrPr = this.ctrPr;
|
||
return NewPr;
|
||
};
|
||
|
||
CMathLimitPr.prototype.Write_ToBinary = function(Writer)
|
||
{
|
||
// Long : type
|
||
Writer.WriteLong(this.type);
|
||
Writer.WriteBool(true);
|
||
this.ctrPr.Write_ToBinary(Writer);
|
||
};
|
||
|
||
CMathLimitPr.prototype.Read_FromBinary = function(Reader)
|
||
{
|
||
// Long : type
|
||
this.type = Reader.GetLong();
|
||
if (Reader.GetBool())
|
||
{
|
||
this.ctrPr.Read_FromBinary(Reader);
|
||
}
|
||
};
|
||
|
||
/**
|
||
*
|
||
* @param bInside
|
||
* @param Type
|
||
* @param FName
|
||
* @param Iterator
|
||
* @constructor
|
||
* @extends {CMathBase}
|
||
*/
|
||
function CLimitPrimary(bInside, Type, FName, Iterator)
|
||
{
|
||
CMathBase.call(this, bInside);
|
||
|
||
this.Type = Type;
|
||
this.FName = null;
|
||
this.Iterator = null;
|
||
|
||
this.init(FName, Iterator);
|
||
}
|
||
CLimitPrimary.prototype = Object.create(CMathBase.prototype);
|
||
CLimitPrimary.prototype.constructor = CLimitPrimary;
|
||
CLimitPrimary.prototype.kind = MATH_PRIMARY_LIMIT;
|
||
CLimitPrimary.prototype.init = function(FName, Iterator)
|
||
{
|
||
this.setDimension(2, 1);
|
||
|
||
if(this.Type == LIMIT_LOW)
|
||
{
|
||
this.FName = FName;
|
||
this.Iterator = new CDenominator(Iterator);
|
||
|
||
this.elements[0][0] = this.FName;
|
||
this.elements[1][0] = this.Iterator;
|
||
}
|
||
else
|
||
{
|
||
this.Iterator = Iterator;
|
||
this.FName = FName;
|
||
|
||
this.elements[0][0] = this.Iterator;
|
||
this.elements[1][0] = this.FName;
|
||
}
|
||
};
|
||
CLimitPrimary.prototype.PreRecalc = function(Parent, ParaMath, ArgSize, RPI, GapsInfo)
|
||
{
|
||
this.Parent = Parent;
|
||
this.ParaMath = ParaMath;
|
||
|
||
this.Set_CompiledCtrPrp(Parent, ParaMath, RPI);
|
||
|
||
if(this.bInside == false)
|
||
GapsInfo.setGaps(this, this.TextPrControlLetter.FontSize);
|
||
|
||
this.FName.PreRecalc(this, ParaMath, ArgSize, RPI);
|
||
|
||
var ArgSzIter = ArgSize.Copy();
|
||
ArgSzIter.Decrease();
|
||
|
||
var bDecreasedComp = RPI.bDecreasedComp;
|
||
RPI.bDecreasedComp = true;
|
||
|
||
this.Iterator.PreRecalc(this, ParaMath, ArgSzIter, RPI);
|
||
|
||
RPI.bDecreasedComp = bDecreasedComp;
|
||
};
|
||
CLimitPrimary.prototype.Resize = function(oMeasure, RPI)
|
||
{
|
||
this.FName.Resize(oMeasure, RPI);
|
||
|
||
this.Iterator.Resize(oMeasure, RPI);
|
||
|
||
this.recalculateSize(oMeasure);
|
||
};
|
||
CLimitPrimary.prototype.recalculateSize = function(oMeasure)
|
||
{
|
||
if(this.Type == LIMIT_LOW)
|
||
this.dH = 0;
|
||
else
|
||
this.dH = 0.06*this.Get_TxtPrControlLetter().FontSize;
|
||
|
||
var SizeFName = this.FName.size,
|
||
SizeIter = this.Iterator.size;
|
||
|
||
var width = SizeFName.width > SizeIter.width ? SizeFName.width : SizeIter.width,
|
||
height = SizeFName.height + SizeIter.height + this.dH,
|
||
ascent;
|
||
|
||
if(this.Type == LIMIT_LOW)
|
||
ascent = SizeFName.ascent;
|
||
else
|
||
ascent = SizeIter.height + this.dH + SizeFName.ascent;
|
||
|
||
|
||
width += this.GapLeft + this.GapRight;
|
||
|
||
this.size.height = height;
|
||
this.size.width = width;
|
||
this.size.ascent = ascent;
|
||
};
|
||
CLimitPrimary.prototype.setPosition = function(pos, PosInfo)
|
||
{
|
||
this.pos.x = pos.x;
|
||
this.pos.y = pos.y;
|
||
|
||
var maxW = this.FName.size.width > this.Iterator.size.width ? this.FName.size.width : this.Iterator.size.width;
|
||
|
||
var alignFNameX = (maxW - this.FName.size.width)/2;
|
||
var alignIterX = (maxW - this.Iterator.size.width)/2;
|
||
|
||
var FNamePos = new CMathPosition();
|
||
var IterPos = new CMathPosition();
|
||
|
||
if(this.Type == LIMIT_LOW)
|
||
{
|
||
FNamePos.x = this.pos.x + this.GapLeft + alignFNameX;
|
||
FNamePos.y = this.pos.y + this.FName.size.ascent;
|
||
|
||
IterPos.x = this.pos.x + this.GapLeft + alignIterX;
|
||
IterPos.y = this.pos.y + this.dH + this.FName.size.height;
|
||
}
|
||
else
|
||
{
|
||
IterPos.x = this.pos.x + this.GapLeft + alignIterX;
|
||
IterPos.y = this.pos.y + this.Iterator.size.ascent;
|
||
|
||
FNamePos.x = this.pos.x + this.GapLeft + alignFNameX;
|
||
FNamePos.y = this.pos.y + this.FName.size.ascent + this.dH + this.Iterator.size.height;
|
||
}
|
||
|
||
// такой порядок нужен для выравнивания Box по операторам
|
||
this.FName.setPosition(FNamePos, PosInfo);
|
||
this.Iterator.setPosition(IterPos, PosInfo);
|
||
|
||
pos.x += this.size.width;
|
||
};
|
||
|
||
/**
|
||
*
|
||
* @param props
|
||
* @constructor
|
||
* @extends {CMathBase}
|
||
*/
|
||
function CLimit(props)
|
||
{
|
||
CMathBase.call(this);
|
||
|
||
this.Id = AscCommon.g_oIdCounter.Get_NewId();
|
||
|
||
this.Pr = new CMathLimitPr(this.CtrPrp);
|
||
|
||
if(props !== null && typeof(props) !== "undefined")
|
||
this.init(props);
|
||
|
||
AscCommon.g_oTableId.Add( this, this.Id );
|
||
}
|
||
CLimit.prototype = Object.create(CMathBase.prototype);
|
||
CLimit.prototype.constructor = CLimit;
|
||
|
||
CLimit.prototype.ClassType = AscDFH.historyitem_type_lim;
|
||
CLimit.prototype.kind = MATH_LIMIT;
|
||
|
||
CLimit.prototype.init = function(props)
|
||
{
|
||
this.Fill_LogicalContent(2, props.content);
|
||
|
||
// посмотреть GetAllFonts
|
||
this.setProperties(props);
|
||
this.fillContent();
|
||
};
|
||
CLimit.prototype.fillContent = function()
|
||
{
|
||
};
|
||
CLimit.prototype.getFName = function()
|
||
{
|
||
return this.Content[0];
|
||
};
|
||
CLimit.prototype.getIterator = function()
|
||
{
|
||
return this.Content[1];
|
||
};
|
||
CLimit.prototype.getBase = function()
|
||
{
|
||
return this.getFName();
|
||
};
|
||
CLimit.prototype.ApplyProperties = function(RPI)
|
||
{
|
||
// реализовано также как и для Word 2010
|
||
// в 2007 реализовано limit для inline формул как степень (закомментированный код)
|
||
|
||
/*if(this.RecalcInfo.bProps == true || RPI.bChangeInline == true)
|
||
{
|
||
this.setDimension(1, 1);
|
||
|
||
if(RPI.bInline == true && RPI.bMathFunc == true)
|
||
{
|
||
var props;
|
||
|
||
if(this.Pr.type == LIMIT_LOW)
|
||
props = {type: DEGREE_SUBSCRIPT, ctrPrp: this.CtrPrp};
|
||
else
|
||
props = {type: DEGREE_SUPERSCRIPT, ctrPrp: this.CtrPrp};
|
||
|
||
this.elements[0][0] = new CDegreeBase(props, true);
|
||
this.elements[0][0].setBase(this.getFName());
|
||
this.elements[0][0].setIterator(this.getIterator());
|
||
this.elements[0][0].fillContent();
|
||
}
|
||
else
|
||
{
|
||
this.elements[0][0] = new CLimitPrimary(true, this.Pr.type, this.getFName(), this.getIterator());
|
||
}
|
||
|
||
this.RecalcInfo.bProps = false;
|
||
}*/
|
||
|
||
if(this.RecalcInfo.bProps == true || (RPI != undefined && RPI.bChangeInline == true))
|
||
{
|
||
this.setDimension(1, 1);
|
||
this.elements[0][0] = new CLimitPrimary(true, this.Pr.type, this.getFName(), this.getIterator());
|
||
this.RecalcInfo.bProps = false;
|
||
}
|
||
|
||
};
|
||
CLimit.prototype.Apply_MenuProps = function(Props)
|
||
{
|
||
if (Props.Type == Asc.c_oAscMathInterfaceType.Limit && Props.Pos !== undefined)
|
||
{
|
||
var Type = Props.Pos == Asc.c_oAscMathInterfaceLimitPos.Bottom ? LIMIT_LOW : LIMIT_UP;
|
||
|
||
if (this.Pr.type !== Type)
|
||
{
|
||
AscCommon.History.Add(new CChangesMathLimitType(this, this.Pr.type, Type));
|
||
this.raw_SetType(Type);
|
||
}
|
||
}
|
||
};
|
||
CLimit.prototype.Get_InterfaceProps = function()
|
||
{
|
||
return new CMathMenuLimit(this);
|
||
};
|
||
CLimit.prototype.raw_SetType = function(Value)
|
||
{
|
||
if(this.Pr.type !== Value)
|
||
{
|
||
this.Pr.type = Value;
|
||
this.RecalcInfo.bProps = true;
|
||
this.ApplyProperties();
|
||
}
|
||
};
|
||
CLimit.prototype.Can_ModifyArgSize = function()
|
||
{
|
||
return this.CurPos == 1 && false === this.Is_SelectInside();
|
||
};
|
||
/**
|
||
*
|
||
* @param {MathTextAndStyles | boolean} oMathText
|
||
* @constructor
|
||
*/
|
||
CLimit.prototype.GetTextOfElement = function(oMathText)
|
||
{
|
||
oMathText = new AscMath.MathTextAndStyles(oMathText);
|
||
|
||
let strLimitSymbol = "";
|
||
let oFuncName = this.getFName();
|
||
let oArgument = this.getIterator();
|
||
|
||
if (oMathText.IsLaTeX())
|
||
{
|
||
oMathText.ResetGlobalStyle();
|
||
oMathText.Add(oFuncName, false);
|
||
oMathText.AddText(new AscMath.MathText((this.Pr.type == 1) ? "\\above" : "\\below", oMathText.GetStyleFromFirst()));
|
||
oMathText.SetNotGetStyleFromFirst();
|
||
// check when word fix bug, for now always wrap
|
||
oMathText.Add(oArgument, true, 2);
|
||
}
|
||
else
|
||
{
|
||
if (Number.isInteger(this.Pr.type))
|
||
{
|
||
strLimitSymbol = (this.Pr.type === 1) ? "┴" : "┬";
|
||
}
|
||
else
|
||
{
|
||
strLimitSymbol = (this.Pr.type.type === 2) ? "┴" : "┬";
|
||
}
|
||
|
||
let oNamePos = oMathText.Add(oFuncName, true);
|
||
|
||
oMathText.AddAfter(oNamePos, new AscMath.MathText(strLimitSymbol, this));
|
||
oMathText.Add(oArgument, true);
|
||
}
|
||
|
||
return oMathText;
|
||
};
|
||
|
||
/**
|
||
*
|
||
* @param CMathMenuLimit
|
||
* @constructor
|
||
* @extends {CMathMenuBase}
|
||
*/
|
||
function CMathMenuLimit(Limit)
|
||
{
|
||
CMathMenuBase.call(this, Limit);
|
||
|
||
this.Type = Asc.c_oAscMathInterfaceType.Limit;
|
||
|
||
if (undefined !== Limit)
|
||
{
|
||
this.Pos = (LIMIT_LOW === Limit.Pr.type) ? Asc.c_oAscMathInterfaceLimitPos.Bottom : Asc.c_oAscMathInterfaceLimitPos.Top;
|
||
}
|
||
else
|
||
{
|
||
this.Pos = undefined;
|
||
}
|
||
}
|
||
CMathMenuLimit.prototype = Object.create(CMathMenuBase.prototype);
|
||
CMathMenuLimit.prototype.constructor = CMathMenuLimit;
|
||
|
||
CMathMenuLimit.prototype.get_Pos = function(){return this.Pos;};
|
||
CMathMenuLimit.prototype.put_Pos = function(Pos){this.Pos = Pos;};
|
||
|
||
window["CMathMenuLimit"] = CMathMenuLimit;
|
||
CMathMenuLimit.prototype["get_Pos"] = CMathMenuLimit.prototype.get_Pos;
|
||
CMathMenuLimit.prototype["put_Pos"] = CMathMenuLimit.prototype.put_Pos;
|
||
|
||
function CMathFuncPr(ctrPr)
|
||
{
|
||
this.ctrPr = new CMathCtrlPr(ctrPr);
|
||
}
|
||
CMathFuncPr.prototype.GetRPr = function ()
|
||
{
|
||
return this.ctrPr.GetRPr();
|
||
};
|
||
CMathFuncPr.prototype.Set_FromObject = function(Obj)
|
||
{
|
||
this.ctrPr.SetRPr(Obj.ctrPrp);
|
||
};
|
||
CMathFuncPr.prototype.Copy = function()
|
||
{
|
||
let NewPr = new CMathFuncPr();
|
||
NewPr.ctrPr = this.ctrPr;
|
||
return NewPr;
|
||
};
|
||
CMathFuncPr.prototype.Write_ToBinary = function(Writer)
|
||
{
|
||
Writer.WriteBool(true);
|
||
this.ctrPr.Write_ToBinary(Writer);
|
||
};
|
||
CMathFuncPr.prototype.Read_FromBinary = function(Reader)
|
||
{
|
||
if (Reader.GetBool())
|
||
{
|
||
this.ctrPr.Read_FromBinary(Reader);
|
||
}
|
||
};
|
||
|
||
/**
|
||
*
|
||
* @param props
|
||
* @constructor
|
||
* @extends {CMathBase}
|
||
*/
|
||
function CMathFunc(props)
|
||
{
|
||
CMathBase.call(this);
|
||
|
||
this.Id = AscCommon.g_oIdCounter.Get_NewId();
|
||
|
||
this.Pr = new CMathFuncPr(this.CtrPrp);
|
||
|
||
if(props !== null && typeof(props) !== "undefined")
|
||
this.init(props);
|
||
|
||
AscCommon.g_oTableId.Add( this, this.Id );
|
||
}
|
||
CMathFunc.prototype = Object.create(CMathBase.prototype);
|
||
CMathFunc.prototype.constructor = CMathFunc;
|
||
|
||
CMathFunc.prototype.ClassType = AscDFH.historyitem_type_mathFunc;
|
||
CMathFunc.prototype.kind = MATH_FUNCTION;
|
||
|
||
CMathFunc.prototype.init = function(props)
|
||
{
|
||
this.Fill_LogicalContent(2, props.content);
|
||
|
||
this.setProperties(props);
|
||
this.fillContent();
|
||
};
|
||
CMathFunc.prototype.PreRecalc = function(Parent, ParaMath, ArgSize, RPI, GapsInfo)
|
||
{
|
||
var bMathFunc = RPI.bMathFunc;
|
||
RPI.bMathFunc = true;
|
||
|
||
CMathBase.prototype.PreRecalc.call(this, Parent, ParaMath, ArgSize, RPI, GapsInfo);
|
||
|
||
RPI.bMathFunc = bMathFunc;
|
||
};
|
||
CMathFunc.prototype.GetLastElement = function()
|
||
{
|
||
return this.Content[1].GetFirstElement();
|
||
};
|
||
CMathFunc.prototype.GetFirstElement = function()
|
||
{
|
||
return this.Content[0].GetFirstElement();
|
||
};
|
||
CMathFunc.prototype.setDistance = function()
|
||
{
|
||
this.dW = this.Get_TxtPrControlLetter().FontSize*0.044;
|
||
};
|
||
CMathFunc.prototype.getFName = function()
|
||
{
|
||
return this.Content[0];
|
||
};
|
||
CMathFunc.prototype.getArgument = function()
|
||
{
|
||
return this.Content[1];
|
||
};
|
||
CMathFunc.prototype.fillContent = function()
|
||
{
|
||
this.NeedBreakContent(1);
|
||
|
||
this.setDimension(1, 2);
|
||
this.elements[0][0] = this.getFName();
|
||
this.elements[0][1] = this.getArgument();
|
||
};
|
||
CMathFunc.prototype.GetTextOfElement = function(oMathText)
|
||
{
|
||
oMathText = new AscMath.MathTextAndStyles(oMathText);
|
||
let oFuncName = this.getFName();
|
||
let oArgument = this.getArgument();
|
||
oMathText.SetGlobalStyle(this);
|
||
|
||
if (oMathText.IsLaTeX())
|
||
{
|
||
let oFuncNameContent = oFuncName.GetTextOfElement(true);
|
||
let strFunc = oFuncNameContent.GetText();
|
||
|
||
//find content before "_", "^", "below" and "above";
|
||
strFunc = strFunc.split("_")[0].split('^')[0].split('\\below')[0].split('\\above')[0];
|
||
|
||
let oSlashesTextForName = new AscMath.MathText("\\", oFuncNameContent.GetFirstStyle());
|
||
let oFirstPosInNameContent = oFuncNameContent.GetFirstPos();
|
||
|
||
if (AscMath.functionNames.includes(strFunc) || AscMath.LimitFunctions.includes(strFunc))
|
||
oFuncNameContent.AddBefore(oFirstPosInNameContent, oSlashesTextForName);
|
||
|
||
oMathText.Add(oFuncNameContent, true, 0);
|
||
oMathText.SetGlobalStyle(oFuncName);
|
||
oMathText.Add(oArgument, true, 2);
|
||
}
|
||
else
|
||
{
|
||
let oNamePos = oMathText.Add(oFuncName, true, 0);
|
||
let oArgumentPos = oMathText.Add(oArgument, true, 1);
|
||
let oArgumentToken = oMathText.GetExact(oArgumentPos);
|
||
|
||
oMathText.AddAfter(oNamePos, new AscMath.MathText("", this.Pr.GetRPr()));
|
||
}
|
||
|
||
return oMathText;
|
||
};
|
||
|
||
//--------------------------------------------------------export----------------------------------------------------
|
||
window['AscCommonWord'] = window['AscCommonWord'] || {};
|
||
window['AscCommonWord'].CMathFunc = CMathFunc;
|
||
window['AscCommonWord'].CLimit = CLimit;
|
||
|
||
AscMath.Limit = CLimit;
|
||
AscMath.Func = CMathFunc;
|