/* * (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);