UNPKG

@syncfusion/ej2-pdfviewer

Version:
892 lines 61.2 kB
import { AnnotationStatus } from '../index'; import { splitArrayCollection, processPathData, getPathString, PathElement } from './../ej2-drawings/index'; import { Browser, isNullOrUndefined } from '@syncfusion/ej2-base'; import { cloneObject } from '../drawing/drawing-util'; var InkAnnotation = /** @class */ (function () { function InkAnnotation(pdfViewer, pdfViewerBase) { this.newObject = []; /** * @private */ this.outputString = ''; /** * @private */ this.inkAnnotationindex = []; /** * @private */ this.isAddAnnotationProgramatically = false; /** * @private */ this.currentPageNumber = ''; /** * @private */ this.inkAnnotationInitialZoom = 1; /** * @private */ this.inkPathDataCollection = []; /** * @private */ this.eraserPath = []; /** * @private */ this.eraserPreviewPageIndex = -1; this.pdfViewer = pdfViewer; this.pdfViewerBase = pdfViewerBase; } /** * @private * @returns {void} */ InkAnnotation.prototype.drawInk = function () { this.pdfViewerBase.disableTextSelectionMode(); this.pdfViewer.tool = 'Ink'; }; InkAnnotation.prototype.drawInkAnnotation = function (pageNumber) { if (this.pdfViewerBase.isToolbarInkClicked) { this.pdfViewerBase.isInkAdded = true; this.pdfViewer.annotationModule.isFormFieldShape = false; var pageIndex = !isNaN(pageNumber) ? pageNumber : this.pdfViewerBase.currentPageNumber - 1; if ((this.outputString && this.outputString !== '') || this.inkPathDataCollection.length > 0) { var currentAnnot = this.addInk(pageIndex); this.pdfViewer.renderDrawing(undefined, pageIndex); this.pdfViewer.clearSelection(pageIndex); this.pdfViewer.select([currentAnnot.id], currentAnnot.annotationSelectorSettings); if (this.pdfViewer.toolbar && this.pdfViewer.toolbar.annotationToolbarModule) { this.pdfViewer.toolbar.annotationToolbarModule.enableSignaturePropertiesTools(true); } if (Browser.isDevice && !this.pdfViewer.enableDesktopMode && this.pdfViewer.enableToolbar && this.pdfViewer.enableAnnotationToolbar) { this.pdfViewer.toolbarModule.annotationToolbarModule.createPropertyTools('Ink'); } } else { this.outputString = ''; this.newObject = []; this.pdfViewerBase.isToolbarInkClicked = false; this.pdfViewer.tool = ''; this.inkPathDataCollection = []; } this.pdfViewerBase.isInkAdded = false; } }; /** * @private * @returns {any} - any */ InkAnnotation.prototype.updateInkDataWithZoom = function () { var updatedPathData = ''; if (this.outputString !== '') { this.inkPathDataCollection.push({ pathData: this.outputString, zoomFactor: this.inkAnnotationInitialZoom }); } if (this.inkPathDataCollection.length > 0) { //for loop to get the path data from the collection with path zoom factor for (var i = 0; i < this.inkPathDataCollection.length; i++) { updatedPathData += this.updatePathDataWithZoom(this.inkPathDataCollection[parseInt(i.toString(), 10)].pathData, this.inkPathDataCollection[parseInt(i.toString(), 10)].zoomFactor); } } else { updatedPathData += this.updatePathDataWithZoom(this.outputString, this.inkAnnotationInitialZoom); } return updatedPathData; }; InkAnnotation.prototype.updatePathDataWithZoom = function (pathData, pathZoomFactor) { var pathString = ''; var zoom = this.pdfViewerBase.getZoomFactor(); var collectionData = processPathData(pathData); var csData = splitArrayCollection(collectionData); for (var j = 0; j < csData.length; j++) { var pathValue = csData[parseInt(j.toString(), 10)]; pathString += pathValue.command + pathValue.x * (zoom / pathZoomFactor) + ',' + pathValue.y * (zoom / pathZoomFactor) + ' '; } return pathString; }; /** * @private * @returns {void} */ InkAnnotation.prototype.storePathData = function () { this.convertToPath(this.newObject); this.newObject = []; }; /** * @param {any} position - It describes about the position of the annotation * @param {number} pageIndex - It describes about the page index value * @private * @returns {void} */ InkAnnotation.prototype.drawInkInCanvas = function (position, pageIndex) { if (this.currentPageNumber !== '' && parseInt(this.currentPageNumber, 10) !== pageIndex) { this.drawInkAnnotation(parseInt(this.currentPageNumber, 10)); this.pdfViewerBase.isToolbarInkClicked = true; this.pdfViewer.tool = 'Ink'; } var zoom = this.pdfViewerBase.getZoomFactor(); this.inkAnnotationInitialZoom = zoom; var ratio = this.pdfViewerBase.getWindowDevicePixelRatio(); var canvas = this.pdfViewerBase.getAnnotationCanvas('_annotationCanvas_', pageIndex); var context = canvas.getContext('2d'); var thickness = this.pdfViewer.inkAnnotationSettings.thickness ? this.pdfViewer.inkAnnotationSettings.thickness : 1; var opacity = !isNullOrUndefined(this.pdfViewer.inkAnnotationSettings.opacity) ? this.pdfViewer.inkAnnotationSettings.opacity : 1; var strokeColor = this.pdfViewer.inkAnnotationSettings.strokeColor ? this.pdfViewer.inkAnnotationSettings.strokeColor : '#ff0000'; if (!Browser.isDevice || (Browser.isDevice && zoom <= 0.7)) { context.setTransform(ratio, 0, 0, ratio, 0, 0); } context.beginPath(); context.lineJoin = 'round'; context.lineCap = 'round'; context.moveTo(position.prevPosition.x, position.prevPosition.y); context.lineTo(position.currentPosition.x, position.currentPosition.y); context.lineWidth = thickness * zoom > 1 ? thickness * zoom : thickness; context.strokeStyle = strokeColor; context.globalAlpha = opacity; // After the addition of a TextMarkup annotation, a LineDash value was introduced. To eliminate it, the value was cleared. context.setLineDash([]); context.stroke(); // context.lineWidth = 2; context.arc(position.prevPosition.x, position.prevPosition.y, 2 / 2, 0, Math.PI * 2, true); context.closePath(); this.pdfViewerBase.prevPosition = position.currentPosition; this.newObject.push(position.currentPosition.x, position.currentPosition.y); this.currentPageNumber = pageIndex.toString(); }; /** * @param {any} position - It describes about the position of the annotation * @private * @returns {void} */ InkAnnotation.prototype.addEraserPath = function (position) { this.eraserPath.push({ x: position.currentPosition.x, y: position.currentPosition.y }); }; /** * Draws a temporary preview stroke during eraser movement. * Shows a black semi-transparent line that follows the cursor. * @param {number} pageIndex - The page on which the preview should be drawn * @param {number} eraserSize - The diameter of the eraser * @private * @returns {void} */ InkAnnotation.prototype.drawEraserPreview = function (pageIndex, eraserSize) { var ratio = this.pdfViewerBase.getWindowDevicePixelRatio(); var canvas = this.pdfViewerBase.getAnnotationCanvas('_annotationCanvas_', pageIndex); var context = canvas.getContext('2d'); context.setTransform(ratio, 0, 0, ratio, 0, 0); context.beginPath(); context.lineJoin = 'round'; context.lineCap = 'round'; context.lineWidth = eraserSize; context.strokeStyle = '#D3D3D333'; var pts = this.eraserPath; if (pts.length > 0) { context.moveTo(pts[0].x, pts[0].y); for (var i = 1; i < pts.length; i++) { context.lineTo(pts[i].x, pts[i].y); } } context.setLineDash([]); context.stroke(); context.closePath(); this.eraserPreviewPageIndex = pageIndex; }; InkAnnotation.prototype.convertToPath = function (newObject) { this.movePath(newObject[0], newObject[1]); this.linePath(newObject[0], newObject[1]); for (var n = 2; n < newObject.length; n = n + 2) { this.linePath(newObject[parseInt(n.toString(), 10)], newObject[n + 1]); } }; InkAnnotation.prototype.linePath = function (x, y) { if (!isNullOrUndefined(x) && !isNullOrUndefined(y)) { this.outputString += 'L' + x + ',' + y + ' '; } }; InkAnnotation.prototype.movePath = function (x, y) { if (!isNullOrUndefined(x) && !isNullOrUndefined(y)) { this.outputString += 'M' + x + ',' + y + ' '; } }; /** * @param {number} pageNumber - It describes about the page number * @private * @returns {any} - any */ InkAnnotation.prototype.addInk = function (pageNumber) { this.outputString = this.updateInkDataWithZoom(); var currentBounds = this.calculateInkSize(this.outputString); var annot; if (this.pdfViewerBase.isToolbarInkClicked) { var annotationName = this.pdfViewer.annotation.createGUID(); var modifiedDate = this.pdfViewer.annotation.stickyNotesAnnotationModule.getDateAndTime(); var pageIndex = !isNaN(pageNumber) ? pageNumber : this.pdfViewerBase.currentPageNumber - 1; var thickness = this.pdfViewer.inkAnnotationSettings.thickness ? this.pdfViewer.inkAnnotationSettings.thickness : 1; var opacity = !isNullOrUndefined(this.pdfViewer.inkAnnotationSettings.opacity) ? this.pdfViewer.inkAnnotationSettings.opacity : 1; var strokeColor = this.pdfViewer.inkAnnotationSettings.strokeColor ? this.pdfViewer.inkAnnotationSettings.strokeColor : '#ff0000'; var isLock = this.pdfViewer.inkAnnotationSettings.isLock ? this.pdfViewer.inkAnnotationSettings.isLock : this.pdfViewer.annotationSettings.isLock; var author = (this.pdfViewer.annotationSettings.author !== 'Guest') ? this.pdfViewer.annotationSettings.author : this.pdfViewer.inkAnnotationSettings.author ? this.pdfViewer.inkAnnotationSettings.author : 'Guest'; var subject = (this.pdfViewer.annotationSettings.subject !== '' && !isNullOrUndefined(this.pdfViewer.annotationSettings.subject)) ? this.pdfViewer.annotationSettings.subject : this.pdfViewer.inkAnnotationSettings.subject ? this.pdfViewer.inkAnnotationSettings.subject : 'Ink'; var customData = !isNullOrUndefined(this.pdfViewer.annotationSettings.customData) ? this.pdfViewer.annotationSettings.customData : this.pdfViewer.inkAnnotationSettings.customData ? this.pdfViewer.inkAnnotationSettings.customData : null; var isPrint = this.pdfViewer.inkAnnotationSettings.isPrint; var allowedInteractions = this.pdfViewer.inkAnnotationSettings.allowedInteractions ? this.pdfViewer.inkAnnotationSettings.allowedInteractions : this.pdfViewer.annotationSettings.allowedInteractions; var annotationSettings = this.pdfViewer.annotationSettings ? this.pdfViewer.annotationSettings : this.pdfViewer.annotationModule.updateAnnotationSettings(this.pdfViewer.inkAnnotationSettings); if (isLock) { annotationSettings.isLock = true; } annot = { id: 'ink' + this.pdfViewerBase.inkCount, bounds: { x: currentBounds.x, y: currentBounds.y, width: currentBounds.width, height: currentBounds.height }, pageIndex: pageIndex, data: this.outputString, customData: customData, shapeAnnotationType: 'Ink', opacity: opacity, strokeColor: strokeColor, thickness: thickness, annotName: annotationName, comments: [], author: author, subject: subject, notes: '', review: { state: '', stateModel: '', modifiedDate: modifiedDate, author: author }, annotationSelectorSettings: this.getSelector('Ink', ''), modifiedDate: modifiedDate, annotationSettings: annotationSettings, isPrint: isPrint, allowedInteractions: allowedInteractions, isCommentLock: false, isLocked: isLock }; var annotObject = { id: 'ink' + this.pdfViewerBase.inkCount, bounds: { x: currentBounds.x, y: currentBounds.y, width: currentBounds.width, height: currentBounds.height }, pageIndex: pageIndex, data: this.outputString, customData: customData, shapeAnnotationType: 'Ink', opacity: opacity, strokeColor: strokeColor, thickness: thickness, annotName: annotationName, comments: [], author: author, subject: subject, notes: '', review: { state: '', stateModel: '', modifiedDate: modifiedDate, author: author }, annotationSelectorSettings: this.getSelector('Ink', ''), modifiedDate: modifiedDate, annotationSettings: annotationSettings, isPrint: isPrint, allowedInteractions: allowedInteractions, isCommentLock: false, isLocked: isLock, status: AnnotationStatus.NewlyAdded, initialZoom: this.inkAnnotationInitialZoom }; var annotation = this.pdfViewer.add(annot); var bounds = { left: annot.bounds.x, top: annot.bounds.y, width: annot.bounds.width, height: annot.bounds.height }; var settings = { opacity: annot.opacity, strokeColor: annot.strokeColor, thickness: annot.thickness, modifiedDate: annot.modifiedDate, width: annot.bounds.width, height: annot.bounds.height, data: this.outputString }; this.pdfViewerBase.inkCount++; var commentsDivid = this.pdfViewer.annotation.stickyNotesAnnotationModule.addComments('ink', (annot.pageIndex + 1), annot.shapeAnnotationType); if (commentsDivid) { document.getElementById(commentsDivid).id = annotationName; } annot.annotName = annotationName; this.pdfViewer.annotation.addAction(pageIndex, null, annotation, 'Addition', '', annotation, annotation); this.pdfViewer.annotationModule.storeAnnotations(pageIndex, annotObject, '_annotations_ink'); this.pdfViewer.fireAnnotationAdd(annot.pageIndex, annot.annotName, 'Ink', bounds, settings); if (this.pdfViewerBase.isInkAdded) { this.outputString = ''; this.newObject = []; this.inkPathDataCollection = []; } this.pdfViewerBase.isToolbarInkClicked = false; this.pdfViewer.tool = ''; } return annot; }; /** * @private * @returns {void} */ InkAnnotation.prototype.setAnnotationMode = function () { if (this.pdfViewerBase.isToolbarInkClicked) { this.drawInkAnnotation(); } else { this.pdfViewerBase.isToolbarInkClicked = true; this.drawInk(); } }; InkAnnotation.prototype.saveInkSignature = function () { var storeObject = this.pdfViewer.annotationsCollection.get(this.pdfViewerBase.documentId + '_annotations_ink'); var annotations = []; for (var j = 0; j < this.pdfViewerBase.pageCount; j++) { annotations[parseInt(j.toString(), 10)] = []; } if (storeObject && !this.pdfViewer.annotationSettings.skipDownload) { var annotationCollection = JSON.parse(JSON.stringify(storeObject)); for (var i = 0; i < annotationCollection.length; i++) { var newArray = []; var pageAnnotationObject = annotationCollection[parseInt(i.toString(), 10)]; if (pageAnnotationObject) { for (var z = 0; pageAnnotationObject.annotations.length > z; z++) { if (this.pdfViewer.printModule && this.pdfViewer.printModule.canPrint && pageAnnotationObject.annotations[parseInt(z.toString(), 10)].isPrint === false) { pageAnnotationObject.annotations.splice(parseInt(z.toString(), 10), 1); z--; continue; } this.pdfViewer.annotationModule.updateModifiedDate(pageAnnotationObject.annotations[parseInt(z.toString(), 10)]); var strokeColorString = pageAnnotationObject.annotations[parseInt(z.toString(), 10)].strokeColor; pageAnnotationObject.annotations[parseInt(z.toString(), 10)].strokeColor = JSON.stringify(this.pdfViewerBase.signatureModule.getRgbCode(strokeColorString)); pageAnnotationObject.annotations[parseInt(z.toString(), 10)].bounds = JSON.stringify(this.pdfViewer.annotation. getInkBounds(pageAnnotationObject.annotations[parseInt(z.toString(), 10)].bounds, pageAnnotationObject.pageIndex)); var collectionData = processPathData(pageAnnotationObject.annotations[parseInt(z.toString(), 10)].data); var csData = splitArrayCollection(collectionData); pageAnnotationObject.annotations[parseInt(z.toString(), 10)].data = JSON.stringify(csData); } newArray = pageAnnotationObject.annotations; } annotations[pageAnnotationObject.pageIndex] = newArray; } annotationCollection = null; } return JSON.stringify(annotations); }; /** * @param {number} pageNumber - It describes about the page number value * @param {any} annotationBase - It describes about the annotation base * @private * @returns {void} */ InkAnnotation.prototype.addInCollection = function (pageNumber, annotationBase) { if (annotationBase) { var pageAnnotations = this.getAnnotations(pageNumber, null); if (pageAnnotations) { pageAnnotations.push(annotationBase); } this.manageInkAnnotations(pageAnnotations, pageNumber); } }; /** * @private * @param {string} data - data * @returns {any} - points */ InkAnnotation.prototype.calculateInkSize = function (data) { var minimumX = -1; var minimumY = -1; var maximumX = -1; var maximumY = -1; var collectionData = processPathData(data); var zoomvalue = this.pdfViewerBase.getZoomFactor(); for (var k = 0; k < collectionData.length; k++) { var val = collectionData[parseInt(k.toString(), 10)]; if (minimumX === -1) { minimumX = (val['x']); maximumX = (val['x']); minimumY = (val['y']); maximumY = (val['y']); } else { var point1 = (val['x']); var point2 = (val['y']); if (minimumX >= point1) { minimumX = point1; } if (minimumY >= point2) { minimumY = point2; } if (maximumX <= point1) { maximumX = point1; } if (maximumY <= point2) { maximumY = point2; } } } var newdifferenceX = maximumX - minimumX; var newdifferenceY = maximumY - minimumY; if (newdifferenceX === 0) { newdifferenceX = 1; } else if (newdifferenceY === 0) { newdifferenceY = 1; } return { x: (minimumX / zoomvalue), y: (minimumY / zoomvalue), width: (newdifferenceX / zoomvalue), height: (newdifferenceY / zoomvalue) }; }; /** * @param {any} annotationCollection - It describes about the annotation collection * @param {number} pageIndex - page index value * @param {boolean} isImport - It ensures whether the isImport is true or not * @param {boolean} isAnnotOrderAction - It ensures whether the isAnnotOrderAction is true or not * @param {boolean} isLastAnnot - It ensures whether the isLastAnnot is true or not * @private * @returns {void} */ InkAnnotation.prototype.renderExistingInkSignature = function (annotationCollection, pageIndex, isImport, isAnnotOrderAction, isLastAnnot) { var annot; var isinkAnnotationAdded = false; if (!isImport) { for (var p = 0; p < this.inkAnnotationindex.length; p++) { if (this.inkAnnotationindex[parseInt(p.toString(), 10)] === pageIndex) { isinkAnnotationAdded = true; break; } } } if (annotationCollection && (!isinkAnnotationAdded || isAnnotOrderAction)) { if (annotationCollection.length > 0 && this.inkAnnotationindex.indexOf(pageIndex) === -1) { this.inkAnnotationindex.push(pageIndex); } for (var n = 0; n < annotationCollection.length; n++) { var currentAnnotation = annotationCollection[parseInt(n.toString(), 10)]; if (currentAnnotation) { var data = currentAnnotation.PathData; if (isImport && data) { if (typeof (data) === 'object' && data.length > 1) { data = getPathString(data); } else { if (!(currentAnnotation.IsPathData || (data.split('command').length <= 1))) { data = getPathString(JSON.parse(data)); } } } this.outputString = data; var calculateInkPosition = this.calculateInkSize(this.outputString); this.outputString = ''; var rectDiff = 0; var rectDifference = 1; var bounds = currentAnnotation.Bounds; if (calculateInkPosition) { if (calculateInkPosition.height < 1) { rectDiff = bounds.Height ? bounds.Height : bounds.height; rectDifference = bounds.Height ? bounds.Height : bounds.height; } else if (calculateInkPosition.width < 1) { rectDiff = bounds.Width ? bounds.Width : bounds.width; rectDifference = bounds.Width ? bounds.Width : bounds.width; } } var currentLeft = !isNullOrUndefined(bounds.X) ? bounds.X + (rectDiff / 2) : bounds.x + (rectDiff / 2); var currentTop = !isNullOrUndefined(bounds.Y) ? bounds.Y + (rectDiff / 2) : bounds.y + (rectDiff / 2); var currentWidth = bounds.Width ? bounds.Width - (rectDifference - 1) : bounds.width - (rectDifference - 1); var currentHeight = bounds.Height ? bounds.Height - (rectDifference - 1) : bounds.height - (rectDifference - 1); var isLock = currentAnnotation.AnnotationSettings ? currentAnnotation.AnnotationSettings.isLock : false; var selectorSettings = currentAnnotation.AnnotationSelectorSettings ? typeof (currentAnnotation.AnnotationSelectorSettings) === 'string' ? JSON.parse(currentAnnotation.AnnotationSelectorSettings) : currentAnnotation.AnnotationSelectorSettings : this.getSelector(currentAnnotation, 'Ink'); var customData = this.pdfViewer.annotation.getCustomData(currentAnnotation); var isPrint = true; if (currentAnnotation.AnnotationSettings) { isPrint = currentAnnotation.AnnotationSettings.isPrint; } else { isPrint = this.pdfViewer.inkAnnotationSettings.isPrint; } isPrint = !isNullOrUndefined(currentAnnotation.IsPrint) ? currentAnnotation.IsPrint : true; if (currentAnnotation.IsLocked) { isLock = currentAnnotation.IsLocked; } if (currentAnnotation.Subject === 'Highlight' && currentAnnotation.Opacity === 1) { currentAnnotation.Opacity = currentAnnotation.Opacity / 2; } currentAnnotation.allowedInteractions = currentAnnotation.AllowedInteractions ? currentAnnotation.AllowedInteractions : this.pdfViewer.annotationModule. updateAnnotationAllowedInteractions(currentAnnotation); currentAnnotation.AnnotationSettings = currentAnnotation.AnnotationSettings ? currentAnnotation.AnnotationSettings : this.pdfViewer.annotationModule.updateAnnotationSettings(currentAnnotation); currentAnnotation.State = currentAnnotation.State ? currentAnnotation.State : ''; currentAnnotation.StateModel = currentAnnotation.StateModel ? currentAnnotation.StateModel : ''; var status_1 = void 0; if (isImport) { status_1 = AnnotationStatus.NewlyAdded; } annot = { id: 'ink' + this.pdfViewerBase.inkCount, annotationIndex: currentAnnotation.AnnotationIndex, bounds: { x: currentLeft, y: currentTop, width: currentWidth, height: currentHeight }, pageIndex: pageIndex, data: data, shapeAnnotationType: 'Ink', opacity: currentAnnotation.Opacity, strokeColor: currentAnnotation.StrokeColor, thickness: currentAnnotation.Thickness, annotName: currentAnnotation.AnnotName, comments: this.pdfViewer.annotationModule. getAnnotationComments(currentAnnotation.Comments, currentAnnotation, currentAnnotation.Author), author: currentAnnotation.Author, allowedInteractions: currentAnnotation.allowedInteractions, subject: currentAnnotation.Subject, modifiedDate: currentAnnotation.ModifiedDate, review: { state: currentAnnotation.State, stateModel: currentAnnotation.StateModel, modifiedDate: currentAnnotation.ModifiedDate, author: currentAnnotation.Author }, notes: currentAnnotation.Note, annotationSettings: currentAnnotation.AnnotationSettings, annotationSelectorSettings: selectorSettings, customData: customData, isPrint: isPrint, isCommentLock: currentAnnotation.IsCommentLock, status: !isNullOrUndefined(currentAnnotation.Status) ? currentAnnotation.Status : status_1 }; var annotObject = { id: 'ink' + this.pdfViewerBase.inkCount, annotationIndex: currentAnnotation.AnnotationIndex, bounds: { x: currentLeft, y: currentTop, width: currentWidth, height: currentHeight }, pageIndex: pageIndex, data: data, shapeAnnotationType: 'Ink', opacity: currentAnnotation.Opacity, strokeColor: currentAnnotation.StrokeColor, thickness: currentAnnotation.Thickness, annotName: currentAnnotation.AnnotName, comments: this.pdfViewer.annotationModule. getAnnotationComments(currentAnnotation.Comments, currentAnnotation, currentAnnotation.Author), author: currentAnnotation.Author, allowedInteractions: currentAnnotation.allowedInteractions, subject: currentAnnotation.Subject, modifiedDate: currentAnnotation.ModifiedDate, review: { state: currentAnnotation.State, stateModel: currentAnnotation.StateModel, modifiedDate: currentAnnotation.ModifiedDate, author: currentAnnotation.Author }, notes: currentAnnotation.Note, annotationSettings: currentAnnotation.AnnotationSettings, annotationSelectorSettings: selectorSettings, customData: customData, isPrint: isPrint, isCommentLock: currentAnnotation.IsCommentLock, originalName: currentAnnotation.OriginalName ? currentAnnotation.OriginalName : null, status: !isNullOrUndefined(currentAnnotation.Status) ? currentAnnotation.Status : status_1 }; this.pdfViewer.add(annot); var canvasPageIndex = currentAnnotation.pageIndex ? currentAnnotation.pageIndex : currentAnnotation.PageNumber; var canvass = this.pdfViewerBase.getAnnotationCanvas('_annotationCanvas_', canvasPageIndex); var isNeedToRender = ((isImport && isLastAnnot) || isNullOrUndefined(isImport) || !isImport) ? true : false; if (isNeedToRender) { this.pdfViewer.renderDrawing(canvass, annot.pageIndex); } this.pdfViewer.annotationModule.storeAnnotations(annot.pageIndex, annotObject, '_annotations_ink'); if (this.isAddAnnotationProgramatically) { var settings = { opacity: annot.opacity, strokeColor: annot.strokeColor, thickness: annot.thickness, modifiedDate: annot.modifiedDate, width: annot.bounds.width, height: annot.bounds.height, data: this.outputString }; this.pdfViewer.fireAnnotationAdd(annot.pageIndex, annot.annotName, 'Ink', bounds, settings); } this.pdfViewerBase.currentSignatureAnnot = null; this.pdfViewerBase.signatureCount++; this.pdfViewerBase.inkCount++; if (this.pdfViewerBase.navigationPane && this.pdfViewerBase.navigationPane.annotationMenuObj && this.pdfViewer.isSignatureEditable) { this.pdfViewerBase.navigationPane.annotationMenuObj.enableItems([this.pdfViewer.localeObj.getConstant('Export Annotations')], true); this.pdfViewerBase.navigationPane.annotationMenuObj.enableItems([this.pdfViewer.localeObj.getConstant('Export XFDF')], true); } } } } }; // To save the imported annotations while downloading or exporting for the page above 10 without a scroll (EJ2-63924) /** * @param {any} annotation - This is annotation * @param {number} pageNumber - This is page number * @private * @returns {void} */ InkAnnotation.prototype.saveImportedInkAnnotation = function (annotation, pageNumber) { var annotationObject = null; var currentBounds = annotation.Bounds; var bounds = { x: currentBounds.X, y: currentBounds.Y, width: currentBounds.Width, height: currentBounds.Height }; var allowedInteractions = this.pdfViewer.annotationModule.updateAnnotationAllowedInteractions(annotation); var customData = this.pdfViewer.annotation.getCustomData(annotation); var comments = this.pdfViewer.annotationModule.getAnnotationComments(annotation.Comments, annotation, annotation.Author); var review = { state: annotation.State, stateModel: annotation.StateModel, modifiedDate: annotation.ModifiedDate, author: annotation.Author }; var annotationSettings = annotation.AnnotationSettings ? annotation.AnnotationSettings : this.pdfViewer.annotationModule.updateAnnotationSettings(annotation); var annotationSelectorSettings = this.getSettings(annotation); var data = annotation.PathData; if (typeof (data) === 'object' && data.length > 1) { data = getPathString(data); } else { if (!annotation.IsPathData && data.split('command').length > 1) { data = getPathString(JSON.parse(data)); } } annotationObject = { allowedInteractions: allowedInteractions, annotName: annotation.AnnotName, annotationSelectorSettings: annotationSelectorSettings, annotationSettings: annotationSettings, author: annotation.Author, bounds: bounds, customData: customData, comments: comments, data: data, id: 'Ink', isCommentLock: annotation.IsCommentLock, isLocked: annotation.IsLocked, isPrint: annotation.IsPrint, modifiedDate: annotation.ModifiedDate, note: annotation.Note, opacity: annotation.Opacity, pageIndex: pageNumber, review: review, shapeAnnotationType: annotation.AnnotationType, strokeColor: annotation.StrokeColor, subject: annotation.Subject, thickness: annotation.Thickness, status: annotation.status }; this.pdfViewer.annotationModule.storeAnnotations(pageNumber, annotationObject, '_annotations_ink'); }; // To get the annotation selector settings InkAnnotation.prototype.getSettings = function (annotation) { var selector = this.pdfViewer.annotationSelectorSettings; if (annotation.AnnotationSelectorSettings) { selector = annotation.AnnotationSelectorSettings; } else { selector = this.getSelector(annotation.ShapeAnnotationType, annotation.Subject); } return selector; }; /** * @param {number} pageNumber - It describes about the page number value * @param {any} annotations - It describes about the annotations * @private * @returns {void} */ InkAnnotation.prototype.storeInkSignatureData = function (pageNumber, annotations) { this.pdfViewer.annotation.addAction(annotations.pageIndex, null, annotations, 'Addition', '', annotations, annotations); var annotation = null; var left = annotations.bounds.left ? annotations.bounds.left : annotations.bounds.x; var top = annotations.bounds.top ? annotations.bounds.top : annotations.bounds.y; if (annotations.wrapper && annotations.wrapper.bounds) { left = annotations.wrapper.bounds.left; top = annotations.wrapper.bounds.top; } annotation = { id: annotations.id, bounds: { x: left, y: top, width: annotations.bounds.width, height: annotations.bounds.height }, shapeAnnotationType: 'Ink', opacity: annotations.opacity, thickness: annotations.thickness, strokeColor: annotations.strokeColor, pageIndex: annotations.pageIndex, data: annotations.data, annotName: annotations.annotName, comments: annotations.comments, author: annotations.author, subject: annotations.subject, modifiedDate: annotations.modifiedDate, review: { state: '', stateModel: '', modifiedDate: annotations.modifiedDate, author: annotations.author }, notes: annotations.notes, annotationSelectorSettings: this.getSelector(annotations, 'Ink'), isCommentLock: annotations.isCommentLock }; var storeObject = this.pdfViewer.annotationsCollection.get(this.pdfViewerBase.documentId + '_annotations_ink'); var index = 0; if (!storeObject) { var shapeAnnotation = { pageIndex: pageNumber, annotations: [] }; shapeAnnotation.annotations.push(annotation); index = shapeAnnotation.annotations.indexOf(annotation); var annotationCollection = []; annotationCollection.push(shapeAnnotation); this.pdfViewer.annotationsCollection.set(this.pdfViewerBase.documentId + '_annotations_ink', annotationCollection); } else { this.pdfViewer.annotationsCollection.delete(this.pdfViewerBase.documentId + '_annotations_ink'); var pageIndex = this.pdfViewer.annotationModule.getPageCollection(storeObject, pageNumber); if (pageIndex != null && storeObject[parseInt(pageIndex.toString(), 10)]) { storeObject[parseInt(pageIndex.toString(), 10)].annotations.push(annotation); index = storeObject[parseInt(pageIndex.toString(), 10)].annotations.indexOf(annotation); } else { var markupAnnotation = { pageIndex: pageNumber, annotations: [] }; markupAnnotation.annotations.push(annotation); index = markupAnnotation.annotations.indexOf(annotation); storeObject.push(markupAnnotation); } this.pdfViewer.annotationsCollection.set(this.pdfViewerBase.documentId + '_annotations_ink', storeObject); } }; InkAnnotation.prototype.getSelector = function (type, subject) { var selector = this.pdfViewer.annotationSelectorSettings; if ((type === 'Ink' || subject === 'Ink') && this.pdfViewer.inkAnnotationSettings.annotationSelectorSettings) { selector = cloneObject(this.pdfViewer.annotationSelectorSettings); this.pdfViewerBase.updateSelector(selector, type); } return selector; }; InkAnnotation.prototype.getAnnotations = function (pageIndex, shapeAnnotations) { var annotationCollection; var storeObject = this.pdfViewer.annotationsCollection.get(this.pdfViewerBase.documentId + '_annotations_ink'); if (storeObject) { var index = this.pdfViewer.annotationModule.getPageCollection(storeObject, pageIndex); if (index != null && storeObject[parseInt(index.toString(), 10)]) { annotationCollection = storeObject[parseInt(index.toString(), 10)].annotations; } else { annotationCollection = shapeAnnotations; } } else { annotationCollection = shapeAnnotations; } return annotationCollection; }; /** * @param {string} property - It describes about the property * @param {number} pageNumber - It describes about the page number * @param {any} annotationBase - It is about the annotation base * @private * @returns {any} - any */ InkAnnotation.prototype.modifySignatureInkCollection = function (property, pageNumber, annotationBase) { if (!isNullOrUndefined(annotationBase.formFieldAnnotationType) && annotationBase.formFieldAnnotationType !== '') { this.pdfViewer.annotationModule.isFormFieldShape = true; } else { this.pdfViewer.annotationModule.isFormFieldShape = false; } this.pdfViewerBase.updateDocumentEditedProperty(true); var currentAnnotObject = null; var pageAnnotations = this.getAnnotations(pageNumber, null); if (pageAnnotations != null && annotationBase) { for (var i = 0; i < pageAnnotations.length; i++) { if (annotationBase.id === pageAnnotations[parseInt(i.toString(), 10)].id) { if (property === 'bounds') { this.pdfViewerBase.isBounds = this.pdfViewerBase.boundsCalculation(pageAnnotations[parseInt(i.toString(), 10)].bounds, annotationBase.wrapper.bounds); if (this.pdfViewerBase.isBounds) { pageAnnotations[parseInt(i.toString(), 10)].bounds = { x: annotationBase.wrapper.bounds.left, y: annotationBase.wrapper.bounds.top, width: annotationBase.bounds.width, height: annotationBase.bounds.height }; } } else if (property === 'stroke') { pageAnnotations[parseInt(i.toString(), 10)].strokeColor = annotationBase.wrapper.children[0].style.strokeColor; } else if (property === 'opacity') { pageAnnotations[parseInt(i.toString(), 10)].opacity = annotationBase.wrapper.children[0].style.opacity; } else if (property === 'thickness') { pageAnnotations[parseInt(i.toString(), 10)].thickness = annotationBase.wrapper.children[0].style.strokeWidth; } else if (property === 'notes') { pageAnnotations[parseInt(i.toString(), 10)].notes = annotationBase.notes; } else if (property === 'delete') { currentAnnotObject = pageAnnotations.splice(i, 1)[0]; break; } if (this.pdfViewerBase.isBounds) { pageAnnotations[parseInt(i.toString(), 10)].modifiedDate = this.pdfViewer.annotation.stickyNotesAnnotationModule.getDateAndTime(); } if (pageAnnotations[parseInt(i.toString(), 10)].status !== 'NewlyAdded') { pageAnnotations[parseInt(i.toString(), 10)].status = AnnotationStatus.ExistingModified; } this.pdfViewer.annotationModule.storeAnnotationCollections(pageAnnotations[parseInt(i.toString(), 10)], pageNumber); } } this.manageInkAnnotations(pageAnnotations, pageNumber); } return currentAnnotObject; }; InkAnnotation.prototype.manageInkAnnotations = function (pageAnnotations, pageNumber) { var storeObject = this.pdfViewer.annotationsCollection.get(this.pdfViewerBase.documentId + '_annotations_ink'); if (storeObject) { this.pdfViewer.annotationsCollection.delete(this.pdfViewerBase.documentId + '_annotations_ink'); var index = this.pdfViewer.annotationModule.getPageCollection(storeObject, pageNumber); if (index != null && storeObject[parseInt(index.toString(), 10)]) { storeObject[parseInt(index.toString(), 10)].annotations = pageAnnotations; } this.pdfViewer.annotationsCollection.set(this.pdfViewerBase.documentId + '_annotations_ink', storeObject); } }; /** * Processes ink erasing using geometry-based midpoint detection (reference sample logic). * Converts SVG path to point arrays, fragments based on eraser geometry, converts back to SVG. * @param {any} inkAnnotation - The ink annotation to erase from * @param {PointModel[]} eraserPath - Array of eraser positions during drag * @param {number} eraserSize - Diameter of eraser * @returns {string} - Fragmented path data string with M commands separating fragments * @private */ InkAnnotation.prototype.processInkErase = function (inkAnnotation, eraserPath, eraserSize) { if (!eraserPath || eraserPath.length < 1) { return inkAnnotation.data; } var pathData = inkAnnotation.data; var collectionData = processPathData(pathData); if (!collectionData || collectionData.length < 1) { return inkAnnotation.data; } var zoom = this.pdfViewerBase.getZoomFactor(); var rawThickness = inkAnnotation.thickness || this.pdfViewer.inkAnnotationSettings.thickness || 1; var strokeThickness = rawThickness * zoom > 1 ? rawThickness * zoom : rawThickness; var hitRadius = eraserSize / 2 + strokeThickness / 2; var distToSeg = function (p, a, b) { var dx = b.x - a.x; var dy = b.y - a.y; var lenSq = dx * dx + dy * dy; var t = lenSq ? Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lenSq)) : 0; return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy)); }; var isErased = function (p) { if (eraserPath.length === 1) { return Math.hypot(p.x - eraserPath[0].x, p.y - eraserPath[0].y) <= hitRadius; } for (var i = 0; i < eraserPath.length - 1; i++) { if (distToSeg(p, eraserPath[i], eraserPath[i + 1]) <= hitRadius) { return true; } } return false; }; var paths = []; var current = []; for (var k = 0; k < collectionData.length; k++) { var pt = collectionData[k]; if (pt.command === 'M') { if (current.length > 1) { paths.push(current); } current = [{ x: pt.x, y: pt.y }]; } else if (pt.command === 'L') { current.push({ x: pt.x, y: pt.y }); } } if (current.length > 1) { paths.push(current); } // Subdivide each ink segment into ~2 px steps for pixel-level erase accuracy var STEP = 2; var segmentedPathData = []; for (var pi = 0; pi < paths.length; pi++) { var path = paths[pi]; var fragment = []; for (var i = 0; i < path.length - 1; i++) { var a = path[i]; var b = path[i + 1]; var dx = b.x - a.x; var dy = b.y - a.y; var steps = Math.max(1, Math.ceil(Math.hypot(dx, dy) / STEP)); for (var s = 0; s < steps; s++) { var p0 = { x: a.x + dx * (s / steps), y: a.y + dy * (s / steps) }; var p1 = { x: a.x + dx * ((s + 1) / steps), y: a.y + dy * ((s + 1) / steps) }; if (!isErased(p0) && !isErased(p1)) { if (fragment.length === 0) { fragment.push(p0); } fragment.push(p1); } else { if (fragment.length > 1) { segmentedPathData.push(fragment); } fragment = []; } } } if (fragment.length > 1) { segmentedPathData.push(fragment); } } if (segmentedPathData.length === 0) { return ''; } var uniquePath = new Set(); for (var fi = 0; fi < segmentedPathData.length; fi++) { var frag = segmentedPathData[fi]; if (frag.length > 1) { var str = "M" + Math.round(frag[0].x) + "," + Math.round(frag[0].y); for (var i = 1; i < frag.length; i++) { str += " L" + Math.round(frag[i].x) + "," + Math.round(frag[i].y); } if (!uniquePath.has(str)) { uniquePath.add(str); } } } return uniquePath.size > 0 ? Array.from(uniquePath).join(' ') : ''; }; /** * Applies erasing by updating the original annotation with fragmented path. * The annotation remains a single annotation with the modified path containing erased gaps. * @param {any} originalAnnotation - The annotation being erased * @param {string} pathData - Erased path data (output from processInkErase) * @param {number} pageIndex - Page containing the annotation * @private * @returns {void} */ InkAnnotation.prototype.applyInkErase = function (originalAnnotation, pathData, pageIndex) { originalAnnotation.data = pathData; var pageAnnotations = this.getAnnotations(pageIndex, null); if (pageAnnotations) { var inkAnnotationObject = this.pdfViewer.nameTable[originalAnnotation.id]; inkAnnotationObject.data = pathData; if (inkAnnotationObject.wrapper && inkAnnotationObject.wrapper.children && inkAnnotationObject.wrapper.children[0] && inkAnnotationObject.wrapper.children[0] instanceof PathElement) { var pathElement = inkAnnotationObject.wrapper.children[0]; pathElement.data = pathData; pathElement.pathData = pathData; var bounds = inkAnnotationObject.wrapper.bounds; pathElement.absoluteBounds = inkAnnotationObject.wrapper.bounds; var actualSize = pathElement.actualSize || bounds; pathElement.desiredSize = actualSize; pathElement.absolutePath = pathElement.updatePath(pathData, bounds, actualSize); } originalAnnotation.modifiedDate = this.pdfViewer.annotation.stickyNotesAnnotationModule.getDateAndTime(); if (originalAnnotation.status !== 'NewlyAdded') { originalAnnotation.status = AnnotationStatus.ExistingModified; } this.pdfViewer.annotationModule.storeAnnotationCollections(originalAnnotation, pageIndex); } this.manageInkAnnotat