scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
677 lines (676 loc) • 34.6 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebGlRenderContext2D = exports.ELineDrawMode = exports.calculateAbsoluteRenderLayer = void 0;
var app_1 = require("../../constants/app");
var Guard_1 = require("../../Core/Guard");
var Rect_1 = require("../../Core/Rect");
var createNativeRect_1 = require("../Visuals/Helpers/createNativeRect");
var NativeObject_1 = require("../Visuals/Helpers/NativeObject");
var DeletableEntity_1 = require("../../Core/DeletableEntity");
var performance_1 = require("../../utils/performance");
var Point_1 = require("../../Core/Point");
var AnchorPoint_1 = require("../../types/AnchorPoint");
var TextPosition_1 = require("../../types/TextPosition");
var colorUtil_1 = require("../../utils/colorUtil");
var parseColor_1 = require("../../utils/parseColor");
var text_1 = require("../../utils/text");
var SURFACE_LAYER_STEP = 1000;
/**
* @param surfaceOrder layer z-order offset of the surface
* @param layerStep specifies the capacity of layers that could be potentially added between the default chart layers
* @param relativeRenderLayer layer number relative to the specific surface layers
* @returns absolute order of the layer on the chart (considering parent chart and previous subChart surface layers)
*/
var calculateAbsoluteRenderLayer = function (surfaceOrder, layerStep, relativeRenderLayer) {
return surfaceOrder * SURFACE_LAYER_STEP + relativeRenderLayer * layerStep;
};
exports.calculateAbsoluteRenderLayer = calculateAbsoluteRenderLayer;
/**
* Defines enumeration constants for Line Drawing modes
*/
var ELineDrawMode;
(function (ELineDrawMode) {
/**
* Points provided define a poly-line (continuous line)
*/
ELineDrawMode["PolyLine"] = "PolyLine";
/**
* Points provided define discontinuous lines, e.g. x1y1 x2y2 is one line, x3y3 x4y4 is the next
*/
ELineDrawMode["DiscontinuousLine"] = "DiscontinuousLine";
})(ELineDrawMode = exports.ELineDrawMode || (exports.ELineDrawMode = {}));
/**
* The WebGlRenderContext2D provides methods for drawing to a WebGL2 / WebAssembly canvas powered by SciChart's Visual Xccelerator engine.
* This context class is used in SciChart's High Performance Realtime {@link https://www.scichart.com/javascript-chart-features | JavaScript Charts}
* to draw shapes, lines, fills, images and more
*/
var WebGlRenderContext2D = /** @class */ (function (_super) {
__extends(WebGlRenderContext2D, _super);
/**
* Creates an instance of the WebGlRenderContext2D
* @param webAssemblyContext The {@link TSciChart | SciChart WebAssembly Context} containing native methods and access to our WebGL2 Engine
* @param viewportSize The Viewport {@link Size}
*/
function WebGlRenderContext2D(webAssemblyContext, viewportSize, canvasId) {
var _this = _super.call(this) || this;
_this.layers = new Map();
_this.effects = [];
_this.webAssemblyContext = webAssemblyContext;
_this.viewportSize = viewportSize;
_this.canvasId = canvasId;
_this.currentClipRect = Rect_1.Rect.create(0, 0, viewportSize.width, viewportSize.height);
_this.currentRotation = 0;
_this.currentTranslationX = 0;
_this.currentTranslationY = 0;
return _this;
}
/**
* Get the native {@link SCRTRenderContext} for direct access to SciChart's WebAssembly Visual Xccelerator engine
*/
WebGlRenderContext2D.prototype.getNativeContext = function () {
if (!this.nativeContext) {
this.nativeContext = this.webAssemblyContext.SCRTGetMainRenderContext2D();
}
return this.nativeContext;
};
/**
* Draw lines: grid lines, etc.
* @param vertices
* @param pen
* @param lineDrawMode
* @param left - offset in pixels from left, typically used for axes
* @param top - offset in pixels from top, typically used for axes
*/
WebGlRenderContext2D.prototype.drawLinesNative = function (vertices, pen, lineDrawMode, clipRect, left, top) {
if (left === void 0) { left = 0; }
if (top === void 0) { top = 0; }
var isStrips = lineDrawMode === ELineDrawMode.PolyLine;
var nativeContext = this.getNativeContext();
this.resetTransform();
this.translate(left, top);
this.setClipRect(clipRect);
var drawLineParams = new this.webAssemblyContext.SCRTDrawLinesParams();
drawLineParams.m_Type = isStrips
? this.webAssemblyContext.SCRTLineType.Strip
: this.webAssemblyContext.SCRTLineType.List;
drawLineParams.SetPen(pen);
drawLineParams.SetPointsVec(vertices);
nativeContext.DrawLines(drawLineParams);
drawLineParams.delete();
};
/**
* Draw rectangles: grid bands, etc.
* @param vertices
* @param brush
* @param left - offset in pixels from left, typically used for axes
* @param top - offset in pixels from top, typically used for axes
*/
WebGlRenderContext2D.prototype.drawRects = function (vertices, brush, clipRect, left, top) {
if (left === void 0) { left = 0; }
if (top === void 0) { top = 0; }
var anchorParams = (0, NativeObject_1.getVector4)(this.webAssemblyContext, 0, 0, 0, 0);
var nativeContext = this.getNativeContext();
this.resetTransform();
this.translate(left, top);
this.setClipRect(clipRect);
// this.EnsureContextTransform(left, top, clipRect);
var drawRectsParams = new this.webAssemblyContext.SCRTDrawRectsParams();
drawRectsParams.SetVerticesVec(vertices);
drawRectsParams.SetBrush(brush);
drawRectsParams.m_vAnchorParams = anchorParams;
nativeContext.DrawRects(drawRectsParams);
drawRectsParams === null || drawRectsParams === void 0 ? void 0 : drawRectsParams.delete();
};
WebGlRenderContext2D.prototype.drawEllipses = function (vertices, pen, left, top) {
if (left === void 0) { left = 0; }
if (top === void 0) { top = 0; }
var nativeContext = this.getNativeContext();
this.resetTransform();
this.translate(left, top);
var drawRectsParams = new this.webAssemblyContext.SCRTDrawRectsParams();
drawRectsParams.SetVerticesVec(vertices);
drawRectsParams.SetPen(pen);
drawRectsParams.SetBrush(null);
drawRectsParams.m_bIsEllipses = true;
nativeContext.DrawRects(drawRectsParams);
drawRectsParams === null || drawRectsParams === void 0 ? void 0 : drawRectsParams.delete();
};
/**
*
* @param vertices
* @param xCenter
* @param yCenter It is viewport height minus Y coordinate
* @param rotation Rotation in Radians
* @param clipRect
* @param pen
* @param brush
* @param left
* @param top
*/
WebGlRenderContext2D.prototype.drawArcs = function (vertices, xCenter, yCenter, rotation, clipRect, pen, brush, left, top) {
if (left === void 0) { left = 0; }
if (top === void 0) { top = 0; }
var nativeContext = this.getNativeContext();
var dx = 0;
var dy = 0;
if (rotation !== 0) {
var l = Math.sqrt(xCenter * xCenter + yCenter * yCenter);
var a = Math.atan2(yCenter, xCenter);
dx = xCenter - l * Math.cos(a + rotation);
dy = yCenter - l * Math.sin(a + rotation);
}
this.resetTransform();
this.translate(dx + left, dy - top);
this.rotate((rotation * 180) / Math.PI);
this.setClipRect(clipRect);
var drawArcsParams = new this.webAssemblyContext.SCRTDrawArcsParams();
drawArcsParams.SetVerticesVec(vertices);
drawArcsParams.SetPen(pen ? pen : null);
drawArcsParams.SetBrush(brush ? brush : null);
nativeContext.DrawArcs(drawArcsParams);
drawArcsParams === null || drawArcsParams === void 0 ? void 0 : drawArcsParams.delete();
};
/**
* Enqueues a draw operation to the specified layer. Use in combination with {@link drawLayers} to flush layered draws
* @param drawFunction the {@link TDrawFunction | Draw Function} to enqueue
* @param layer the {@link ERenderLayer | Layer} to draw to
*/
WebGlRenderContext2D.prototype.enqueueLayeredDraw = function (drawFunction, layer) {
if (!this.layers.has(layer)) {
this.layers.set(layer, []);
}
this.layers.get(layer).push(drawFunction);
};
/**
* Flushes the {@link layers} which have been enqueued with drawing operations in order.
* Use this in combination with {@link enqueueLayeredDraw} to draw in layers
*/
WebGlRenderContext2D.prototype.drawLayers = function () {
var _a, _b;
var parentContextId = this.canvasId;
var allLayersDrawStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.AllLayersDrawStart, {
parentContextId: parentContextId,
level: performance_1.EPerformanceDebugLevel.Verbose
});
var keys = Array.from(this.layers.keys()).sort(function (a, b) { return a - b; });
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var key = keys_1[_i];
var layerDrawStartMark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.SingleLayerDrawStart, {
contextId: "Layer-".concat(key),
parentContextId: parentContextId,
level: performance_1.EPerformanceDebugLevel.Verbose
});
var drawFunctionsInCurrentLayer = this.layers.get(key);
for (var _c = 0, drawFunctionsInCurrentLayer_1 = drawFunctionsInCurrentLayer; _c < drawFunctionsInCurrentLayer_1.length; _c++) {
var drawFunc = drawFunctionsInCurrentLayer_1[_c];
drawFunc();
}
performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.SingleLayerDrawEnd, {
relatedId: (_a = layerDrawStartMark === null || layerDrawStartMark === void 0 ? void 0 : layerDrawStartMark.detail) === null || _a === void 0 ? void 0 : _a.relatedId,
contextId: "Layer-".concat(key),
parentContextId: parentContextId,
level: performance_1.EPerformanceDebugLevel.Verbose
});
}
performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.AllLayersDrawEnd, {
relatedId: (_b = allLayersDrawStartMark === null || allLayersDrawStartMark === void 0 ? void 0 : allLayersDrawStartMark.detail) === null || _b === void 0 ? void 0 : _b.relatedId,
parentContextId: parentContextId,
level: performance_1.EPerformanceDebugLevel.Verbose
});
};
/**
* Applies a {@link ShaderEffect} to the rendering pipeline. Calling {@link WebGL2RenderingContext.popShaderEffect} pops the effect from the stack
* reverting to normal drawing
* @param effect the {@link ShaderEffect} to apply to subsequent draw operations
*/
WebGlRenderContext2D.prototype.pushShaderEffect = function (effect) {
if (effect) {
this.effects.push(effect);
if (!app_1.IS_TEST_ENV) {
this.getNativeContext().AddSeriesEffect(effect.getNativeEffect());
}
}
};
/**
* Pops a {@link ShaderEffect} from the rendering pipeline. Call {@link WebGL2RenderingContext.pushShaderEffect} to apply an effect
*/
WebGlRenderContext2D.prototype.popShaderEffect = function () {
var effect = this.effects.pop();
if (effect && !app_1.IS_TEST_ENV) {
this.getNativeContext().RemoveSeriesEffect(effect.getNativeEffect());
}
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.createPen = function (stroke, strokeThickness, strokeDashArray, antiAliased) {
if (strokeDashArray === void 0) { strokeDashArray = []; }
if (antiAliased === void 0) { antiAliased = true; }
throw new Error("Use Pen2DCache for creating pens instead!");
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.createSolidBrush = function (fill, opacity) {
throw new Error("Use BrushCache for creating brushes instead!");
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.delete = function () {
// Todo: Any cached items delete here
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.drawLine = function (x1, y1, x2, y2, pen, offsetRect, clipRect) {
if (!x1 && !y1 && !x2 && !y2) {
return;
}
Guard_1.Guard.notNull(pen, "pen");
Guard_1.Guard.isTrue(pen.getPenType() === "WasmPen", "pen must be an instance of WasmPen to be used with the WasmRenderContext");
var scrtPen = pen.scrtPen;
Guard_1.Guard.notNull(scrtPen, "WasmPen.scrtPen");
var isStrips = true;
var nativeContext = this.getNativeContext();
var vertices = (0, NativeObject_1.getVectorColorVertex)(this.webAssemblyContext);
var vertex0 = (0, NativeObject_1.getVertex)(this.webAssemblyContext, x1, y1);
vertices.push_back(vertex0);
var vertex1 = (0, NativeObject_1.getVertex)(this.webAssemblyContext, x2, y2);
vertices.push_back(vertex1);
this.resetTransform();
this.translate(offsetRect.x, offsetRect.y);
this.setClipRect(clipRect);
var drawLineParams = new this.webAssemblyContext.SCRTDrawLinesParams();
drawLineParams.m_Type = isStrips
? this.webAssemblyContext.SCRTLineType.Strip
: this.webAssemblyContext.SCRTLineType.List;
drawLineParams.SetPen(scrtPen);
drawLineParams.SetPointsVec(vertices);
nativeContext.DrawLines(drawLineParams);
drawLineParams.delete();
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.drawLines = function (xyValues, strokePen, offsetRect, clipRect, lineDrawMode) {
if (lineDrawMode === void 0) { lineDrawMode = ELineDrawMode.PolyLine; }
Guard_1.Guard.notNull(strokePen, "pen");
Guard_1.Guard.notNull(xyValues, "xyValues");
Guard_1.Guard.isTrue(strokePen.getPenType() === "WasmPen", "pen must be an instance of WasmPen to be used with the WasmRenderContext");
Guard_1.Guard.isTrue(xyValues.length > 0 && xyValues.length % 2 === 0, "xyValues length must be a multiple of 2, values arranged as x0y0 x1y1 x2y2...");
var scrtPen = strokePen.scrtPen;
Guard_1.Guard.notNull(scrtPen, "WebGlPen.scrtPen");
var isStrips = lineDrawMode === ELineDrawMode.PolyLine;
var nativeContext = this.getNativeContext();
var vertices = (0, NativeObject_1.getVectorColorVertex)(this.webAssemblyContext);
for (var i = 0; i < xyValues.length; i += 2) {
var vertex = (0, NativeObject_1.getVertex)(this.webAssemblyContext, xyValues[i], xyValues[i + 1]);
// Setting a sub-property directly MUST BE AVOIDED because it creates a copy of an object and leaks the memory
// Never do this: vertex.m_vPosition.z = 0;
vertices.push_back(vertex);
}
this.resetTransform();
this.translate(offsetRect.x, offsetRect.y);
this.setClipRect(clipRect);
var drawLineParams = new this.webAssemblyContext.SCRTDrawLinesParams();
drawLineParams.m_Type = isStrips
? this.webAssemblyContext.SCRTLineType.Strip
: this.webAssemblyContext.SCRTLineType.List;
drawLineParams.SetPen(scrtPen);
drawLineParams.SetPointsVec(vertices);
nativeContext.DrawLines(drawLineParams);
drawLineParams.delete();
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.drawTriangleStrip = function (xValues, yValues, offsetRect, clipRect, fillBrush) {
if (fillBrush) {
Guard_1.Guard.arraysSameLength(xValues, "xValues", yValues, "yValues");
var nativeContext = this.getNativeContext();
var scrtBrush = fillBrush.scrtBrush;
Guard_1.Guard.notNull(scrtBrush, "WebGlBrush.scrtBrush");
var vertices = (0, NativeObject_1.getVectorColorTextureVertex)(this.webAssemblyContext);
var size = xValues.length;
for (var i = 0; i < size; i++) {
var x = xValues[i];
var y = yValues[i];
var vertex = (0, NativeObject_1.getTextureVertex)(this.webAssemblyContext, x, y);
vertices.push_back(vertex);
}
this.resetTransform();
this.translate(offsetRect.x, offsetRect.y);
this.setClipRect(clipRect);
var drawParams = new this.webAssemblyContext.SCRTDrawPrimitivesParams();
drawParams.SetVerticesVec(vertices);
drawParams.SetBrush(scrtBrush);
nativeContext.DrawPrimitives(drawParams);
drawParams.delete();
}
};
/**
* Helper function to draw a texture a {@link SCRTRectVertex}
* @param webAssemblyContext The {@link TSciChart | SciChart 2D WebAssembly Context} containing native methods and
* access to our WebGL2 Engine and WebAssembly numerical methods
* @param texture
* @param x
* @param y
* @param width
* @param height
*/
WebGlRenderContext2D.prototype.drawTexture = function (texture, x, y, width, height) {
var nativeContext = this.getNativeContext();
var brush = new this.webAssemblyContext.SCRTTextureBrush(texture, this.webAssemblyContext.eSCRTBrushMappingMode.PerPrimitive, 1);
// draw as a single strip with 4 verts
var quadVerts = (0, NativeObject_1.getVectorColorTextureVertex)(this.webAssemblyContext);
var bottomLeft = (0, NativeObject_1.getTextureVertex)(this.webAssemblyContext, x, y, app_1.NEUTRAL_COLOR, 0, 0);
quadVerts.push_back(bottomLeft);
var topLeft = (0, NativeObject_1.getTextureVertex)(this.webAssemblyContext, x + width, y, app_1.NEUTRAL_COLOR, 1, 0);
quadVerts.push_back(topLeft);
var bottomRight = (0, NativeObject_1.getTextureVertex)(this.webAssemblyContext, x, y + height, app_1.NEUTRAL_COLOR, 0, 1);
quadVerts.push_back(bottomRight);
var topRight = (0, NativeObject_1.getTextureVertex)(this.webAssemblyContext, x + width, y + height, app_1.NEUTRAL_COLOR, 1, 1);
quadVerts.push_back(topRight);
var drawParams = new this.webAssemblyContext.SCRTDrawPrimitivesParams();
drawParams.SetVerticesVec(quadVerts);
drawParams.SetBrush(brush);
nativeContext.DrawPrimitives(drawParams);
brush === null || brush === void 0 ? void 0 : brush.delete();
drawParams.delete();
};
WebGlRenderContext2D.prototype.drawRotatedRect = function (width, height, baselineHeight, padding, verticalAnchorPoint, horizontalAnchorPoint, position, rotation, clipRect, fillBrush) {
var scrtBrush = fillBrush.scrtBrush;
Guard_1.Guard.notNull(scrtBrush, "WebGlBrush.scrtBrush");
var fromCenterToTop;
var fromCenterToBottom;
switch (verticalAnchorPoint) {
case AnchorPoint_1.EVerticalAnchorPoint.Bottom:
fromCenterToTop = baselineHeight + padding.bottom + padding.top;
fromCenterToBottom = height - baselineHeight;
break;
case AnchorPoint_1.EVerticalAnchorPoint.Top:
fromCenterToTop = 0;
fromCenterToBottom = height + padding.bottom + padding.top;
break;
default:
fromCenterToTop = baselineHeight / 2 + (padding.bottom + padding.top) / 2;
fromCenterToBottom = height - baselineHeight / 2 + (padding.bottom + padding.top) / 2;
}
var fromCenterToLeft;
var fromCenterToRight;
switch (horizontalAnchorPoint) {
case AnchorPoint_1.EHorizontalAnchorPoint.Right:
fromCenterToLeft = width + padding.left + padding.right;
fromCenterToRight = 0;
break;
case AnchorPoint_1.EHorizontalAnchorPoint.Left:
fromCenterToLeft = 0;
fromCenterToRight = width + padding.left + padding.right;
break;
default:
fromCenterToLeft = width / 2 + padding.left;
fromCenterToRight = width / 2 + padding.right;
}
var rect = Rect_1.Rect.createWithPoints(new Point_1.Point(-fromCenterToLeft, -fromCenterToTop), new Point_1.Point(fromCenterToRight, fromCenterToBottom));
var nativeContext = this.getNativeContext();
var vertices = (0, NativeObject_1.getVectorRectVertex)(this.webAssemblyContext);
var anchorParams = (0, NativeObject_1.getVector4)(this.webAssemblyContext, 0, 0, 0, 0);
var nativeRect = (0, createNativeRect_1.createNativeRect)(this.webAssemblyContext, rect.x, rect.y, rect.right, rect.bottom);
vertices.push_back(nativeRect);
this.resetTransform();
this.translate(position.x, position.y);
this.rotate(rotation);
this.setClipRect(clipRect);
var drawRectsParams = new this.webAssemblyContext.SCRTDrawRectsParams();
drawRectsParams.SetVerticesVec(vertices);
drawRectsParams.SetBrush(scrtBrush);
drawRectsParams.m_vAnchorParams = anchorParams;
nativeContext.DrawRects(drawRectsParams);
drawRectsParams === null || drawRectsParams === void 0 ? void 0 : drawRectsParams.delete();
};
/**
* @inheritDoc
*/
WebGlRenderContext2D.prototype.drawRect = function (rect, offsetRect, clipRect, strokePen, fillBrush, bevelCorners, strokeThickness) {
if (fillBrush) {
var nativeContext = this.getNativeContext();
var scrtBrush = fillBrush.scrtBrush;
Guard_1.Guard.notNull(scrtBrush, "WebGlBrush.scrtBrush");
var vertices = (0, NativeObject_1.getVectorRectVertex)(this.webAssemblyContext);
var anchorParams = (0, NativeObject_1.getVector4)(this.webAssemblyContext, 0, 0, 0, 0);
var nativeRect = (0, createNativeRect_1.createNativeRect)(this.webAssemblyContext, rect.x, rect.y, rect.right, rect.bottom);
vertices.push_back(nativeRect);
this.resetTransform();
this.translate(offsetRect.x, offsetRect.y);
this.setClipRect(clipRect);
var drawRectsParams = new this.webAssemblyContext.SCRTDrawRectsParams();
drawRectsParams.SetVerticesVec(vertices);
drawRectsParams.SetBrush(scrtBrush);
drawRectsParams.m_vAnchorParams = anchorParams;
nativeContext.DrawRects(drawRectsParams);
drawRectsParams === null || drawRectsParams === void 0 ? void 0 : drawRectsParams.delete();
}
if (strokePen) {
if (bevelCorners) {
this.drawLines([
rect.right,
rect.top,
rect.right,
rect.bottom,
rect.left,
rect.bottom,
rect.left,
rect.top,
rect.right,
rect.top,
rect.right,
rect.bottom
], strokePen, offsetRect, clipRect, ELineDrawMode.PolyLine);
}
else {
var hst = Math.round(strokeThickness / 2) - 1;
this.drawLines([
rect.right,
rect.top - hst,
rect.right,
rect.bottom + hst,
rect.right,
rect.bottom,
rect.left,
rect.bottom,
rect.left,
rect.bottom + hst,
rect.left,
rect.top - hst,
rect.left,
rect.top,
rect.right,
rect.top
], strokePen, offsetRect, clipRect, ELineDrawMode.DiscontinuousLine);
}
}
};
WebGlRenderContext2D.prototype.drawTextBackground = function (textWidth, textHeight, rotation, rotationCenter, chartViewRect, verticalAnchorPoint, horizontalAnchorPoint, padding, fillBrush) {
this.drawRotatedRect(textWidth, textHeight, textHeight, padding, verticalAnchorPoint, horizontalAnchorPoint, rotationCenter, rotation, chartViewRect, fillBrush);
};
WebGlRenderContext2D.prototype.drawNativeText = function (rotationRadians, xCoord, yCoord, offsetRect, chartViewRect, fontFamily, fontSize, textColor, textColorOpacity, backgroundFillBrush, verticalAnchorPoint, horizontalAnchorPoint, text, padding, scale, lineSpacing) {
if (scale === void 0) { scale = 1; }
if (lineSpacing === void 0) { lineSpacing = 3; }
var colorNum = (0, parseColor_1.parseColorToUIntArgb)(textColor);
var colorNumWithOpacity = (0, colorUtil_1.uintArgbColorOverrideOpacity)(colorNum, textColorOpacity);
var style = {
fontFamily: fontFamily,
fontSize: fontSize
};
var font = this.getFont(style, false, false);
var textBounds = (0, NativeObject_1.getTextBounds)(this.webAssemblyContext);
font.CalculateStringBounds(text !== null && text !== void 0 ? text : "", textBounds, lineSpacing);
var rotationCenterX = xCoord + offsetRect.x;
var rotationCenterY = yCoord + offsetRect.y;
var _a = (0, text_1.getNativeTextPosition)(xCoord, yCoord, horizontalAnchorPoint, verticalAnchorPoint, textBounds, padding), textPositionX = _a.x, textPositionY = _a.y;
var textWidth = textBounds.m_fWidth;
var textHeight = textBounds.m_fHeight;
var alignMode = (0, TextPosition_1.convertMultiLineAlignment)(TextPosition_1.EMultiLineAlignment.Center, this.webAssemblyContext);
var oldScale = font.GetScale();
var scaleChanged = false;
if (oldScale !== scale) {
font.SetScale(scale);
scaleChanged = true;
}
var x = textPositionX + offsetRect.x;
var y = textPositionY + offsetRect.y;
if (backgroundFillBrush) {
this.drawTextBackground(textWidth, textHeight, -((rotationRadians * 180) / Math.PI), new Point_1.Point(rotationCenterX, rotationCenterY), chartViewRect, verticalAnchorPoint, horizontalAnchorPoint, padding, backgroundFillBrush);
this.resetTransform();
}
var rotationVector = (0, NativeObject_1.getVector4)(this.webAssemblyContext, rotationCenterX, rotationCenterY, rotationRadians, 0);
font.DrawStringAdvanced(text, colorNumWithOpacity, Math.round(x), Math.round(y), rotationVector, alignMode, lineSpacing);
if (scaleChanged) {
font.SetScale(oldScale);
}
// always drawing immediately
font.End();
};
WebGlRenderContext2D.prototype.printBlendMode = function () {
var blendMode = this.getNativeContext().GetBlendMode();
switch (blendMode) {
case this.webAssemblyContext.eSCRTBlendMode.BlendDefault:
console.log("BlendDefault");
break;
case this.webAssemblyContext.eSCRTBlendMode.BlendAdditiveOneAlpha:
console.log("BlendAdditiveOneAlpha");
break;
case this.webAssemblyContext.eSCRTBlendMode.BlendAdditiveColor:
console.log("BlendAdditiveColor");
break;
case this.webAssemblyContext.eSCRTBlendMode.BlendAdditiveAlpha:
console.log("BlendAdditiveAlpha");
break;
case this.webAssemblyContext.eSCRTBlendMode.BlendDisabled:
console.log("BlendDisabled");
break;
default:
throw new Error("Unhandled blendmode ");
}
};
/**
* Get a native font. Fonts are cached and shared within webassembly so there is no need to cache them in JS.
* Set advanced: true if you are planning to rotate or scale the text.
* Set drawEarly: true if you are planning to call font.End() early. Otherwise all native text will be drawn at the end of the render cycle.
*/
WebGlRenderContext2D.prototype.getFont = function (labelStyle, advanced, drawEarly) {
var _this = this;
if (advanced === void 0) { advanced = false; }
if (drawEarly === void 0) { drawEarly = false; }
var fontKey = (0, NativeObject_1.getFontKey)(this.webAssemblyContext, labelStyle, advanced, drawEarly);
var nativeContext = this.getNativeContext();
var nativeFont = nativeContext.AquireFont(fontKey);
if (!nativeFont) {
throw new Error("Could not create font " + fontKey.m_strName);
}
else {
if (!nativeFont.m_isDrawing) {
nativeFont.Begin();
}
}
var currentFontName = nativeFont.GetFaceName();
if (currentFontName === "SCRT_Loading") {
setTimeout(function () {
var _a;
performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.Invalidate, { parentContextId: _this.canvasId });
_this.webAssemblyContext.TSRRequestCanvasDraw((_a = _this.canvasId) !== null && _a !== void 0 ? _a : "undefinedCanvasId");
}, 100);
}
else if (currentFontName !== fontKey.m_strName) {
// @ts-ignore
if (!fontKey.warned) {
console.warn("Font ".concat(fontKey.m_strName, " could not be found on the server and has not been registered. Falling back to default font.\n Use await scichartSurface.registerFont if you need to load the font from a remote url"));
// @ts-ignore
fontKey.warned = true;
}
}
return nativeFont;
};
/** End all fonts, causing text to be drawn */
WebGlRenderContext2D.prototype.endFonts = function (force) {
var _a;
if (force === void 0) { force = false; }
var mark = performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawNativeTextStart, {
contextId: this.canvasId,
level: performance_1.EPerformanceDebugLevel.Verbose
});
var nativeContext = this.getNativeContext();
var keys = (0, NativeObject_1.getAllFontKeys)(this.webAssemblyContext);
for (var _i = 0, keys_2 = keys; _i < keys_2.length; _i++) {
var fontKey = keys_2[_i];
var nativeFont = nativeContext.AquireFont(fontKey);
if (nativeFont && nativeFont.m_isDrawing) {
nativeFont.End();
}
}
performance_1.PerformanceDebugHelper.mark(performance_1.EPerformanceMarkType.DrawNativeTextEnd, {
contextId: this.canvasId,
relatedId: (_a = mark === null || mark === void 0 ? void 0 : mark.detail) === null || _a === void 0 ? void 0 : _a.relatedId,
level: performance_1.EPerformanceDebugLevel.Verbose
});
};
WebGlRenderContext2D.prototype.setClipRect = function (clipRect) {
var nativeContext = this.getNativeContext();
nativeContext.SetClipRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
this.currentClipRect = clipRect;
};
/**
*
* @param clipRect Clipping rectangle
* @param translationX Translation on X axis in pixels
* @param translationY Translation on Y axis in pixels
* @param angle Angle in degrees
*/
WebGlRenderContext2D.prototype.setTranslationRotationAndClip = function (clipRect, translationX, translationY, angle) {
if (angle === void 0) { angle = 0; }
this.resetTransform();
this.translate(translationX, translationY);
if (angle !== 0)
this.rotate(angle);
this.setClipRect(clipRect);
};
WebGlRenderContext2D.prototype.resetAndClip = function (clipRect) {
this.resetTransform();
this.setClipRect(clipRect);
};
WebGlRenderContext2D.prototype.rotate = function (rotationAngle) {
var nativeContext = this.getNativeContext();
nativeContext.Rotate(rotationAngle);
};
WebGlRenderContext2D.prototype.translate = function (translationX, translationY) {
var nativeContext = this.getNativeContext();
nativeContext.Translate(translationX, translationY);
};
WebGlRenderContext2D.prototype.resetTransform = function () {
var nativeContext = this.getNativeContext();
nativeContext.ResetTransform();
};
/**
* Should store references to all cached WebGlResources {@link ICacheable}
* Is used to invalidate the resources when the WebGL context is lost.
*/
WebGlRenderContext2D.webGlResourcesRefs = new Set();
return WebGlRenderContext2D;
}(DeletableEntity_1.DeletableEntity));
exports.WebGlRenderContext2D = WebGlRenderContext2D;