Files
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

1430 lines
62 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, undefined) {
var PathType = {
POINT: 0,
LINE: 1,
ARC: 2,
BEZIER_3: 3,
BEZIER_4: 4,
END: 5
};
function EditShapeGeometryTrack(originalObject, drawingObjects, extX, extY) {
AscFormat.ExecuteNoHistory(function() {
this.originalObject = originalObject;
this.drawingObjects = drawingObjects;
this.originalGeometry = this.getOriginalObjectGeometry();
this.geometry = this.originalGeometry.createDuplicate();
this.geometry.parent = originalObject.spPr.geometry.parent;
this.originalShape = originalObject;
this.shapeWidth = extX ? extX : originalObject.extX;
this.shapeHeight = extY ? extY : originalObject.extY;
var oPen = originalObject.pen;
var oBrush = originalObject.brush;
this.transform = originalObject.transform;
this.invertTransform = originalObject.invertTransform;
this.overlayObject = new AscFormat.OverlayObject(this.geometry, this.shapeWidth, this.shapeHeight, oBrush, oPen, this.transform);
this.xMin = 0;
this.yMin = 0;
this.xMax = this.shapeWidth;
this.yMax = this.shapeHeight;
this.geometry.Recalculate(this.shapeWidth, this.shapeHeight);
this.arrPathCommandsType = [];
this.convertToBezier();
this.createGeometryEditList();
this.originalX = originalObject.x;
this.originalY = originalObject.y;
this.originalExtX = originalObject.extX;
this.originalExtY = originalObject.extY;
this.originalRot = originalObject.rot;
var oPen1 = new AscFormat.CLn();
oPen1.w = 15000;
oPen1.Fill = AscFormat.CreateSolidFillRGBA(255, 255, 255, 255);
var oPen2 = new AscFormat.CLn();
oPen2.w = 15000;
oPen2.Fill = AscFormat.CreateSolidFillRGBA(0x61, 0x9e, 0xde, 255);
oPen2.prstDash = 0;
this.pen1 = oPen1;
this.pen2 = oPen2;
this.overlayGeometry = this.geometry.createDuplicate();
this.overlayObjectTrack = new AscFormat.OverlayObject(this.overlayGeometry, this.shapeWidth, this.shapeHeight, null, oPen1, this.transform);
this.addedPointIdx = null;
}, this, []);
}
EditShapeGeometryTrack.prototype.getOriginalObjectGeometry = function() {
if(Asc.editor.isPdfEditor() && this.originalObject instanceof AscPDF.CAnnotationPolygon) {
return this.originalObject.GetGeometryEdit();
}
return this.originalObject.spPr.geometry;
};
EditShapeGeometryTrack.prototype.draw = function(overlay)
{
var gmEditPoint = this.getGmEditPt();
if(gmEditPoint)
{
var dOldAlpha = null;
var oGraphics = overlay.Graphics ? overlay.Graphics : overlay;
if(AscFormat.isRealNumber(this.originalShape.selectStartPage) && overlay.SetCurrentPage)
{
overlay.SetCurrentPage(this.originalShape.selectStartPage);
}
if(AscFormat.isRealNumber(oGraphics.globalAlpha) && oGraphics.put_GlobalAlpha)
{
dOldAlpha = oGraphics.globalAlpha;
oGraphics.put_GlobalAlpha(false, 1);
}
if(overlay.DrawGeomEditPoint && !Asc.editor.isPdfEditor())
{
overlay.DrawGeomEditPoint(this.transform, gmEditPoint);
}
this.overlayObjectTrack.pen = this.pen1;
this.overlayObjectTrack.draw(overlay, this.transform);
this.overlayObjectTrack.pen = this.pen2;
this.overlayObjectTrack.draw(overlay, this.transform);
if(AscFormat.isRealNumber(dOldAlpha) && oGraphics.put_GlobalAlpha)
{
oGraphics.put_GlobalAlpha(true, dOldAlpha);
}
}
//Check correct
//this.overlayObject.TransformMatrix = this.originalShape.transform;
//this.overlayObject.draw(overlay);
};
EditShapeGeometryTrack.prototype.drawSelect = function(oDrawingDocument, nGmEditPointIdx) {
if(!this.isCorrect()) {
return;
}
var geometry = this.geometry;
var gmEditList = this.gmEditList;
var gmEditPoint = this.getGmEditPt();
var pathLst = geometry.pathLst;
var matrix = this.transform;
var oBounds = this.getBounds();
oBounds.min_x -= 5;
oBounds.min_y -= 5;
oBounds.max_x += 5;
oBounds.max_y += 5;
if(Asc.editor.isPdfEditor()) {
gmEditPoint = null;
}
oDrawingDocument.AutoShapesTrack.DrawGeometryEdit(matrix, pathLst, gmEditList, gmEditPoint, oBounds);
};
EditShapeGeometryTrack.prototype.getGmSelection = function() {
return this.drawingObjects.selection.geometrySelection;
};
EditShapeGeometryTrack.prototype.getGmEditPtIdx = function() {
var oGeomSelection = this.getGmSelection();
if(!oGeomSelection) {
return null;
}
return oGeomSelection.getGmEditPtIdx();
};
EditShapeGeometryTrack.prototype.getGmEditPt = function() {
if(!this.isCorrect()) {
return null;
}
if(this.addedPointIdx !== null) {
return this.gmEditList[this.addedPointIdx];
}
var oPt = this.gmEditList[this.getGmEditPtIdx()];
return oPt || null;
};
EditShapeGeometryTrack.prototype.getOriginalPt = function() {
if(!this.isCorrect()) {
return null;
}
if(this.originalAddedPoint) {
return this.originalAddedPoint;
}
var oGeomSelection = this.drawingObjects.selection.geometrySelection;
if(!oGeomSelection) {
return null;
}
return oGeomSelection.getTrack().getGmEditPt();
};
EditShapeGeometryTrack.prototype.track = function(e, posX, posY) {
AscFormat.ExecuteNoHistory(function(){
var geometry = this.geometry;
var gmEditPoint = this.getGmEditPt();
if(!gmEditPoint) {
return;
}
geometry.gdLstInfo = [];
geometry.cnxLstInfo = [];
for(var i = 0; i < geometry.pathLst.length; i++) {
geometry.pathLst[i].ArrPathCommandInfo = [];
}
var invert_transform = this.originalShape.invertTransform;
var _relative_x = invert_transform.TransformPointX(posX, posY);
var _relative_y = invert_transform.TransformPointY(posX, posY);
var originalPoint = this.getOriginalPt();
var nextPoint = gmEditPoint.nextPoint;
var prevPoint = gmEditPoint.prevPoint;
var currentPath = geometry.pathLst[gmEditPoint.pathIndex];
var arrPathCommand = currentPath.ArrPathCommand;
this.gmEditPtIdx = this.drawingObjects.selection.geometrySelection.getGmEditPtIdx();
var cur_command_type_array = this.arrPathCommandsType[gmEditPoint.pathIndex];
var cur_command_type_1 = cur_command_type_array[gmEditPoint.pathC1];
var cur_command_type_2 = cur_command_type_array[gmEditPoint.pathC2];
if(gmEditPoint.isHitInFirstCPoint) {
arrPathCommand[gmEditPoint.pathC1].X1 = _relative_x;
arrPathCommand[gmEditPoint.pathC1].Y1 = _relative_y;
if(cur_command_type_1 === PathType.LINE) {
cur_command_type_array[gmEditPoint.pathC1] = PathType.BEZIER_4;
}
var g1X = gmEditPoint.g1X;
var g1Y = gmEditPoint.g1Y;
gmEditPoint.g1X = _relative_x;
gmEditPoint.g1Y = _relative_y;
if(cur_command_type_1 === PathType.ARC && cur_command_type_2 === PathType.ARC) {
var isEllipseArc = Math.abs((gmEditPoint.X - g1X) * (gmEditPoint.g2Y - g1Y) - (gmEditPoint.g2X - g1X) * (gmEditPoint.Y - g1Y));
if(Math.floor(isEllipseArc) === 0) {
var g2X = gmEditPoint.g1X - gmEditPoint.X;
var g2Y = gmEditPoint.g1Y - gmEditPoint.Y;
arrPathCommand[gmEditPoint.pathC2].X0 = gmEditPoint.X - g2X;
arrPathCommand[gmEditPoint.pathC2].Y0 = gmEditPoint.Y - g2Y;
gmEditPoint.g2X = gmEditPoint.X - g2X;
gmEditPoint.g2Y = gmEditPoint.Y - g2Y;
} else {
var pathElemType = this.arrPathCommandsType[gmEditPoint.pathIndex];
pathElemType[gmEditPoint.pathC1] = PathType.BEZIER_4;
pathElemType[gmEditPoint.pathC2] = PathType.BEZIER_4;
}
}
} else if(gmEditPoint.isHitInSecondCPoint) {
arrPathCommand[gmEditPoint.pathC2].X0 = _relative_x;
arrPathCommand[gmEditPoint.pathC2].Y0 = _relative_y;
if(cur_command_type_2 === PathType.LINE) {
cur_command_type_array[gmEditPoint.pathC2] = PathType.BEZIER_4;
}
var g2X = gmEditPoint.g2X;
var g2Y = gmEditPoint.g2Y;
gmEditPoint.g2X = _relative_x;
gmEditPoint.g2Y = _relative_y;
if(cur_command_type_1 === PathType.ARC && cur_command_type_2 === PathType.ARC) {
var isEllipseArc = Math.abs((gmEditPoint.X - gmEditPoint.g1X) * (g2Y - gmEditPoint.g1Y) - (g2X - gmEditPoint.g1X) * (gmEditPoint.Y - gmEditPoint.g1Y));
if(Math.floor(isEllipseArc) === 0) {
var g1X = gmEditPoint.g2X - gmEditPoint.X;
var g1Y = gmEditPoint.g2Y - gmEditPoint.Y;
arrPathCommand[gmEditPoint.pathC1].X1 = gmEditPoint.X - g1X;
arrPathCommand[gmEditPoint.pathC1].Y1 = gmEditPoint.Y - g1Y;
gmEditPoint.g1X = gmEditPoint.X - g1X;
gmEditPoint.g1Y = gmEditPoint.Y - g1Y;
} else {
var pathElemType = this.arrPathCommandsType[gmEditPoint.pathIndex];
pathElemType[gmEditPoint.pathC1] = PathType.BEZIER_4;
pathElemType[gmEditPoint.pathC2] = PathType.BEZIER_4;
}
}
} else {
var X0, X1, Y0, Y1;
//second curve relative to point
var pathCommand = arrPathCommand[gmEditPoint.pathC1];
var isPathCommand = (gmEditPoint.g1X !== undefined && gmEditPoint.g1Y !== undefined);
X0 = cur_command_type_1 === PathType.LINE ? (prevPoint.X + _relative_x / 2) / (3 / 2) : prevPoint.g2X;
Y0 = cur_command_type_1 === PathType.LINE ? (prevPoint.Y + _relative_y / 2) / (3 / 2) : prevPoint.g2Y;
if (isPathCommand) {
X1 = cur_command_type_1 === PathType.LINE ? (prevPoint.X + _relative_x * 2) / 3 : _relative_x - originalPoint.X + originalPoint.g1X;
Y1 = cur_command_type_1 === PathType.LINE ? (prevPoint.Y + _relative_y * 2) / 3 : _relative_y - originalPoint.Y + originalPoint.g1Y;
}
var id = pathCommand.id === PathType.POINT ? PathType.POINT : PathType.BEZIER_4;
var command = {
id: id,
X0: X0,
Y0: Y0,
X1: X1,
Y1: Y1,
X2: _relative_x,
Y2: _relative_y,
X: _relative_x,
Y: _relative_y
};
if(gmEditPoint.g1X !== undefined && gmEditPoint.g1Y !== undefined) {
gmEditPoint.g1X = command.X1;
gmEditPoint.g1Y = command.Y1;
}
gmEditPoint.X = _relative_x;
gmEditPoint.Y = _relative_y;
if(gmEditPoint.pathC1 && gmEditPoint.pathC2 && (gmEditPoint.pathC1 > gmEditPoint.pathC2)) {
arrPathCommand[gmEditPoint.pathC2 - 1].X = _relative_x;
arrPathCommand[gmEditPoint.pathC2 - 1].Y = _relative_y;
}
arrPathCommand[gmEditPoint.pathC1] = command;
//second curve relative to point
if(gmEditPoint.pathC2) {
var X0, X1, Y0, Y1;
var pathCommand = arrPathCommand[gmEditPoint.pathC2];
var isPathCommand = (gmEditPoint.g2X !== undefined && gmEditPoint.g2Y !== undefined);
if (isPathCommand) {
X0 = cur_command_type_2 === PathType.LINE ? (nextPoint.X + _relative_x * 2) / 3 : _relative_x - originalPoint.X + originalPoint.g2X;
Y0 = cur_command_type_2 === PathType.LINE ? (nextPoint.Y + _relative_y * 2) / 3 : _relative_y - originalPoint.Y + originalPoint.g2Y;
}
X1 = cur_command_type_2 === PathType.LINE ? (nextPoint.X + _relative_x / 2) / (3 / 2) : nextPoint.g1X;
Y1 = cur_command_type_2 === PathType.LINE ? (nextPoint.Y + _relative_y / 2) / (3 / 2) : nextPoint.g1Y;
var id = pathCommand.id === PathType.POINT ? PathType.POINT : PathType.BEZIER_4;
var command = {
id: id,
X0: X0,
Y0: Y0,
X1: X1,
Y1: Y1,
X2: nextPoint.X,
Y2: nextPoint.Y,
X: nextPoint.X,
Y: nextPoint.Y
};
if (isPathCommand) {
gmEditPoint.g2X = command.X0;
gmEditPoint.g2Y = command.Y0;
}
gmEditPoint.X = _relative_x;
gmEditPoint.Y = _relative_y;
arrPathCommand[gmEditPoint.pathC2] = command;
}
}
this.overlayGeometry.pathLst.length = 1;
var oDrawPath = this.overlayGeometry.pathLst[0];
if(oDrawPath) {
oDrawPath.ArrPathCommand.length = 0;
oDrawPath.stroke = true;
if(prevPoint) {
oDrawPath.ArrPathCommand.push({id:AscFormat.moveTo, X: prevPoint.X, Y: prevPoint.Y});
if(arrPathCommand[gmEditPoint.pathC1]) {
oDrawPath.ArrPathCommand.push(arrPathCommand[gmEditPoint.pathC1]);
}
if(arrPathCommand[gmEditPoint.pathC2]) {
oDrawPath.ArrPathCommand.push(arrPathCommand[gmEditPoint.pathC2]);
}
}
else {
oDrawPath.ArrPathCommand.push({id:AscFormat.moveTo, X: gmEditPoint.X, Y: gmEditPoint.Y});
if(arrPathCommand[gmEditPoint.pathC2]) {
oDrawPath.ArrPathCommand.push(arrPathCommand[gmEditPoint.pathC2]);
}
}
}
}, this, []);
};
EditShapeGeometryTrack.prototype.getBounds = function() {
var bounds_checker = new AscFormat.CSlideBoundsChecker();
bounds_checker.init(Page_Width, Page_Height, Page_Width, Page_Height);
this.overlayObject.TransformMatrix = this.originalShape.transform;
this.overlayObject.draw(bounds_checker);
var tr = this.originalShape.transform;
var arr_p_x = [];
var arr_p_y = [];
arr_p_x.push(tr.TransformPointX(0,0));
arr_p_y.push(tr.TransformPointY(0,0));
arr_p_x.push(tr.TransformPointX(this.originalShape.extX,0));
arr_p_y.push(tr.TransformPointY(this.originalShape.extX,0));
arr_p_x.push(tr.TransformPointX(this.originalShape.extX,this.originalShape.extY));
arr_p_y.push(tr.TransformPointY(this.originalShape.extX,this.originalShape.extY));
arr_p_x.push(tr.TransformPointX(0,this.originalShape.extY));
arr_p_y.push(tr.TransformPointY(0,this.originalShape.extY));
this.calculateMinMax();
var oRectBounds = this.getRectBounds();
arr_p_x.push(oRectBounds.XLT);
arr_p_x.push(oRectBounds.XRB);
arr_p_y.push(oRectBounds.YLT);
arr_p_y.push(oRectBounds.YRB);
bounds_checker.Bounds.min_x = Math.min.apply(Math, arr_p_x);
bounds_checker.Bounds.max_x = Math.max.apply(Math, arr_p_x);
bounds_checker.Bounds.min_y = Math.min.apply(Math, arr_p_y);
bounds_checker.Bounds.max_y = Math.max.apply(Math, arr_p_y);
var oOffset = this.getXfrmOffset();
bounds_checker.Bounds.posX = oOffset.OffX;
bounds_checker.Bounds.posY = oOffset.OffY;
bounds_checker.Bounds.extX = this.xMax - this.xMin;
bounds_checker.Bounds.extY = this.yMax - this.yMin;
return bounds_checker.Bounds;
};
EditShapeGeometryTrack.prototype.addPathCommandInfo = function (command, arrPathElem, x1, y1, x2, y2, x3, y3) {
AscFormat.ExecuteNoHistory(function () {
switch (command) {
case 0: {
var path = new AscFormat.Path();
path.setExtrusionOk(x1 || false);
path.setFill(y1 || "norm");
path.setStroke(x2 != undefined ? x2 : true);
path.setPathW(y2);
path.setPathH(x3);
this.AddPath(path);
break;
}
case 1: {
this.geometry.pathLst[arrPathElem].moveTo(x1, y1);
break;
}
case 2: {
this.geometry.pathLst[arrPathElem].lnTo(x1, y1);
break;
}
case 3: {
this.geometry.pathLst[arrPathElem].arcTo(x1/*wR*/, y1/*hR*/, x2/*stAng*/, y2/*swAng*/);
break;
}
case 4: {
this.geometry.pathLst[arrPathElem].quadBezTo(x1, y1, x2, y2);
break;
}
case 5: {
this.geometry.pathLst[arrPathElem].cubicBezTo(x1, y1, x2, y2, x3, y3);
break;
}
case 6: {
this.geometry.pathLst[arrPathElem].close();
break;
}
}
}, this, []);
};
EditShapeGeometryTrack.prototype.getRectBounds = function() {
var oTr = this.transform;
var aTX = [];
var aTY = [];
aTX.push(oTr.TransformPointX(this.xMin, this.yMin));
aTX.push(oTr.TransformPointX(this.xMax, this.yMin));
aTX.push(oTr.TransformPointX(this.xMax, this.yMax));
aTX.push(oTr.TransformPointX(this.xMin, this.yMax));
aTY.push(oTr.TransformPointY(this.xMin, this.yMin));
aTY.push(oTr.TransformPointY(this.xMax, this.yMin));
aTY.push(oTr.TransformPointY(this.xMax, this.yMax));
aTY.push(oTr.TransformPointY(this.xMin, this.yMax));
var dXLT = Math.min.apply(Math, aTX);
var dXRB = Math.max.apply(Math, aTX);
var dYLT = Math.min.apply(Math, aTY);
var dYRB = Math.max.apply(Math, aTY);
return {XLT: dXLT, XRB: dXRB, YLT: dYLT, YRB: dYRB }
};
EditShapeGeometryTrack.prototype.getXfrmOffset = function () {
const oRectBounds = this.getRectBounds();
const dXLT = oRectBounds.XLT;
const dXRB = oRectBounds.XRB;
const dYLT = oRectBounds.YLT;
const dYRB = oRectBounds.YRB;
const dExtX = this.xMax - this.xMin;
const dExtY = this.yMax - this.yMin;
const dXC = (dXLT + dXRB) / 2.0;
const dYC = (dYLT + dYRB) / 2.0;
let dOffX = dXC - dExtX / 2.0;
let dOffY = dYC - dExtY / 2.0;
const oGroup = this.originalObject.group;
if (oGroup) {
dOffX -= oGroup.transform.tx;
dOffY -= oGroup.transform.ty;
}
return { OffX: dOffX, OffY: dOffY };
};
EditShapeGeometryTrack.prototype.checkDrawingPartWithHistory = function () {
if (this.originalObject.checkDrawingPartWithHistory) {
const newObject = this.originalObject.checkDrawingPartWithHistory();
if (newObject) {
this.originalObject = newObject;
this.originalShape = newObject;
}
}
};
EditShapeGeometryTrack.prototype.trackEnd = function (bWord) {
this.addCommandsInPathInfo();
const oSpPr = this.originalObject.spPr;
const oXfrm = oSpPr.xfrm;
const dExtX = this.xMax - this.xMin;
const dExtY = this.yMax - this.yMin;
if (this.originalObject.animMotionTrack) {
const oOffset = this.getXfrmOffset();
this.originalObject.updateAnimation(oOffset.OffX, oOffset.OffY, dExtX, dExtY, 0, this.geometry, true);
} else {
oXfrm.setExtX(dExtX);
oXfrm.setExtY(dExtY);
if (!AscFormat.isRealNumber(oXfrm.rot)) {
oXfrm.setRot(0);
}
if (bWord && !this.originalObject.group) {
oXfrm.setOffX(0);
oXfrm.setOffY(0);
} else {
const oOffset = this.getXfrmOffset();
oXfrm.setOffX(oOffset.OffX);
oXfrm.setOffY(oOffset.OffY);
}
oSpPr.setGeometry(this.geometry.createDuplicate());
this.originalObject.checkDrawingBaseCoords();
}
if (this.addedPointIdx !== null) {
const oGmSelection = this.getGmSelection();
if (oGmSelection) {
oGmSelection.setGmEditPointIdx(this.addedPointIdx);
}
}
if (this.drawingObjects) {
this.drawingObjects.resetConnectors([this.originalObject]);
}
};
EditShapeGeometryTrack.prototype.convertToBezier = function() {
var geometry = this.geometry;
AscFormat.ExecuteNoHistory(
function () {
var countArc = 0;
for(var j = 0; j < geometry.pathLst.length; j++) {
geometry.pathLst[j].ArrPathCommandInfo = [];
var pathPoints = geometry.pathLst[j].ArrPathCommand;
var arrCommandsType = [];
for (var i = 0; i < pathPoints.length; i++) {
var elem = pathPoints[i];
var elemX = null, elemY = null;
switch (elem.id) {
case PathType.POINT:
elemX = elem.X;
elemY = elem.Y;
arrCommandsType.push(PathType.POINT);
break;
case PathType.LINE:
elemX = elem.X;
elemY = elem.Y;
arrCommandsType.push(PathType.LINE);
break;
case PathType.ARC:
var oDrawer = new AscFormat.PathAccumulator();
AscFormat.ArcToCurvers(oDrawer, elem.stX, elem.stY, elem.wR, elem.hR, elem.stAng, elem.swAng);
var aPathCommands = oDrawer.pathCommand;
pathPoints.splice(i, 1);
for(var nIdx = 0; nIdx < aPathCommands.length; ++nIdx) {
var oCommand = aPathCommands[nIdx];
switch (oCommand.id) {
case AscFormat.moveTo: {
if(nIdx === 0 && pathPoints[i - 1] && pathPoints[i - 1].id === PathType.POINT) {
pathPoints[i - 1].X = oCommand.X;
pathPoints[i - 1].Y = oCommand.Y;
}
break;
}
case AscFormat.bezier4: {
if((oCommand.X0 !== oCommand.X1 || oCommand.X1 !== oCommand.X2) && (oCommand.Y0 !== oCommand.Y1 || oCommand.Y1 !== oCommand.Y2)) {
var elemArc = {
id: PathType.ARC,
X0: oCommand.X0,
Y0: oCommand.Y0,
X1: oCommand.X1,
Y1: oCommand.Y1,
X2: oCommand.X2,
Y2: oCommand.Y2
};
arrCommandsType.push(PathType.ARC);
pathPoints.splice(i, 0, elemArc);
i++;
}
break;
}
}
}
i = i - 1;
countArc++;
break;
case PathType.BEZIER_3:
elemX = elem.X1;
elemY = elem.Y1;
arrCommandsType.push(PathType.BEZIER_3);
break;
case PathType.BEZIER_4:
elemX = elem.X2;
elemY = elem.Y2;
arrCommandsType.push(PathType.BEZIER_4);
break;
case PathType.END:
arrCommandsType.push(PathType.END);
break;
}
if (elemX !== undefined && elemY !== undefined && elem.id !== PathType.ARC && elem.id !== PathType.END) {
pathPoints[i] = elem;
}
}
var start_index = 0;
// insert pathCommand when end point is not equal to the start point, then draw a line between them
for (var cur_index = 1; cur_index < pathPoints.length; cur_index++) {
if(pathPoints[cur_index].id === PathType.POINT) {
start_index = cur_index;
}
if (pathPoints[cur_index].id === PathType.END && (!pathPoints[cur_index + 1] || pathPoints[cur_index + 1].id === PathType.POINT)) {
var prevCommand = pathPoints[cur_index - 1];
var pointCommand = pathPoints[start_index];
var prevCommandX = this.getCommandLastPointX(prevCommand);
var prevCommandY = this.getCommandLastPointY(prevCommand);
var firstPointX = parseFloat(pathPoints[start_index].X.toFixed(2));
var firstPointY = parseFloat(pathPoints[start_index].Y.toFixed(2));
var lastPointX = parseFloat(prevCommandX.toFixed(2));
var lastPointY = parseFloat(prevCommandY.toFixed(2));
if (firstPointX !== lastPointX || firstPointY !== lastPointY) {
pathPoints.splice(cur_index, 0,
{
id: PathType.LINE,
X: pointCommand.X,
Y: pointCommand.Y
});
arrCommandsType.splice(cur_index, 0, PathType.LINE);
++cur_index;
}
}
}
var oThis = this;
pathPoints.forEach(function (elem, cur_index) {
var prevCommand = pathPoints[cur_index - 1];
if(prevCommand) {
var prevCommandX = oThis.getCommandLastPointX(prevCommand);
var prevCommandY = oThis.getCommandLastPointY(prevCommand);
}
switch (elem.id) {
case 1:
pathPoints[cur_index] = {
id: PathType.LINE,
X0: (prevCommandX + elem.X / 2) / (3 / 2),
Y0: (prevCommandY + elem.Y / 2) / (3 / 2),
X1: (prevCommandX + elem.X * 2) / 3,
Y1: (prevCommandY + elem.Y * 2) / 3,
X2: elem.X,
Y2: elem.Y
};
break;
case 3:
pathPoints[cur_index] = {
id: PathType.BEZIER_3,
X0: (elem.X0 + prevCommandX) / 2,
Y0: (elem.Y0 + prevCommandY) / 2,
X1: (elem.X1 + elem.X0) / 2,
Y1: (elem.Y1 + elem.Y0) / 2,
X2: elem.X1,
Y2: elem.Y1
};
break;
}
});
if(this.arrPathCommandsType.length < geometry.pathLst.length) {
this.arrPathCommandsType.push(arrCommandsType);
}
}
geometry.setPreset(null);
geometry.rectS = null;
geometry.ahXYLst.length = 0;
geometry.ahXYLstInfo.length = 0;
geometry.ahPolarLst.length = 0;
geometry.ahPolarLstInfo.length = 0;
geometry.cnxLstInfo.length = 0;
geometry.cnxLst.length = 0;
}, this, []);
};
EditShapeGeometryTrack.prototype.createGeometryEditList = function() {
AscFormat.ExecuteNoHistory(function(){
var geometry = this.geometry;
this.gmEditList = [];
for(var j = 0; j < geometry.pathLst.length; j++) {
var start_index = 0, isFirstAndLastPointsEqual = false;
var pathPoints = geometry.pathLst[j].ArrPathCommand;
for (var index = 0; index < pathPoints.length; index++) {
var curCommand = pathPoints[index];
var nextPath = pathPoints[index + 1];
if (curCommand.id !== PathType.END) {
var nextIndex = 0;
var isAddingStartPoint = false;
if (!nextPath || nextPath.id === PathType.POINT || nextPath.id === PathType.END) {
nextIndex = isFirstAndLastPointsEqual ? (index === start_index ? null : start_index + 1) : null;
if (nextPath) {
start_index = nextPath.id === PathType.POINT ? index + 1 : index + 2;
isFirstAndLastPointsEqual = false;
}
} else {
nextIndex = index + 1;
}
if (curCommand.id === PathType.POINT) {
//finding last point in figure element
var i = 1;
while((index + i <= pathPoints.length - 1) && pathPoints[index + i].id !== PathType.POINT) {
++i;
}
if(pathPoints[index + i - 1].id === PathType.END) {
--i;
}
var firstPoint = pathPoints[start_index];
var firstPointX = this.getCommandLastPointX(firstPoint);
firstPointX = parseFloat(firstPointX.toFixed(2));
var firstPointY = this.getCommandLastPointY(firstPoint);
firstPointY = parseFloat(firstPointY.toFixed(2));
var lastPoint = pathPoints[index + i - 1];
var lastPointX = this.getCommandLastPointX(lastPoint);
lastPointX = parseFloat(lastPointX.toFixed(2));
var lastPointY = this.getCommandLastPointY(lastPoint);
lastPointY = parseFloat(lastPointY.toFixed(2));
(firstPointX !== lastPointX || firstPointY !== lastPointY) ? isAddingStartPoint = true : isFirstAndLastPointsEqual = true;
}
if(pathPoints[index].id !== PathType.POINT || isAddingStartPoint) {
var nextCommand = pathPoints[nextIndex];
var g1X = curCommand.X1;
var g1Y = curCommand.Y1;
var g2X = nextCommand ? nextCommand.X0 : undefined;
var g2Y = nextCommand ? nextCommand.Y0 : undefined;
var curPoint = {
g1X: g1X,
g1Y: g1Y,
g2X: g2X,
g2Y: g2Y,
X: (this.getCommandLastPointX(curCommand)),
Y: (this.getCommandLastPointY(curCommand)),
pathC1: index,
pathC2: nextIndex,
pathIndex: j
};
this.gmEditList.push(curPoint);
}
}
curCommand.id = (curCommand.id !== PathType.POINT && curCommand.id !== PathType.END) ? PathType.BEZIER_4 : curCommand.id;
}
}
var startIndex = 0;
for (var cur_index = 0; cur_index < this.gmEditList.length; cur_index++) {
if(this.gmEditList[cur_index].pathC2 > this.gmEditList[cur_index].pathC1) {
this.gmEditList[cur_index].nextPoint = this.gmEditList[cur_index + 1];
this.gmEditList[cur_index + 1].prevPoint = this.gmEditList[cur_index];
} else {
this.gmEditList[cur_index].nextPoint = this.gmEditList[startIndex];
this.gmEditList[startIndex].prevPoint = this.gmEditList[cur_index];
startIndex = cur_index + 1;
}
}
//update gmEditPoint coords
var gmEditPoint = this.getGmEditPt();
if(gmEditPoint) {
var pointC1 = gmEditPoint.pathC1;
var pointC2 = gmEditPoint.pathC2;
var isHitInFirstCPoint = gmEditPoint.isHitInFirstCPoint;
var isHitInSecondCPoint = gmEditPoint.isHitInSecondCPoint;
var oThis = this;
this.gmEditList.forEach(function(elem) {
if(elem.pathIndex === gmEditPoint.pathIndex && elem.pathC1 === pointC1 && elem.pathC2 === pointC2) {
gmEditPoint = elem;
gmEditPoint.isHitInFirstCPoint = isHitInFirstCPoint;
gmEditPoint.isHitInSecondCPoint = isHitInSecondCPoint;
}
})
}
}, this, []);
};
EditShapeGeometryTrack.prototype.calculateMinMax = function() {
var geometry = this.geometry;
var last_x = this.gmEditList[0].X,
last_y = this.gmEditList[0].Y,
xMin = last_x, yMin = last_y, xMax = last_x, yMax = last_y;
for (var i = 0; i < geometry.pathLst.length; i++) {
var arrPathCommand = geometry.pathLst[i].ArrPathCommand;
geometry.pathLst[i].ArrPathCommandInfo = [];
for (var j = 0; j < arrPathCommand.length; ++j) {
var path_command = arrPathCommand[j];
if (path_command.id === PathType.BEZIER_4) {
var bezier_polygon = AscFormat.partition_bezier4(last_x, last_y, path_command.X0, path_command.Y0, path_command.X1, path_command.Y1, path_command.X2, path_command.Y2, AscFormat.APPROXIMATE_EPSILON);
for (var point_index = 1; point_index < bezier_polygon.length; ++point_index) {
var cur_point = bezier_polygon[point_index];
if (xMin > cur_point.x)
xMin = cur_point.x;
if (xMax < cur_point.x)
xMax = cur_point.x;
if (yMin > cur_point.y)
yMin = cur_point.y;
if (yMax < cur_point.y)
yMax = cur_point.y;
last_x = path_command.X2;
last_y = path_command.Y2;
}
}
}
}
this.xMin = xMin;
this.xMax = xMax;
this.yMin = yMin;
this.yMax = yMax;
};
EditShapeGeometryTrack.prototype.addCommandsInPathInfo = function() {
AscFormat.ExecuteNoHistory(
function(){
var geometry = this.geometry;
this.geometry.setPreset(null);
this.calculateMinMax();
var w = this.xMax - this.xMin, h = this.yMax - this.yMin;
var kw, kh, pathW, pathH;
if (w > 0) {
pathW = 43200;
kw = 43200 / w;
}
else {
pathW = 0;
kw = 0;
}
if (h > 0) {
pathH = 43200;
kh = 43200 / h;
}
else {
pathH = 0;
kh = 0;
}
for (var i = 0; i < geometry.pathLst.length; i++) {
var oPath = geometry.pathLst[i];
oPath.ArrPathCommandInfo.length = 0;
var arrPathCommand = oPath.ArrPathCommand;
var lastX = null, lastY = null;
for (var j = 0; j < arrPathCommand.length; ++j) {
switch (arrPathCommand[j].id) {
case PathType.POINT: {
lastX = arrPathCommand[j].X;
lastY = arrPathCommand[j].Y;
this.addPathCommandInfo(1, i, (((arrPathCommand[j].X - this.xMin) * kw) >> 0) + "", (((arrPathCommand[j].Y - this.yMin) * kh) >> 0) + "");
break;
}
case PathType.BEZIER_4: {
//check if it is possible to add line
var bLine = false;
if(AscFormat.isRealNumber(lastX) && AscFormat.isRealNumber(lastY)) {
var dX = arrPathCommand[j].X0 - lastX;
var dY = arrPathCommand[j].Y0 - lastY;
var dEps = 0.01;
if(AscFormat.fApproxEqual(dY, 0, dEps)) {
if(AscFormat.fApproxEqual(arrPathCommand[j].Y1 - lastY, 0, dEps) && AscFormat.fApproxEqual(arrPathCommand[j].Y2 - lastY, 0, dEps)) {
bLine = true;
}
}
else {
var dK = dX / dY;
dX = arrPathCommand[j].X1 - lastX;
dY = arrPathCommand[j].Y1 - lastY;
if(!AscFormat.fApproxEqual(dY, 0, dEps)) {
var dK1 = dX / dY;
if(AscFormat.fApproxEqual(dK1, dK, dEps)) {
dX = arrPathCommand[j].X2 - lastX;
dY = arrPathCommand[j].Y2 - lastY;
if(!AscFormat.fApproxEqual(dY, 0, dEps)) {
dK1 = dX / dY;
if(AscFormat.fApproxEqual(dK1, dK, dEps)) {
bLine = true;
}
}
}
}
}
}
if(bLine) {
this.addPathCommandInfo(2, i, (((arrPathCommand[j].X2 - this.xMin) * kw) >> 0) + "", (((arrPathCommand[j].Y2 - this.yMin) * kh) >> 0) + "");
}
else {
this.addPathCommandInfo(5, i, (((arrPathCommand[j].X0 - this.xMin) * kw) >> 0) + "", (((arrPathCommand[j].Y0 - this.yMin) * kh) >> 0) + "", (((arrPathCommand[j].X1 - this.xMin) * kw) >> 0) + "", (((arrPathCommand[j].Y1 - this.yMin) * kh) >> 0) + "", (((arrPathCommand[j].X2 - this.xMin) * kw) >> 0) + "", (((arrPathCommand[j].Y2 - this.yMin) * kh) >> 0) + "");
}
lastX = arrPathCommand[j].X2;
lastY = arrPathCommand[j].Y2;
break;
}
case PathType.END: {
this.addPathCommandInfo(6, i);
}
}
}
geometry.pathLst[i].pathW = pathW;
geometry.pathLst[i].pathH = pathH;
}
}, this, []
);
};
EditShapeGeometryTrack.prototype.findBezier4Param = function(XT, YT, X0, Y0, X1, Y1, X2, Y2, X3, Y3) {
var nSteps = 1000;
var dStride = 1/nSteps;
var dT = 0;
var dTResult = dT;
var CX = this.bezier4Pos(dT, X0, X1, X2, X3);
var CY = this.bezier4Pos(dT, Y0, Y1, Y2, Y3);
var dDist = Math.abs(XT - CX) + Math.abs(YT - CY);
var dMinDist = dDist;
for(var nStep = 0; nStep < nSteps; ++nStep) {
dT+= dStride;
CX = this.bezier4Pos(dT, X0, X1, X2, X3);
CY = this.bezier4Pos(dT, Y0, Y1, Y2, Y3);
dDist = Math.abs(XT - CX) + Math.abs(YT - CY);
if(dDist < dMinDist) {
dTResult = dT;
dMinDist = dDist;
}
}
return dTResult;
};
EditShapeGeometryTrack.prototype.findBezier3Param = function(XT, YT, X0, Y0, X1, Y1, X2, Y2) {
var nSteps = 1000;
var dStride = 1/nSteps;
var dT = 0;
var dTResult = dT;
var CX = this.bezier3Pos(dT, X0, X1, X2);
var CY = this.bezier3Pos(dT, Y0, Y1, Y2);
var dDist = Math.abs(XT - CX) + Math.abs(YT - CY);
var dMinDist = dDist;
for(var nStep = 0; nStep < nSteps; ++nStep) {
dT+= dStride;
CX = this.bezier3Pos(dT, X0, X1, X2);
CY = this.bezier3Pos(dT, Y0, Y1, Y2);
dDist = Math.abs(XT - CX) + Math.abs(YT - CY);
if(dDist < dMinDist) {
dTResult = dT;
dMinDist = dDist;
}
}
return dTResult;
};
EditShapeGeometryTrack.prototype.bezier4Pos = function(t, C0, C1, C2, C3) {
var dDT = 1 - t;
var dDT2 = dDT*dDT;
var dDT3 = dDT2*dDT;
var dT = t;
var dT2 = dT*dT;
var dT3 = dT2*dT;
return C0*dDT3 + 3*C1*t*dDT2 + 3*C2*dDT*t*t + C3*t*t*t;
};
EditShapeGeometryTrack.prototype.bezier3Pos = function(t, C0, C1, C2) {
var dDT = 1 - t;
var dDT2 = dDT*dDT;
var dT = t;
var dT2 = dT*dT;
return C0*dDT2 + 2*C1*t*dDT + C2*dT2;
};
EditShapeGeometryTrack.prototype.addPoint = function(oAddingPoint, X, Y) {
return AscFormat.ExecuteNoHistory(function() {
var geometry = this.geometry;
var commandIndex = oAddingPoint.commandIndex;
var pathIndex = oAddingPoint.pathIndex;
var tx = this.invertTransform.TransformPointX(X, Y);
var ty = this.invertTransform.TransformPointY(X, Y);
var pathElem = geometry.pathLst[pathIndex].ArrPathCommand;
var curCommand = pathElem[commandIndex];
var gmEditListElem = this.gmEditList.filter(function(elem) {
return elem.pathC1 === commandIndex;
})[0];
var prevCommand_1 = gmEditListElem.prevPoint;
var prevCommand_2 = prevCommand_1.prevPoint;
var curCommandX = this.getCommandLastPointX(curCommand);
var curCommandY = this.getCommandLastPointY(curCommand);
var X0 = prevCommand_1.X + (tx - prevCommand_2.X) / 4;
var Y0 = prevCommand_1.Y + (ty - prevCommand_2.Y) / 4;
var X1 = tx - (curCommandX - prevCommand_1.X) / 4;
var Y1 = ty - (curCommandY - prevCommand_1.Y) / 4;
var newPathElem = {id: PathType.BEZIER_4, X0: X0, Y0: Y0, X1: X1, Y1: Y1, X2: tx, Y2: ty};
///curCommand.X0 = tx + (curCommandX - prevCommand_1.X) / 4;
///curCommand.Y0 = ty + (curCommandY - prevCommand_1.Y) / 4;
//pathElem.splice(commandIndex, 0, newPathElem);
// this.arrPathCommandsType[pathIndex].splice(commandIndex, 0, PathType.BEZIER_4);
var oPrevCommand = pathElem[commandIndex - 1];
if(!oPrevCommand) {
return;
}
var dSplitT;
var dPrevX = this.getCommandLastPointX(oPrevCommand);
var dPrevY = this.getCommandLastPointY(oPrevCommand);
var aCommands;
var oFirstCommand, oSecondCommand;
var nIdx;
if(curCommand.id === AscFormat.bezier4) {
dSplitT = this.findBezier4Param(tx, ty, dPrevX, dPrevY, curCommand.X0, curCommand.Y0,
curCommand.X1, curCommand.Y1,
curCommand.X2, curCommand.Y2);
aCommands = splitCurveAt(dSplitT, dPrevX, dPrevY, curCommand.X0, curCommand.Y0,
curCommand.X1, curCommand.Y1,
curCommand.X2, curCommand.Y2);
nIdx = 2;
oFirstCommand = {
id:AscFormat.bezier4,
X0: aCommands[nIdx++],
Y0: aCommands[nIdx++],
X1: aCommands[nIdx++],
Y1: aCommands[nIdx++],
X2: aCommands[nIdx++],
Y2: aCommands[nIdx++]
};
oSecondCommand = {
id:AscFormat.bezier4,
X0: aCommands[nIdx++],
Y0: aCommands[nIdx++],
X1: aCommands[nIdx++],
Y1: aCommands[nIdx++],
X2: aCommands[nIdx++],
Y2: aCommands[nIdx++]
};
pathElem.splice(commandIndex, 1);
this.arrPathCommandsType[pathIndex].splice(commandIndex, 1);
pathElem.splice(commandIndex, 0, oFirstCommand);
this.arrPathCommandsType[pathIndex].splice(commandIndex, 0, PathType.BEZIER_4);
pathElem.splice(commandIndex + 1, 0, oSecondCommand);
this.arrPathCommandsType[pathIndex].splice(commandIndex + 1, 0, PathType.BEZIER_4);
}
else if(curCommand.id === AscFormat.bezier3) {
dSplitT = this.findBezier3Param(tx, ty, dPrevX, dPrevY, curCommand.X0, curCommand.Y0,
curCommand.X1, curCommand.Y1);
aCommands = splitCurveAt(dSplitT, dPrevX, dPrevY, curCommand.X0, curCommand.Y0,
curCommand.X1, curCommand.Y1);
nIdx = 2;
oFirstCommand = {
id:AscFormat.bezier4,
X0: aCommands[nIdx++],
Y0: aCommands[nIdx++],
X1: aCommands[nIdx++],
Y1: aCommands[nIdx++],
X2: aCommands[nIdx++],
Y2: aCommands[nIdx++]
};
oSecondCommand = {
id:AscFormat.bezier4,
X0: aCommands[nIdx++],
Y0: aCommands[nIdx++],
X1: aCommands[nIdx++],
Y1: aCommands[nIdx++],
X2: aCommands[nIdx++],
Y2: aCommands[nIdx++]
};
pathElem.splice(commandIndex, 1);
this.arrPathCommandsType[pathIndex].splice(commandIndex, 1);
pathElem.splice(commandIndex, 0, oFirstCommand);
this.arrPathCommandsType[pathIndex].splice(commandIndex, 0, PathType.BEZIER_4);
pathElem.splice(commandIndex + 1, 0, oSecondCommand);
this.arrPathCommandsType[pathIndex].splice(commandIndex + 1, 0, PathType.BEZIER_4);
}
geometry.pathLst[pathIndex].ArrPathCommandInfo = [];
this.addCommandsInPathInfo();
this.createGeometryEditList();
var oHitData = this.hitToGmEditLst(X, Y, true);
if(oHitData) {
this.addedPointIdx = oHitData.gmEditPointIdx;
var oPt = this.gmEditList[this.addedPointIdx];
if(oPt) {
var oOriginalAddedPoint = {
g1X: oPt.g1X,
g1Y: oPt.g1Y,
g2X: oPt.g2X,
g2Y: oPt.g2Y,
X: oPt.X,
Y: oPt.Y,
pathC1: oPt.pathC1,
pathC2: oPt.pathC2,
pathIndex: oPt.pathC2
};
this.originalAddedPoint = oOriginalAddedPoint;
}
var oGeomSelection = this.getGmSelection();
if(oGeomSelection) {
oGeomSelection.resetGmEditPointIdx();
}
}
// AscCommon.History.Create_NewPoint(0);
// this.trackEnd();
// editor.WordControl.m_oLogicDocument.Recalculate();
}, this, []);
};
EditShapeGeometryTrack.prototype.getCommandLastPointX = function(oCommand) {
return this.getCommandLastPointCoord(oCommand.X, oCommand.X1, oCommand.X2);
};
EditShapeGeometryTrack.prototype.getCommandLastPointY = function(oCommand) {
return this.getCommandLastPointCoord(oCommand.Y, oCommand.Y1, oCommand.Y2);
};
EditShapeGeometryTrack.prototype.getCommandLastPointCoord = function(C, C1, C2) {
if(C !== undefined) {
return C;
}
if(C2 !== undefined) {
return C2;
}
if(C1 !== undefined) {
return C1;
}
return null;
};
EditShapeGeometryTrack.prototype.deletePoint = function() {
AscFormat.ExecuteNoHistory(function() {
var geometry = this.geometry;
var gmEditPoint = this.getGmEditPt();
if(!gmEditPoint) {
return;
}
var pathIndex = gmEditPoint.pathIndex,
pathElem = geometry.pathLst[pathIndex],
arrayCommands = geometry.pathLst[pathIndex].ArrPathCommand;
// if(pathElem && pathElem.stroke === true && pathElem.fill === "none") {
// return;
// }
var pathC1 = gmEditPoint.pathC1,
pathC2 = gmEditPoint.pathC2,
pointCount = 0;
var increment_index = pathC1;
var decrement_index = pathC1;
while(arrayCommands[decrement_index] && arrayCommands[decrement_index].id !== PathType.POINT) {
--decrement_index;
++pointCount;
}
while(arrayCommands[increment_index + 1] && arrayCommands[increment_index + 1].id !== PathType.END) {
++increment_index;
++pointCount;
}
if(pointCount > 2) {
if (pathC1 > pathC2) {
if(arrayCommands[pathC1 - 1]) {
var prevCommandX = this.getCommandLastPointX(arrayCommands[pathC1 - 1]);
var prevCommandY = this.getCommandLastPointY(arrayCommands[pathC1 - 1]);
arrayCommands[decrement_index] = {id: PathType.POINT, X: prevCommandX, Y: prevCommandY};
}
// var t = pathC1;
// pathC1 = pathC2;
// pathC2 = t;
}
var curArrCommandsType = this.arrPathCommandsType[pathIndex];
//if next command is line, then recalculate to make it
var nextPath = gmEditPoint.nextPoint.pathC1;
if (curArrCommandsType[nextPath] && (curArrCommandsType[nextPath] === PathType.LINE)) {
var prevX = gmEditPoint.prevPoint.X, prevY = gmEditPoint.prevPoint.Y,
nextX = gmEditPoint.nextPoint.X, nextY = gmEditPoint.nextPoint.Y;
arrayCommands[nextPath].X0 = (nextX + prevX * 2) / 3;
arrayCommands[nextPath].Y0 = (nextY + prevY * 2) / 3;
arrayCommands[nextPath].X1 = (nextX + prevX / 2) / (3 / 2);
arrayCommands[nextPath].Y1 = (nextY + prevY / 2) / (3 / 2);
}
var oNextCommand = arrayCommands[pathC2];
var oFirstCommand = arrayCommands.splice(pathC1, 1)[0];
curArrCommandsType.splice(pathC1, 1);
if(oFirstCommand.id === AscFormat.bezier3 && oNextCommand.id === AscFormat.bezier3) {
oNextCommand.X0 = (oNextCommand.X0 + oFirstCommand.X0)/2;
oNextCommand.Y0 = (oNextCommand.Y0 + oFirstCommand.Y0)/2;
}
if(oFirstCommand.id === AscFormat.bezier4 && oNextCommand.id === AscFormat.bezier4) {
oNextCommand.X0 = oFirstCommand.X0;
oNextCommand.Y0 = oFirstCommand.Y0;
}
this.createGeometryEditList();
this.addCommandsInPathInfo();
}
var oGeomSelection = this.getGmSelection();
if(oGeomSelection) {
oGeomSelection.resetGmEditPointIdx();
}
}, this, []);
};
//EditShapeGeometryTrack.prototype.AddGeomPoint = function(id, X, Y, g1X, g1Y, g2X, g2Y, pathC1, pathC2, prevPoint, nextPoint, isHitInFirstCPoint, isHitInSecondCPoint, isStartPoint, pathIndex)
//{
// this.gmEditPoint = {};
// this.gmEditPoint.id = id;
// this.gmEditPoint.X = X;
// this.gmEditPoint.Y = Y;
// this.gmEditPoint.g1X = g1X;
// this.gmEditPoint.g1Y = g1Y;
// this.gmEditPoint.g2X = g2X;
// this.gmEditPoint.g2Y = g2Y;
// this.gmEditPoint.pathC1 = pathC1;
// this.gmEditPoint.pathC2 = pathC2;
// this.gmEditPoint.nextPoint = {
// id: nextPoint.id, X: nextPoint.X, Y: nextPoint.Y, g1X: nextPoint.g1X, g1Y: nextPoint.g1Y,
// g2X: nextPoint.g2X, g2Y: nextPoint.g2Y, pathC1 : nextPoint.pathC1, pathC2 : nextPoint.pathC2
// };
// this.gmEditPoint.prevPoint = {
// id: prevPoint.id, X: prevPoint.X, Y: prevPoint.Y, g1X: prevPoint.g1X, g1Y: prevPoint.g1Y,
// g2X: prevPoint.g2X, g2Y: prevPoint.g2Y, pathC1 : prevPoint.pathC1, pathC2 : prevPoint.pathC2
// };
// this.gmEditPoint.isHitInFirstCPoint = isHitInFirstCPoint;
// this.gmEditPoint.isHitInSecondCPoint = isHitInSecondCPoint;
// this.gmEditPoint.isStartPoint = isStartPoint;
// this.gmEditPoint.pathIndex = pathIndex;
//
// this.originalEditPoint = {X: X, Y: Y, g1X: g1X, g1Y: g1Y, g2X: g2X, g2Y: g2Y};
//};
EditShapeGeometryTrack.prototype.hitToGmEditLst = function(x, y, findNearest) {
var dx, dy;
var distance = this.originalObject.convertPixToMM(AscCommon.global_mouseEvent.KoefPixToMM * AscCommon.TRACK_CIRCLE_RADIUS);
var tx = this.invertTransform.TransformPointX(x, y);
var ty = this.invertTransform.TransformPointY(x, y);
var minDist = 10000;
var oCandidate = null;
for (var i = this.gmEditList.length - 1; i >= 0; i--) {
var gmArr = this.gmEditList[i];
dx = tx - gmArr.X;
dy = ty - gmArr.Y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
oCandidate = new CGeomHitData(i, null, null, false);
}
}
if(findNearest) {
return oCandidate;
}
if (minDist < distance) {
return oCandidate;
}
return null;
};
EditShapeGeometryTrack.prototype.hitToGeomEdit = function(oCanvas, x, y) {
if(!this.isCorrect()) {
return null;
}
var dxC1, dyC1, dxC2, dyC2;
var distance = this.originalObject.convertPixToMM(AscCommon.global_mouseEvent.KoefPixToMM * AscCommon.TRACK_CIRCLE_RADIUS);
var geometry = this.geometry;
var gmEditPoint = this.getGmEditPt();
var tx = this.invertTransform.TransformPointX(x, y);
var ty = this.invertTransform.TransformPointY(x, y);
if(gmEditPoint) {
// не разрешаем ломать линии в pdf
if (Asc.editor.isPdfEditor() == false) {
dxC1 = tx - gmEditPoint.g1X;
dyC1 = ty - gmEditPoint.g1Y;
dxC2 = tx - gmEditPoint.g2X;
dyC2 = ty - gmEditPoint.g2Y;
if (Math.sqrt(dxC1 * dxC1 + dyC1 * dyC1) < distance) {
return new CGeomHitData(this.getGmEditPtIdx(), true, false, false);
} else if (Math.sqrt(dxC2 * dxC2 + dyC2 * dyC2) < distance) {
return new CGeomHitData(this.getGmEditPtIdx(), false, true, false);
}
}
}
var oGeomData = this.hitToGmEditLst(x, y, false);
if(oGeomData) {
return oGeomData;
}
// не разрешаем ломать линии в pdf
if (Asc.editor.isPdfEditor())
return null;
var oAddingPoint = {pathIndex: null, commandIndex: null};
var isHitInPath = geometry.hitInPath(oCanvas, tx, ty, oAddingPoint);
if(isHitInPath) {
return new CGeomHitData(null, null, null, oAddingPoint);
}
return null;
};
EditShapeGeometryTrack.prototype.isCorrect = function() {
if(this.originalGeometry !== this.getOriginalObjectGeometry() ||
!AscFormat.fApproxEqual(this.originalX, this.originalObject.x) ||
!AscFormat.fApproxEqual(this.originalY, this.originalObject.y) ||
!AscFormat.fApproxEqual(this.originalExtX, this.originalObject.extX) ||
!AscFormat.fApproxEqual(this.originalExtY, this.originalObject.extY) ||
!AscFormat.fApproxEqual(this.originalRot, this.originalObject.rot)) {
return false;
}
return true;
};
function CGeomHitData(gmEditPointIdx, isHitInFirstCPoint, isHitInSecondCPoint, addingNewPoint) {
this.gmEditPointIdx = gmEditPointIdx;
this.isHitInFirstCPoint = isHitInFirstCPoint;
this.isHitInSecondCPoint = isHitInSecondCPoint;
this.addingNewPoint = addingNewPoint;
}
CGeomHitData.prototype.getPtIdx = function() {
return this.gmEditPointIdx;
};
window['AscFormat'] = window['AscFormat'] || {};
window['AscFormat'].EditShapeGeometryTrack = EditShapeGeometryTrack;
function splitCurveAt(t, x1, y1, x2, y2, x3, y3, x4, y4) {
var x1_, y1_, x2_, y2_, x3_, y3_, x4_, y4_;
if(x4 === undefined || y4 === undefined) {
x1_ = x1;
y1_ = y1;
x2_ = x1 + (2/3)*(x2 - x1);
y2_ = y1 + (2/3)*(y2 - y1);
x3_ = x3 + (2/3)*(x2 - x3);
y3_ = y3 + (2/3)*(y2 - y3);
x4_ = x3;
y4_ = y3;
}
else {
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
x3_ = x3;
y3_ = y3;
x4_ = x4;
y4_ = y4;
}
var x12 = (x2_-x1_)*t+x1_;
var y12 = (y2_-y1_)*t+y1_;
var x23 = (x3_-x2_)*t+x2_;
var y23 = (y3_-y2_)*t+y2_;
var x34 = (x4_-x3_)*t+x3_;
var y34 = (y4_-y3_)*t+y3_;
var x123 = (x23-x12)*t+x12;
var y123 = (y23-y12)*t+y12;
var x234 = (x34-x23)*t+x23;
var y234 = (y34-y23)*t+y23;
var x1234 = (x234-x123)*t+x123;
var y1234 = (y234-y123)*t+y123;
return [x1_, y1_, x12, y12, x123, y123, x1234, y1234, x234, y234, x34, y34, x4_, y4_];
}
})(window);