Files
DocumentServer-v-9.2.0/sdkjs/word/Drawing/ShapeDrawer.js
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

2652 lines
95 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){
// Import
var getFullImageSrc2 = AscCommon.getFullImageSrc2;
var CShapeColor = AscFormat.CShapeColor;
var c_oAscFill = Asc.c_oAscFill;
function DrawLineEnd(xEnd, yEnd, xPrev, yPrev, type, w, len, drawer, trans)
{
switch (type)
{
case AscFormat.LineEndType.None:
break;
case AscFormat.LineEndType.Arrow:
{
if (Asc.editor.isPdfEditor() == true) {
drawer.CheckDash();
}
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.ReverseArrow:
{
if (Asc.editor.isPdfEditor() == true) {
drawer.CheckDash();
}
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd - len * _ex;
var tmpy = yEnd - len * _ey;
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.Diamond:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len/2 * _ex;
var tmpy = yEnd + len/2 * _ey;
var x1 = xEnd + _vx * w/2;
var y1 = yEnd + _vy * w/2;
var x3 = xEnd - _vx * w/2;
var y3 = yEnd - _vy * w/2;
var tmpx2 = xEnd - len/2 * _ex;
var tmpy2 = yEnd - len/2 * _ey;
drawer._s();
drawer._m(trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
drawer._l(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(tmpx2, tmpy2), trans.TransformPointY(tmpx2, tmpy2));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._z();
if (Asc.editor.isPdfEditor()) {
let oRGBColor;
if (drawer.Shape.GetRGBColor) {
oRGBColor = drawer.Shape.GetRGBColor(drawer.Shape.GetFillColor());
}
else if (drawer.Shape.group) {
oRGBColor = drawer.Shape.group.GetRGBColor(drawer.Shape.group.GetFillColor());
}
if (oRGBColor) {
drawer.Graphics.m_oPen.Color.R = oRGBColor.r;
drawer.Graphics.m_oPen.Color.G = oRGBColor.g;
drawer.Graphics.m_oPen.Color.B = oRGBColor.b;
}
}
drawer.drawStrokeFillStyle();
drawer._e();
drawer._s();
drawer._m(trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
drawer._l(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(tmpx2, tmpy2), trans.TransformPointY(tmpx2, tmpy2));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._z();
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.Square:
{
var angle = Math.atan2(yEnd - yPrev, xEnd - xPrev);
function rotatePoints(aPoints) {
// Поворачиваем каждую вершину вокруг центра
for (var i = 0; i < aPoints.length; i++) {
var x = aPoints[i].x - xEnd;
var y = aPoints[i].y - yEnd;
// Применяем матрицу поворота
var rotatedX = x * Math.cos(angle) - y * Math.sin(angle);
var rotatedY = x * Math.sin(angle) + y * Math.cos(angle);
// Возвращаем вершины на место
aPoints[i].x = rotatedX + xEnd;
aPoints[i].y = rotatedY + yEnd;
}
}
var x1 = xEnd - w/2;
var y1 = yEnd + w/2;
var x2 = xEnd - w/2;
var y2 = yEnd - w/2;
var x3 = xEnd + w/2;
var y3 = yEnd - w/2;
var x4 = xEnd + w/2;
var y4 = yEnd + w/2;
let aSmall = [
{ x: x1, y: y1 },
{ x: x2, y: y2 },
{ x: x3, y: y3 },
{ x: x4, y: y4 }
]
rotatePoints(aSmall);
drawer._s();
drawer._m(trans.TransformPointX(aSmall[0].x, aSmall[0].y), trans.TransformPointY(aSmall[0].x, aSmall[0].y));
for (var i = 1; i < aSmall.length; i++) {
drawer._l(trans.TransformPointX(aSmall[i].x, aSmall[i].y), trans.TransformPointY(aSmall[i].x, aSmall[i].y));
}
drawer._z();
if (Asc.editor.isPdfEditor()) {
let oRGBColor;
if (drawer.Shape.GetRGBColor) {
oRGBColor = drawer.Shape.GetRGBColor(drawer.Shape.GetFillColor());
}
else if (drawer.Shape.group) {
oRGBColor = drawer.Shape.group.GetRGBColor(drawer.Shape.group.GetFillColor());
}
if (oRGBColor) {
drawer.Graphics.m_oPen.Color.R = oRGBColor.r;
drawer.Graphics.m_oPen.Color.G = oRGBColor.g;
drawer.Graphics.m_oPen.Color.B = oRGBColor.b;
}
}
drawer.drawStrokeFillStyle();
drawer._e();
x1 = xEnd - w * 2/4;
y1 = yEnd + w * 2/4;
x2 = xEnd - w * 2/4;
y2 = yEnd - w * 2/4;
x3 = xEnd + w * 2/4;
y3 = yEnd - w * 2/4;
x4 = xEnd + w * 2/4;
y4 = yEnd + w * 2/4;
let aBig = [
{ x: x1, y: y1 },
{ x: x2, y: y2 },
{ x: x3, y: y3 },
{ x: x4, y: y4 }
]
rotatePoints(aBig);
drawer._s();
drawer._m(trans.TransformPointX(aBig[0].x, aBig[0].y), trans.TransformPointY(aBig[0].x, aBig[0].y));
for (var i = 1; i < aBig.length; i++) {
drawer._l(trans.TransformPointX(aBig[i].x, aBig[i].y), trans.TransformPointY(aBig[i].x, aBig[i].y));
}
drawer._z();
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.Oval:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len/2 * _ex;
var tmpy = yEnd + len/2 * _ey;
var tmpx2 = xEnd - len/2 * _ex;
var tmpy2 = yEnd - len/2 * _ey;
var cx1 = tmpx + _vx * 3*w/4;
var cy1 = tmpy + _vy * 3*w/4;
var cx2 = tmpx2 + _vx * 3*w/4;
var cy2 = tmpy2 + _vy * 3*w/4;
var cx3 = tmpx - _vx * 3*w/4;
var cy3 = tmpy - _vy * 3*w/4;
var cx4 = tmpx2 - _vx * 3*w/4;
var cy4 = tmpy2 - _vy * 3*w/4;
drawer._s();
drawer._m(trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
drawer._c(trans.TransformPointX(cx1, cy1), trans.TransformPointY(cx1, cy1),
trans.TransformPointX(cx2, cy2), trans.TransformPointY(cx2, cy2),
trans.TransformPointX(tmpx2, tmpy2), trans.TransformPointY(tmpx2, tmpy2));
drawer._c(trans.TransformPointX(cx4, cy4), trans.TransformPointY(cx4, cy4),
trans.TransformPointX(cx3, cy3), trans.TransformPointY(cx3, cy3),
trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
if (Asc.editor.isPdfEditor()) {
let oRGBColor;
if (drawer.Shape.GetRGBColor) {
oRGBColor = drawer.Shape.GetRGBColor(drawer.Shape.GetFillColor());
}
else if (drawer.Shape.group) {
oRGBColor = drawer.Shape.group.GetRGBColor(drawer.Shape.group.GetFillColor());
}
if (oRGBColor) {
drawer.Graphics.m_oPen.Color.R = oRGBColor.r;
drawer.Graphics.m_oPen.Color.G = oRGBColor.g;
drawer.Graphics.m_oPen.Color.B = oRGBColor.b;
}
}
drawer.drawStrokeFillStyle();
drawer._e();
drawer._s();
drawer._m(trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
drawer._c(trans.TransformPointX(cx1, cy1), trans.TransformPointY(cx1, cy1),
trans.TransformPointX(cx2, cy2), trans.TransformPointY(cx2, cy2),
trans.TransformPointX(tmpx2, tmpy2), trans.TransformPointY(tmpx2, tmpy2));
drawer._c(trans.TransformPointX(cx4, cy4), trans.TransformPointY(cx4, cy4),
trans.TransformPointX(cx3, cy3), trans.TransformPointY(cx3, cy3),
trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.Stealth:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
var x4 = xEnd + (len - w/2) * _ex;
var y4 = yEnd + (len - w/2) * _ey;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._l(trans.TransformPointX(x4, y4), trans.TransformPointY(x4, y4));
drawer._z();
drawer.drawStrokeFillStyle();
drawer._e();
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._l(trans.TransformPointX(x4, y4), trans.TransformPointY(x4, y4));
drawer._z();
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.ReverseTriangle:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd - len * _ex;
var tmpy = yEnd - len * _ey;
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._z();
if (Asc.editor.isPdfEditor()) {
let oRGBColor;
if (drawer.Shape.GetRGBColor) {
oRGBColor = drawer.Shape.GetRGBColor(drawer.Shape.GetFillColor());
}
else if (drawer.Shape.group) {
oRGBColor = drawer.Shape.group.GetRGBColor(drawer.Shape.group.GetFillColor());
}
if (oRGBColor) {
drawer.Graphics.m_oPen.Color.R = oRGBColor.r;
drawer.Graphics.m_oPen.Color.G = oRGBColor.g;
drawer.Graphics.m_oPen.Color.B = oRGBColor.b;
}
}
drawer.drawStrokeFillStyle();
drawer._e();
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._z();
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.Triangle:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._z();
if (Asc.editor.isPdfEditor()) {
let oRGBColor;
if (drawer.Shape.GetRGBColor) {
oRGBColor = drawer.Shape.GetRGBColor(drawer.Shape.GetFillColor());
}
else if (drawer.Shape.group) {
oRGBColor = drawer.Shape.group.GetRGBColor(drawer.Shape.group.GetFillColor());
}
if (oRGBColor) {
drawer.Graphics.m_oPen.Color.R = oRGBColor.r;
drawer.Graphics.m_oPen.Color.G = oRGBColor.g;
drawer.Graphics.m_oPen.Color.B = oRGBColor.b;
}
}
drawer.drawStrokeFillStyle();
drawer._e();
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._z();
drawer.ds();
drawer._e();
break;
}
case AscFormat.LineEndType.Butt:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
var angle = Math.atan2(yEnd - yPrev, xEnd - xPrev);
// Вычисляем координаты конца перпендикулярной линии
var perpendicularLength = w;
var x1 = xEnd + perpendicularLength * Math.cos(angle - Math.PI / 2);
var y1 = yEnd + perpendicularLength * Math.sin(angle - Math.PI / 2);
var x2 = xEnd - perpendicularLength * Math.cos(angle - Math.PI / 2);
var y2 = yEnd - perpendicularLength * Math.sin(angle - Math.PI / 2);
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer.ds();
break;
}
case AscFormat.LineEndType.Slash:
{
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
var angle = Math.atan2(yEnd - yPrev, xEnd - xPrev) + (30 * Math.PI / 180);
// Вычисляем координаты конца перпендикулярной линии
var perpendicularLength = w;
var x1 = xEnd + perpendicularLength * Math.cos(angle - Math.PI / 2);
var y1 = yEnd + perpendicularLength * Math.sin(angle - Math.PI / 2);
var x2 = xEnd - perpendicularLength * Math.cos(angle - Math.PI / 2);
var y2 = yEnd - perpendicularLength * Math.sin(angle - Math.PI / 2);
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer.ds();
break;
}
// visio types are handled below
}
if (type === AscFormat.LineEndType.vsdxOpenASMEArrow ||
type === AscFormat.LineEndType.vsdxFilledASMEArrow ||
type === AscFormat.LineEndType.vsdxClosedASMEArrow) {
len *= 1.5;
let isFilled = type === AscFormat.LineEndType.vsdxFilledASMEArrow;
let isOpen = type === AscFormat.LineEndType.vsdxOpenASMEArrow;
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, isFilled, isOpen, w, len);
} else if (type === AscFormat.LineEndType.vsdxOpenSharpArrow ||
type === AscFormat.LineEndType.vsdxFilledSharpArrow ||
type === AscFormat.LineEndType.vsdxClosedSharpArrow) {
let isFilled = type === AscFormat.LineEndType.vsdxFilledSharpArrow;
let isOpen = type === AscFormat.LineEndType.vsdxOpenSharpArrow;
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, isFilled, isOpen, w, len);
} else if (type === AscFormat.LineEndType.vsdxOpen90Arrow ||
type === AscFormat.LineEndType.vsdxFilled90Arrow ||
type === AscFormat.LineEndType.vsdxClosed90Arrow) {
len /= 2;
let isFilled = type === AscFormat.LineEndType.vsdxFilled90Arrow;
let isOpen = type === AscFormat.LineEndType.vsdxOpen90Arrow;
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, isFilled, isOpen, w, len);
} else if (type === AscFormat.LineEndType.vsdxIndentedFilledArrow ||
type === AscFormat.LineEndType.vsdxIndentedClosedArrow ||
type === AscFormat.LineEndType.vsdxOutdentedFilledArrow ||
type === AscFormat.LineEndType.vsdxOutdentedClosedArrow) {
let isArrowFilled = type === AscFormat.LineEndType.vsdxIndentedFilledArrow ||
type === AscFormat.LineEndType.vsdxOutdentedFilledArrow;
let isIndented = type === AscFormat.LineEndType.vsdxIndentedFilledArrow ||
type === AscFormat.LineEndType.vsdxIndentedClosedArrow;
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen; // cos a
_ey /= _elen; // sin a
// a now is 90 - a + invert cos
var _vx = _ey;
var _vy = -_ex;
// (xEnd, yEnd) - right arrow point
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
// (x1, y1) - top arrow point
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
// (x3, y3) - bottom arrow point
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
let controlPointShift = isIndented? 0.75 * len : 1.25 * len;
var x4 = xEnd + controlPointShift * _ex;
var y4 = yEnd + controlPointShift * _ey;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
let cpxLocal = trans.TransformPointX(x4, y4);
let cpyLocal = trans.TransformPointY(x4, y4);
let endXLocal = trans.TransformPointX(x1, y1);
let endYLocal = trans.TransformPointY(x1, y1);
drawer._c2(cpxLocal, cpyLocal, endXLocal, endYLocal);
drawer._z();
stokeOrFillPath(drawer, isArrowFilled);
drawer._e();
} else if (type === AscFormat.LineEndType.vsdxOpenFletch ||
type === AscFormat.LineEndType.vsdxFilledFletch ||
type === AscFormat.LineEndType.vsdxClosedFletch) {
let isArrowFilled = false;
let isArrowClosed = false;
if (type === AscFormat.LineEndType.vsdxFilledFletch) {
isArrowClosed = true;
isArrowFilled = true;
} else if (type === AscFormat.LineEndType.vsdxClosedFletch) {
isArrowFilled = false;
isArrowClosed = true;
}
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen; // cos a
_ey /= _elen; // sin a
// a now is 90 - a + invert cos
var _vx = _ey;
var _vy = -_ex;
// (xEnd, yEnd) - right arrow point
// left arrow point?
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
// (x1, y1) - top arrow point
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
// (x3, y3) - bottom arrow point
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
let controlPointShift = 0.5 * len;
var x4 = xEnd + controlPointShift * _ex;
var y4 = yEnd + controlPointShift * _ey;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
let cpxLocal = trans.TransformPointX(x4, y4);
let cpyLocal = trans.TransformPointY(x4, y4);
let endXLocal = trans.TransformPointX(xEnd, yEnd);
let endYLocal = trans.TransformPointY(xEnd, yEnd);
drawer._c2(cpxLocal, cpyLocal, endXLocal, endYLocal);
// drawer._m(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._c2(cpxLocal, cpyLocal, trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
if (isArrowClosed) {
// drawer._m(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._c2(cpxLocal, cpyLocal, trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
}
// drawer._z();
stokeOrFillPath(drawer, isArrowFilled);
drawer._e();
} else if (type === AscFormat.LineEndType.vsdxDimensionLine) {
const drawLineAngle = Math.atan2(yEnd - yPrev, xEnd - xPrev) + (45 * Math.PI / 180);
// Вычисляем координаты конца перпендикулярной линии
const perpendicularLength = w * Math.sin(Math.PI / 4); // don't know why it's not just =w here
const x1 = xEnd + perpendicularLength * Math.cos(drawLineAngle); // top right point for visio
const y1 = yEnd + perpendicularLength * Math.sin(drawLineAngle); // top right point for visio
const x2 = xEnd - perpendicularLength * Math.cos(drawLineAngle);
const y2 = yEnd - perpendicularLength * Math.sin(drawLineAngle);
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer.ds();
} else if (type === AscFormat.LineEndType.vsdxFilledDot ||
type === AscFormat.LineEndType.vsdxClosedDot) {
let isFilled = type === AscFormat.LineEndType.vsdxFilledDot;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, 0, w, len, isFilled);
} else if (type === AscFormat.LineEndType.vsdxFilledSquare ||
type === AscFormat.LineEndType.vsdxClosedSquare) {
let isArrowFilled = type === AscFormat.LineEndType.vsdxFilledSquare;
let _ex = xPrev - xEnd;
let _ey = yPrev - yEnd;
let _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen; // cos a
_ey /= _elen; // sin a
let isRotated = false;
_ex = isRotated? _ex : 1; // cos a
_ey = isRotated? _ey : 0; // sin a
// a now is 90 - a + invert cos
let _vx = _ey;
let _vy = -_ex;
// (xEnd, yEnd) - right arrow point
let paramsScale = 0.4;
// left arrow point?
let tmpx = xEnd + len * paramsScale * _ex;
let tmpy = yEnd + len * paramsScale * _ey;
// (x1, y1) - left top arrow point
let x1 = tmpx + _vx * w * paramsScale;
let y1 = tmpy + _vy * w * paramsScale;
// (x2, y2) - left bottom arrow point
let x2 = tmpx - _vx * w * paramsScale;
let y2 = tmpy - _vy * w * paramsScale;
// right arrow point?
let tmpxRight = xEnd - len * paramsScale * _ex;
let tmpyRight = yEnd - len * paramsScale * _ey;
// (x3, y3) - left top arrow point
let x3 = tmpxRight + _vx * w * paramsScale;
let y3 = tmpyRight + _vy * w * paramsScale;
// (x4, y4) - left bottom arrow point
let x4 = tmpxRight - _vx * w * paramsScale;
let y4 = tmpyRight - _vy * w * paramsScale;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._l(trans.TransformPointX(x4, y4), trans.TransformPointY(x4, y4));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer._z();
stokeOrFillPath(drawer, isArrowFilled);
drawer._e();
} else if (type === AscFormat.LineEndType.vsdxDiamond) {
drawRhomb(drawer, xPrev, yPrev, xEnd, yEnd, 0);
} else if (type === AscFormat.LineEndType.vsdxBackslash) {
let _ex = xPrev - xEnd;
let _ey = yPrev - yEnd;
const arrowPartLen = Math.sqrt(_ex * _ex + _ey * _ey);
const arrowCos = _ex / arrowPartLen;
const arrowSin = _ey / arrowPartLen;
const xShift = len * arrowCos;
const yShift = len * arrowSin;
const drawLineAngle = Math.atan2(yEnd - yPrev, xEnd - xPrev) - (45 * Math.PI / 180);
// Вычисляем координаты конца перпендикулярной линии
const perpendicularLength = w * Math.sin(Math.PI / 4); // don't know why it's not just =w here
const x1 = xEnd + perpendicularLength * Math.cos(drawLineAngle) + xShift; // top right point for visio
const y1 = yEnd + perpendicularLength * Math.sin(drawLineAngle) + yShift; // top right point for visio
const x2 = xEnd - perpendicularLength * Math.cos(drawLineAngle) + xShift;
const y2 = yEnd - perpendicularLength * Math.sin(drawLineAngle) + yShift;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer.ds();
drawer._e();
} else if (type === AscFormat.LineEndType.vsdxOpenOneDash) {
let shift = 0.75 * len;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
} else if (type === AscFormat.LineEndType.vsdxOpenTwoDash) {
let shift = 0.75 * len;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift * 1.5);
} else if (type === AscFormat.LineEndType.vsdxOpenThreeDash) {
let shift = 0.75 * len;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift * 1.5);
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift * 2);
} else if (type === AscFormat.LineEndType.vsdxFork) {
drawFork(drawer, xPrev, yPrev, xEnd, yEnd);
} else if (type === AscFormat.LineEndType.vsdxDashFork) {
drawFork(drawer, xPrev, yPrev, xEnd, yEnd);
let shift = 1.5 * len * 0.75;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
} else if (type === AscFormat.LineEndType.vsdxClosedFork) {
let isFilled = false;
drawFork(drawer, xPrev, yPrev, xEnd, yEnd);
let shift = 0.75 * len * 1.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, isFilled);
} else if (type === AscFormat.LineEndType.vsdxClosedPlus) {
let shift = 0.75 * len * 1.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, false);
shift = 0.75 * len * 0.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
} else if (type === AscFormat.LineEndType.vsdxClosedOneDash) {
let shift = 0.75 * len * 1.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, false);
} else if (type === AscFormat.LineEndType.vsdxClosedTwoDash) {
let shift = 0.75 * len * 2;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 1.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, false);
} else if (type === AscFormat.LineEndType.vsdxClosedThreeDash) {
let shift = 0.75 * len * 2.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 2;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 1.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, false);
} else if (type === AscFormat.LineEndType.vsdxClosedDiamond) {
let shift = 0.75 * len * 1.25;
drawRhomb(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, false);
} else if (type === AscFormat.LineEndType.vsdxFilledOneDash) {
let shift = 0.75 * len * 1.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, true);
} else if (type === AscFormat.LineEndType.vsdxFilledTwoDash) {
let shift = 0.75 * len * 2;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 1.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, true);
} else if (type === AscFormat.LineEndType.vsdxFilledThreeDash) {
let shift = 0.75 * len * 2.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 2;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 1.5;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, true);
} else if (type === AscFormat.LineEndType.vsdxFilledDiamond) {
let shift = 0.75 * len * 1.25;
drawRhomb(drawer, xPrev, yPrev, xEnd, yEnd, shift);
shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, true);
} else if (type === AscFormat.LineEndType.vsdxFilledDoubleArrow) {
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, true, false, w, len);
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, len, true, false, w, len);
} else if (type === AscFormat.LineEndType.vsdxClosedDoubleArrow) {
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, false, false, w, len);
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, len, false, false, w, len);
} else if (type === AscFormat.LineEndType.vsdxClosedNoDash) {
let shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, false);
} else if (type === AscFormat.LineEndType.vsdxFilledNoDash) {
let shift = 0.75 * len * 0.5;
drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, true);
} else if (type === AscFormat.LineEndType.vsdxOpenDoubleArrow) {
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, false, true, w, len);
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, len, false, true, w, len);
} else if (type === AscFormat.LineEndType.vsdxOpenArrowSingleDash) {
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, false, true, w, len);
let shift = 0.75 * len * 2;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
} else if (type === AscFormat.LineEndType.vsdxOpenDoubleArrowSingleDash) {
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, 0, false, true, w, len);
drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, len, false, true, w, len);
let shift = 0.75 * len * 2 + len;
drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift);
}
/**
* @param {CShapeDrawer} drawer
* @param {boolean} isFilled - if not filled it is stroke bcs if both repeat all commands
*/
function stokeOrFillPath(drawer, isFilled) {
if (isFilled) {
if (Asc.editor.isPdfEditor()) {
let oRGBColor;
if (drawer.Shape.GetRGBColor) {
oRGBColor = drawer.Shape.GetRGBColor(drawer.Shape.GetFillColor());
}
else if (drawer.Shape.group) {
oRGBColor = drawer.Shape.group.GetRGBColor(drawer.Shape.group.GetFillColor());
}
if (oRGBColor) {
drawer.Graphics.m_oPen.Color.R = oRGBColor.r;
drawer.Graphics.m_oPen.Color.G = oRGBColor.g;
drawer.Graphics.m_oPen.Color.B = oRGBColor.b;
}
}
drawer.drawStrokeFillStyle();
}
let isStroke = !isFilled;
if (isStroke) {
drawer.ds();
}
}
/**
* Draws fork BEFORE line end
* @param drawer
* @param xPrev
* @param yPrev
* @param xEnd
* @param yEnd
*/
function drawFork(drawer, xPrev, yPrev, xEnd, yEnd) {
var arrowAngle = Math.atan2(yEnd - yPrev, xEnd - xPrev);
var perpendicularAngle = arrowAngle - (90 * Math.PI / 180);
// Вычисляем координаты конца перпендикулярной линии
var perpendicularLength = w / 2;
let horLength = w * 0.75;
var x1 = xEnd + perpendicularLength * Math.cos(perpendicularAngle); // top right point
var y1 = yEnd + perpendicularLength * Math.sin(perpendicularAngle); // top right point
var x2 = xEnd - perpendicularLength * Math.cos(perpendicularAngle); // bottom right point
var y2 = yEnd - perpendicularLength * Math.sin(perpendicularAngle); // bottom right point
let x3 = xEnd - horLength * Math.cos(arrowAngle); // left point
let y3 = yEnd - horLength * Math.sin(arrowAngle); // left point
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer.ds();
drawer._e();
}
/**
* Draws vertical line ON line end
* @param drawer
* @param xPrev
* @param yPrev
* @param xEnd
* @param yEnd
* @param shift
*/
function drawVerticalLine(drawer, xPrev, yPrev, xEnd, yEnd, shift) {
let arrowAngle = Math.atan2(yEnd - yPrev, xEnd - xPrev);
var drawLineAngle = arrowAngle - (90 * Math.PI / 180);
// Вычисляем координаты конца перпендикулярной линии
var perpendicularLength = w / 2;
var x1 = xEnd + perpendicularLength * Math.cos(drawLineAngle) - shift * Math.cos(arrowAngle); // top right point for visio
var y1 = yEnd + perpendicularLength * Math.sin(drawLineAngle) - shift * Math.sin(arrowAngle); // top right point for visio
var x2 = xEnd - perpendicularLength * Math.cos(drawLineAngle) - shift * Math.cos(arrowAngle);
var y2 = yEnd - perpendicularLength * Math.sin(drawLineAngle) - shift * Math.sin(arrowAngle);
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer.ds();
drawer._e();
}
/**
* Draws center ON line end
* @param drawer
* @param xPrev
* @param yPrev
* @param xEnd
* @param yEnd
* @param shift - horizontal shift distance
* @param w
* @param len
* @param isArrowFilled
*/
function drawCircle(drawer, xPrev, yPrev, xEnd, yEnd, shift, w, len, isArrowFilled) {
len *= 0.75;
w *= 0.75;
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen; // cos a
_ey /= _elen; // sin a
var _vx = _ey;
var _vy = -_ex;
var tmpx = xEnd + (len / 2 + shift) * _ex; // left circle point
var tmpy = yEnd + (len / 2 + shift) * _ey; // left circle point
var tmpx2 = xEnd - (len / 2 - shift) * _ex; // right circle point
var tmpy2 = yEnd - (len / 2 - shift) * _ey; // right circle point
// left top control point
var cx1 = tmpx + _vx * 3*w/4;
var cy1 = tmpy + _vy * 3*w/4;
// right top control point
var cx2 = tmpx2 + _vx * 3*w/4;
var cy2 = tmpy2 + _vy * 3*w/4;
// left bottom control point
var cx3 = tmpx - _vx * 3*w/4;
var cy3 = tmpy - _vy * 3*w/4;
// right bottom control point
var cx4 = tmpx2 - _vx * 3*w/4;
var cy4 = tmpy2 - _vy * 3*w/4;
drawer._s();
drawer._m(trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
drawer._c(trans.TransformPointX(cx1, cy1), trans.TransformPointY(cx1, cy1),
trans.TransformPointX(cx2, cy2), trans.TransformPointY(cx2, cy2),
trans.TransformPointX(tmpx2, tmpy2), trans.TransformPointY(tmpx2, tmpy2));
drawer._c(trans.TransformPointX(cx4, cy4), trans.TransformPointY(cx4, cy4),
trans.TransformPointX(cx3, cy3), trans.TransformPointY(cx3, cy3),
trans.TransformPointX(tmpx, tmpy), trans.TransformPointY(tmpx, tmpy));
stokeOrFillPath(drawer, isArrowFilled);
drawer._e();
}
/**
* Draws BEFORE line end
* @param drawer
* @param xPrev
* @param yPrev
* @param xEnd
* @param yEnd
* @param shift
*/
function drawRhomb(drawer, xPrev, yPrev, xEnd, yEnd, shift) {
let isArrowFilled = false;
let _ex = xPrev - xEnd;
let _ey = yPrev - yEnd;
const _elen = Math.sqrt(_ex * _ex + _ey * _ey);
_ex /= _elen; // cos a
_ey /= _elen; // sin a
let isRotated = true;
_ex = isRotated? _ex : 1; // cos a
_ey = isRotated? _ey : 0; // sin a
// a now is 90 - a + invert cos
const _vx = _ey;
const _vy = -_ex;
// (xEnd, yEnd) - right arrow point
xEnd = xEnd + shift * _ex;
yEnd = yEnd + shift * _ey;
let heightScale = 0.5;
let widthScale = 1;
// middle arrow point
const tmpx = xEnd + len * widthScale * _ex;
const tmpy = yEnd + len * widthScale * _ey;
// (x1, y1) - middle top arrow point
const x1 = tmpx + _vx * w * heightScale;
const y1 = tmpy + _vy * w * heightScale;
// (x2, y2) - middle bottom arrow point
const x2 = tmpx - _vx * w * heightScale;
const y2 = tmpy - _vy * w * heightScale;
// most left point
const x3 = tmpx + len * widthScale * _ex;
const y3 = tmpy + len * widthScale * _ey;
drawer._s();
drawer._m(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
drawer._l(trans.TransformPointX(x2, y2), trans.TransformPointY(x2, y2));
drawer._z();
stokeOrFillPath(drawer, isArrowFilled);
drawer._e();
}
/**
* Draws arrow BEFORE line end
* @param drawer
* @param xPrev
* @param yPrev
* @param xEnd
* @param yEnd
* @param shift
* @param isFilled
* @param isOpen
* @param w
* @param len
*/
function drawArrow(drawer, xPrev, yPrev, xEnd, yEnd, shift, isFilled, isOpen, w, len) {
if (Asc.editor.isPdfEditor() == true) {
drawer.CheckDash();
}
var _ex = xPrev - xEnd;
var _ey = yPrev - yEnd;
var _elen = Math.sqrt(_ex*_ex + _ey*_ey);
_ex /= _elen;
_ey /= _elen;
var _vx = _ey;
var _vy = -_ex;
xEnd += shift * _ex;
yEnd += shift * _ey;
// (xEnd, yEnd) - right arrow point
var tmpx = xEnd + len * _ex;
var tmpy = yEnd + len * _ey;
// (x1, y1) - top arrow point
var x1 = tmpx + _vx * w/2;
var y1 = tmpy + _vy * w/2;
// (x3, y3) - bottom arrow point
var x3 = tmpx - _vx * w/2;
var y3 = tmpy - _vy * w/2;
drawer._s();
drawer._m(trans.TransformPointX(x1, y1), trans.TransformPointY(x1, y1));
drawer._l(trans.TransformPointX(xEnd, yEnd), trans.TransformPointY(xEnd, yEnd));
drawer._l(trans.TransformPointX(x3, y3), trans.TransformPointY(x3, y3));
if (!isOpen) {
drawer._z();
}
stokeOrFillPath(drawer, isFilled);
drawer._e();
}
}
function CShapeDrawer()
{
this.Shape = null;
this.Graphics = null;
this.UniFill = null;
this.Ln = null;
this.Transform = null;
this.bIsTexture = false;
this.bIsNoFillAttack = false;
this.bIsNoStrokeAttack = false;
this.bDrawSmartAttack = false;
this.FillUniColor = null;
this.StrokeUniColor = null;
this.StrokeWidth = 0;
this.min_x = 0xFFFF;
this.min_y = 0xFFFF;
this.max_x = -0xFFFF;
this.max_y = -0xFFFF;
this.OldLineJoin = null;
this.IsArrowsDrawing = false;
this.IsCurrentPathCanArrows = true;
this.bIsCheckBounds = false;
this.IsRectShape = false;
}
CShapeDrawer.prototype =
{
Clear : function()
{
//this.Shape = null;
//this.Graphics = null;
this.UniFill = null;
this.Ln = null;
this.Transform = null;
this.bIsTexture = false;
this.bIsNoFillAttack = false;
this.bIsNoStrokeAttack = false;
this.FillUniColor = null;
this.StrokeUniColor = null;
this.StrokeWidth = 0;
this.min_x = 0xFFFF;
this.min_y = 0xFFFF;
this.max_x = -0xFFFF;
this.max_y = -0xFFFF;
this.OldLineJoin = null;
this.IsArrowsDrawing = false;
this.IsCurrentPathCanArrows = true;
this.bIsCheckBounds = false;
this.IsRectShape = false;
},
isPdf : function()
{
return this.Graphics.isPdf() || this.Graphics.isNativeDrawer();
},
CheckPoint : function(_x,_y)
{
// TODO: !!!
var x = _x;
var y = _y;
if (false && this.Graphics.MaxEpsLine !== undefined)
{
x = this.Graphics.Graphics.m_oFullTransform.TransformPointX(_x,_y);
y = this.Graphics.Graphics.m_oFullTransform.TransformPointY(_x,_y);
}
if (x < this.min_x)
this.min_x = x;
if (y < this.min_y)
this.min_y = y;
if (x > this.max_x)
this.max_x = x;
if (y > this.max_y)
this.max_y = y;
},
CheckDash : function()
{
if (Asc.editor.isPdfEditor()) {
let aDash;
if (this.Shape.GetDash)
aDash = this.Shape.GetDash();
else if (this.Shape.group && this.Shape.group.GetDash)
aDash = this.Shape.group.GetDash();
else if (this.Shape.IsDrawing && this.Shape.IsDrawing()) {
if (AscCommon.DashPatternPresets[this.Ln.prstDash]) {
aDash = AscCommon.DashPatternPresets[this.Ln.prstDash].slice();
for (var indexD = 0; indexD < aDash.length; indexD++)
aDash[indexD] *= 2 * this.StrokeWidth;
}
}
if (aDash) {
this.Graphics.p_dash(aDash.map(function(measure) {
return measure / 2;
}));
}
}
else if (this.Ln.prstDash != null && AscCommon.DashPatternPresets[this.Ln.prstDash])
{
var _arr = AscCommon.DashPatternPresets[this.Ln.prstDash].slice();
for (var indexD = 0; indexD < _arr.length; indexD++)
_arr[indexD] *= this.StrokeWidth;
this.Graphics.p_dash(_arr);
}
else if (this.isPdf())
{
this.Graphics.p_dash(null);
}
},
fromShape2 : function(shape, graphics, geom)
{
this.fromShape(shape, graphics);
if (!geom && !graphics.bDrawRectWithLines)
{
this.IsRectShape = true;
}
else
{
if (geom.preset == "rect" && !graphics.bDrawRectWithLines)
this.IsRectShape = true;
}
},
fromShape : function(shape, graphics)
{
this.IsRectShape = false;
this.Shape = shape;
this.Graphics = graphics;
this.UniFill = shape.brush;
this.Ln = shape.pen;
this.Transform = shape.TransformMatrix;
this.min_x = 0xFFFF;
this.min_y = 0xFFFF;
this.max_x = -0xFFFF;
this.max_y = -0xFFFF;
var bIsCheckBounds = false;
if (this.UniFill == null || this.UniFill.fill == null)
this.bIsNoFillAttack = true;
else
{
var _fill = this.UniFill.fill;
switch (_fill.type)
{
case c_oAscFill.FILL_TYPE_BLIP:
{
this.bIsTexture = true;
break;
}
case c_oAscFill.FILL_TYPE_SOLID:
{
if(_fill.color)
{
this.FillUniColor = _fill.color.RGBA;
}
else
{
this.FillUniColor = new AscFormat.CUniColor().RGBA;
}
break;
}
case c_oAscFill.FILL_TYPE_GRAD:
{
var _c = _fill.colors;
if (_c.length == 0)
this.FillUniColor = new AscFormat.CUniColor().RGBA;
else
{
if(_fill.colors[0].color)
{
this.FillUniColor = _fill.colors[0].color.RGBA;
}
else
{
this.FillUniColor = new AscFormat.CUniColor().RGBA;
}
}
bIsCheckBounds = true;
break;
}
case c_oAscFill.FILL_TYPE_PATT:
{
bIsCheckBounds = true;
break;
}
case c_oAscFill.FILL_TYPE_NOFILL:
{
this.bIsNoFillAttack = true;
break;
}
default:
{
this.bIsNoFillAttack = true;
break;
}
}
}
if (this.Ln == null || this.Ln.Fill == null || this.Ln.Fill.fill == null)
{
this.bIsNoStrokeAttack = true;
}
else
{
var _fill = this.Ln.Fill.fill;
switch (_fill.type)
{
case c_oAscFill.FILL_TYPE_BLIP:
{
this.StrokeUniColor = new AscFormat.CUniColor().RGBA;
break;
}
case c_oAscFill.FILL_TYPE_SOLID:
{
if(_fill.color)
{
this.StrokeUniColor = _fill.color.RGBA;
}
else
{
this.StrokeUniColor = new AscFormat.CUniColor().RGBA;
}
break;
}
case c_oAscFill.FILL_TYPE_GRAD:
{
var _c = _fill.colors;
if (_c == 0)
this.StrokeUniColor = new AscFormat.CUniColor().RGBA;
else
{
if(_fill.colors[0].color)
{
this.StrokeUniColor = _fill.colors[0].color.RGBA;
}
else
{
this.StrokeUniColor = new AscFormat.CUniColor().RGBA;
}
}
break;
}
case c_oAscFill.FILL_TYPE_PATT:
{
if(_fill.fgClr)
{
this.StrokeUniColor = _fill.fgClr.RGBA;
}
else
{
this.StrokeUniColor = new AscFormat.CUniColor().RGBA;
}
break;
}
case c_oAscFill.FILL_TYPE_NOFILL:
{
this.bIsNoStrokeAttack = true;
break;
}
default:
{
this.bIsNoStrokeAttack = true;
break;
}
}
this.StrokeWidth = (this.Ln.w == null) ? 12700 : parseInt(this.Ln.w);
this.StrokeWidth /= 36000.0;
this.p_width(1000 * this.StrokeWidth);
this.CheckDash();
if (graphics.isBoundsChecker() && !this.bIsNoStrokeAttack)
graphics.LineWidth = this.StrokeWidth;
if (this.Graphics.m_oContext != null && this.Ln.Join != null && this.Ln.Join.type != null)
this.OldLineJoin = this.Graphics.m_oContext.lineJoin;
}
if (this.bIsTexture || bIsCheckBounds)
{
// сначала нужно определить границы
this.bIsCheckBounds = true;
this.check_bounds();
this.bIsCheckBounds = false;
}
},
draw : function(geom)
{
if (this.bIsNoStrokeAttack && this.bIsNoFillAttack)
return;
var bIsPatt = false;
if (this.UniFill != null && this.UniFill.fill != null &&
((this.UniFill.fill.type == c_oAscFill.FILL_TYPE_PATT) || (this.UniFill.fill.type == c_oAscFill.FILL_TYPE_GRAD)))
{
bIsPatt = true;
}
if (this.isPdf() && (this.bIsTexture || bIsPatt))
{
this.Graphics.put_TextureBoundsEnabled(true);
this.Graphics.put_TextureBounds(this.min_x, this.min_y, this.max_x - this.min_x, this.max_y - this.min_y);
}
if(geom)
{
geom.draw(this);
}
else
{
this._s();
this._m(0, 0);
this._l(this.Shape.extX, 0);
this._l(this.Shape.extX, this.Shape.extY);
this._l(0, this.Shape.extY);
this._z();
this.drawFillStroke(true, "norm", true && !this.bIsNoStrokeAttack);
this._e();
}
if (this.isPdf() && (this.bIsTexture || bIsPatt))
{
this.Graphics.put_TextureBoundsEnabled(false);
}
if (this.Graphics.isBoundsChecker() && this.Graphics.AutoCheckLineWidth)
{
this.Graphics.CorrectBounds2();
}
this.Graphics.p_dash(null);
},
p_width : function(w)
{
this.Graphics.p_width(w);
},
_m : function(x, y)
{
if (this.bIsCheckBounds)
{
this.CheckPoint(x, y);
return;
}
this.Graphics._m(x, y);
},
_l : function(x, y)
{
if (this.bIsCheckBounds)
{
this.CheckPoint(x, y);
return;
}
this.Graphics._l(x, y);
},
_c : function(x1, y1, x2, y2, x3, y3)
{
if (this.bIsCheckBounds)
{
this.CheckPoint(x1, y1);
this.CheckPoint(x2, y2);
this.CheckPoint(x3, y3);
return;
}
this.Graphics._c(x1, y1, x2, y2, x3, y3);
},
/**
* @param x1 - cpx
* @param y1 - cpy
* @param x2 - end x
* @param y2 - end y
*/
_c2 : function(x1, y1, x2, y2)
{
if (this.bIsCheckBounds)
{
this.CheckPoint(x1, y1);
this.CheckPoint(x2, y2);
return;
}
this.Graphics._c2(x1, y1, x2, y2);
},
/**
* @param {{x: Number, y: Number, z? :Number}} startPoint
* @param {{x: Number, y: Number, z? :Number}[]} controlPoints
* @param {{x: Number, y: Number, z? :Number}} endPoint
*/
_cN : function(startPoint, controlPoints, endPoint)
{
if (this.bIsCheckBounds)
{
this.CheckPoint(startPoint.x, startPoint.y);
controlPoints.forEach(function (controlPoint) {
this.CheckPoint(controlPoint.x, controlPoint.y);
})
this.CheckPoint(endPoint.x, endPoint.y);
return;
}
this.Graphics._cN(startPoint, controlPoints, endPoint);
},
_z : function()
{
this.IsCurrentPathCanArrows = false;
if (this.bIsCheckBounds)
return;
this.Graphics._z();
},
_s : function()
{
this.IsCurrentPathCanArrows = true;
this.Graphics._s();
},
_e : function()
{
this.IsCurrentPathCanArrows = true;
this.Graphics._e();
},
drawTransitionTextures : function(oCanvas1, dAlpha1, oCanvas2, dAlpha2)
{
const dOldGlobalAlpha = this.Graphics.m_oContext.globalAlpha;
const dX = this.min_x;
const dY = this.min_y;
const dW = this.max_x - this.min_x;
const dH = this.max_y - this.min_y;
this.Graphics.m_oContext.globalAlpha = dAlpha1;
this.Graphics.drawImage(null, dX, dY, dW, dH, undefined, null, oCanvas1);
this.Graphics.m_oContext.globalAlpha = dAlpha2;
this.Graphics.drawImage(null, dX, dY, dW, dH, undefined, null, oCanvas2);
this.Graphics.m_oContext.globalAlpha = dOldGlobalAlpha;
},
drawArrows: function (bIsSaveToPdfMode) {
this.IsArrowsDrawing = true;
this.Graphics.p_dash(null);
const graphicsCtx = this.Graphics.isTrack() && !bIsSaveToPdfMode
? this.Graphics.Graphics
: this.Graphics;
const fullTransform = bIsSaveToPdfMode
? (this.isPdf() ? this.Graphics.GetTransform() : this.Graphics.m_oFullTransform)
: graphicsCtx.m_oFullTransform;
const inverseTransform = AscCommon.global_MatrixTransformer.Invert(fullTransform);
const point1 = { x: fullTransform.TransformPointX(0, 0), y: fullTransform.TransformPointY(0, 0) };
const point2 = { x: fullTransform.TransformPointX(1, 1), y: fullTransform.TransformPointY(1, 1) };
const transformScaleFactor = Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2)) / Math.sqrt(2);
const lineSize = bIsSaveToPdfMode
? (this.isPdf() ? this.Graphics.GetLineWidth() : graphicsCtx.m_oContext.lineWidth)
: graphicsCtx.m_oContext.lineWidth;
const penWidth = lineSize * transformScaleFactor;
const maxWidth = bIsSaveToPdfMode
? 2.5 / AscCommon.g_dKoef_mm_to_pix
: (graphicsCtx.IsThumbnail === true ? 2 : undefined);
const arrCoef = bIsSaveToPdfMode
? 1
: this.isArrPix ? (1 / AscCommon.g_dKoef_mm_to_pix) : 1;
const geometry = this.Shape.getGeometry();
const paths = geometry.getContinuousSubpaths ? geometry.getContinuousSubpaths() : [];
if (this.Ln.headEnd != null) {
const arrowLength = this.Ln.headEnd.GetLen(penWidth, maxWidth) / transformScaleFactor;
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
const headAngle = path.getHeadArrowAngle(arrowLength);
if (AscFormat.isRealNumber(headAngle)) {
// Each continuous subpath starts with a moveTo command
// so we can use the first point of the path as the arrow tip point
const arrowEndPoint = {
x: fullTransform.TransformPointX(path.ArrPathCommand[0].X, path.ArrPathCommand[0].Y),
y: fullTransform.TransformPointY(path.ArrPathCommand[0].X, path.ArrPathCommand[0].Y)
};
const arrowStartPoint = {
x: fullTransform.TransformPointX(path.ArrPathCommand[0].X - Math.cos(headAngle * Math.PI / 180), path.ArrPathCommand[0].Y - Math.sin(headAngle * Math.PI / 180)),
y: fullTransform.TransformPointY(path.ArrPathCommand[0].X - Math.cos(headAngle * Math.PI / 180), path.ArrPathCommand[0].Y - Math.sin(headAngle * Math.PI / 180))
};
DrawLineEnd(
arrowEndPoint.x, arrowEndPoint.y,
arrowStartPoint.x, arrowStartPoint.y,
this.Ln.headEnd.type,
arrCoef * this.Ln.headEnd.GetWidth(penWidth, maxWidth),
arrCoef * this.Ln.headEnd.GetLen(penWidth, maxWidth),
this, inverseTransform
);
}
}
}
if (this.Ln.tailEnd != null) {
const arrowLength = this.Ln.tailEnd.GetLen(penWidth, maxWidth) / transformScaleFactor;
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
const tailAngle = path.getTailArrowAngle(arrowLength);
if (AscFormat.isRealNumber(tailAngle)) {
// Each continuous subpath starts with a moveTo command
// so we can use the first point of the path as the arrow tip point
function getPathEndPoint(commands) {
for (let i = commands.length - 1; i >= 0; i--) {
const command = commands[i];
if (command.id === AscFormat.lineTo) {
return { x: command.X, y: command.Y };
}
if (command.id === AscFormat.bezier4) {
return { x: command.X2, y: command.Y2 };
}
}
return null;
}
const pathEndPoint = getPathEndPoint(path.ArrPathCommand);
if (!pathEndPoint) {
continue;
}
const arrowEndPoint = {
x: fullTransform.TransformPointX(pathEndPoint.x, pathEndPoint.y),
y: fullTransform.TransformPointY(pathEndPoint.x, pathEndPoint.y)
};
const arrowStartPoint = {
x: fullTransform.TransformPointX(pathEndPoint.x - Math.cos(tailAngle * Math.PI / 180), pathEndPoint.y - Math.sin(tailAngle * Math.PI / 180)),
y: fullTransform.TransformPointY(pathEndPoint.x - Math.cos(tailAngle * Math.PI / 180), pathEndPoint.y - Math.sin(tailAngle * Math.PI / 180))
};
DrawLineEnd(
arrowEndPoint.x, arrowEndPoint.y,
arrowStartPoint.x, arrowStartPoint.y,
this.Ln.tailEnd.type,
arrCoef * this.Ln.tailEnd.GetWidth(penWidth, maxWidth),
arrCoef * this.Ln.tailEnd.GetLen(penWidth, maxWidth),
this, inverseTransform
);
}
}
}
this.IsArrowsDrawing = false;
this.CheckDash();
},
drawBlipFill: function () {
const graphics = this.Graphics.isTrack() ? this.Graphics.Graphics : this.Graphics;
if (!graphics) return;
const imageName = this.UniFill.fill.RasterImageId;
const imageUrl = AscCommon.getFullImageSrc2(imageName);
const imageData = Asc.editor.ImageLoader.map_image_index[imageUrl];
const isImageLoaded = imageData != undefined && imageData.Image != null && imageData.Status == AscFonts.ImageLoadStatus.Complete;
if (!isImageLoaded) return;
graphics.save();
graphics.clip();
const isTile = AscCommon.isRealObject(this.UniFill.fill.tile);
const isTileSupported = !(AscCommon.AscBrowser.isIE && imageName && imageName.lastIndexOf('.svg') == imageName.length - 4);
if (isTile && isTileSupported) {
this.drawBlipFillTile(imageData);
} else if (this.UniFill.IsTransitionTextures) {
this.drawTransitionTextures(this.UniFill.canvas1, this.UniFill.alpha1, this.UniFill.canvas2, this.UniFill.alpha2);
} else {
this.drawBlipFillStretch(imageData);
}
graphics.restore();
},
drawBlipFillTile: function (imageData) {
const graphics = this.Graphics.isTrack() ? this.Graphics.Graphics : this.Graphics;
if (!graphics) return;
const transform = this.Shape.getTransformMatrix
? this.Shape.getTransformMatrix()
: new AscCommon.CMatrix();
const invertedTransform = AscCommon.global_MatrixTransformer.Invert(transform);
const tile = this.UniFill.fill.tile;
const rotWithShape = this.UniFill.fill.rotWithShape || this.UniFill.fill.rotWithShape === null;
// Scaling
const imageDPI = 96; // Image DPI is not supported yet (so we use a fixed value of 96 DPI)
const canvasDPI = 96;
const scaleCoefX = AscCommon.g_dKoef_pix_to_mm * (canvasDPI / imageDPI);
const scaleCoefY = AscCommon.g_dKoef_pix_to_mm * (canvasDPI / imageDPI);
const scaleX = tile.sx ? (tile.sx / 1000) / 100 : 1;
const scaleY = tile.sy ? (tile.sy / 1000) / 100 : 1;
// Offsets (aligning and direct offsets)
function getAlignment(key) {
switch (key) {
case AscCommon.c_oAscRectAlignType.tl: return [0, 0];
case AscCommon.c_oAscRectAlignType.t: return [0.5, 0];
case AscCommon.c_oAscRectAlignType.tr: return [1, 0];
case AscCommon.c_oAscRectAlignType.l: return [0, 0.5];
case AscCommon.c_oAscRectAlignType.ctr: return [0.5, 0.5];
case AscCommon.c_oAscRectAlignType.r: return [1, 0.5];
case AscCommon.c_oAscRectAlignType.bl: return [0, 1];
case AscCommon.c_oAscRectAlignType.b: return [0.5, 1];
case AscCommon.c_oAscRectAlignType.br: return [1, 1];
default: return [0, 0];
}
}
const align = AscFormat.isRealNumber(tile.algn) && tile.algn >= 0 && tile.algn <= 8
? tile.algn
: AscCommon.c_oAscRectAlignType.tl; // AscCommon.c_oAscRectAlignType
let alignOffsetX, alignOffsetY;
if (rotWithShape) {
const shapeWidth = this.max_x - this.min_x;
const shapeHeight = this.max_y - this.min_y;
const imageWidth = imageData.Image.width * scaleX * scaleCoefX;
const imageHeight = imageData.Image.height * scaleY * scaleCoefY;
alignOffsetX = getAlignment(align)[0] * (shapeWidth - imageWidth);
alignOffsetY = getAlignment(align)[1] * (shapeHeight - imageHeight);
} else {
const shapeBounds = this.Shape.getBounds();
const shapeWidth = shapeBounds.w;
const shapeHeight = shapeBounds.h;
const imageWidth = imageData.Image.width * scaleX * scaleCoefX;
const imageHeight = imageData.Image.height * scaleY * scaleCoefY;
alignOffsetX = shapeBounds.x + getAlignment(align)[0] * (shapeWidth - imageWidth);
alignOffsetY = shapeBounds.y + getAlignment(align)[1] * (shapeHeight - imageHeight);
}
const offsetX = tile.tx ? tile.tx * AscCommonWord.g_dKoef_emu_to_mm : 0;
const offsetY = tile.ty ? tile.ty * AscCommonWord.g_dKoef_emu_to_mm : 0;
// Mirroring
const flipH = tile.flip === AscFormat.CBlipFillTile.flipTypes.x || tile.flip === AscFormat.CBlipFillTile.flipTypes.xy;
const flipV = tile.flip === AscFormat.CBlipFillTile.flipTypes.y || tile.flip === AscFormat.CBlipFillTile.flipTypes.xy;
// Opacity
const isTransparent = this.UniFill.transparent != null && this.UniFill.transparent != 255;
const useTransparency = this.Graphics.isSupportTextDraw() && isTransparent;
const alpha = useTransparency ? this.UniFill.transparent / 255 : 1;
graphics.drawBlipFillTile(
rotWithShape ? null : invertedTransform,
imageData.src,
alpha,
scaleX * scaleCoefX,
scaleY * scaleCoefY,
offsetX + alignOffsetX,
offsetY + alignOffsetY,
flipH, flipV
);
graphics.m_bPenColorInit = false;
graphics.m_bBrushColorInit = false;
},
drawBlipFillStretch: function (imageData) {
const graphics = this.Graphics.isTrack() ? this.Graphics.Graphics : this.Graphics;
if (!graphics) return;
const transform = this.Shape.getTransformMatrix
? this.Shape.getTransformMatrix()
: new AscCommon.CMatrix();
const invertedTransform = AscCommon.global_MatrixTransformer.Invert(transform);
const rotWithShape = this.UniFill.fill.rotWithShape || this.UniFill.fill.rotWithShape === null;
// Margins
const fillRect = AscCommon.isRealObject(this.UniFill.fill.stretch) && AscCommon.isRealObject(this.UniFill.fill.stretch.fillRect)
? this.UniFill.fill.stretch.fillRect
: new AscFormat.CFillRect(0, 0, 100, 100);
let dstRect;
if (rotWithShape) {
const shapeWidth = this.max_x - this.min_x;
const shapeHeight = this.max_y - this.min_y;
dstRect = {
l: this.min_x + shapeWidth * fillRect.l / 100,
t: this.min_y + shapeHeight * fillRect.t / 100,
r: this.max_x - shapeWidth * (100 - fillRect.r) / 100,
b: this.max_y - shapeHeight * (100 - fillRect.b) / 100,
};
} else {
const shapeBounds = this.Shape.getBounds();
const shapeWidth = shapeBounds.w;
const shapeHeight = shapeBounds.h;
dstRect = {
l: shapeBounds.x + shapeWidth * (fillRect.l / 100),
t: shapeBounds.y + shapeHeight * (fillRect.t / 100),
r: shapeBounds.x + shapeWidth - shapeWidth * (100 - fillRect.r) / 100,
b: shapeBounds.y + shapeHeight - shapeHeight * (100 - fillRect.b) / 100,
};
}
// Opacity
const isTransparent = this.UniFill.transparent != null && this.UniFill.transparent != 255;
const useTransparency = this.IsRectShape ? true : graphics.isSupportTextDraw() && !graphics.isTrack();
const alpha = (isTransparent && useTransparency) ? this.UniFill.transparent / 255 : 1;
// this.UniFill.fill.srcRect === this.Shape.brush.fill.srcRect === this.Shape.blipFill.srcRect
const srcRect = this.UniFill.fill.srcRect;
graphics.drawBlipFillStretch(
rotWithShape ? null : invertedTransform,
imageData.src,
alpha,
dstRect.l, dstRect.t, dstRect.r - dstRect.l, dstRect.b - dstRect.t,
srcRect,
this.UniFill.fill.canvas
);
},
df: function (mode) {
if (mode == "none" || this.bIsNoFillAttack)
return;
if (this.Graphics.isTrack())
this.Graphics.m_oOverlay.ClearAll = true;
if (this.Graphics.isBoundsChecker() === true)
return;
var bIsIntegerGridTRUE = false;
if (this.bIsTexture) {
if (this.Graphics.m_bIntegerGrid === true) {
this.Graphics.SetIntegerGrid(false);
bIsIntegerGridTRUE = true;
}
if (this.isPdf()) {
const image = getFullImageSrc2(this.UniFill.fill.RasterImageId);
const type = this.UniFill.fill.tile != null && this.Graphics.m_oContext !== undefined ? 1 : 0;
this.Graphics.put_brushTexture(image, type);
} else {
this.drawBlipFill();
}
if (bIsIntegerGridTRUE) {
this.Graphics.SetIntegerGrid(true);
}
return;
}
if (this.UniFill != null && this.UniFill.fill != null)
{
var _fill = this.UniFill.fill;
if (_fill.type == c_oAscFill.FILL_TYPE_PATT)
{
if (this.Graphics.m_bIntegerGrid === true)
{
this.Graphics.SetIntegerGrid(false);
bIsIntegerGridTRUE = true;
}
var _is_ctx = false;
if (!this.Graphics.isSupportTextDraw() || undefined === this.Graphics.m_oContext || (null == this.UniFill.transparent) || (this.UniFill.transparent == 255))
{
_is_ctx = false;
}
else
{
_is_ctx = true;
}
var _gr = this.Graphics.isTrack() ? this.Graphics.Graphics : this.Graphics;
var _ctx = _gr.m_oContext;
var _patt_name = AscCommon.global_hatch_names[_fill.ftype];
if (undefined == _patt_name)
_patt_name = "cross";
var _fc = _fill.fgClr && _fill.fgClr.RGBA || {R: 0, G: 0, B: 0, A: 255};
var _bc = _fill.bgClr && _fill.bgClr.RGBA || {R: 255, G: 255, B: 255, A: 255};
var __fa = (null === this.UniFill.transparent) ? _fc.A : 255;
var __ba = (null === this.UniFill.transparent) ? _bc.A : 255;
var _test_pattern = AscCommon.GetHatchBrush(_patt_name, _fc.R, _fc.G, _fc.B, __fa, _bc.R, _bc.G, _bc.B, __ba);
var patt = _ctx.createPattern(_test_pattern.Canvas, "repeat");
_ctx.save();
const editorInfo = this.getEditorInfo();
var koefX = editorInfo.scale;
var koefY = editorInfo.scale;
if (this.Graphics.IsThumbnail)
{
koefX = 1;
koefY = 1;
}
// TODO: !!!
_ctx.translate(this.min_x, this.min_y);
if (this.Graphics.MaxEpsLine === undefined)
{
_ctx.scale(koefX * this.Graphics.TextureFillTransformScaleX, koefY * this.Graphics.TextureFillTransformScaleY);
}
else
{
_ctx.scale(koefX * this.Graphics.Graphics.TextureFillTransformScaleX, koefY * this.Graphics.Graphics.TextureFillTransformScaleY);
}
if (_is_ctx === true)
{
var _old_global_alpha = _ctx.globalAlpha;
if (null != this.UniFill.transparent)
_ctx.globalAlpha = this.UniFill.transparent / 255;
_ctx.fillStyle = patt;
_ctx.fill();
_ctx.globalAlpha = _old_global_alpha;
}
else
{
_ctx.fillStyle = patt;
_ctx.fill();
}
_ctx.restore();
_gr.m_bPenColorInit = false;
_gr.m_bBrushColorInit = false;
if (bIsIntegerGridTRUE)
{
this.Graphics.SetIntegerGrid(true);
}
return;
}
else if (_fill.type == c_oAscFill.FILL_TYPE_GRAD)
{
if (this.Graphics.m_bIntegerGrid === true)
{
this.Graphics.SetIntegerGrid(false);
bIsIntegerGridTRUE = true;
}
var _is_ctx = false;
if (!this.Graphics.isSupportTextDraw() || undefined === this.Graphics.m_oContext || (null == this.UniFill.transparent) || (this.UniFill.transparent == 255))
{
_is_ctx = false;
}
else
{
_is_ctx = true;
}
var _gr = this.Graphics.isTrack() ? this.Graphics.Graphics : this.Graphics;
var _ctx = _gr.m_oContext;
var gradObj = null;
if (_fill.lin)
{
var _angle = _fill.lin.angle;
if (_fill.rotateWithShape === false)
{
var matrix_transform = this.Graphics.isTrack() ? this.Graphics.Graphics.m_oTransform : this.Graphics.m_oTransform;
if (matrix_transform)
{
//_angle -= (60000 * this.Graphics.m_oTransform.GetRotation());
_angle = AscCommon.GradientGetAngleNoRotate(_angle, matrix_transform);
}
}
var points = this.getGradientPoints(this.min_x, this.min_y, this.max_x, this.max_y, _angle, _fill.lin.scale);
gradObj = _ctx.createLinearGradient(points.x0, points.y0, points.x1, points.y1);
}
else if (_fill.path)
{
var _cx = (this.min_x + this.max_x) / 2;
var _cy = (this.min_y + this.max_y) / 2;
var _r = Math.max(this.max_x - this.min_x, this.max_y - this.min_y) / 2;
gradObj = _ctx.createRadialGradient(_cx, _cy, 1, _cx, _cy, _r);
}
else
{
//gradObj = _ctx.createLinearGradient(this.min_x, this.min_y, this.max_x, this.min_y);
var points = this.getGradientPoints(this.min_x, this.min_y, this.max_x, this.max_y, 0, false);
gradObj = _ctx.createLinearGradient(points.x0, points.y0, points.x1, points.y1);
}
const nTransparent = this.UniFill.transparent;
let bUseGlobalAlpha = (null !== nTransparent && undefined !== nTransparent);
const aColors = _fill.colors;
const nClrCount = aColors.length;
if(_fill.path && AscCommon.AscBrowser.isMozilla && bUseGlobalAlpha)
{
bUseGlobalAlpha = false;
const dTransparent = nTransparent / 255.0;
for (let nClr = 0; nClr < nClrCount; nClr++)
{
let oClr = aColors[nClr];
gradObj.addColorStop(oClr.pos / 100000, oClr.color.getCSSWithTransparent(dTransparent));
}
}
else
{
for (let nClr = 0; nClr < nClrCount; nClr++)
{
let oClr = aColors[nClr];
gradObj.addColorStop(oClr.pos / 100000, oClr.color.getCSSColor(nTransparent));
}
}
_ctx.fillStyle = gradObj;
if (bUseGlobalAlpha)
{
var _old_global_alpha = this.Graphics.m_oContext.globalAlpha;
_ctx.globalAlpha = this.UniFill.transparent / 255;
_ctx.fill();
_ctx.globalAlpha = _old_global_alpha;
}
else
{
_ctx.fill();
}
_gr.m_bPenColorInit = false;
_gr.m_bBrushColorInit = false;
if (bIsIntegerGridTRUE)
{
this.Graphics.SetIntegerGrid(true);
}
return;
}
}
var rgba = this.FillUniColor;
if (mode == "darken")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.darken();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
else if (mode == "darkenLess")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.darkenLess();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
else if (mode == "lighten")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.lighten();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
else if (mode == "lightenLess")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.lightenLess();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
if(rgba)
{
if (this.UniFill != null && this.UniFill.transparent != null)
rgba.A = this.UniFill.transparent;
this.Graphics.b_color1(rgba.R, rgba.G, rgba.B, rgba.A);
}
this.Graphics.df();
},
isArrowPresent: function()
{
if(this.IsCurrentPathCanArrows && this.Ln && this.Ln.isArrowPresent() && !this.IsArrowsDrawing)
return true;
return false;
},
ds : function()
{
if (this.bIsNoStrokeAttack)
return;
if (this.Graphics.isTrack())
this.Graphics.m_oOverlay.ClearAll = true;
if (null != this.OldLineJoin && !this.IsArrowsDrawing)
{
switch (this.Ln.Join.type)
{
case AscFormat.LineJoinType.Round:
{
this.Graphics.m_oContext.lineJoin = "round";
break;
}
case AscFormat.LineJoinType.Bevel:
{
this.Graphics.m_oContext.lineJoin = "bevel";
break;
}
case AscFormat.LineJoinType.Empty:
{
this.Graphics.m_oContext.lineJoin = "miter";
break;
}
case AscFormat.LineJoinType.Miter:
{
this.Graphics.m_oContext.lineJoin = "miter";
break;
}
}
}
var isArrowsPresent = this.isArrowPresent();
var rgba = this.StrokeUniColor;
let nAlpha = 0xFF;
if(!isArrowsPresent && !this.IsArrowsDrawing || Asc.editor.isPdfEditor() || this.Shape.isShadowSp)
{
if (this.Ln && this.Ln.Fill != null && this.Ln.Fill.transparent != null)
nAlpha = this.Ln.Fill.transparent;
}
this.Graphics.p_color(rgba.R, rgba.G, rgba.B, nAlpha);
if (this.IsRectShape && this.Graphics.AddSmartRect !== undefined)
{
if (undefined !== this.Shape.extX)
this.Graphics.AddSmartRect(0, 0, this.Shape.extX, this.Shape.extY, this.StrokeWidth);
else
this.Graphics.ds();
}
else
{
this.Graphics.ds();
}
if (null != this.OldLineJoin && !this.IsArrowsDrawing)
{
this.Graphics.m_oContext.lineJoin = this.OldLineJoin;
}
if (isArrowsPresent) {
const bIsSaveToPdfMode = false;
this.drawArrows(bIsSaveToPdfMode);
}
},
drawFillStroke : function(bIsFill, fill_mode, bIsStroke)
{
if (this.Graphics.isTrack())
this.Graphics.m_oOverlay.ClearAll = true;
if(this.Graphics.isBoundsChecker())
return;
if (!this.isPdf())
{
if (bIsFill)
this.df(fill_mode);
if (bIsStroke)
this.ds();
}
else
{
if (this.bIsNoStrokeAttack)
bIsStroke = false;
var isArrowsPresent = this.isArrowPresent();
if (bIsStroke)
{
if (null != this.OldLineJoin && !this.IsArrowsDrawing)
{
this.Graphics.put_PenLineJoin(AscFormat.ConvertJoinAggType(this.Ln.Join.type));
}
var rgba = this.StrokeUniColor;
let nAlpha = 0xFF;
if(!isArrowsPresent && !this.IsArrowsDrawing)
{
if (this.Ln && this.Ln.Fill != null && this.Ln.Fill.transparent != null)
nAlpha = this.Ln.Fill.transparent;
}
this.Graphics.p_color(rgba.R, rgba.G, rgba.B, nAlpha);
}
if (fill_mode == "none" || this.bIsNoFillAttack)
bIsFill = false;
var bIsPattern = false;
if (bIsFill)
{
if (this.bIsTexture)
{
if (null == this.UniFill.fill.tile)
{
if (null == this.UniFill.fill.srcRect)
{
if (this.UniFill.fill.RasterImageId && this.UniFill.fill.RasterImageId.indexOf(".svg") != 0)
{
this.Graphics.put_brushTexture(getFullImageSrc2(this.UniFill.fill.RasterImageId), 0);
}
else
{
if (this.UniFill.fill.canvas)
{
this.Graphics.put_brushTexture(this.UniFill.fill.canvas.toDataURL("image/png"), 0);
}
else
{
this.Graphics.put_brushTexture(getFullImageSrc2(this.UniFill.fill.RasterImageId), 0);
}
}
}
else
{
if (this.IsRectShape)
{
this.Graphics.drawImage(getFullImageSrc2(this.UniFill.fill.RasterImageId), this.min_x, this.min_y, (this.max_x - this.min_x), (this.max_y - this.min_y), undefined, this.UniFill.fill.srcRect);
bIsFill = false;
}
else
{
// TODO: support srcRect
this.Graphics.put_brushTexture(getFullImageSrc2(this.UniFill.fill.RasterImageId), 0);
}
}
}
else
{
if (this.UniFill.fill.canvas)
{
this.Graphics.put_brushTexture(this.UniFill.fill.canvas.toDataURL("image/png"), 1);
}
else
{
this.Graphics.put_brushTexture(getFullImageSrc2(this.UniFill.fill.RasterImageId), 1);
}
}
this.Graphics.put_BrushTextureAlpha(this.UniFill.transparent);
}
else
{
var _fill = this.UniFill.fill;
if (_fill.type == c_oAscFill.FILL_TYPE_PATT)
{
var _patt_name = AscCommon.global_hatch_names[_fill.ftype];
if (undefined == _patt_name)
_patt_name = "cross";
var _fc = _fill.fgClr && _fill.fgClr.RGBA || {R: 0, G: 0, B: 0, A: 255};
var _bc = _fill.bgClr && _fill.bgClr.RGBA || {R: 255, G: 255, B: 255, A: 255};
var __fa = (null === this.UniFill.transparent) ? _fc.A : 255;
var __ba = (null === this.UniFill.transparent) ? _bc.A : 255;
var _pattern = AscCommon.GetHatchBrush(_patt_name, _fc.R, _fc.G, _fc.B, __fa, _bc.R, _bc.G, _bc.B, __ba);
var _url64 = "";
try
{
_url64 = _pattern.toDataURL();
}
catch (err)
{
_url64 = "";
}
this.Graphics.put_brushTexture(_url64, 1);
if (null != this.UniFill.transparent)
this.Graphics.put_BrushTextureAlpha(this.UniFill.transparent);
else
this.Graphics.put_BrushTextureAlpha(255);
bIsPattern = true;
}
else if (_fill.type == c_oAscFill.FILL_TYPE_GRAD)
{
var points = null;
if (_fill.lin)
{
var _angle = _fill.lin.angle;
if (_fill.rotateWithShape === false && this.Graphics.m_oTransform)
{
//_angle -= (60000 * this.Graphics.m_oTransform.GetRotation());
_angle = AscCommon.GradientGetAngleNoRotate(_angle, this.Graphics.m_oTransform);
}
points = this.getGradientPoints(this.min_x, this.min_y, this.max_x, this.max_y, _angle, _fill.lin.scale);
}
else if (_fill.path)
{
var _cx = (this.min_x + this.max_x) / 2;
var _cy = (this.min_y + this.max_y) / 2;
var _r = Math.max(this.max_x - this.min_x, this.max_y - this.min_y) / 2;
points = { x0 : _cx, y0 : _cy, x1 : _cx, y1 : _cy, r0 : 1, r1 : _r };
}
else
{
points = this.getGradientPoints(this.min_x, this.min_y, this.max_x, this.max_y, 0, false);
}
this.Graphics.put_BrushGradient(_fill, points, this.UniFill.transparent);
}
else
{
var rgba = this.FillUniColor;
if (fill_mode == "darken")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.darken();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
else if (fill_mode == "darkenLess")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.darkenLess();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
else if (fill_mode == "lighten")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.lighten();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
else if (fill_mode == "lightenLess")
{
var _color1 = new CShapeColor(rgba.R, rgba.G, rgba.B);
var rgb = _color1.lightenLess();
rgba = { R: rgb.r, G: rgb.g, B: rgb.b, A: rgba.A };
}
if (rgba)
{
if (this.UniFill != null && this.UniFill.transparent != null)
rgba.A = this.UniFill.transparent;
this.Graphics.b_color1(rgba.R, rgba.G, rgba.B, rgba.A);
}
}
}
}
if (bIsFill && bIsStroke)
{
if (this.bIsTexture || bIsPattern)
{
this.Graphics.drawpath(256);
this.Graphics.drawpath(1);
}
else
{
this.Graphics.drawpath(256 + 1);
}
}
else if (bIsFill)
{
this.Graphics.drawpath(256);
}
else if (bIsStroke)
{
this.Graphics.drawpath(1);
}
else if (false)
{
// такого быть не должно по идее
this.Graphics.b_color1(0, 0, 0, 0);
this.Graphics.drawpath(256);
}
if (isArrowsPresent) {
const bIsSaveToPdfMode = true;
this.drawArrows(bIsSaveToPdfMode);
}
}
},
drawStrokeFillStyle : function()
{
if (!this.isPdf())
{
var gr = this.Graphics.isTrack() ? this.Graphics.Graphics : this.Graphics;
var tmp = gr.m_oBrush.Color1;
var p_c = gr.m_oPen.Color;
gr.b_color1(p_c.R, p_c.G, p_c.B, p_c.A);
gr.df();
gr.b_color1(tmp.R, tmp.G, tmp.B, tmp.A);
}
else
{
var tmp = this.Graphics.GetBrush().Color1;
var p_c = this.Graphics.GetPen().Color;
this.Graphics.b_color1(p_c.R, p_c.G, p_c.B, p_c.A);
this.Graphics.df();
this.Graphics.b_color1(tmp.R, tmp.G, tmp.B, tmp.A);
}
},
check_bounds : function()
{
this.Shape.check_bounds(this);
},
// common funcs
getNormalPoint : function(x0, y0, angle, x1, y1)
{
return AscCommon.getNormalPoint(x0, y0, angle, x1, y1);
},
getGradientPoints : function(min_x, min_y, max_x, max_y, _angle, scale)
{
return AscCommon.getGradientPoints(min_x, min_y, max_x, max_y, _angle, scale);
},
DrawPresentationComment : function(type, x, y, w, h)
{
},
getEditorInfo: function()
{
var _ret = {};
_ret.editor = Asc.editor || window.editor;
switch (_ret.editor.editorId)
{
case AscCommon.c_oEditorId.Word:
case AscCommon.c_oEditorId.Presentation:
{
_ret.scale = _ret.editor.WordControl.m_nZoomValue / 100;
break;
}
case AscCommon.c_oEditorId.Spreadsheet:
{
_ret.scale = _ret.editor.asc_getZoom();
break;
}
default:
break;
}
return _ret;
}
};
function ShapeToImageConverter(shape, pageIndex, sImageFormat)
{
AscCommon.IsShapeToImageConverter = true;
var _bounds_cheker = new AscFormat.CSlideBoundsChecker();
var dKoef = AscCommon.g_dKoef_mm_to_pix;
var w_mm = 210;
var h_mm = 297;
var w_px = (w_mm * dKoef) >> 0;
var h_px = (h_mm * dKoef) >> 0;
_bounds_cheker.init(w_px, h_px, w_mm, h_mm);
_bounds_cheker.transform(1,0,0,1,0,0);
_bounds_cheker.AutoCheckLineWidth = true;
_bounds_cheker.CheckLineWidth(shape);
shape.draw(_bounds_cheker, /*pageIndex*/0);
_bounds_cheker.CorrectBounds2();
var _need_pix_width = _bounds_cheker.Bounds.max_x - _bounds_cheker.Bounds.min_x + 1;
var _need_pix_height = _bounds_cheker.Bounds.max_y - _bounds_cheker.Bounds.min_y + 1;
if (_need_pix_width <= 0 || _need_pix_height <= 0)
return null;
/*
if (shape.pen)
{
var _w_pen = (shape.pen.w == null) ? 12700 : parseInt(shape.pen.w);
_w_pen /= 36000.0;
_w_pen *= g_dKoef_mm_to_pix;
_need_pix_width += (2 * _w_pen);
_need_pix_height += (2 * _w_pen);
_bounds_cheker.Bounds.min_x -= _w_pen;
_bounds_cheker.Bounds.min_y -= _w_pen;
}*/
var _canvas = null;
if (window["NATIVE_EDITOR_ENJINE"] === true && window["IS_NATIVE_EDITOR"] !== true)
{
_need_pix_width = _need_pix_width >> 0;
_need_pix_height = _need_pix_height >> 0;
_canvas = new CNativeGraphics();
_canvas.width = _need_pix_width;
_canvas.height = _need_pix_height;
_canvas.create(window["native"], _need_pix_width, _need_pix_height, _need_pix_width / dKoef, _need_pix_height / dKoef);
_canvas.CoordTransformOffset(-_bounds_cheker.Bounds.min_x, -_bounds_cheker.Bounds.min_y);
_canvas.transform(1, 0, 0, 1, 0, 0);
shape.draw(_canvas, 0);
}
else
{
_canvas = document.createElement("canvas");
_canvas.width = _need_pix_width >> 0;
_canvas.height = _need_pix_height >> 0;
var _ctx = _canvas.getContext("2d");
var g = new AscCommon.CGraphics;
g.init(_ctx, w_px, h_px, w_mm, h_mm);
g.m_oFontManager = AscCommon.g_fontManager;
g.m_oCoordTransform.tx = -_bounds_cheker.Bounds.min_x;
g.m_oCoordTransform.ty = -_bounds_cheker.Bounds.min_y;
g.transform(1, 0, 0, 1, 0, 0);
shape.draw(g, 0);
}
if (AscCommon.g_fontManager) {
AscCommon.g_fontManager.m_pFont = null;
}
if (AscCommon.g_fontManager2) {
AscCommon.g_fontManager2.m_pFont = null;
}
AscCommon.IsShapeToImageConverter = false;
var _ret = { ImageNative : _canvas, ImageUrl : "" };
try
{
const sFormat = sImageFormat || "image/png";
_ret.ImageUrl = _canvas.toDataURL(sFormat);
}
catch (err)
{
if (shape.brush != null && shape.brush.fill && shape.brush.fill.RasterImageId)
_ret.ImageUrl = getFullImageSrc2(shape.brush.fill.RasterImageId);
else
_ret.ImageUrl = "";
}
if (_canvas.isNativeGraphics === true)
_canvas.Destroy();
return _ret;
}
//------------------------------------------------------------export----------------------------------------------------
window['AscCommon'] = window['AscCommon'] || {};
window['AscCommon'].CShapeDrawer = CShapeDrawer;
window['AscCommon'].ShapeToImageConverter = ShapeToImageConverter;
window['AscCommon'].IsShapeToImageConverter = false;
window['AscCommon'].DrawLineEnd = DrawLineEnd;
})(window);