UNPKG

@syncfusion/ej2-documenteditor

Version:

Feature-rich document editor control with built-in support for context menu, options pane and dialogs.

894 lines 150 kB
import { isNullOrUndefined, L10n } from '@syncfusion/ej2-base'; import { Rect, ImageElementBox, LineWidget, ParagraphWidget, BodyWidget, TextElementBox, HeaderFooterWidget, ListTextElementBox, TableRowWidget, TableWidget, TableCellWidget, FieldElementBox, TabElementBox, BlockWidget, CommentCharacterElementBox, ShapeElementBox, EditRangeStartElementBox, ShapeBase, TextFrame, BookmarkElementBox, EditRangeEndElementBox } from './page'; import { Layout } from './layout'; import { PageLayoutViewer, WebLayoutViewer } from './viewer'; import { HelperMethods, Point } from '../editor/editor-helper'; import { CharacterRangeType } from '../../index'; import { FontScriptType } from '../../index'; import { DocumentCanvasElement } from './document-canvas'; import { Dictionary } from '../../base/dictionary'; /** * @private */ var Renderer = /** @class */ (function () { function Renderer(documentHelper) { /** * @private */ this.commentMarkDictionary = new Dictionary(); this.isPrinting = false; this.isExporting = false; this.pageLeft = 0; this.pageTop = 0; this.pageIndex = -1; this.isFieldCode = false; this.leftPosition = 0; this.topPosition = 0; this.height = 0; this.documentHelper = documentHelper; } Object.defineProperty(Renderer.prototype, "pageCanvas", { get: function () { if (this.isPrinting) { if (isNullOrUndefined(this.pageCanvasIn)) { this.pageCanvasIn = document.createElement('canvas'); this.pageCanvasIn.getContext('2d').save(); } return this.pageCanvasIn; } if (this.isExporting) { if (isNullOrUndefined(this.exportPageCanvas)) { this.exportPageCanvas = new DocumentCanvasElement(); } return this.exportPageCanvas; } else { return isNullOrUndefined(this.viewer) ? undefined : this.documentHelper.containerCanvas; } }, enumerable: true, configurable: true }); Object.defineProperty(Renderer.prototype, "spellChecker", { get: function () { return this.documentHelper.owner.spellChecker; }, enumerable: true, configurable: true }); Object.defineProperty(Renderer.prototype, "selectionCanvas", { get: function () { return isNullOrUndefined(this.viewer) ? undefined : this.documentHelper.selectionCanvas; }, enumerable: true, configurable: true }); Object.defineProperty(Renderer.prototype, "pageContext", { get: function () { return this.pageCanvas.getContext('2d'); }, enumerable: true, configurable: true }); Object.defineProperty(Renderer.prototype, "selectionContext", { get: function () { return this.selectionCanvas.getContext('2d'); }, enumerable: true, configurable: true }); Object.defineProperty(Renderer.prototype, "viewer", { get: function () { return this.documentHelper.owner.viewer; }, enumerable: true, configurable: true }); Renderer.prototype.renderWidgets = function (page, left, top, width, height) { if (isNullOrUndefined(this.pageCanvas) || isNullOrUndefined(page)) { return; } this.pageContext.fillStyle = HelperMethods.getColor(this.documentHelper.backgroundColor); this.pageContext.beginPath(); if (this.viewer instanceof WebLayoutViewer) { height = height > this.documentHelper.visibleBounds.height ? height : this.documentHelper.visibleBounds.height; var marginTop = top; if (page.index === 0) { marginTop = top - this.viewer.padding.top; } /* eslint-disable-next-line max-len */ this.pageContext.fillRect(left - this.viewer.padding.left, marginTop, width + this.viewer.padding.left, height + this.viewer.padding.top); } else { this.pageContext.fillRect(left, top, width, height); } this.pageContext.closePath(); if (this.viewer instanceof PageLayoutViewer) { this.pageContext.strokeStyle = this.documentHelper.owner.pageOutline; this.pageContext.strokeRect(left, top, width, height); } this.pageLeft = left; this.pageTop = top; this.pageIndex = page.index; if (this.isPrinting) { this.setPageSize(page); } else { this.pageContext.beginPath(); this.pageContext.save(); this.pageContext.rect(left, top, width, height); this.pageContext.clip(); } this.height = height; if (page.headerWidget) { this.renderHFWidgets(page, page.headerWidgetIn, width, true); } if (page.footerWidget) { this.renderHFWidgets(page, page.footerWidgetIn, width, false); } for (var i = 0; i < page.bodyWidgets.length; i++) { this.render(page, page.bodyWidgets[parseInt(i.toString(), 10)]); if (page.footnoteWidget && this.documentHelper.owner.layoutType === 'Pages') { this.renderfootNoteWidget(page, page.footnoteWidget, width); } } if (page.endnoteWidget && this.documentHelper.owner.layoutType === 'Pages') { this.renderfootNoteWidget(page, page.endnoteWidget, width); } if (this.documentHelper.owner.enableHeaderAndFooter && !this.isPrinting) { this.renderHeaderSeparator(page, this.pageLeft, this.pageTop, page.headerWidgetIn); } this.pageLeft = 0; this.pageTop = 0; this.pageContext.restore(); }; Renderer.prototype.setPageSize = function (page) { this.pageContext.clearRect(0, 0, this.pageCanvas.width, this.pageCanvas.height); this.selectionContext.clearRect(0, 0, this.selectionCanvas.width, this.selectionCanvas.height); this.pageContext.restore(); this.selectionContext.restore(); var width = page.boundingRectangle.width; var height = page.boundingRectangle.height; var dpr = Math.max(window.devicePixelRatio, this.documentHelper.owner.documentEditorSettings.printDevicePixelRatio); if (this.pageCanvas.width !== width * dpr || this.pageCanvas.height !== height * dpr) { this.pageCanvas.height = height * dpr; this.pageCanvas.width = width * dpr; this.pageCanvas.style.height = height + 'px'; this.pageCanvas.style.width = width + 'px'; this.pageContext.globalAlpha = 1; this.pageContext.scale(dpr, dpr); } this.pageContext.fillStyle = '#FFFFFF'; this.pageContext.fillRect(0, 0, this.pageCanvas.width, this.pageCanvas.height); this.pageContext.fillStyle = '#000000'; }; Renderer.prototype.renderHFWidgets = function (page, widget, width, isHeader) { if (this.isFieldCode) { this.isFieldCode = false; } if (!this.isPrinting) { this.pageContext.globalAlpha = this.documentHelper.owner.enableHeaderAndFooter ? 1 : 0.65; } var cliped = false; var height = 0; var pageHt = 0; var headerFooterHeight = page.boundingRectangle.height / 100 * 40; if (isHeader) { var topMargin = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.topMargin); var widgetHeight = Math.max((widget.y + widget.height), topMargin); if (widgetHeight > headerFooterHeight) { cliped = true; this.pageContext.beginPath(); this.pageContext.save(); this.pageContext.rect(this.pageLeft, this.pageTop, width, this.getScaledValue(headerFooterHeight)); this.pageContext.clip(); } } else { var footerDistance = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.footerDistance); var footerHeight = void 0; if (isNullOrUndefined(page.footerWidgetIn.sectionFormat)) { footerHeight = page.boundingRectangle.height - /* eslint-disable-next-line max-len */ Math.max(page.footerWidgetIn.height + footerDistance, HelperMethods.convertPointToPixel(page.footerWidgetIn.sectionFormat.bottomMargin)); } else { footerHeight = page.boundingRectangle.height - /* eslint-disable-next-line max-len */ Math.max(page.footerWidgetIn.height + footerDistance, HelperMethods.convertPointToPixel(page.footerWidgetIn.sectionFormat.bottomMargin)); } height = Math.max(page.boundingRectangle.height - headerFooterHeight, footerHeight); pageHt = page.boundingRectangle.height - footerDistance; } this.renderFloatingItems(page, widget.floatingElements, 'Behind'); for (var i = 0; i < widget.childWidgets.length; i++) { var block = widget.childWidgets[parseInt(i.toString(), 10)]; if (!isHeader) { height += block.height; } // if (isHeader || !isHeader && this.getScaledValue(Math.round(height)) <= this.getScaledValue(Math.round(pageHt))) { this.renderWidget(page, block); // } } this.renderFloatingItems(page, widget.floatingElements, 'InFrontOfText'); if (cliped) { this.pageContext.restore(); } if (!this.isPrinting) { this.pageContext.globalAlpha = this.documentHelper.owner.enableHeaderAndFooter ? 0.50 : 1; } }; Renderer.prototype.renderHeaderSeparator = function (page, left, top, widget) { //Header Widget var topMargin = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.topMargin); var y = this.getScaledValue(Math.max((widget.y + widget.height), Math.abs(topMargin))); var pageWidth = this.getScaledValue(page.boundingRectangle.width); var ctx = this.pageContext; ctx.save(); ctx.globalAlpha = 0.85; var headerFooterHeight = (this.getScaledValue(page.boundingRectangle.height) / 100) * 40; //Maximum header height limit y = Math.min(y, headerFooterHeight); //Dash line Separator this.renderDashLine(ctx, left, top + y, pageWidth, '#000000', false); var type = this.getHeaderFooterType(page, true); var index = this.viewer.getHeaderFooter(widget.headerFooterType); var sectionIndex = page.sectionIndex; var l10n = new L10n('documenteditor', this.documentHelper.owner.defaultLocale); l10n.setLocale(this.documentHelper.owner.locale); if (this.documentHelper.headersFooters.length > 1) { var sectionMarkIndex = sectionIndex + 1; type = type + " -" + l10n.getConstant('Section') + " " + sectionMarkIndex + "-"; } ctx.font = '9pt Arial'; var width = ctx.measureText(type).width; this.renderHeaderFooterMark(ctx, left + 5, top + y, width + 10, 20); this.renderHeaderFooterMarkText(ctx, type, left + 10, y + top + 15); var headerFooterWidget; if (this.documentHelper.headersFooters[parseInt(sectionIndex.toString(), 10)]) { headerFooterWidget = this.documentHelper.headersFooters[parseInt(sectionIndex.toString(), 10)][parseInt(index.toString(), 10)]; } if (sectionIndex != 0 && !headerFooterWidget) { var content = l10n.getConstant('Same as Previous'); var width_1 = ctx.measureText(content).width; var right = this.viewer.containerWidth - width_1 - 75 + left; this.renderHeaderFooterMark(ctx, right, top + y, width_1 + 10, 20); this.renderHeaderFooterMarkText(ctx, content, right + 5, y + top + 15); } if (page.footerWidget) { //Footer Widget var footerDistance = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.footerDistance); var footerHeight = this.getScaledValue(page.boundingRectangle.height) - /* eslint-disable-next-line max-len */ this.getScaledValue(Math.max(page.footerWidgetIn.height + footerDistance, Math.abs(HelperMethods.convertPointToPixel(page.footerWidgetIn.sectionFormat.bottomMargin)))); //Maximum footer height limit footerHeight = Math.max((this.getScaledValue(page.boundingRectangle.height) - headerFooterHeight), footerHeight); this.renderDashLine(ctx, left, top + footerHeight, pageWidth, '#000000', false); var type_1 = this.getHeaderFooterType(page, false); var sectionIndex_1 = page.sectionIndex; if (this.documentHelper.headersFooters.length > 1) { var sectionMarkIndex = sectionIndex_1 + 1; type_1 = type_1 + " -" + l10n.getConstant('Section') + " " + sectionMarkIndex + "-"; } width = ctx.measureText(type_1).width; this.renderHeaderFooterMark(ctx, left + 5, top + footerHeight - 20, width + 10, 20); this.renderHeaderFooterMarkText(ctx, type_1, left + 10, top + footerHeight - 5); var index_1 = this.viewer.getHeaderFooter(page.footerWidget.headerFooterType); var headerFooterWidget_1; if (this.documentHelper.headersFooters[parseInt(sectionIndex_1.toString(), 10)]) { headerFooterWidget_1 = this.documentHelper.headersFooters[parseInt(sectionIndex_1.toString(), 10)][parseInt(index_1.toString(), 10)]; } if (sectionIndex_1 != 0 && !headerFooterWidget_1) { var content = l10n.getConstant('Same as Previous'); var width_2 = ctx.measureText(content).width; var right = this.viewer.containerWidth - width_2 - 75 + left; this.renderHeaderFooterMark(ctx, right, top + footerHeight - 20, width_2 + 10, 20); this.renderHeaderFooterMarkText(ctx, content, right + 5, top + footerHeight - 5); } ctx.restore(); } }; Renderer.prototype.getFooterHeight = function (page) { var footerWidgetHeight = ((page.boundingRectangle.height) / 100) * 40; var footerDistance = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.footerDistance); var actualHeight = page.boundingRectangle.height - Math.max(page.footerWidgetIn.height + footerDistance, HelperMethods.convertPointToPixel(page.footerWidgetIn.sectionFormat.bottomMargin)); return Math.max((page.boundingRectangle.height) - footerWidgetHeight, actualHeight); }; Renderer.prototype.getHeaderFooterType = function (page, isHeader) { var type; var l10n = new L10n('documenteditor', this.documentHelper.owner.defaultLocale); l10n.setLocale(this.documentHelper.owner.locale); type = isHeader ? l10n.getConstant('Header') : l10n.getConstant('Footer'); if (page.bodyWidgets[0].sectionFormat.differentFirstPage && (isNullOrUndefined(page.previousPage) || page.sectionIndex !== page.previousPage.sectionIndex)) { type = isHeader ? l10n.getConstant('First Page Header') : l10n.getConstant('First Page Footer'); } else if (page.bodyWidgets[0].sectionFormat.differentOddAndEvenPages) { if ((this.documentHelper.pages.indexOf(page) + 1) % 2 === 0) { type = isHeader ? l10n.getConstant('Even Page Header') : l10n.getConstant('Even Page Footer'); } else { type = isHeader ? l10n.getConstant('Odd Page Header') : l10n.getConstant('Odd Page Footer'); } } return type; }; /* eslint-disable-next-line max-len */ Renderer.prototype.renderDashLine = function (context, x, y, width, fillStyle, isSmallDash) { context.beginPath(); context.strokeStyle = fillStyle; context.lineWidth = 1; if (isSmallDash) { context.setLineDash([3, 2]); } else { context.setLineDash([6, 4]); } context.moveTo(x, y); context.lineTo(x + width, y); context.stroke(); context.setLineDash([]); context.closePath(); }; Renderer.prototype.renderSolidLine = function (context, x, y, width, fillStyle) { context.beginPath(); context.strokeStyle = fillStyle; context.lineWidth = 0.5; context.moveTo(x, y); context.lineTo(x + width, y); context.stroke(); context.closePath(); }; Renderer.prototype.renderHeaderFooterMark = function (ctx, x, y, w, h) { ctx.beginPath(); ctx.fillStyle = 'lightgray'; ctx.fillRect(x, y, w, h); ctx.strokeStyle = 'black'; ctx.strokeRect(x, y, w, h); ctx.closePath(); }; Renderer.prototype.renderHeaderFooterMarkText = function (ctx, content, x, y) { ctx.beginPath(); ctx.fillStyle = '#000000'; ctx.textBaseline = 'alphabetic'; ctx.fillText(content, x, y); ctx.closePath(); }; Renderer.prototype.render = function (page, bodyWidget) { if (this.isFieldCode) { this.isFieldCode = false; } /* eslint-disable */ for (var i = 0; i < page.bodyWidgets.length; i++) { if (!isNullOrUndefined(page.bodyWidgets[i].floatingElements)) { this.renderFloatingItems(page, page.bodyWidgets[i].floatingElements, 'Behind'); } } /* eslint-enable */ var isClipped = false; if (!(this.viewer instanceof WebLayoutViewer) && bodyWidget.sectionFormat.columns.length > 1) { var colIndex = page.bodyWidgets.indexOf(bodyWidget); var xPos = void 0; var width = void 0; if (bodyWidget.columnIndex === 0) { /* eslint-disable */ xPos = page.bodyWidgets[colIndex].x - HelperMethods.convertPointToPixel(page.bodyWidgets[colIndex].sectionFormat.leftMargin); width = HelperMethods.convertPointToPixel(page.bodyWidgets[colIndex].sectionFormat.leftMargin) + bodyWidget.sectionFormat.columns[bodyWidget.columnIndex].width + (bodyWidget.sectionFormat.columns[bodyWidget.columnIndex].space / 2); /* eslint-enable */ } else if (colIndex === bodyWidget.sectionFormat.columns.length - 1) { /* eslint-disable */ xPos = page.bodyWidgets[colIndex].x - (bodyWidget.sectionFormat.columns[bodyWidget.columnIndex - 1].space / 2); width = HelperMethods.convertPointToPixel(page.bodyWidgets[colIndex].sectionFormat.rightMargin) + bodyWidget.sectionFormat.columns[bodyWidget.columnIndex].width + (bodyWidget.sectionFormat.columns[bodyWidget.columnIndex - 1].space / 2); /* eslint-enable */ } else { /* eslint-disable */ xPos = page.bodyWidgets[colIndex].x - (bodyWidget.sectionFormat.columns[bodyWidget.columnIndex].space / 2); width = bodyWidget.sectionFormat.columns[bodyWidget.columnIndex].width + bodyWidget.sectionFormat.columns[bodyWidget.columnIndex].space; /* eslint-enable */ } /* eslint-disable */ this.clipRect(xPos, page.bodyWidgets[colIndex].y, this.getScaledValue(width), this.getScaledValue(page.boundingRectangle.height)); /* eslint-enable */ isClipped = true; } for (var i = 0; i < bodyWidget.childWidgets.length; i++) { var widget = bodyWidget.childWidgets[parseInt(i.toString(), 10)]; if (i === 0 && bodyWidget.childWidgets[0] instanceof TableWidget && (bodyWidget.childWidgets[0].childWidgets.length > 0) && page.repeatHeaderRowTableWidget) { /* eslint-disable-next-line max-len */ this.renderHeader(page, widget, this.documentHelper.layout.getHeader(bodyWidget.childWidgets[0])); } this.renderWidget(page, widget); } if (isClipped) { this.pageContext.restore(); } /* eslint-disable */ for (var i = 0; i < page.bodyWidgets.length; i++) { if (!isNullOrUndefined(page.bodyWidgets[i].floatingElements)) { this.renderFloatingItems(page, page.bodyWidgets[i].floatingElements, 'InFrontOfText'); } } /* eslint-enable */ for (var i = 0; i < page.bodyWidgets.length; i++) { if (page.bodyWidgets[parseInt(i.toString(), 10)].sectionFormat.lineBetweenColumns === true) { if (page.bodyWidgets[parseInt(i.toString(), 10)].columnIndex !== 0 && page.bodyWidgets.length > 1) { var topMargin = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.topMargin); var linestartY = this.getScaledValue(Math.max((page.headerWidgetIn.y + page.headerWidgetIn.height), topMargin)); var headerFooterHeight = (this.getScaledValue(page.boundingRectangle.height) / 100) * 40; var footerDistance = HelperMethods.convertPointToPixel(page.bodyWidgets[0].sectionFormat.footerDistance); var footerHeight = this.getScaledValue(page.boundingRectangle.height) - /* eslint-disable-next-line max-len */ this.getScaledValue(Math.max(page.footerWidgetIn.height + footerDistance, HelperMethods.convertPointToPixel(page.footerWidgetIn.sectionFormat.bottomMargin))); footerHeight = Math.max((this.getScaledValue(page.boundingRectangle.height) - headerFooterHeight), footerHeight); var inBetweenSpace = (page.bodyWidgets[parseInt(i.toString(), 10)].x - (page.bodyWidgets[parseInt(i.toString(), 10)].previousRenderedWidget.x + page.bodyWidgets[parseInt(i.toString(), 10)].previousRenderedWidget.width)) / 2; var startX = inBetweenSpace + (page.bodyWidgets[parseInt(i.toString(), 10)].previousRenderedWidget.x + page.bodyWidgets[parseInt(i.toString(), 10)].previousRenderedWidget.width); var startY = linestartY / this.documentHelper.zoomFactor; var endX = startX; var endY = void 0; if (page.footnoteWidget) { endY = ((footerHeight - (page.footerWidgetIn.height / 2)) - page.footnoteWidget.height * this.documentHelper.zoomFactor) / this.documentHelper.zoomFactor; } else { endY = (footerHeight - (page.footerWidgetIn.height / 2)) / this.documentHelper.zoomFactor; } var firstBody = this.documentHelper.layout.getBodyWidget(page.bodyWidgets[parseInt(i.toString(), 10)], true); var height = this.documentHelper.layout.getNextWidgetHeight(firstBody); startY = page.bodyWidgets[parseInt(i.toString(), 10)].y; endY = height; var color = '#000000'; this.renderSingleBorder(color, startX, startY, endX, endY, 0.5, "Single"); } } } }; Renderer.prototype.renderFloatingItems = function (page, floatingElements, wrappingType) { if (!isNullOrUndefined(floatingElements) && floatingElements.length > 0) { var overLappedShapeWidgets = new Dictionary(); /* eslint-disable */ floatingElements.sort(function (a, b) { if (a instanceof TableWidget || b instanceof TableWidget) { return 0; } else { return a.zOrderPosition - b.zOrderPosition; } }); for (var i = 0; i < floatingElements.length; i++) { if (floatingElements[i] instanceof TableWidget) { continue; } var shape = floatingElements[i]; if ((wrappingType === "Behind" && shape.textWrappingStyle !== "Behind") || (wrappingType !== "Behind" && shape.textWrappingStyle === "Behind")) { continue; } if (!this.isOverLappedShapeWidget(shape) || (!isNullOrUndefined(floatingElements[i + 1]) && shape.paragraph !== floatingElements[i + 1].paragraph)) { if (shape instanceof ImageElementBox) { this.renderImageElementBox(shape, shape.x, shape.y, 0); } else if (shape instanceof ShapeElementBox) { var shapeLeft = this.getScaledValue(shape.x, 1); var shapeTop = this.getScaledValue(shape.y, 2); this.renderShapeElementBox(shape, shapeLeft, shapeTop, page); } } else if (!overLappedShapeWidgets.containsKey(shape.zOrderPosition)) { overLappedShapeWidgets.add(shape.zOrderPosition, shape); } } if (overLappedShapeWidgets.length > 0) { var sortedOverLappedShapeWidgets = overLappedShapeWidgets.keys.sort(); for (var j = 0; j < sortedOverLappedShapeWidgets.length; j++) { var shape = overLappedShapeWidgets.get(sortedOverLappedShapeWidgets[j]); if (shape instanceof ImageElementBox) { this.renderImageElementBox(shape, shape.x, shape.y, 0); } else if (shape instanceof ShapeElementBox) { var shapeLeft = this.getScaledValue(shape.x, 1); var shapeTop = this.getScaledValue(shape.y, 2); this.renderShapeElementBox(shape, shapeLeft, shapeTop, page); } } } } }; Renderer.prototype.isOverLappedShapeWidget = function (floatingElement) { return ((floatingElement instanceof ImageElementBox && floatingElement.textWrappingStyle !== 'Inline' && floatingElement.textWrappingStyle !== 'Behind' && !(this.documentHelper.compatibilityMode !== 'Word2013' && (floatingElement.isBelowText && floatingElement.textWrappingStyle !== 'InFrontOfText'))) || (floatingElement instanceof ShapeElementBox && floatingElement.textWrappingStyle !== 'Inline' && floatingElement.textWrappingStyle !== 'Behind' && !(this.documentHelper.compatibilityMode !== 'Word2013' && (floatingElement.isBelowText && floatingElement.textWrappingStyle !== 'InFrontOfText')))); }; Renderer.prototype.renderShapeElementBox = function (shape, shapeLeft, shapeTop, page) { var isZeroShapeHeight = (shape.height === 0) ? true : false; var shapeType = shape.autoShapeType; var blocks = shape.textFrame.childWidgets; this.pageContext.beginPath(); if (shape.fillFormat && shape.fillFormat.color && shape.fillFormat.fill && shapeType !== 'StraightConnector') { this.pageContext.fillStyle = shape.fillFormat.color; this.pageContext.fillRect(shapeLeft, shapeTop, this.getScaledValue(shape.width), this.getScaledValue(shape.height)); } if (!isNullOrUndefined(shapeType)) { if (shape.lineFormat.line && shape.lineFormat.lineFormatType !== 'None') { this.pageContext.lineWidth = shape.lineFormat.weight; this.pageContext.strokeStyle = HelperMethods.getColor(shape.lineFormat.color); if (shapeType !== 'StraightConnector') { this.pageContext.strokeRect(shapeLeft, shapeTop, this.getScaledValue(shape.width), this.getScaledValue(shape.height)); } else { this.pageContext.moveTo(shapeLeft, shapeTop); this.pageContext.lineTo(shapeLeft + this.getScaledValue(shape.width), shapeTop + this.getScaledValue(shape.height)); this.pageContext.stroke(); } } } this.pageContext.closePath(); var isClipped = false; if (shape.width != 0 && shape.height != 0) { isClipped = true; this.clipRect(shape.x, shape.y, this.getScaledValue(shape.width), this.getScaledValue(shape.height)); } for (var i = 0; i < blocks.length; i++) { this.renderWidget(page, blocks[i]); if (isZeroShapeHeight && shapeType !== 'StraightConnector') { shape.height = HelperMethods.round((shape.height + blocks[i].height), 5); } } if (isZeroShapeHeight) { isZeroShapeHeight = false; } if (isClipped) { this.pageContext.restore(); } }; Renderer.prototype.renderWidget = function (page, widget) { if (this.documentHelper.owner.enableLockAndEdit) { this.renderLockRegionBorder(page, widget); } if (widget instanceof ParagraphWidget) { this.renderParagraphWidget(page, widget); } else { this.renderTableWidget(page, widget); } }; Renderer.prototype.renderLockRegionBorder = function (page, widget) { if (!widget.isInsideTable && widget instanceof BlockWidget && widget.locked) { var settinsModel = this.documentHelper.owner.documentEditorSettings.collaborativeEditingSettings; var sectionFormat = page.bodyWidgets[0].sectionFormat; var leftPosition = HelperMethods.convertPointToPixel(sectionFormat.leftMargin) - 5; var pageWidth = sectionFormat.pageWidth - sectionFormat.leftMargin - sectionFormat.rightMargin; pageWidth = HelperMethods.convertPointToPixel(pageWidth) + 10; if (this.viewer instanceof WebLayoutViewer) { leftPosition = widget.x - 5; pageWidth = (this.documentHelper.visibleBounds.width - (this.viewer.padding.right * 5)) / this.documentHelper.zoomFactor; } var previousWidget = widget.previousRenderedWidget; var nextWidget = widget.nextRenderedWidget; var color = widget.lockedBy === this.documentHelper.owner.currentUser ? settinsModel.editableRegionColor : settinsModel.lockedRegionColor; var topPosition = widget.y; var height = widget.y + widget.height; //Left border this.renderSingleBorder(color, leftPosition, topPosition, leftPosition, height, 1, "Single"); //Top border if (isNullOrUndefined(previousWidget) || !previousWidget.locked || widget.lockedBy !== previousWidget.lockedBy) { this.renderSingleBorder(color, leftPosition, topPosition, leftPosition + pageWidth, topPosition, 1, "Single"); } //Right border this.renderSingleBorder(color, leftPosition + pageWidth, topPosition, leftPosition + pageWidth, height, 1, "Single"); if (isNullOrUndefined(nextWidget) || !nextWidget.locked || widget.lockedBy !== nextWidget.lockedBy) { // Bottom border this.renderSingleBorder(color, leftPosition, height, leftPosition + pageWidth, height, 1, "Single"); } } }; Renderer.prototype.renderHeader = function (page, widget, header) { if (isNullOrUndefined(header)) { return; } //Updated client area for current page page.viewer.updateClientArea(page.bodyWidgets[0], page); var top = page.viewer.clientArea.y; var parentTable = header.ownerTable.getSplitWidgets()[0]; for (var i = 0; i <= header.rowIndex; i++) { if (parentTable.childWidgets.length === 0) { return; } var row = parentTable.childWidgets[i]; if (widget.childWidgets.indexOf(row) !== -1) { continue; } var headerWidget = row.clone(); headerWidget.containerWidget = row.containerWidget; page.viewer.updateClientAreaLocation(headerWidget, new Rect(page.viewer.clientArea.x, top, headerWidget.width, headerWidget.height)); page.documentHelper.layout.updateChildLocationForRow(top, headerWidget); var cell = undefined; //Renders table cell outline rectangle - Border and background color. for (var j = 0; j < headerWidget.childWidgets.length; j++) { cell = headerWidget.childWidgets[j]; this.renderTableCellWidget(page, cell); } top += headerWidget.height; } if (widget.y !== top) { //this.Location.Y = top; page.documentHelper.layout.updateChildLocationForTable(top, widget); } }; Renderer.prototype.renderParagraphWidget = function (page, paraWidget) { var top = paraWidget.y; var left = paraWidget.x; var isClipped = false; var firstLine = paraWidget.firstChild; var paddingLeft = 0; if (!isNullOrUndefined(firstLine)) { for (var i = 0; i < firstLine.children.length; i++) { var element = firstLine.children[i]; if (element instanceof TextElementBox) { paddingLeft = element.padding.left; break; } } } if (paddingLeft > 0) { this.clipRect(paraWidget.x + paddingLeft, this.getScaledValue(page.boundingRectangle.y), this.getScaledValue(page.boundingRectangle.width), this.getScaledValue(page.boundingRectangle.height)); isClipped = true; } if (!(paraWidget.containerWidget instanceof HeaderFooterWidget && paraWidget.containerWidget.isEmpty && !isNullOrUndefined(this.documentHelper.selection) && !isNullOrUndefined(this.documentHelper.selection.start.paragraph) && !this.documentHelper.selection.start.paragraph.isInHeaderFooter)) { this.renderParagraphBorder(page, paraWidget); } if (isClipped) { this.pageContext.restore(); } for (var i = 0; i < paraWidget.childWidgets.length; i++) { var widget = paraWidget.childWidgets[i]; top += widget.marginTop; this.renderLine(widget, page, left, top); top += widget.height; } }; Renderer.prototype.renderParagraphBorder = function (page, paragraphWidet) { var leftBorder = paragraphWidet.paragraphFormat.borders.left; var topBorder = paragraphWidet.paragraphFormat.borders.top; var rightBorder = paragraphWidet.paragraphFormat.borders.right; var bottomBorder = paragraphWidet.paragraphFormat.borders.bottom; var startX = 0; var startY = 0; var endX = 0; var endY = 0; var lineWidth = 0; var firstLine = paragraphWidet.firstChild; var lastLine = paragraphWidet.lastChild; var canRenderParagraphBorders = this.documentHelper.canRenderBorder(paragraphWidet); if (!isNullOrUndefined(leftBorder) && leftBorder.lineStyle !== 'None') { startX = this.documentHelper.getParagraphLeftPosition(paragraphWidet) - HelperMethods.convertPointToPixel(leftBorder.space); endX = startX; endY = startY + paragraphWidet.height; if (topBorder.lineStyle !== 'None' && firstLine.isFirstLine() && !canRenderParagraphBorders.skipTopBorder) { startY = paragraphWidet.y + this.getTopMargin(paragraphWidet) - (HelperMethods.convertPointToPixel(topBorder.lineWidth + topBorder.space)); endY = startY + paragraphWidet.height - (this.getTopMargin(paragraphWidet) - (HelperMethods.convertPointToPixel(topBorder.lineWidth + topBorder.space))); } else { startY = paragraphWidet.y; endY = startY + paragraphWidet.height; } if (bottomBorder.lineStyle !== 'None' && lastLine.isLastLine() && !canRenderParagraphBorders.skipBottomBorder) { endY = (endY + HelperMethods.convertPointToPixel(bottomBorder.lineWidth + bottomBorder.space)) - this.getBottomMargin(paragraphWidet); } lineWidth = HelperMethods.convertPointToPixel(leftBorder.lineWidth); this.renderSingleBorder(leftBorder.color, startX, startY, endX, endY, lineWidth, leftBorder.lineStyle); } if (!isNullOrUndefined(topBorder) && topBorder.lineStyle !== 'None' && firstLine.isFirstLine() && !canRenderParagraphBorders.skipTopBorder) { startX = this.documentHelper.getParagraphLeftPosition(paragraphWidet); endX = startX + this.getContainerWidth(paragraphWidet, page); startY = paragraphWidet.y + this.getTopMargin(paragraphWidet) - (HelperMethods.convertPointToPixel(topBorder.lineWidth + topBorder.space)); endY = startY; if (leftBorder.lineStyle !== 'None') { startX -= HelperMethods.convertPointToPixel(leftBorder.space); } if (rightBorder.lineStyle !== 'None') { endX += HelperMethods.convertPointToPixel(rightBorder.space); } lineWidth = HelperMethods.convertPointToPixel(topBorder.lineWidth); this.renderSingleBorder(topBorder.color, startX, startY, endX, endY, lineWidth, topBorder.lineStyle); } if (!isNullOrUndefined(rightBorder) && rightBorder.lineStyle !== 'None') { startX = this.documentHelper.getParagraphLeftPosition(paragraphWidet) + this.getContainerWidth(paragraphWidet, page) + HelperMethods.convertPointToPixel(rightBorder.space); startY = endY; endX = startX; endY = startY + paragraphWidet.height; if (topBorder.lineStyle !== 'None' && firstLine.isFirstLine() && !canRenderParagraphBorders.skipTopBorder) { startY = paragraphWidet.y + this.getTopMargin(paragraphWidet) - (HelperMethods.convertPointToPixel(topBorder.lineWidth + topBorder.space)); endY = startY + paragraphWidet.height - (this.getTopMargin(paragraphWidet) - (HelperMethods.convertPointToPixel(topBorder.lineWidth + topBorder.space))); } else { startY = paragraphWidet.y; endY = startY + paragraphWidet.height; } if (bottomBorder.lineStyle !== 'None' && lastLine.isLastLine() && !canRenderParagraphBorders.skipBottomBorder) { endY = (endY + HelperMethods.convertPointToPixel(bottomBorder.lineWidth + bottomBorder.space)) - this.getBottomMargin(paragraphWidet); } lineWidth = HelperMethods.convertPointToPixel(rightBorder.lineWidth); this.renderSingleBorder(rightBorder.color, startX, startY, endX, endY, lineWidth, rightBorder.lineStyle); } if (!isNullOrUndefined(bottomBorder) && bottomBorder.lineStyle !== 'None' && lastLine.isLastLine() && !canRenderParagraphBorders.skipBottomBorder) { startX = this.documentHelper.getParagraphLeftPosition(paragraphWidet); endX = startX + this.getContainerWidth(paragraphWidet, page); startY = (paragraphWidet.y + paragraphWidet.height + HelperMethods.convertPointToPixel(bottomBorder.lineWidth + bottomBorder.space)) - (this.getBottomMargin(paragraphWidet)); endY = startY; if (leftBorder.lineStyle !== 'None') { startX -= HelperMethods.convertPointToPixel(leftBorder.space); } if (rightBorder.lineStyle !== 'None') { endX += HelperMethods.convertPointToPixel(rightBorder.space); } lineWidth = HelperMethods.convertPointToPixel(bottomBorder.lineWidth); this.renderSingleBorder(bottomBorder.color, startX, startY, endX, endY, lineWidth, bottomBorder.lineStyle); } }; Renderer.prototype.getContainerWidth = function (paraWidget, page) { var hangingIndent = 0; if (paraWidget.paragraphFormat.firstLineIndent < 0) { hangingIndent = Math.abs(paraWidget.paragraphFormat.firstLineIndent); } if (paraWidget.isInsideTable) { var cell = paraWidget.associatedCell; return (cell.width + cell.margin.left + cell.margin.right) - cell.leftBorderWidth; } else { if (this.viewer instanceof WebLayoutViewer) { var indent = HelperMethods.convertPointToPixel(paraWidget.leftIndent + paraWidget.rightIndent); return (this.documentHelper.visibleBounds.width - (indent) - (this.viewer.padding.right * 4) - (this.viewer.padding.left * 2)) / this.documentHelper.zoomFactor; } else { var section = paraWidget.bodyWidget; if (section instanceof BodyWidget && section.sectionFormat.columns.length > 1) { var colIndex = section.columnIndex; return section.sectionFormat.columns[colIndex].width + HelperMethods.convertPointToPixel(hangingIndent - (paraWidget.rightIndent + paraWidget.leftIndent)); } else { var width = section.sectionFormat.pageWidth - section.sectionFormat.leftMargin - section.sectionFormat.rightMargin; return HelperMethods.convertPointToPixel(width + hangingIndent - (paraWidget.rightIndent + paraWidget.leftIndent)); } } } }; Renderer.prototype.getTopMargin = function (paragraph) { if (paragraph.isEmpty()) { return paragraph.childWidgets[0].margin.top; } else { var widget = paragraph.childWidgets[0]; var topMargin = 0; if (!isNullOrUndefined(widget.margin)) { topMargin = widget.margin.top; } return topMargin; } }; Renderer.prototype.getBottomMargin = function (paragarph) { if (paragarph.isEmpty()) { return paragarph.childWidgets[paragarph.childWidgets.length - 1].margin.bottom; } else { var widget = paragarph.childWidgets[paragarph.childWidgets.length - 1]; var bottomMargin = 0; if (!isNullOrUndefined(widget.margin)) { bottomMargin = widget.margin.bottom; } return bottomMargin; } }; Renderer.prototype.renderfootNoteWidget = function (page, footnote, width) { var isEmptyPage = footnote.page.bodyWidgets.length === 1 && ((footnote.page.bodyWidgets[0].childWidgets.length === 1 && footnote.page.bodyWidgets[0].childWidgets[0].isEmpty != undefined && footnote.page.bodyWidgets[0].childWidgets[0].isEmpty()) || footnote.page.bodyWidgets[0].childWidgets.length === 0); var footerY = this.getFooterHeight(page); var height = footnote.y + footnote.height; if (height > footerY) { height = (footerY - footnote.y); } this.pageContext.beginPath(); this.pageContext.save(); this.pageContext.rect(this.pageLeft, this.getScaledValue(footnote.y, 2), this.getScaledValue(width), this.getScaledValue(height)); this.pageContext.clip(); for (var i = 0; i < footnote.bodyWidgets.length; i++) { var bodyWidget = footnote.bodyWidgets[i]; var footNoteReference = bodyWidget.footNoteReference; for (var j = 0; j < bodyWidget.childWidgets.length; j++) { var widget = bodyWidget.childWidgets[j]; if (i === 0 && j === 0) { var ctx = this.pageContext; var xPos = page.bodyWidgets[0].x; if (page.bodyWidgets.length > 1 && !isNullOrUndefined(bodyWidget.nextWidget) && !(bodyWidget.nextWidget.sectionFormat.breakCode === 'NoBreak')) { var footWidth = page.bodyWidgets[0].width; this.renderSolidLine(ctx, this.getScaledValue(xPos, 1), this.getScaledValue(footnote.y + (footnote.margin.top / 2) + 1, 2), footWidth * this.documentHelper.zoomFactor, '#000000'); } else { this.renderSolidLine(ctx, this.getScaledValue(xPos, 1), this.getScaledValue(footnote.y + (footnote.margin.top / 2) + 1, 2), 210 * this.documentHelper.zoomFactor, '#000000'); } } if (j === 0 && !isNullOrUndefined(footNoteReference) && widget.childWidgets[0].children[0] instanceof TextElementBox && !this.documentHelper.owner.editor.isFootNoteInsert) { //if (j < 1 || (j > 0 && widget.footNoteReference !== (bodyWidget.childWidgets[j - 1] as BlockWidget).footNoteReference)) { var footNoteElement = widget.childWidgets[0].children[0]; footNoteElement.text = footNoteElement.text.replace(footNoteElement.text, footNoteReference.text); footNoteElement.width = footNoteReference.width; //} } this.renderWidget(page, widget); } } this.pageContext.restore(); }; Renderer.prototype.renderTableWidget = function (page, tableWidget) { if (this.isFieldCode) { return; } for (var i = 0; i < tableWidget.childWidgets.length; i++) { var widget = tableWidget.childWidgets[i]; this.renderTableRowWidget(page, widget); if (tableWidget.tableFormat.cellSpacing > 0) { this.renderTableOutline(tableWidget); } if (widget.isRenderBookmarkEnd && this.documentHelper.owner.documentEditorSettings.showBookmarks) { var cellWidget = widget.lastChild; var border = cellWidget.ownerTable.isBidiTable ? TableCellWidget.getCellLeftBorder(cellWidget) : TableCellWidget.getCellRightBorder(cellWidget); var lineWidth = HelperMethods.convertPointToPixel(border.getLineWidth()); var lastPara = this.documentHelper.selection.getLastParagraph(widget.lastChild); var height = lastPara.lastChild.height - lastPara.lastChild.margin.bottom; this.renderBookmark(this.getScaledValue((cellWidget.x + cellWidget.width + cellWidget.margin.right - lineWidth / 2) + this.documentHelper.textHelper.getParagraphMarkWidth(lastPara.characterFormat), 1), this.getScaledValue(cellWidget.y - cellWidget.margin.top, 2), this.getScaledValue(height), 1); } } }; Renderer.prototype.renderTableRowWidget = function (page, rowWidget) { for (var i = 0; i < rowWidget.childWidgets.length; i++) { var widget = rowWidget.childWidgets[i]; this.renderTableCellWidget(page, widget); if (widget.isRenderBookmarkEnd && this.documentHelper.owner.documentEditorSettings.showBookmarks) { var lastPara = this.documentHelper.selection.getLastParagraph(widget); var lastLine = lastPara.lastChild; var position = this.documentHelper.selection.getEndPosition(lastPara); if (this.documentHelper.owner.documentEditorSettings.showHiddenMarks && !this.isPrinting) { var xLeft = this.documentHelper.textHelper.getWidth(String.fromCharCode(164), lastLine.paragraph.characterFormat) + position.x; this.renderBookmark(this.getScaledValue(xLeft, 1), this.getScaledValue(position.y, 2), this.getScaledValue(lastLine.height - lastLine.margin.bottom), 1); } else { this.renderBookmark(this.getScaledValue(position.x, 1), this.getScaledValue(position.y, 2), this.getScaledValue(lastLine.height - lastLine.margin.bottom), 1); } } } }; Renderer.prototype.renderTableCellWidget = function (page, cellWidget) { if (!this.isPrinting) { var cellTopMargin = 0; var cellBottomMargin = 0; cellTopMargin = cellWidget.margin.top - cellWidget.containerWidget.topBorderWidth; cellBottomMargin = cellWidget.margin.bottom - cellWidget.containerWidget.bottomBorderWidth; if (this.getScaledValue(cellWidget.y, 2) + cellWidget.height + cellBottomMargin * this.documentHelper.zoomFactor < 0 || (this.getScaledValue(cellWidget.y, 2) - cellTopMargin > this.documentHelper.visibleBounds.height)) { return; } } var widgetHeight = 0; this.renderSelectionHighlightOnTable(page, cellWidget); this.renderTableCellOutline(page.documentHelper, cellWidget); for (var i = 0; i < cellWidget.childWidgets.length; i++) { var widget = cellWidget.childWidgets[i]; // MS word render the content in right margin also. // So, we need to add right margin value while cliping the content var width = (cellWidget.width + cellWidget.margin.left + cellWidget.margin.right) - cellWidget.leftBorderWidth; if (!this.isPrinting) { this.clipRect(cellWidget.x - cellWidget.margin.left, cellWidget.y, this.getScaledValue(width), this.getScaledValue(this.height)); } this.renderWidget(pa