Files
DocumentServer-v-9.2.0/sdkjs/common/Drawings/GraphicsBase.js
T
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

893 lines
21 KiB
JavaScript

/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
"use strict";
(function(window, undefined){
var darkModeEdge = 10;
function _darkModeCheckColor(r, g, b)
{
return (r < darkModeEdge && g < darkModeEdge && b < darkModeEdge) ? true : false;
}
function _darkModeCheckColor2(r, g, b)
{
if (r < darkModeEdge && g < darkModeEdge && b < darkModeEdge) return true;
var max = 255 - darkModeEdge;
if (r > max && g > max && b > max) return true;
return false;
}
AscCommon.darkModeCorrectColor = function(r, g, b)
{
if (r < darkModeEdge && g < darkModeEdge && b < darkModeEdge)
return { R : 255 - r, G: 255 - g, B : 255 - b };
return { R : r, G : g, B : b };
};
AscCommon.darkModeCorrectColor2 = function(r, g, b)
{
var oHSL = {}, oRGB = {};
AscFormat.CColorModifiers.prototype.RGB2HSL(r, g, b, oHSL);
var dKoefL = (255 - 58) / 255;
oHSL.L = 255 - ((dKoefL * oHSL.L) >> 0);
AscFormat.CColorModifiers.prototype.HSL2RGB(oHSL, oRGB, true);
return oRGB;
};
AscCommon.RendererType = {
Base : 0,
Drawer : 1,
PDF : 2,
BoundsChecker : 3,
Track : 4,
TextDrawer : 5,
NativeDrawer : 6
};
function CGraphicsBase(type, isUseGrState)
{
this.type = (undefined === type) ? AscCommon.RendererType.Base : type;
this.isDarkMode = false;
this.shapeDrawCounter = 0;
this.isFormDraw = 0;
this.globalAlpha = 1;
this.textAlpha = undefined;
this.GrState = null;
// Flags
this.IsNoDrawingEmptyPlaceholder = false;
this.IsDemonstrationMode = false;
this.IsThumbnail = false;
this.IsDrawSmart = false;
this.IsPrintMode = false;
this.IsPrintPreview = false;
if (true === isUseGrState)
{
this.GrState = new AscCommon.CGrState();
this.GrState.Parent = this;
}
}
// TYPE
CGraphicsBase.prototype.isBoundsChecker = function()
{
return (this.type === AscCommon.RendererType.BoundsChecker);
};
CGraphicsBase.prototype.isPdf = function()
{
return (this.type === AscCommon.RendererType.PDF);
};
CGraphicsBase.prototype.isNativeDrawer = function()
{
return (this.type === AscCommon.RendererType.NativeDrawer);
};
CGraphicsBase.prototype.isTrack = function()
{
return (this.type === AscCommon.RendererType.Track);
};
CGraphicsBase.prototype.isTextDrawer = function()
{
return (this.type === AscCommon.RendererType.TextDrawer);
};
// DARK MODE REGION
CGraphicsBase.prototype._darkMode1 = function()
{
this.isDarkMode = true;
function _darkColor(_this, _func) {
return function(r, g, b, a) {
if (_this.isDarkMode && _darkModeCheckColor(r, g, b))
_func.call(_this, 255 - r, 255 - g, 255 - b, a);
else
_func.call(_this, r, g, b, a);
};
}
this.p_color_old = this.p_color; this.p_color = _darkColor(this, this.p_color_old);
this.b_color1_old = this.b_color1; this.b_color1 = _darkColor(this, this.b_color1_old);
this.b_color2_old = this.b_color2; this.b_color2 = _darkColor(this, this.b_color2_old);
};
CGraphicsBase.prototype._darkMode2 = function()
{
this.isDarkMode = true;
function _darkColor(_this, _func) {
return function(r, g, b, a) {
var isCorrect = _this.isDarkMode;
if (isCorrect && 0 !== this.shapeDrawCounter)
if (!(1 === this.shapeDrawCounter && this.isFormDraw)) //форму первого уровня не корректируем
isCorrect = false;
if (isCorrect && _darkModeCheckColor2(r, g, b))
_func.call(_this, 255 - r, 255 - g, 255 - b, a);
else
_func.call(_this, r, g, b, a);
};
}
this.p_color_old = this.p_color; this.p_color = _darkColor(this, this.p_color_old);
this.b_color1_old = this.b_color1; this.b_color1 = _darkColor(this, this.b_color1_old);
this.b_color2_old = this.b_color2; this.b_color2 = _darkColor(this, this.b_color2_old);
};
CGraphicsBase.prototype._darkMode3 = function()
{
this.isDarkMode = true;
function _darkColor(_this, _func) {
return function(r, g, b, a) {
var isCorrect = _this.isDarkMode;
if (isCorrect && 0 !== this.shapeDrawCounter)
if (!(1 === this.shapeDrawCounter && this.isFormDraw)) //форму первого уровня не корректируем
isCorrect = false;
if (isCorrect)
{
var c = AscCommon.darkModeCorrectColor2(r, g, b);
_func.call(_this, c.R, c.G, c.B, a);
}
else
{
_func.call(_this, r, g, b, a);
}
};
}
this.p_color_old = this.p_color; this.p_color = _darkColor(this, this.p_color_old);
this.b_color1_old = this.b_color1; this.b_color1 = _darkColor(this, this.b_color1_old);
this.b_color2_old = this.b_color2; this.b_color2 = _darkColor(this, this.b_color2_old);
};
CGraphicsBase.prototype.setDarkMode = function(mode)
{
if (undefined === mode)
this._darkMode3();
else
{
if (mode === 1)
this._darkMode1();
else if (mode === 2)
this.darkMode2();
else
this.darkMode3();
}
};
CGraphicsBase.prototype.StartDrawShape = function(type, isForm)
{
this.shapeDrawCounter++;
this.isFormDraw = isForm;
};
CGraphicsBase.prototype.EndDrawShape = function()
{
this.isFormDraw = false;
this.shapeDrawCounter--;
};
// GLOBAL ALPHA
CGraphicsBase.prototype.Start_GlobalAlpha = function()
{
};
CGraphicsBase.prototype.End_GlobalAlpha = function()
{
};
CGraphicsBase.prototype.setEndGlobalAlphaColor = function(r, g, b)
{
this.endGlobalAlphaColor = (undefined === r) ? undefined : { R : r, G : g, B : b };
};
CGraphicsBase.prototype.put_GlobalAlpha = function(enable, alpha)
{
this.globalAlpha = (false === enable) ? 1 : alpha;
};
// TEXT ALPHA (placeholders)
CGraphicsBase.prototype.setTextGlobalAlpha = function(alpha)
{
this.textAlpha = alpha;
};
CGraphicsBase.prototype.getTextGlobalAlpha = function()
{
return this.textAlpha;
};
CGraphicsBase.prototype.resetTextGlobalAlpha = function()
{
this.textAlpha = undefined;
};
// PEN
CGraphicsBase.prototype.p_color = function(r, g, b, a)
{
};
CGraphicsBase.prototype.p_width = function(w)
{
};
CGraphicsBase.prototype.p_dash = function(params)
{
};
// BRUSH
CGraphicsBase.prototype.b_color1 = function(r, g, b, a)
{
};
CGraphicsBase.prototype.b_color2 = function(r, g, b, a)
{
};
// TRANSFORM
CGraphicsBase.prototype.grStateIsUseBaseTransform = function()
{
return true;
};
CGraphicsBase.prototype.grStateSaveBaseTransform = function()
{
this._m_oBaseTransform = this.m_oBaseTransform;
this.m_oBaseTransform = null;
};
CGraphicsBase.prototype.grStateRestoreBaseTransform = function()
{
this.m_oBaseTransform = this._m_oBaseTransform;
delete this._m_oBaseTransform;
};
CGraphicsBase.prototype.reset = function()
{
};
CGraphicsBase.prototype.transform = function(sx,shy,shx,sy,tx,ty)
{
};
CGraphicsBase.prototype.transform3 = function(m, isNeedInvert)
{
};
CGraphicsBase.prototype.CalculateFullTransform = function()
{
};
// PATH
CGraphicsBase.prototype._s = function()
{
};
CGraphicsBase.prototype._e = function()
{
};
CGraphicsBase.prototype._z = function()
{
};
CGraphicsBase.prototype._m = function(x, y)
{
};
CGraphicsBase.prototype._l = function(x, y)
{
};
CGraphicsBase.prototype._c = function(x1,y1,x2,y2,x3,y3)
{
};
CGraphicsBase.prototype._c2 = function(x1,y1,x2,y2)
{
};
CGraphicsBase.prototype.ds = function()
{
};
CGraphicsBase.prototype.df = function()
{
};
// STATE
CGraphicsBase.prototype.save = function()
{
};
CGraphicsBase.prototype.restore = function()
{
};
CGraphicsBase.prototype.clip = function()
{
};
CGraphicsBase.prototype.StartClipPath = function()
{
};
CGraphicsBase.prototype.EndClipPath = function()
{
};
// GRSTATE
CGraphicsBase.prototype.SavePen = function()
{
this.GrState && this.GrState.SavePen();
};
CGraphicsBase.prototype.RestorePen = function()
{
this.GrState && this.GrState.RestorePen();
};
CGraphicsBase.prototype.SaveBrush = function()
{
this.GrState && this.GrState.SaveBrush();
};
CGraphicsBase.prototype.RestoreBrush = function()
{
this.GrState && this.GrState.RestoreBrush();
};
CGraphicsBase.prototype.SavePenBrush = function()
{
this.GrState && this.GrState.SavePenBrush();
};
CGraphicsBase.prototype.RestorePenBrush = function()
{
this.GrState && this.GrState.RestorePenBrush();
};
CGraphicsBase.prototype.SaveGrState = function()
{
this.GrState && this.GrState.SaveGrState();
};
CGraphicsBase.prototype.RestoreGrState = function()
{
this.GrState && this.GrState.RestoreGrState();
};
CGraphicsBase.prototype.RemoveLastClip = function()
{
this.GrState && this.GrState.RemoveLastClip();
};
CGraphicsBase.prototype.RestoreLastClip = function()
{
this.GrState && this.GrState.RestoreLastClip();
};
CGraphicsBase.prototype.AddClipRect = function(x, y, w, h)
{
if (!this.GrState)
return;
var rect = new AscCommon._rect();
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
this.GrState.AddClipRect(rect);
};
CGraphicsBase.prototype.RemoveClipRect = function()
{
// NOT USED (remove & add, add...)
};
CGraphicsBase.prototype.SetClip = function(r)
{
};
CGraphicsBase.prototype.RemoveClip = function()
{
};
// EDITOR
CGraphicsBase.prototype.isSupportEditFeatures = function()
{
return false;
};
CGraphicsBase.prototype.DrawHeaderEdit = function(yPos, lock_type, sectionNum, bIsRepeat, type)
{
};
CGraphicsBase.prototype.DrawFooterEdit = function(yPos, lock_type, sectionNum, bIsRepeat, type)
{
};
CGraphicsBase.prototype.DrawLockParagraph = function(lock_type, x, y1, y2)
{
};
CGraphicsBase.prototype.DrawLockObjectRect = function(lock_type, x, y, w, h)
{
};
CGraphicsBase.prototype.DrawEmptyTableLine = function(x1,y1,x2,y2)
{
};
CGraphicsBase.prototype.DrawSpellingLine = function(y0, x0, x1, w)
{
};
CGraphicsBase.prototype.drawCustomRange = function(handlerId, rangeId, x0, y0, w, h, baseLine)
{
};
CGraphicsBase.prototype.drawCollaborativeChanges = function(x, y, w, h, Color)
{
};
CGraphicsBase.prototype.drawMailMergeField = function(x, y, w, h)
{
};
CGraphicsBase.prototype.drawSearchResult = function(x, y, w, h)
{
};
CGraphicsBase.prototype.drawFlowAnchor = function(x, y)
{
};
CGraphicsBase.prototype.drawPermissionMark = function(x, y, h, isStart, isActive)
{
};
CGraphicsBase.prototype.DrawFootnoteRect = function(x, y, w, h)
{
};
CGraphicsBase.prototype.DrawPresentationComment = function(type, x, y, w, h)
{
};
CGraphicsBase.prototype.drawBlipFillTile = function () { };
CGraphicsBase.prototype.drawBlipFillStretch = function () { };
// INTEGER GRID
CGraphicsBase.prototype.SetIntegerGrid = function(param)
{
};
CGraphicsBase.prototype.GetIntegerGrid = function()
{
return false;
};
// COMMON FUNCS
CGraphicsBase.prototype.rect = function(x,y,w,h)
{
let r = (x + w);
let b = (y + h);
this._s();
this._m(x, y);
this._l(r, y);
this._l(r, b);
this._l(x, b);
this._z();
};
CGraphicsBase.prototype.TableRect = function(x,y,w,h)
{
this.rect(x,y,w,h);
this.df();
};
CGraphicsBase.prototype.drawHorLine = function(align, y, x, r, penW)
{
this.p_width(1000 * penW);
this._s();
var _y = y;
switch (align)
{
case 0:
{
_y = y + penW / 2;
break;
}
case 1:
{
break;
}
case 2:
{
_y = y - penW / 2;
}
}
this._m(x, y);
this._l(r, y);
this.ds();
this._e();
};
CGraphicsBase.prototype.drawHorLine2 = function(align, y, x, r, penW)
{
this.p_width(1000 * penW);
var _y = y;
switch (align)
{
case 0:
{
_y = y + penW / 2;
break;
}
case 1:
{
break;
}
case 2:
{
_y = y - penW / 2;
break;
}
}
this._s();
this._m(x, (_y - penW));
this._l(r, (_y - penW));
this.ds();
this._s();
this._m(x, (_y + penW));
this._l(r, (_y + penW));
this.ds();
this._e();
};
CGraphicsBase.prototype.drawVerLine = function(align, x, y, b, penW)
{
this.p_width(1000 * penW);
this._s();
var _x = x;
switch (align)
{
case 0:
{
_x = x + penW / 2;
break;
}
case 1:
{
break;
}
case 2:
{
_x = x - penW / 2;
}
}
this._m(_x, y);
this._l(_x, b);
this.ds();
};
CGraphicsBase.prototype.drawHorLineExt = function(align, y, x, r, penW, leftMW, rightMW)
{
this.drawHorLine(align, y, x + leftMW, r + rightMW, penW);
};
CGraphicsBase.prototype.drawPolygon = function(oPath, lineWidth, shift)
{
this.p_width(lineWidth * 1000);
this._s();
let Points = oPath.Points;
let nCount = Points.length;
// берем предпоследнюю точку, т.к. последняя совпадает с первой
let PrevX = Points[nCount - 2].X, PrevY = Points[nCount - 2].Y;
let _x = Points[nCount - 2].X, _y = Points[nCount - 2].Y;
let StartX, StartY;
for (var nIndex = 0; nIndex < nCount; nIndex++)
{
if(PrevX > Points[nIndex].X)
{
_y = Points[nIndex].Y - shift;
}
else if(PrevX < Points[nIndex].X)
{
_y = Points[nIndex].Y + shift;
}
if(PrevY < Points[nIndex].Y)
{
_x = Points[nIndex].X - shift;
}
else if(PrevY > Points[nIndex].Y)
{
_x = Points[nIndex].X + shift;
}
PrevX = Points[nIndex].X;
PrevY = Points[nIndex].Y;
if(nIndex > 0)
{
if (1 === nIndex)
{
StartX = _x;
StartY = _y;
this._m(_x, _y);
}
else
{
this._l(_x, _y);
}
}
}
this._l(StartX, StartY);
this._z();
this.ds();
this._e();
};
CGraphicsBase.prototype.drawPolygonByRects = function(rects, lineWidth, shift)
{
let polygon = new AscCommon.CPolygon();
polygon.fill(rects);
let paths = polygon.GetPaths(shift ? shift : 0);
for (let i = 0, count = paths.length; i < count; ++i)
{
this.drawPolygon(paths[i], lineWidth, 0);
}
};
/**
* made with the use of:
* http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api/
* uses de Casteljau's algorithm
* @param {{x: Number, y: Number, z? :Number}} startPoint
* @param {{x: Number, y: Number, z? :Number}[]} controlPoints
* @param {{x: Number, y: Number, z? :Number}} endPoint
*/
CGraphicsBase.prototype._cN = function(startPoint, controlPoints, endPoint)
{
function sumDistanceBetweenPoints(points)
{
function distance(a, b){
return Math.sqrt(Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y, 2));
}
/**Compute the incremental step*/
let tLength = 0;
for(let i=0; i < points.length - 1; i++){
tLength += distance(points[i], points[i+1]);
}
return tLength;
}
function transformPoints(points, dpi)
{
let pointsCopy = Array(points.length);
let mmToIch = 0.03937007874;
for(let i=0; i < pointsCopy.length; i++){
pointsCopy[i] = {x: null, y: null};
// pointsCopy[i].x = transform.TransformPointX(points[i].x, points[i].y);
// pointsCopy[i].y = transform.TransformPointY(points[i].x, points[i].y);
pointsCopy[i].x = points[i].x * mmToIch * dpi;
pointsCopy[i].y = points[i].y * mmToIch * dpi;
}
return pointsCopy;
}
/** Computes a point's coordinates for a value of t
* @param {Number} t - a value between o and 1
* @param {{x: Number, y: Number, z? :Number}} startPoint
* @param {{x: Number, y: Number, z? :Number}[]} controlPoints
* @param {{x: Number, y: Number, z? :Number}} endPoint
* @return {{x: Number, y: Number}} point
**/
function computeBezierPoint(t, startPoint, controlPoints, endPoint)
{
/**Computes Bernstain
*@param {Integer} i - the i-th index
*@param {Integer} n - the total number of points
*@param {Number} t - the value of parameter t , between 0 and 1
**/
function computeBernstainCoef(i,n,t)
{
/**Computes factorial*/
function fact(k){
if(k==0 || k==1){
return 1;
}
else{
return k * fact(k-1);
}
}
//if(n < i) throw "Wrong";
return fact(n) / (fact(i) * fact(n-i))* Math.pow(t, i) * Math.pow(1-t, n-i);
}
var points = [].concat(startPoint, controlPoints, endPoint);
var r = {
x: 0,
y: 0
};
var n = points.length-1;
for(var i=0; i <= n; i++){
r.x += points[i].x * computeBernstainCoef(i, n, t);
r.y += points[i].y * computeBernstainCoef(i, n, t);
}
return r;
}
// to calculate points count curve length should be calculated in pixels (approximately)
// so arguments should be in mm units and graphics.transform should be applied already
let calculatePointsCount = false;
let interpolationPointsCount;
if (calculatePointsCount) {
// https://www.figma.com/file/FT0m9czNuvK34TK227cQ6e/pointsToCalculatePerOnePixelLengthUnit?type=design&node-id=0%3A1&mode=design&t=0S7e2nxkt2sbCHqw-1
// not integer more like precision coefficient. can be 0.3 for example
let pointsToCalculatePerOnePixelLengthUnit = 1;
let dpi = 96;
let bezierPoints = [].concat(startPoint, controlPoints, endPoint);
// this.m_oFullTransform doesn't exist in that Graphics
// convert length to pixels length units
// https://www.figma.com/file/FT0m9czNuvK34TK227cQ6e/pointsToCalculatePerOnePixelLengthUnit?type=design&node-id=41-49&mode=design&t=pH5bF1EvWeWjzkS0-0
// Canvas resize is not considered!
let bezierPointsCopy = transformPoints(bezierPoints, dpi);
// As we calculate length of a curve as sum of control points there might be performance issue with
// high order curves because they have many control points and so length will be considered
// as long and there will be many control points
// add + 1 to avoid divide by 0 later when calculating interpolation step which is 1/interpolationPointsCount
interpolationPointsCount = pointsToCalculatePerOnePixelLengthUnit *
sumDistanceBetweenPoints(bezierPointsCopy) + 1;
} else {
interpolationPointsCount = 1000;
}
// this.p_width(lineWidth);
// this._s(); // beginPath
// this._m(startPoint.x, startPoint.y);
// in fact real pointsCount is larger by 1 point. bcs if pointsCount = 2 t will be 0, 1/2 and 1 - 3 times total
for (let t = 0; t <= 1; t+= 1/interpolationPointsCount) {
let point = computeBezierPoint(t, startPoint, controlPoints, endPoint);
this._l(point.x, point.y);
}
// https://github.com/ONLYOFFICE/sdkjs/blob/ebcb7401438a8260151cd96f7568d521e04f91e9/word/Drawing/Graphics.js#L438
// this._z(); // close path
// this.ds(); // draw stroke
// this._e(); // beginPath
};
// FONT
CGraphicsBase.prototype.FreeFont = function()
{
};
CGraphicsBase.prototype.ClearLastFont = function()
{
};
CGraphicsBase.prototype.GetFont = function()
{
};
CGraphicsBase.prototype.SetFont = function(font)
{
};
CGraphicsBase.prototype.GetTextPr = function()
{
};
CGraphicsBase.prototype.SetTextPr = function(textPr, theme)
{
};
CGraphicsBase.prototype.SetFontSlot = function(slot, fontSizeKoef)
{
};
CGraphicsBase.prototype.SetFontInternal = function(name, size, style)
{
};
// TEXT
CGraphicsBase.prototype.isSupportTextDraw = function()
{
return true;
};
CGraphicsBase.prototype.isSupportTextOutline = function()
{
return false;
};
CGraphicsBase.prototype.FillText = function(x,y,text)
{
};
CGraphicsBase.prototype.t = function(text,x,y,isBounds)
{
};
CGraphicsBase.prototype.FillText2 = function(x,y,text,cropX,cropW)
{
};
CGraphicsBase.prototype.t2 = function(text,x,y,cropX,cropW)
{
};
CGraphicsBase.prototype.FillTextCode = function(x,y,lUnicode)
{
};
CGraphicsBase.prototype.tg = function(text,x,y,codepoints)
{
};
// IMAGES
CGraphicsBase.prototype.isVectorImage = function(img)
{
if (img.isVectorImage !== undefined)
return img.isVectorImage;
if (!img.src)
return false;
let fileName = AscCommon.g_oDocumentUrls.getImageLocal(img.src);
img.isVectorImage = (fileName && fileName.endsWith(".svg")) ? true : false;
return img.isVectorImage;
};
CGraphicsBase.prototype.drawImage2 = function(img,x,y,w,h,alpha,srcRect)
{
};
CGraphicsBase.prototype.drawImage = function(img,x,y,w,h,alpha,srcRect,nativeImage)
{
};
// COMMANDS
CGraphicsBase.prototype.Start_Command = function(commandId)
{
};
CGraphicsBase.prototype.End_Command = function(commandId)
{
};
CGraphicsBase.prototype.SetBorder = function(border)
{
};
//------------------------------------------------------------export----------------------------------------------------
window['AscCommon'] = window['AscCommon'] || {};
window['AscCommon'].CGraphicsBase = CGraphicsBase;
})(window);