/* * (c) Copyright Ascensio System SIA 2010-2015 * * 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 Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * 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 CMathFractionPr() { this.type = BAR_FRACTION; } CMathFractionPr.prototype.Set_FromObject = function (Obj) { if (undefined !== Obj.type && null !== Obj.type) { this.type = Obj.type; } }; CMathFractionPr.prototype.Copy = function (Obj) { var NewPr = new CMathFractionPr(); NewPr.type = this.type; return NewPr; }; CMathFractionPr.prototype.Write_ToBinary = function (Writer) { Writer.WriteLong(this.type); }; CMathFractionPr.prototype.Read_FromBinary = function (Reader) { this.type = Reader.GetLong(); }; function CFraction(props) { CFraction.superclass.constructor.call(this); this.Id = g_oIdCounter.Get_NewId(); this.Numerator = null; this.Denominator = null; this.Pr = new CMathFractionPr(); this.bHideBar = false; if (props !== null && typeof(props) !== "undefined") { this.init(props); } g_oTableId.Add(this, this.Id); } Asc.extendClass(CFraction, CMathBase); CFraction.prototype.ClassType = historyitem_type_frac; CFraction.prototype.kind = MATH_FRACTION; CFraction.prototype.init = function (props) { this.Fill_LogicalContent(2); this.setProperties(props); this.fillContent(); }; CFraction.prototype.getType = function () { return this.Pr.type; }; CFraction.prototype.draw = function (x, y, pGraphics, PDSE) { if (this.Pr.type == BAR_FRACTION || this.Pr.type == NO_BAR_FRACTION) { this.drawBarFraction(x, y, pGraphics, PDSE); } else { if (this.Pr.type == SKEWED_FRACTION) { this.drawSkewedFraction(x, y, pGraphics, PDSE); } else { if (this.Pr.type == LINEAR_FRACTION) { this.drawLinearFraction(x, y, pGraphics, PDSE); } } } }; CFraction.prototype.drawBarFraction = function (x, y, pGraphics, PDSE) { var mgCtrPrp = this.Get_TxtPrControlLetter(); var penW = mgCtrPrp.FontSize * 25.4 / 96 * 0.08; var numHeight = this.elements[0][0].size.height; var width = this.size.width - this.GapLeft - this.GapRight; var x1 = this.pos.x + x + this.GapLeft, x2 = x1 + width, y1 = this.pos.y + y + numHeight - penW; if (!this.bHideBar) { pGraphics.SetFont(mgCtrPrp); this.Make_ShdColor(PDSE, this.Get_CompiledCtrPrp()); pGraphics.drawHorLine(0, y1, x1, x2, penW); } CFraction.superclass.draw.call(this, x, y, pGraphics, PDSE); }; CFraction.prototype.drawSkewedFraction = function (x, y, pGraphics, PDSE) { var mgCtrPrp = this.Get_TxtPrControlLetter(); var penW = mgCtrPrp.FontSize / 12.5 * g_dKoef_pix_to_mm; var gap = this.dW / 2 - penW / 7.5; var plh = 9.877777777777776 * mgCtrPrp.FontSize / 36; var minHeight = 2 * this.dW, middleHeight = plh * 4 / 3, maxHeight = (3 * this.dW + 5 * plh) * 2 / 3; var tg; var tg1 = -2.22, tg2 = -3.7; var X = this.pos.x + x + this.GapLeft, Y = this.pos.y + y; var heightSlash = this.size.height * 2 / 3; if (heightSlash < maxHeight) { if (heightSlash < minHeight) { heightSlash = minHeight; tg = tg1; } else { heightSlash = this.size.height * 2 / 3; tg = (heightSlash - maxHeight) * (tg1 - tg2) / (middleHeight - maxHeight) + tg2; } var b = this.elements[0][0].size.height - tg * (this.elements[0][0].size.width + gap); var y1 = this.elements[0][0].size.height / 3, y2 = this.elements[0][0].size.height / 3 + heightSlash; var x1 = (y1 - b) / tg, x2 = (y2 - b) / tg; var xx1 = X + x1, xx2 = X + x2; var yy1 = Y + y1, yy2 = Y + y2; } else { heightSlash = maxHeight; tg = tg2; var coeff = this.elements[0][0].size.height / this.size.height; var shift = heightSlash * coeff; var minVal = plh / 2, maxVal = heightSlash - minVal; if (shift < minVal) { shift = minVal; } else { if (shift > maxVal) { shift = maxVal; } } var y0 = this.elements[0][0].size.height - shift; var b = this.elements[0][0].size.height - tg * (this.elements[0][0].size.width + gap); var y1 = y0, y2 = y0 + heightSlash; var x1 = (y1 - b) / tg, x2 = (y2 - b) / tg; var xx1 = X + x1, xx2 = X + x2; var yy1 = Y + y1, yy2 = Y + y2; } pGraphics.SetFont(mgCtrPrp); pGraphics.p_width(penW * 1000); this.Make_ShdColor(PDSE, this.Get_CompiledCtrPrp()); pGraphics._s(); pGraphics._m(xx1, yy1); pGraphics._l(xx2, yy2); pGraphics.ds(); CFraction.superclass.draw.call(this, x, y, pGraphics, PDSE); }; CFraction.prototype.drawLinearFraction = function (x, y, pGraphics, PDSE) { var shift = 0.1 * this.dW; var X = this.pos.x + x + this.GapLeft, Y = this.pos.y + y; var x1 = X + this.elements[0][0].size.width + this.dW - shift, y1 = Y, x2 = X + this.elements[0][0].size.width + shift, y2 = Y + this.size.height; var mgCtrPrp = this.Get_TxtPrControlLetter(); var penW = mgCtrPrp.FontSize / 12.5 * g_dKoef_pix_to_mm; pGraphics.SetFont(mgCtrPrp); pGraphics.p_width(penW * 1000); this.Make_ShdColor(PDSE, this.Get_CompiledCtrPrp()); pGraphics._s(); pGraphics._m(x1, y1); pGraphics._l(x2, y2); pGraphics.ds(); CFraction.superclass.draw.call(this, x, y, pGraphics, PDSE); }; CFraction.prototype.getNumerator = function () { var numerator; if (this.Pr.type == BAR_FRACTION || this.Pr.type == NO_BAR_FRACTION) { numerator = this.elements[0][0].getElement(); } else { numerator = this.elements[0][0]; } return numerator; }; CFraction.prototype.getDenominator = function () { var denominator; if (this.Pr.type == BAR_FRACTION || this.Pr.type == NO_BAR_FRACTION) { denominator = this.elements[1][0].getElement(); } else { denominator = this.elements[0][1]; } return denominator; }; CFraction.prototype.getNumeratorMathContent = function () { return this.Content[0]; }; CFraction.prototype.getDenominatorMathContent = function () { return this.Content[1]; }; CFraction.prototype.PreRecalc = function (Parent, ParaMath, ArgSize, RPI, GapsInfo) { this.Parent = Parent; this.ParaMath = ParaMath; var ArgSzNumDen = ArgSize.Copy(); if (RPI.bInline == true && (this.Pr.type === BAR_FRACTION || this.Pr.type == NO_BAR_FRACTION)) { ArgSzNumDen.decrease(); this.ArgSize.SetValue(-1); } else { if (RPI.bDecreasedComp == true) { this.ArgSize.SetValue(-1); } else { this.ArgSize.SetValue(0); } } this.RecalcInfo.bCtrPrp = true; this.Set_CompiledCtrPrp(Parent, ParaMath, RPI); this.ApplyProperties(RPI); var NewRPI = RPI.Copy(); if (this.Pr.type !== LINEAR_FRACTION) { NewRPI.bDecreasedComp = true; } if (this.bInside == false) { GapsInfo.setGaps(this, this.TextPrControlLetter.FontSize); } this.Numerator.PreRecalc(this, ParaMath, ArgSzNumDen, NewRPI); this.Denominator.PreRecalc(this, ParaMath, ArgSzNumDen, NewRPI); }; CFraction.prototype.recalculateSize = function (oMeasure) { if (this.Pr.type == BAR_FRACTION || this.Pr.type == NO_BAR_FRACTION) { this.recalculateBarFraction(oMeasure); } else { if (this.Pr.type == SKEWED_FRACTION) { this.recalculateSkewed(oMeasure); } else { if (this.Pr.type == LINEAR_FRACTION) { this.recalculateLinear(oMeasure); } } } }; CFraction.prototype.recalculateBarFraction = function (oMeasure) { var num = this.elements[0][0].size, den = this.elements[1][0].size; var mgCtrPrp = this.Get_TxtPrControlLetter(); var width = num.width > den.width ? num.width : den.width; var height = num.height + den.height; var ascent = num.height + this.ParaMath.GetShiftCenter(oMeasure, mgCtrPrp); width += this.GapLeft + this.GapRight; this.size = { width: width, height: height, ascent: ascent }; }; CFraction.prototype.recalculateSkewed = function (oMeasure) { var mgCtrPrp = this.Get_TxtPrControlLetter(); this.dW = 5.011235894097222 * mgCtrPrp.FontSize / 36; var width = this.elements[0][0].size.width + this.dW + this.elements[0][1].size.width; var height = this.elements[0][0].size.height + this.elements[0][1].size.height; var ascent = this.elements[0][0].size.height + this.ParaMath.GetShiftCenter(oMeasure, mgCtrPrp); width += this.GapLeft + this.GapRight; this.size = { width: width, height: height, ascent: ascent }; }; CFraction.prototype.recalculateLinear = function () { var AscentFirst = this.elements[0][0].size.ascent, DescentFirst = this.elements[0][0].size.height - this.elements[0][0].size.ascent, AscentSecond = this.elements[0][1].size.ascent, DescentSecond = this.elements[0][1].size.height - this.elements[0][1].size.ascent; var H = AscentFirst + DescentSecond; var mgCtrPrp = this.Get_TxtPrControlLetter(); var gap = 5.011235894097222 * mgCtrPrp.FontSize / 36; var H3 = gap * 4.942252165543792, H4 = gap * 7.913378248315688, H5 = gap * 9.884504331087584; if (H < H3) { this.dW = gap; } else { if (H < H4) { this.dW = 2 * gap; } else { if (H < H5) { this.dW = 2.8 * gap; } else { this.dW = 3.4 * gap; } } } var ascent = AscentFirst > AscentSecond ? AscentFirst : AscentSecond; var descent = DescentFirst > DescentSecond ? DescentFirst : DescentSecond; var height = ascent + descent; var width = this.elements[0][0].size.width + this.dW + this.elements[0][1].size.width; width += this.GapLeft + this.GapRight; this.size = { height: height, width: width, ascent: ascent }; }; CFraction.prototype.setPosition = function (pos, PosInfo) { if (this.Pr.type == SKEWED_FRACTION) { this.pos.x = pos.x; this.pos.y = pos.y - this.size.ascent; var X = this.pos.x + this.GapLeft, Y = this.pos.y; var PosNum = new CMathPosition(); PosNum.x = X; PosNum.y = Y; var PosDen = new CMathPosition(); PosDen.x = X + this.elements[0][0].size.width + this.dW; PosDen.y = Y + this.elements[0][0].size.height; this.elements[0][0].setPosition(PosNum, PosInfo); this.elements[0][1].setPosition(PosDen, PosInfo); } else { CFraction.superclass.setPosition.call(this, pos, PosInfo); } }; CFraction.prototype.fillContent = function () { this.Numerator = new CNumerator(this.Content[0]); this.Denominator = new CDenominator(this.Content[1]); if (this.Pr.type == BAR_FRACTION || this.Pr.type == NO_BAR_FRACTION) { this.setDimension(2, 1); if (this.Pr.type == NO_BAR_FRACTION) { this.bHideBar = true; } this.elements[0][0] = this.Numerator; this.elements[1][0] = this.Denominator; } else { if (this.Pr.type == SKEWED_FRACTION) { this.setDimension(1, 2); this.elements[0][0] = this.Numerator.getElement(); this.elements[0][1] = this.Denominator.getElement(); } else { if (this.Pr.type == LINEAR_FRACTION) { this.setDimension(1, 2); this.elements[0][0] = this.Numerator.getElement(); this.elements[0][1] = this.Denominator.getElement(); } } } }; CFraction.prototype.Document_UpdateInterfaceState = function (MathProps) { MathProps.Type = c_oAscMathInterfaceType.Fraction; MathProps.Pr = null; }; function CFractionBase(bInside, MathContent) { CFractionBase.superclass.constructor.call(this, bInside); this.gap = 0; this.init(MathContent); } Asc.extendClass(CFractionBase, CMathBase); CFractionBase.prototype.init = function (MathContent) { this.setDimension(1, 1); this.elements[0][0] = MathContent; }; CFractionBase.prototype.getElement = function () { return this.elements[0][0]; }; CFractionBase.prototype.setElement = function (Element) { this.elements[0][0] = Element; }; CFractionBase.prototype.getPropsForWrite = function () { return {}; }; CFractionBase.prototype.Get_Id = function () { return this.elements[0][0].Get_Id(); }; function CNumerator(MathContent) { CNumerator.superclass.constructor.call(this, true, MathContent); } Asc.extendClass(CNumerator, CFractionBase); CNumerator.prototype.recalculateSize = function () { var arg = this.elements[0][0].size; var mgCtrPrp = this.Get_TxtPrControlLetter(); var Descent = arg.height - arg.ascent; g_oTextMeasurer.SetFont(mgCtrPrp); var Height = g_oTextMeasurer.GetHeight(); var gapNum, minGap; if (this.Parent.kind == MATH_LIMIT || this.Parent.kind == MATH_GROUP_CHARACTER) { gapNum = Height / 4.14; minGap = Height / 13.8; var delta = gapNum - Descent; this.gap = delta > minGap ? delta : minGap; } else { gapNum = Height / 3.05; minGap = Height / 9.77; var delta = gapNum - Descent; this.gap = delta > minGap ? delta : minGap; } var width = arg.width; var height = arg.height + this.gap; var ascent = arg.ascent; this.size = { width: width, height: height, ascent: ascent }; }; CNumerator.prototype.setPosition = function (pos, PosInfo) { this.elements[0][0].setPosition(pos, PosInfo); }; function CDenominator(MathContent) { CDenominator.superclass.constructor.call(this, true, MathContent); } Asc.extendClass(CDenominator, CFractionBase); CDenominator.prototype.recalculateSize = function () { var arg = this.elements[0][0].size; var mgCtrPrp = this.Get_TxtPrControlLetter(); var Ascent = arg.ascent - 4.938888888888888 * mgCtrPrp.FontSize / 36; g_oTextMeasurer.SetFont(mgCtrPrp); var Height = g_oTextMeasurer.GetHeight(); var gapDen, minGap; if (this.Parent.kind == MATH_LIMIT || this.Parent.kind == MATH_GROUP_CHARACTER) { gapDen = Height / 2.6; minGap = Height / 10; } else { gapDen = Height / 2.03; minGap = Height / 6.1; } var delta = gapDen - Ascent; this.gap = delta > minGap ? delta : minGap; var width = arg.width; var height = arg.height + this.gap; var ascent = arg.ascent + this.gap; this.size = { width: width, height: height, ascent: ascent }; }; CDenominator.prototype.setPosition = function (pos, PosInfo) { var NewPos = new CMathPosition(); NewPos.x = pos.x; NewPos.y = pos.y + this.gap; this.elements[0][0].setPosition(NewPos, PosInfo); };