{"version":3,"sources":["../js/GreenlightCanvas.js"],"names":["Canvas","ContainerId","CanvasId","CanvasClass","Doc","PageNo","AnnotationCanvas","mainCanvas","canvasType","zIndex","this","g_szCanvasId","g_oDoc","g_iCurrentPage","g_oAnnotationCanvas","g_bMainCanvas","isThreeDCanvas","c_iMargin","g_oViewer","c_iDPI","g_iCanvasType","g_oCanvas","g_oContext","g_oContainer","g_oSVG","g_oNavCanvasObj","g_oNavCanvasOver","g_oaImages","g_oImage","g_oImgData","undefined","g_iScaledImageWidth","g_iScaledImageHeight","g_iRatio","g_iRotDegrees","g_iTempRotDegrees","g_bIsAnimating","g_bIsDragging","g_iFullImageRequestId","g_iPartialImageRequestId","g_iOrigin_x","g_iOrigin_y","g_iCurrOffset_x","g_iCurrOffset_y","g_iZoomLevel","g_iTempZoomLevel","g_iZoomDiff","g_iX","g_iY","g_iCompareImage_x","g_iCompareImage_y","g_iDragOffset_x","g_iDragOffset_y","g_iTemp2DragOffset_x","g_iTemp2DragOffset_y","g_iCenterShift_x","g_iCenterShift_y","g_iOriginalResolution","g_iCurrentResolution","g_szRealtimeRenderReference","g_bOverrideSingleColourChange","g_oaNavigatorData","g_iAnimateFrames","getAnimationFramesForZoomSpeed","g_oSettings","g_oUserSettings","ZoomSpeed","g_oCanvasZoom","CanvasZoom","setup2DCanvas","g_bLogRequests","g_bLogImages","g_oActiveCanvasList","push","prototype","getImageRequest","bIsOneToOneScale","oImageRequest","ImageRequest","SessionId","g_szSessionId","ApprovalId","g_oArtworkViewer","CompareMode","g_oCompareMode","ArtworkViewerImageBox","calculateVisibleImagePortion","CompareViewerImageBox","g_oCompare","calculateCompareVisibleImagePortion","IsCompareImageRequest","CompareGhosting","g_iCompareGhosting","CompareTolerance","g_iCompareTolerance","OverrideSingleColourChange","NewImageRequest","ZoomLevel","OverprintPreview","g_oSeparations","g_bOverprintPreview","OverprintColour","eCompareMode","DifferencesOnly","console","log","viewportWidth","width","viewportHeight","height","imageStart_x","imageStart_y","imageEnd_x","imageEnd_y","userImageObjW","userImageObjH","requestedImageObjW","requestedImageObjH","compareImageObjW","compareImageObjH","scaledImageObjW","scaledImageObjH","compareOffset_x","compareOffset_y","visibleCompareOffset_x","visibleCompareOffset_y","co","calculateCompareOffsetInPx","x","y","iCompareRotation","getCompareRotation","NoCompare","Math","round","floor","co2","calculateVisibleCompareOffsetInPx","compare_x","compare_y","iCanvasWidthDifference","max","min","length","ImageWidth","ImageHeight","navCanvasOver","navCanvasObj","hasSeparations","navCtx","navCenterShift","imageStartPoint_x","imageStartPoint_y","visibleStartPoint_x","visibleStartPoint_y","visibleDist_x","visibleDist_y","g_oNavigatorData","clearRect","beginPath","rect","fillStyle","fill","resizeSeparationListItems","reziseChecklistItems","oRequestedImageObject","ImageObject","Width","Height","oUserImageObject","oCompareImageObject","oScaledImageObject","oImagePercentages","ImageDimensions","MinX","MinY","MaxX","MaxY","oArtworkViewerImageBox","ImageBox","RequestedApproval","documentId","RequestedPage","RequestedImageName","documentName","RequestedImageType","documentType","RequestedImageObject","ImagePercentages","UserImageObject","CompareImageObject","ScaledImageObject","OriginalResolution","pages","documentResolutionPPI","CompareOffsetX","CompareOffsetY","VisibleCompareOffsetX","VisibleCompareOffsetY","CompareRotationDegrees","VisibleSeparations","$","grep","img","Visible","rotate","mid_x","mid_y","a","cos","sin","angle","PI","rotated_x","rotated_y","changeCurrentPage","text","css","g_oAnnotations","g_szPrevCursorStyle","attr","iControlIndex","comboControl_GetControlById","iDocumentIndex","comboControl_GetDocumentById","iPageIndex","iPageId","i","documentPageNumber","documentPageId","comboControl_GetPageById","comboControl_SelectOption","g_oGreenlightMessages","displayErrorBubble","c_szInvalidDocument","clearImgData","dragInitiate","event","oSyncCanvas","coords","getClickCoords","oArtworkCanvas","oAnnotationCanvas","changeCanvasFunction","dragRedraw","dragDiscontinue","AnnotationAction","mouseMove","bRedraw","off","redraw","iMargin","synchroniseZoomPanProperties","drawBackground","colour","closePath","drawImages","getPNGData","getRatio","iScaledImageWidth","iScaledImageHeight","drawImage","szBackgroundColour","isSVGApproval","putImageData","getimagePNGData","bGetNewImageCallType","bIsAlignmentUpdate","getImagePngDataPDF","updateSVGCanvas","szSrc","oCurrentCanvas","src","Image","onload","finalizeRenderingImage","clearRealtimeRenderImage","fadeIn","IsGetNewImageCallType","iImageRequestId","random","oJSON","bGetImage","_this","post","url","data","JSON","stringify","contentType","cache","dataType","success","oResponse","Success","Errors","getImagePngDataPDF_CH","Contents","displayErrorContentHTML","error","fadeOut","oResponseContents","oImageDetails","parse","oVisibleImageSeparations","iImageDrawStart_x","iImageDrawStart_y","iImageWidth","iImageHeight","imageDimensionsStart_x","imageDimensionsStart_y","imageDimensionsEnd_x","imageDimensionsEnd_y","abs","oImage","ImageData","w","window","open","document","write","outerHTML","bIsInitialImageRender","CurrentResolution","RealtimeRenderReference","HeightResolution","MatchVisibleSeparations","getImageData","getCanvasFiles","bUseCompareCallback","requestId","callAsynchronously","ViewportWidth","offsetWidth","deepCopyObject","PageNumber","oCanvas","async","getCanvasFiles_CH","jqXhr","textStatus","errorThrown","g_oSVGLoader","loadSVGFile","Files","populateSeparationImages","SetupSeparationsDiv","g_oCompareViewer","eCanvasType","Artwork","getSyncCanvas","RenderSeparationElements","oSeparation","hRatio","vRatio","offsetHeight","id","getCompareRatio","translate","documentHasSeparations","eDocumentTypes","SVG","CopyMagic","initialiseCanvas","resetCanvas","documentStatus","g_oArchive","g_ArchivedDocumentStatus","initialiseArchiveModule","done","oSVG","clone","find","remove","navigator","userAgent","indexOf","c_szSVGNotSupported","oURL","oSVGString","XMLSerializer","serializeToString","replace","RegExp","oDOMURL","bFirefox","toLowerCase","URL","webkitURL","oSVGObject","Blob","type","createObjectURL","encodeURIComponent","e","target","complete","setTimeout","createElement","getContext","toDataURL","revokeObjectURL","isEmptyObject","ShowAnnotations","redrawAnnotations","navOnMove","navOverlayContext","newCoords","newStartPoint_x","newStartPoint_y","navPointerUp","pan","findAnnotation","g_bAnnotationsFound","bGetNewImage","Annotation","canvasToSyncFrom","getLinkedArtworkCanvas","repositionSpeechBubbles","bAllowZoomLevelOneReRendering","SliderHorizontal","SliderVertical","redrawCanvasSlider","g_bAlignmentModeActive","itop","position","top","offset","left","drawAlignmentMarkers","SideBySide","ThreeD","SideBySideDiff","hide","drawTextHighlight","oContext","distx","disty","removeTextHighlight","g_iTempDragOffset_x","g_iTempDragOffset_y","g_iDragXDiff","g_iDragYDiff","updateZoomSlider","resize","content","innerHeight","resizeViewerCell","children","setupAnnotationsDiv","g_oSVGCopyMagic","setupCopyMagicSlideOut","rotateAnimate","iRotDegrees","rotateAnimateFrame","iCurrentAnimationFrame","iDesiredAnimationFrames","prop","requestAnimationFrame","bind","getElementById","addClass","appendChild","isViewerUsingRealtimeRender","szRealtimeRenderReference","Status","jqXHR","isClickWithinImageBounds","style","isPointInPath"],"mappings":"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","file":"GreenlightCanvas-703a7628ca.js","sourcesContent":["/*\r\n* Copyright (c) 2017 SGS Europe. All rights reserved.\r\n*\r\n* This program is the CONFIDENTIAL and PROPRIETARY property of SGS Europe.\r\n* Any unauthorised use, reproduction, or transfer of this program is strictly\r\n* prohibited.\r\n*\r\n* File Name:\tGreenlightCanvas.js\r\n*\r\n* Description:\tContains the code for the Canvas Object.\r\n*\r\n*/\r\n\r\n(function () {\r\n\r\n\t\"use strict\";\r\n\r\n\t/**\r\n\t * Prototype for the Canvas object.\r\n\t * There are two canvases for each viewport, one for the artwork viewer and another for annotations\r\n\t * Depending on the compare mode there may be three viewports\r\n\t * There is also a canvas for the navigator feature based on this prototype object\r\n\t *\r\n\t * @param {string} ContainerId - Id of the container the canvas is contained in.\r\n\t * @param {string} CanvasId - Id of the canvas element.\r\n\t * @param {string} CanvasClass - Class to put onto the canvas.\r\n\t * @param {object} Doc - The document that has been loaded into the canvas. Defaults to null.\r\n\t * @param {object} AnnotationCanvas - Link to the Annotation Canvas object. Defaults to null.\r\n\t *\t@param {bool} mainCanvas - Boolean to determine if this is the main canvas and not a compare canvas.\r\n\t * @param {int} The type of canvas we are creating (from enum)\r\n\t * @class\r\n\t */\r\n\tfunction Canvas(ContainerId, CanvasId, CanvasClass, Doc, PageNo, AnnotationCanvas, mainCanvas, canvasType, zIndex) {\r\n\r\n\t\t// Id of the canvas element.\r\n\t\tthis.g_szCanvasId = CanvasId;\r\n\r\n\t\t// The document connected to the canvas.\r\n\t\tthis.g_oDoc = Doc || null;\r\n\r\n\t\t// Current page of document.\r\n\t\tthis.g_iCurrentPage = PageNo;\r\n\r\n\t\t// Link to the Annotation Canvas object.\r\n\t\tthis.g_oAnnotationCanvas = AnnotationCanvas || null;\r\n\r\n\t\t// Boolean to determine if this is the main canvas and not a compare canvas.\r\n\t\tthis.g_bMainCanvas = mainCanvas || false;\r\n\r\n\t\t// Set that this is a ThreeD canvas.\r\n\t\tthis.isThreeDCanvas = false;\r\n\r\n\t\t// Constant.\r\n\t\tthis.c_iMargin = 10 * g_oViewer.c_iDPI; // Configurable space around image.\r\n\r\n\t\t// The type of canvas we are creating\r\n\t\tthis.g_iCanvasType = canvasType;\r\n\r\n\t\t// The canvas element.\r\n\t\tthis.g_oCanvas = {};\r\n\r\n\t\t// Context.\r\n\t\tthis.g_oContext = {};\r\n\r\n\t\t// Div Container.\r\n\t\tthis.g_oContainer = {};\r\n\r\n\t\t// SVG element.\r\n\t\tthis.g_oSVG = {};\r\n\r\n\t\t// Navigation.\r\n\t\tthis.g_oNavCanvasObj = null;\r\n\t\tthis.g_oNavCanvasOver = null;\r\n\r\n\t\t// Images within the canvas.\r\n\t\tthis.g_oaImages = [];\r\n\t\tthis.g_oImage = {};\r\n\t\tthis.g_oImgData = undefined;\r\n\r\n\t\t// Scaled Image width and height.\r\n\t\tthis.g_iScaledImageWidth = 0;\r\n\t\tthis.g_iScaledImageHeight = 0;\r\n\r\n\t\t// The current Ratio.\r\n\t\tthis.g_iRatio = 0;\r\n\r\n\t\t// Current rotation state of the canvas.\r\n\t\tthis.g_iRotDegrees = 0;\r\n\r\n\t\t// Temp used when animating.\r\n\t\tthis.g_iTempRotDegrees = 0;\r\n\r\n\t\t// Are we currently Animating.\r\n\t\tthis.g_bIsAnimating = false;\r\n\r\n\t\t// Are we currently dragging.\r\n\t\tthis.g_bIsDragging = false;\r\n\r\n\t\t// The current image request ids.\r\n\t\tthis.g_iFullImageRequestId = 0;\r\n\t\tthis.g_iPartialImageRequestId = 0;\r\n\r\n\t\t// Temporary coordinates remembered when dragging, drawing annotation, etc of origin point.\r\n\t\tthis.g_iOrigin_x = 0;\r\n\t\tthis.g_iOrigin_y = 0;\r\n\r\n\t\tthis.g_iCurrOffset_x = 0;\r\n\t\tthis.g_iCurrOffset_y = 0;\r\n\r\n\t\t// The current zoom level.\r\n\t\tthis.g_iZoomLevel = 1;\r\n\t\tthis.g_iTempZoomLevel = 1;\r\n\t\tthis.g_iZoomDiff = 0;\r\n\t\tthis.g_iX = 0;\r\n\t\tthis.g_iY = 0;\r\n\r\n\t\t// Compare offset is used when positioning two images offset to each other during a compare session.\r\n\t\tthis.g_iCompareImage_x = 0;\r\n\t\tthis.g_iCompareImage_y = 0;\r\n\r\n\t\tthis.g_iDragOffset_x = 0;\r\n\t\tthis.g_iDragOffset_y = 0;\r\n\t\tthis.g_iTemp2DragOffset_x = 0;\r\n\t\tthis.g_iTemp2DragOffset_y = 0;\r\n\r\n\t\t// CenterShift describes the amount of clear space each side of the image on the canvas.\r\n\t\tthis.g_iCenterShift_x = 0;\r\n\t\tthis.g_iCenterShift_y = 0;\r\n\r\n\t\t// The original render resolution.\r\n\t\tthis.g_iOriginalResolution = 0;\r\n\r\n\t\t// The current render resolution.\r\n\t\tthis.g_iCurrentResolution = 0;\r\n\r\n\t\t// A reference to the real-time rendered image. If this is an empty string then there is no real-time render image.\r\n\t\tthis.g_szRealtimeRenderReference = \"\";\r\n\r\n\t\t// Boolean property to indicate if the user wants the last colour separation to be rendered in its original colour instead of black.\r\n\t\tthis.g_bOverrideSingleColourChange = false;\r\n\r\n\t\t// NavigatorData - Temporary data used for navigator canvas only so we can draw changes to the rectangle.\r\n\t\t//0. [Canvas draw start point x. , Canvas draw start point y.]\r\n\t\t//1. [Canvas distance x, Canvas distance y]\r\n\t\t//2. [Current rectangle x start point, current rectangle y start point]\r\n\t\t//3. [Current rectangle x distance, current rectangle y distance]\r\n\t\tthis.g_oaNavigatorData = [];\r\n\r\n\t\t// Number of frames to animate when performing a transition.\r\n\t\tthis.g_iAnimateFrames = getAnimationFramesForZoomSpeed(g_oSettings.g_oUserSettings.ZoomSpeed);\r\n\r\n\t\t// Setup the canvas zoom functionality.\r\n\t\tthis.g_oCanvasZoom = new CanvasZoom(this);\r\n\r\n\t\t// Setup the canvas.\r\n\t\tthis.setup2DCanvas(ContainerId, CanvasClass, zIndex);\r\n\r\n\t\t// Debug.\r\n\t\tthis.g_bLogRequests = false; // If we should log any image requests to the server.\r\n\t\tthis.g_bLogImages = false; // If we should log any images returned from the server.\r\n\r\n\t\t// Add this canvas to the list of viewer canvas.\r\n\t\tg_oViewer.g_oActiveCanvasList.push(this);\r\n\t}\r\n\r\n\t/**\r\n\t * Calculates the Visible Image Portion to display in the canvas.\r\n\t * @param {int} bIsOneToOneScale - If we are fully zoomed out get full image.\r\n\t * @returns {object} - The Imaging Request object that is sent to the server.\r\n\t */\r\n\tCanvas.prototype.getImageRequest = function (bIsOneToOneScale) {\r\n\r\n\t\t// Declare a new image request.\r\n\t\tvar oImageRequest = new ImageRequest();\r\n\r\n\t\t// Populate the image request.\r\n\t\toImageRequest.SessionId = g_szSessionId;\r\n\t\toImageRequest.ApprovalId = g_oViewer.g_oArtworkViewer.ApprovalId;\r\n\t\toImageRequest.CompareMode = g_oViewer.g_oCompareMode;\r\n\r\n\t\toImageRequest.ArtworkViewerImageBox = this.calculateVisibleImagePortion(bIsOneToOneScale);\r\n\t\toImageRequest.CompareViewerImageBox = g_oCompare.calculateCompareVisibleImagePortion(this, bIsOneToOneScale);\r\n\r\n\t\toImageRequest.IsCompareImageRequest = (this.g_szCanvasId !== \"ArtworkViewer\");\r\n\t\toImageRequest.CompareGhosting = g_oCompare.g_iCompareGhosting;\r\n\t\toImageRequest.CompareTolerance = g_oCompare.g_iCompareTolerance;\r\n\t\toImageRequest.OverrideSingleColourChange = this.g_bOverrideSingleColourChange;\r\n\t\toImageRequest.NewImageRequest = bIsOneToOneScale;\r\n\t\toImageRequest.ZoomLevel = this.g_iZoomLevel;\r\n\t\toImageRequest.OverprintPreview = g_oSeparations.g_bOverprintPreview;\r\n\t\toImageRequest.OverprintColour = g_oSettings.g_oUserSettings.OverprintColour;\r\n\r\n\t\t// Always get differences on the differences canvas.\r\n\t\tif (this.g_szCanvasId === \"DifferencesViewer\" || this.g_szCanvasId === \"DifferencesViewer2\") {\r\n\t\t\toImageRequest.CompareMode = eCompareMode.DifferencesOnly;\r\n\t\t}\r\n\r\n\t\t// Log the image request if required.\r\n\t\tif (this.g_bLogRequests) {\r\n\t\t\tconsole.log(oImageRequest);\r\n\t\t}\r\n\r\n\t\t// Return the image request.\r\n\t\treturn oImageRequest;\r\n\t};\r\n\r\n\tCanvas.prototype.calculateVisibleImagePortion = function (bIsOneToOneScale) {\r\n\t\tvar viewportWidth = this.g_oCanvas.width,\r\n\t\t\tviewportHeight = this.g_oCanvas.height,\r\n\t\t\timageStart_x = 0,\r\n\t\t\timageStart_y = 0,\r\n\t\t\timageEnd_x = 0,\r\n\t\t\timageEnd_y = 0,\r\n\t\t\tuserImageObjW = 0,\r\n\t\t\tuserImageObjH = 0,\r\n\t\t\trequestedImageObjW = 0,\r\n\t\t\trequestedImageObjH = 0,\r\n\t\t\tcompareImageObjW = 0,\r\n\t\t\tcompareImageObjH = 0,\r\n\t\t\tscaledImageObjW = this.g_iScaledImageWidth,\r\n\t\t\tscaledImageObjH = this.g_iScaledImageHeight,\r\n\t\t\tcompareOffset_x = 0,\r\n\t\t\tcompareOffset_y = 0,\r\n\t\t\tvisibleCompareOffset_x = 0,\r\n\t\t\tvisibleCompareOffset_y = 0;\r\n\r\n\t\t// Get the compare offset of the canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(this);\r\n\t\tcompareOffset_x = co.x;\r\n\t\tcompareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(this);\r\n\r\n\t\tif (g_oViewer.g_oCompareMode !== eCompareMode.NoCompare) {\r\n\t\t\trequestedImageObjW = this.g_iCompareImage_x;\r\n\t\t\trequestedImageObjH = this.g_iCompareImage_y;\r\n\t\t}\r\n\t\telse {\r\n\t\t\trequestedImageObjW = scaledImageObjW;\r\n\t\t\trequestedImageObjH = scaledImageObjH;\r\n\t\t}\r\n\r\n\t\t// Make sure the numbers are cast as int\r\n\t\trequestedImageObjW = Math.round(requestedImageObjW);\r\n\t\trequestedImageObjH = Math.round(requestedImageObjH);\r\n\r\n\t\t// If the image is not one to one scale.\r\n\t\tif (!bIsOneToOneScale) {\r\n\r\n\t\t\t// Calculate the positions based on the canvas rotation.\r\n\t\t\tswitch (this.g_iRotDegrees) {\r\n\t\t\t\tcase 90:\r\n\t\t\t\tcase 270:\r\n\t\t\t\t\tvar compare_x = compareOffset_x < 0 && this.g_szCanvasId === \"ArtworkViewer\" ? compareOffset_x : 0 - compareOffset_x;\r\n\t\t\t\t\tvar compare_y = compareOffset_x < 0 && this.g_szCanvasId === \"ArtworkViewer\" ? compareOffset_y : 0 - compareOffset_y;\r\n\r\n\t\t\t\t\t// Calculate the difference in canvas width and height.\r\n\t\t\t\t\tvar iCanvasWidthDifference = (this.g_oCanvas.width - this.g_oCanvas.height);\r\n\r\n\t\t\t\t\t// See 180 and default for explanation of the calculations\r\n\t\t\t\t\t// For rotated images we need to swap the measurements around\r\n\t\t\t\t\tswitch (iCompareRotation) {\r\n\r\n\t\t\t\t\t\tcase 90:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_y + compare_y - (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x + this.g_oCanvas.height + iCanvasWidthDifference;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_x + compare_x + this.g_oCanvas.width - (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y - this.g_oCanvas.width + iCanvasWidthDifference;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\r\n\t\t\t\t\t\t\timageStart_y = 1 - imageStart_y;\r\n\t\t\t\t\t\t\timageEnd_y = 1 - imageEnd_y;\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 180:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_x + compare_x + this.g_oCanvas.height + (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x - this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_x = 1 - imageStart_x;\r\n\t\t\t\t\t\t\timageEnd_x = 1 - imageEnd_x;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_y + compare_y + this.g_oCanvas.width - (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y - this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\r\n\t\t\t\t\t\t\timageStart_y = 1 - imageStart_y;\r\n\t\t\t\t\t\t\timageEnd_y = 1 - imageEnd_y;\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 270:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_y + compare_y + this.g_oCanvas.width + (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x - this.g_oCanvas.width - iCanvasWidthDifference;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_x = 1 - imageStart_x;\r\n\t\t\t\t\t\t\timageEnd_x = 1 - imageEnd_x;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_x + compare_x + (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y + this.g_oCanvas.height - iCanvasWidthDifference;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_x + compare_x + (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x + this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_y + compare_y - (iCanvasWidthDifference / 2);\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y + this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Ensure the image start and end positions are within the bounds of the image.\r\n\t\t\t\t\timageStart_x = Math.max(0, imageStart_x);\r\n\t\t\t\t\timageStart_x = Math.min(1, imageStart_x);\r\n\t\t\t\t\timageStart_y = Math.max(0, imageStart_y);\r\n\t\t\t\t\timageStart_y = Math.min(1, imageStart_y);\r\n\t\t\t\t\timageEnd_x = Math.min(1, imageEnd_x);\r\n\t\t\t\t\timageEnd_x = Math.max(0, imageEnd_x);\r\n\t\t\t\t\timageEnd_y = Math.min(1, imageEnd_y);\r\n\t\t\t\t\timageEnd_y = Math.max(0, imageEnd_y);\r\n\r\n\t\t\t\t\t// If we are zoomed in and have a compare rotation of 90 or 270, swap the viewport width and height.\r\n\t\t\t\t\tif ((iCompareRotation == 90 || iCompareRotation == 270) && this.g_iZoomLevel != 1) {\r\n\t\t\t\t\t\tviewportWidth = this.g_oCanvas.height;\r\n\t\t\t\t\t\tviewportHeight = this.g_oCanvas.width;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// the userImageObj properties define the actual size of the image that needs to be returned to the user.\r\n\t\t\t\t\t// They are calculated by the percentage of the image that is visible multiplied by the scaled image size.\r\n\t\t\t\t\t// But, this image size cannot be bigger (obviously) than the actual user viewport.\r\n\t\t\t\t\tuserImageObjW = Math.min(viewportHeight, Math.round((imageEnd_x - imageStart_x) * this.g_iScaledImageWidth));\r\n\t\t\t\t\tuserImageObjH = Math.min(viewportWidth, Math.round((imageEnd_y - imageStart_y) * this.g_iScaledImageHeight));\r\n\r\n\t\t\t\t\t// If we have an active compare mode.\r\n\t\t\t\t\tif (g_oViewer.g_oCompareMode != eCompareMode.NoCompare && this.g_iZoomLevel == 1) {\r\n\t\t\t\t\t\tcompareImageObjW = Math.min(viewportHeight, this.g_iCompareImage_x);\r\n\t\t\t\t\t\tcompareImageObjH = Math.min(viewportWidth, this.g_iCompareImage_y);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 180:\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tvar compare_x = compareOffset_x < 0 && this.g_szCanvasId === \"ArtworkViewer\" ? compareOffset_x : 0 - compareOffset_x;\r\n\t\t\t\t\tvar compare_y = compareOffset_x < 0 && this.g_szCanvasId === \"ArtworkViewer\" ? compareOffset_y : 0 - compareOffset_y;\r\n\r\n\t\t\t\t\t// The start and end of the image is calculated as a percentage of its overall width and height\r\n\t\t\t\t\t// It cannot be wider than the user's viewport (obviously)\r\n\t\t\t\t\t// It must account for drag offset and margin as this will affect how much of the image is visible\r\n\t\t\t\t\t// It must be limited to a minimum of zero, negative values will cause an argument exception on the server\r\n\t\t\t\t\t// It must also account for any compare rotation of the image.\r\n\t\t\t\t\t// It must finally be divided by the scaled image height to get a percentage so this can be used by the server to scale accordingly\r\n\t\t\t\t\tswitch (iCompareRotation) {\r\n\r\n\t\t\t\t\t\tcase 90:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_y + compare_y;\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x + this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_x + compare_x + this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y - this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\r\n\t\t\t\t\t\t\timageStart_y = 1 - imageStart_y;\r\n\t\t\t\t\t\t\timageEnd_y = 1 - imageEnd_y;\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 180:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_x + compare_x + this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x - this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_x = 1 - imageStart_x;\r\n\t\t\t\t\t\t\timageEnd_x = 1 - imageEnd_x;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_y + compare_y + this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y - this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\r\n\t\t\t\t\t\t\timageStart_y = 1 - imageStart_y;\r\n\t\t\t\t\t\t\timageEnd_y = 1 - imageEnd_y;\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 270:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_y + compare_y + this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x - this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_x = 1 - imageStart_x;\r\n\t\t\t\t\t\t\timageEnd_x = 1 - imageEnd_x;\r\n\r\n\t\t\t\t\t\t\timageStart_y = - this.g_iCenterShift_x + compare_x;\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y + this.g_oCanvas.width;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\timageStart_x = - this.g_iCenterShift_x + compare_x;\r\n\t\t\t\t\t\t\timageEnd_x = imageStart_x + this.g_oCanvas.width\r\n\t\t\t\t\t\t\timageStart_x /= this.g_iScaledImageWidth;\r\n\t\t\t\t\t\t\timageEnd_x /= this.g_iScaledImageWidth;\r\n\r\n\t\t\t\t\t\t\timageStart_y = -this.g_iCenterShift_y + compare_y;\r\n\t\t\t\t\t\t\timageEnd_y = imageStart_y + this.g_oCanvas.height;\r\n\t\t\t\t\t\t\timageStart_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\timageEnd_y /= this.g_iScaledImageHeight;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Ensure the image start and end positions are within the bounds of the image.\r\n\t\t\t\t\timageStart_x = Math.max(0, imageStart_x);\r\n\t\t\t\t\timageStart_x = Math.min(1, imageStart_x);\r\n\t\t\t\t\timageStart_y = Math.max(0, imageStart_y);\r\n\t\t\t\t\timageStart_y = Math.min(1, imageStart_y);\r\n\t\t\t\t\timageEnd_x = Math.min(1, imageEnd_x);\r\n\t\t\t\t\timageEnd_x = Math.max(0, imageEnd_x);\r\n\t\t\t\t\timageEnd_y = Math.min(1, imageEnd_y);\r\n\t\t\t\t\timageEnd_y = Math.max(0, imageEnd_y);\r\n\r\n\t\t\t\t\t// If we are zoomed in and have a compare rotation of 90 or 270, swap the viewport width and height.\r\n\t\t\t\t\tif ((iCompareRotation == 90 || iCompareRotation == 270) && this.g_iZoomLevel != 1) {\r\n\t\t\t\t\t\tviewportWidth = this.g_oCanvas.height;\r\n\t\t\t\t\t\tviewportHeight = this.g_oCanvas.width;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// the userImageObj properties define the actual size of the image that needs to be returned to the user.\r\n\t\t\t\t\t// They are calculated by the percentage of the image that is visible multiplied by the scaled image size.\r\n\t\t\t\t\t// But, this image size cannot be bigger (obviously) than the actual user viewport.\r\n\t\t\t\t\tuserImageObjW = Math.min(viewportWidth, Math.round((imageEnd_x - imageStart_x) * this.g_iScaledImageWidth));\r\n\t\t\t\t\tuserImageObjH = Math.min(viewportHeight, Math.round((imageEnd_y - imageStart_y) * this.g_iScaledImageHeight));\r\n\r\n\t\t\t\t\t// If we have an active compare mode.\r\n\t\t\t\t\tif (g_oViewer.g_oCompareMode != eCompareMode.NoCompare && this.g_iZoomLevel == 1) {\r\n\t\t\t\t\t\tcompareImageObjW = Math.min(viewportWidth, this.g_iCompareImage_x);\r\n\t\t\t\t\t\tcompareImageObjH = Math.min(viewportHeight, this.g_iCompareImage_y);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// If we have compare rotation and we are zoomed into the image.\r\n\t\t\tif (iCompareRotation > 0 && this.g_iZoomLevel != 1) {\r\n\r\n\t\t\t\t// If we are in a compare rotation of 90 or 270.\r\n\t\t\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\r\n\t\t\t\t\t// Keep the compare image width and height unswapped.\r\n\t\t\t\t\tcompareImageObjW = userImageObjH;\r\n\t\t\t\t\tcompareImageObjH = userImageObjW;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// If we have no compare mode or the compare image properties have not been set.\r\n\t\t\tif (g_oViewer.g_oCompareMode === eCompareMode.NoCompare || compareImageObjW === undefined || compareImageObjH === undefined || compareImageObjW === 0 || compareImageObjH === 0) {\r\n\r\n\t\t\t\t// Set these to the user image properties.\r\n\t\t\t\tcompareImageObjW = userImageObjW;\r\n\t\t\t\tcompareImageObjH = userImageObjH;\r\n\t\t\t}\r\n\r\n\t\t\t// Work out how much compare offset is visible.\r\n\t\t\tvar co2 = g_oCompare.calculateVisibleCompareOffsetInPx(this, requestedImageObjW, requestedImageObjH, compareOffset_x, compareOffset_y);\r\n\r\n\t\t\t// Only include the compare offset margin if the zoom level is 1.\r\n\t\t\tcompareOffset_x = (this.g_iZoomLevel == 1 ? Math.floor(co2.x) : 0);\r\n\t\t\tcompareOffset_y = (this.g_iZoomLevel == 1 ? Math.floor(co2.y) : 0);\r\n\r\n\t\t\t// Always include the visible compare offset (regardless of zoom level) as this is required for overlay.\r\n\t\t\tvisibleCompareOffset_x = Math.floor(co2.x);\r\n\t\t\tvisibleCompareOffset_y = Math.floor(co2.y);\r\n\t\t}\r\n\t\telse {\r\n\t\t\t// We're just going to get the whole image back.\r\n\t\t\timageStart_x = 0;\r\n\t\t\timageStart_y = 0;\r\n\t\t\timageEnd_x = 1;\r\n\t\t\timageEnd_y = 1;\r\n\r\n\t\t\t// Calculate the actual size that we need the image back at.\r\n\t\t\tuserImageObjW = Math.floor((imageEnd_x - imageStart_x) * (this.g_iScaledImageWidth));\r\n\t\t\tuserImageObjH = Math.floor((imageEnd_y - imageStart_y) * (this.g_iScaledImageHeight));\r\n\t\t\tcompareImageObjW = Math.floor(this.g_iCompareImage_x / this.g_iZoomLevel);\r\n\t\t\tcompareImageObjH = Math.floor(this.g_iCompareImage_y / this.g_iZoomLevel);\r\n\t\t\trequestedImageObjW = Math.floor(requestedImageObjW / this.g_iZoomLevel);\r\n\t\t\trequestedImageObjH = Math.floor(requestedImageObjH / this.g_iZoomLevel);\r\n\r\n\t\t\tscaledImageObjW = Math.floor(scaledImageObjW / this.g_iZoomLevel);\r\n\t\t\tscaledImageObjH = Math.floor(scaledImageObjH / this.g_iZoomLevel);\r\n\r\n\t\t\t// If we have no compare mode or the compare image properties have not been set.\r\n\t\t\tif (g_oViewer.g_oCompareMode === eCompareMode.NoCompare || compareImageObjW === undefined || compareImageObjH === undefined || compareImageObjW === 0 || compareImageObjH === 0) {\r\n\r\n\t\t\t\t// Set these to the user image properties.\r\n\t\t\t\tcompareImageObjW = Math.floor(userImageObjW / this.g_iZoomLevel);\r\n\t\t\t\tcompareImageObjH = Math.floor(userImageObjH / this.g_iZoomLevel);\r\n\t\t\t}\r\n\r\n\t\t\tcompareOffset_x = Math.floor(compareOffset_x /= this.g_iZoomLevel);\r\n\t\t\tcompareOffset_y = Math.floor(compareOffset_y /= this.g_iZoomLevel);\r\n\t\t\tuserImageObjW = Math.floor(userImageObjW / this.g_iZoomLevel);\r\n\t\t\tuserImageObjH = Math.floor(userImageObjH / this.g_iZoomLevel);\r\n\r\n\t\t\t// Work out how much compare offset is visible.\r\n\t\t\tvar co2 = g_oCompare.calculateVisibleCompareOffsetInPx(this, requestedImageObjW, requestedImageObjH, compareOffset_x, compareOffset_y);\r\n\r\n\t\t\t// Always include the visible compare offset (regardless of zoom level) as this is required for overlay.\r\n\t\t\tvisibleCompareOffset_x = Math.floor(co2.x);\r\n\t\t\tvisibleCompareOffset_y = Math.floor(co2.y);\r\n\t\t}\r\n\r\n\t\t// check if we have any images available otherwise exit.\r\n\t\tif (this.g_oaImages.length == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar fullImageWidth = this.g_oaImages[0].ImageWidth;\r\n\t\tvar fullImageHeight = this.g_oaImages[0].ImageHeight;\r\n\r\n\t\tif (imageStart_x > 1) imageStart_x = 1;\r\n\t\tif (imageStart_y > 1) imageStart_y = 1;\r\n\r\n\t\t// Update Navigation Canvas.\r\n\t\tvar navCanvasOver = this.g_oNavCanvasOver;\r\n\t\tvar navCanvasObj = this.g_oNavCanvasObj;\r\n\t\tif (this.g_bMainCanvas && this.hasSeparations() && this.g_oNavCanvasOver != null && !bIsOneToOneScale) {\r\n\t\t\tvar navCtx = this.g_oNavCanvasOver.g_oContext;\r\n\t\t\tvar navCenterShift = [navCanvasOver.g_iCenterShift_x, navCanvasOver.g_iCenterShift_y];\r\n\t\t\tvar imageStartPoint_x = (navCenterShift[0] - (navCanvasObj.g_iScaledImageWidth / 2));\r\n\t\t\tvar imageStartPoint_y = (navCenterShift[1] - (navCanvasObj.g_iScaledImageHeight / 2));\r\n\t\t\tvar visibleStartPoint_x = imageStartPoint_x + (imageStart_x * navCanvasObj.g_iScaledImageWidth);\r\n\t\t\tvar visibleStartPoint_y = imageStartPoint_y + (imageStart_y * navCanvasObj.g_iScaledImageHeight);\r\n\t\t\tvar visibleDist_x = (imageEnd_x - imageStart_x) * navCanvasObj.g_iScaledImageWidth;\r\n\t\t\tvar visibleDist_y = (imageEnd_y - imageStart_y) * navCanvasObj.g_iScaledImageHeight;\r\n\r\n\t\t\t// Store current rectangle data so it can be used when dragging and dropping on navigation canvas.\r\n\t\t\tnavCanvasOver.g_oNavigatorData = [];\r\n\t\t\tnavCanvasOver.g_oNavigatorData.push([imageStartPoint_x, imageStartPoint_y]);\r\n\t\t\tnavCanvasOver.g_oNavigatorData.push([navCanvasObj.g_iScaledImageWidth, navCanvasObj.g_iScaledImageHeight]);\r\n\t\t\tnavCanvasOver.g_oNavigatorData.push([visibleStartPoint_x, visibleStartPoint_y]);\r\n\t\t\tnavCanvasOver.g_oNavigatorData.push([visibleDist_x, visibleDist_y]);\r\n\r\n\t\t\tnavCtx.clearRect(0, 0, navCanvasOver.g_oCanvas.width, navCanvasOver.g_oCanvas.height);\r\n\t\t\tnavCtx.beginPath();\r\n\t\t\tnavCtx.rect(imageStartPoint_x, imageStartPoint_y, navCanvasObj.g_iScaledImageWidth, navCanvasObj.g_iScaledImageHeight);\r\n\r\n\t\t\tnavCtx.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\t\t\tnavCtx.fill();\r\n\t\t\tnavCtx.clearRect(visibleStartPoint_x, visibleStartPoint_y, visibleDist_x, visibleDist_y);\r\n\r\n\t\t\t// Resize the separation and checklist items following the nav canvas update.\r\n\t\t\tresizeSeparationListItems();\r\n\t\t\treziseChecklistItems();\r\n\t\t}\r\n\r\n\t\tvar oRequestedImageObject = new ImageObject();\r\n\t\toRequestedImageObject.Width = requestedImageObjW;\r\n\t\toRequestedImageObject.Height = requestedImageObjH;\r\n\r\n\t\tvar oUserImageObject = new ImageObject();\r\n\t\toUserImageObject.Width = userImageObjW;\r\n\t\toUserImageObject.Height = userImageObjH;\r\n\r\n\t\tvar oCompareImageObject = new ImageObject();\r\n\t\toCompareImageObject.Width = (compareImageObjW > 0 ? compareImageObjW : 0);\r\n\t\toCompareImageObject.Height = (compareImageObjH > 0 ? compareImageObjH : 0);\r\n\r\n\t\tvar oScaledImageObject = new ImageObject();\r\n\t\toScaledImageObject.Width = scaledImageObjW;\r\n\t\toScaledImageObject.Height = scaledImageObjH;\r\n\r\n\t\tvar oImagePercentages = new ImageDimensions();\r\n\t\toImagePercentages.MinX = imageStart_x;\r\n\t\toImagePercentages.MinY = imageStart_y;\r\n\t\toImagePercentages.MaxX = imageEnd_x;\r\n\t\toImagePercentages.MaxY = imageEnd_y;\r\n\r\n\t\tvar oArtworkViewerImageBox = new ImageBox();\r\n\t\toArtworkViewerImageBox.RequestedApproval = this.g_oDoc.documentId;\r\n\t\toArtworkViewerImageBox.RequestedPage = this.g_iCurrentPage;\r\n\t\toArtworkViewerImageBox.RequestedImageName = this.g_oDoc.documentName;\r\n\t\toArtworkViewerImageBox.RequestedImageType = this.g_oDoc.documentType;\r\n\t\toArtworkViewerImageBox.RequestedImageObject = oRequestedImageObject;\r\n\t\toArtworkViewerImageBox.ImagePercentages = oImagePercentages;\r\n\t\toArtworkViewerImageBox.UserImageObject = oUserImageObject;\r\n\t\toArtworkViewerImageBox.CompareImageObject = oCompareImageObject;\r\n\t\toArtworkViewerImageBox.ScaledImageObject = oScaledImageObject;\r\n\t\toArtworkViewerImageBox.OriginalResolution = this.g_oDoc.pages[this.g_iCurrentPage - 1].documentResolutionPPI;\r\n\t\toArtworkViewerImageBox.CompareOffsetX = (compareOffset_x > 0 ? compareOffset_x : 0);\r\n\t\toArtworkViewerImageBox.CompareOffsetY = (compareOffset_y > 0 ? compareOffset_y : 0);\r\n\t\toArtworkViewerImageBox.VisibleCompareOffsetX = (visibleCompareOffset_x > 0 ? visibleCompareOffset_x : 0);\r\n\t\toArtworkViewerImageBox.VisibleCompareOffsetY = (visibleCompareOffset_y > 0 ? visibleCompareOffset_y : 0);\r\n\t\toArtworkViewerImageBox.CompareRotationDegrees = iCompareRotation;\r\n\t\toArtworkViewerImageBox.VisibleSeparations = $.grep(this.g_oaImages, function (img) { return img.Visible; });\r\n\r\n\t\treturn oArtworkViewerImageBox;\r\n\t}\r\n\r\n\tCanvas.prototype.rotate = function (x, y, mid_x, mid_y, a) {\r\n\r\n\t\t// Get the cos and sin.\r\n\t\tvar cos = Math.cos;\r\n\t\tvar sin = Math.sin;\r\n\r\n\t\t// Convert the angle to radians.\r\n\t\tvar angle = a * Math.PI / 180;\r\n\r\n\t\t// Subtract midpoints, so that midpoint is translated to origin and add it in the end again.\r\n\t\tvar rotated_x = (x - mid_x) * cos(angle) - (y - mid_y) * sin(angle) + mid_x;\r\n\t\tvar rotated_y = (x - mid_x) * sin(angle) + (y - mid_y) * cos(angle) + mid_y;\r\n\r\n\t\t// Return the rotated co-ordinates.\r\n\t\treturn {rotated_x: rotated_x, rotated_y: rotated_y};\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the selected page.\r\n\t */\r\n\tCanvas.prototype.changeCurrentPage = function () {\r\n\r\n\t\t// Update the page number.\r\n\t\t$(\"#divPageSelectCounter\").text(this.g_iCurrentPage + \"/\" + this.g_oDoc.pages.length);\r\n\r\n\t\t// If this is the main canvas.\r\n if (this.g_bMainCanvas) {\r\n\r\n // In case there are no annotations, manually set the cursor style\r\n $(\"AnnotationViewer\").css(\"cursor\", \"default\");\r\n g_oAnnotations.g_szPrevCursorStyle = \"default\";\r\n\r\n\t\t\t// Update the page number.\r\n\t\t\t$(\"#divPageSelectCounter\").text(this.g_iCurrentPage + \"/\" + this.g_oDoc.pages.length);\r\n\r\n\t\t\t// Show or hide the buttons.\r\n\t\t\tif (this.g_iCurrentPage === 1) {\r\n\t\t\t\t$(\"#btnPageBack\").attr(\"src\", \"img/Last-Page_disabled_48.png\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t$(\"#btnPageBack\").attr(\"src\", \"img/Last-Page_blue_48.png\");\r\n\t\t\t}\r\n\t\t\tif (this.g_iCurrentPage === this.g_oDoc.pages.length) {\r\n\t\t\t\t$(\"#btnPageForward\").attr(\"src\", \"img/Next-Page_disabled_48.png\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t$(\"#btnPageForward\").attr(\"src\", \"img/Next-Page_blue_48.png\");\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update the annotation canvas.\r\n\t\tthis.g_oAnnotationCanvas.g_oContext.clearRect(\r\n\t\t\t0,\r\n\t\t\t0,\r\n\t\t\tthis.g_oAnnotationCanvas.g_oCanvas.width,\r\n\t\t\tthis.g_oAnnotationCanvas.g_oCanvas.height\r\n\t\t);\r\n\r\n\t\t// Clear the nav canvas image if available.\r\n\t\tif (this.g_oNavCanvasObj != null) {\r\n\t\t\tthis.g_oNavCanvasObj.g_oImage = {};\r\n\t\t}\r\n\r\n\t\t// Get the index of the approval document control.\r\n\t\tvar iControlIndex = comboControl_GetControlById(\"approvalNameComboControl\", true);\r\n\r\n\t\t// If this is not the main canvas.\r\n\t\tif (!this.g_bMainCanvas) {\r\n\r\n\t\t\t// Get the index of the compare document control.\r\n\t\t\tiControlIndex = comboControl_GetControlById(\"approvalCompareComboControl\", true);\r\n\t\t}\r\n\r\n\t\t// Get the index of the approval document.\r\n\t\tvar iDocumentIndex = comboControl_GetDocumentById(iControlIndex, this.g_oDoc.documentId, true);\r\n\r\n\t\t// Get the index of the approval page.\r\n\t\tvar iPageIndex = -1;\r\n\t\tif (this.g_oDoc.pages.length > 1) {\r\n\r\n\t\t\t// Get the id of the currently selected page.\r\n\t\t\tvar iPageId = 0;\r\n\r\n\t\t\t// Loop through each of the document pages.\r\n\t\t\tfor (var i = 0; i < this.g_oDoc.pages.length; i++) {\r\n\r\n\t\t\t\t// If this is the current page.\r\n\t\t\t\tif (this.g_oDoc.pages[i].documentPageNumber == this.g_iCurrentPage) {\r\n\r\n\t\t\t\t\t// Extract the id of the current page.\r\n\t\t\t\t\tiPageId = this.g_oDoc.pages[i].documentPageId;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Get the index of the approval page.\r\n\t\t\tiPageIndex = comboControl_GetPageById(iControlIndex, iDocumentIndex, iPageId, true);\r\n\t\t}\r\n\r\n\t\t// validate that we have a document index.\r\n\t\tif (iDocumentIndex != undefined) {\r\n\t\t\t// Set the current document and page as the selected control item.\r\n\t\t\tcomboControl_SelectOption(iControlIndex, iDocumentIndex, iPageIndex, true);\r\n\t\t}\r\n\t\telse {\r\n\t\t\tg_oGreenlightMessages.displayErrorBubble(g_oViewer.c_szInvalidDocument);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Clear the canvas image.\r\n\t */\r\n\tCanvas.prototype.clearImgData = function () {\r\n\t\tthis.g_oImgData = undefined;\r\n\t};\r\n\r\n\t/**\r\n\t * Starts the drag event.\r\n\t * @param {event} event - The click event.\r\n\t */\r\n\tCanvas.prototype.dragInitiate = function (event, oSyncCanvas) {\r\n\t\tvar coords = getClickCoords(event, this);\r\n\r\n\t\t// Set that the current canvas is being dragged.\r\n\t\tthis.g_bIsDragging = true;\r\n\r\n\t\t// If we have any sync canvas, set that these are being dragged.\r\n\t\tfor (var i = 0; i < oSyncCanvas.length; i++) {\r\n\t\t\toSyncCanvas[i].g_bIsDragging = true;\r\n\t\t}\r\n\r\n\t\tthis.g_iOrigin_x = coords[0];\r\n\t\tthis.g_iOrigin_y = coords[1];\r\n\t\tthis.g_iCurrOffset_x = this.g_iDragOffset_x;\r\n\t\tthis.g_iCurrOffset_y = this.g_iDragOffset_y;\r\n\r\n\t\tvar oArtworkCanvas = this;\r\n var oAnnotationCanvas = this.g_oAnnotationCanvas;\r\n\r\n\t\tchangeCanvasFunction(\"#\" + oAnnotationCanvas.g_szCanvasId, 'pointermove', function (event) {\r\n\t\t\toArtworkCanvas.dragRedraw(event, oSyncCanvas);\r\n\t\t});\r\n\r\n\t\tchangeCanvasFunction(\"#\" + oAnnotationCanvas.g_szCanvasId, 'pointerup', function (event) {\r\n oArtworkCanvas.dragDiscontinue(true, oSyncCanvas);\r\n\r\n changeCanvasFunction(\"#\" + oAnnotationCanvas.g_szCanvasId, 'pointermove.annotationUI', function (event) {\r\n AnnotationAction.prototype.mouseMove(event, oArtworkCanvas, oAnnotationCanvas);\r\n });\r\n\t\t});\r\n\t};\r\n\r\n\t/**\r\n\t * End of the drag event.\r\n\t * @param {bool} bRedraw - Whether to redraw or not.\r\n\t * @param {object} oSyncCanvas - List of comparison canvases.\r\n\t */\r\n\tCanvas.prototype.dragDiscontinue = function (bRedraw, oSyncCanvas) {\r\n\r\n $(\".annotationViewer\").off(\"pointermove\");\r\n\r\n this.g_bIsDragging = false;\r\n\t\tthis.redraw(bRedraw);\r\n\r\n\t\t// If we have any sync canvas.\r\n\t\tfor (var i = 0; i < oSyncCanvas.length; i++) {\r\n\t\t\toSyncCanvas[i].g_bIsDragging = false;\r\n\t\t\toSyncCanvas[i].redraw(bRedraw);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Moves the offsets as the user drags. Depends on rotation.\r\n\t * @param event - The drag event.\r\n\t */\r\n\tCanvas.prototype.dragRedraw = function (event, oSyncCanvas) {\r\n\t\tvar coords, x, y;\r\n\t\tcoords = getClickCoords(event, this);\r\n\t\tx = coords[0];\r\n\t\ty = coords[1];\r\n\t\t\r\n\t\t// Have we stayed within bounds of canvas, using the margin.\r\n\t\tvar iMargin = this.c_iMargin;\r\n\t\tif ((x < this.g_oCanvas.width - iMargin && x > iMargin) && (y < this.g_oCanvas.height - iMargin && y > iMargin)) {\r\n\t\t\tswitch (this.g_iRotDegrees) {\r\n\t\t\t\tcase 90:\r\n\t\t\t\t\tthis.g_iDragOffset_x = (this.g_iOrigin_y - y) + this.g_iCurrOffset_x;\r\n\t\t\t\t\tthis.g_iDragOffset_y = -(this.g_iOrigin_x - x) + this.g_iCurrOffset_y;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 180:\r\n\t\t\t\t\tthis.g_iDragOffset_x = -(this.g_iOrigin_x - x) + this.g_iCurrOffset_x;\r\n\t\t\t\t\tthis.g_iDragOffset_y = -(this.g_iOrigin_y - y) + this.g_iCurrOffset_y;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 270:\r\n\t\t\t\t\tthis.g_iDragOffset_x = -(this.g_iOrigin_y - y) + this.g_iCurrOffset_x;\r\n\t\t\t\t\tthis.g_iDragOffset_y = (this.g_iOrigin_x - x) + this.g_iCurrOffset_y;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tthis.g_iDragOffset_x = (this.g_iOrigin_x - x) + this.g_iCurrOffset_x;\r\n\t\t\t\t\tthis.g_iDragOffset_y = (this.g_iOrigin_y - y) + this.g_iCurrOffset_y;\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\t// If not within bounds, halt the drag.\r\n\t\telse {\r\n\t\t\tthis.dragDiscontinue(false, oSyncCanvas);\r\n\t\t}\r\n\r\n\t\t// Update the artwork with the pan.\r\n\t\tthis.g_iCenterShift_x += this.g_iDragOffset_x;\r\n\t\tthis.g_iCenterShift_y += this.g_iDragOffset_y;\r\n\t\tthis.redraw(true);\r\n\r\n\t\t// If we have any sync canvas, sync the pan on these canvas.\r\n\t\tfor (var i = 0; i < oSyncCanvas.length; i++) {\r\n\t\t\toSyncCanvas[i].synchroniseZoomPanProperties(this);\r\n\t\t\toSyncCanvas[i].redraw(true);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Draws a solid background on the canvas.\r\n\t * @param {string} colour - The colour to draw the background in, starting with a #.\r\n\t */\r\n\tCanvas.prototype.drawBackground = function (colour) {\r\n\r\n\t\t// Draw a solid background in the chosen colour.\r\n\t\tthis.g_oContext.beginPath();\r\n\t\tthis.g_oContext.rect(\r\n\t\t\tthis.g_iCenterShift_x,\r\n\t\t\tthis.g_iCenterShift_y,\r\n\t\t\tMath.max(this.g_iScaledImageWidth, this.g_iCompareImage_x),\r\n\t\t\tMath.max(this.g_iScaledImageHeight, this.g_iCompareImage_y)\r\n\t\t);\r\n\t\tthis.g_oContext.fillStyle = colour;\r\n\t\tthis.g_oContext.closePath();\r\n\t\tthis.g_oContext.fill();\r\n\t};\r\n\r\n\t/**\r\n\t * This function draws the artwork images to canvas\r\n\t * @param {bool} getPNGData - is a switch to let us specify whether we are calling this function after returning new images from the server\r\n\t * If false the implication is that we're only doing an incremental draw for something like a zoom animation\r\n\t * We don't need to bother with the overhead of the putImageData in that case\r\n\t */\r\n\tCanvas.prototype.drawImages = function (getPNGData) {\r\n\r\n\t\t// Get the ratio of the canvas.\r\n\t\tthis.getRatio();\r\n\r\n\t\t// If we have an annotation canvas, get the ratio of the annotation canvas.\r\n\t\tif (this.g_oAnnotationCanvas != null) {\r\n\t\t\tthis.g_oAnnotationCanvas.getRatio();\r\n\t\t}\r\n\r\n\t\t// Erase any previously drawn content.\r\n\t\tthis.g_oContext.clearRect(0, 0, this.g_oCanvas.width, this.g_oCanvas.height);\r\n\r\n\t\t// If this is a PDF image.\r\n\t\tif (this.hasSeparations()) {\r\n\r\n\t\t\t// Outline the width and height to draw the image.\r\n\t\t\tvar iScaledImageWidth = this.g_iScaledImageWidth;\r\n\t\t\tvar iScaledImageHeight = this.g_iScaledImageHeight;\r\n\r\n\t\t\t// Determine the compare rotation of the image.\r\n\t\t\tif (g_oCompare.getCompareRotation(this) == 90 || g_oCompare.getCompareRotation(this) == 270) {\r\n\t\t\t\tiScaledImageWidth = this.g_iScaledImageHeight;\r\n\t\t\t\tiScaledImageHeight = this.g_iScaledImageWidth;\r\n\t\t\t}\r\n\r\n\t\t\t// Draw the image.\r\n\t\t\tthis.g_oContext.drawImage(\r\n\t\t\t\tthis.g_oImage,\r\n\t\t\t\tthis.g_iCenterShift_x,\r\n\t\t\t\tthis.g_iCenterShift_y,\r\n\t\t\t\tMath.max(iScaledImageWidth, this.g_iCompareImage_x),\r\n\t\t\t\tMath.max(iScaledImageHeight, this.g_iCompareImage_y)\r\n\t\t\t);\r\n\t\t}\r\n\t\t// If this is not a PDF image.\r\n\t\telse {\r\n\r\n\t\t\t// Draw a solid background for the empty space.\r\n\t\t\tvar szBackgroundColour = (this.isSVGApproval() ? \"#FFFFFF\" : \"#818783\"); // Determine the background colour based on the document type.\r\n\t\t\tthis.drawBackground(szBackgroundColour);\r\n\r\n\t\t\t// Draw the image.\r\n\t\t\tthis.g_oContext.drawImage(\r\n\t\t\t\tthis.g_oImage,\r\n\t\t\t\tthis.g_iCenterShift_x,\r\n\t\t\t\tthis.g_iCenterShift_y,\r\n\t\t\t\tthis.g_iScaledImageWidth,\r\n\t\t\t\tthis.g_iScaledImageHeight\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\t// Then we will re-overlay the saved image data. This provides a preview when panning before the server returns the new image.\r\n\t\tif (this.g_oImgData && this.g_iZoomLevel !== 1 && getPNGData && !this.g_bIsAnimating) {\r\n\t\t\tswitch (this.g_iRotDegrees) {\r\n\t\t\t\tcase 90:\r\n\t\t\t\t\tthis.g_oContext.putImageData(this.g_oImgData, -(this.g_iTemp2DragOffset_y - this.g_iDragOffset_y), (this.g_iTemp2DragOffset_x - this.g_iDragOffset_x));\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 180:\r\n\t\t\t\t\tthis.g_oContext.putImageData(this.g_oImgData, -(this.g_iTemp2DragOffset_x - this.g_iDragOffset_x), -(this.g_iTemp2DragOffset_y - this.g_iDragOffset_y));\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 270:\r\n\t\t\t\t\tthis.g_oContext.putImageData(this.g_oImgData, (this.g_iTemp2DragOffset_y - this.g_iDragOffset_y), -(this.g_iTemp2DragOffset_x - this.g_iDragOffset_x));\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tthis.g_oContext.putImageData(this.g_oImgData, (this.g_iTemp2DragOffset_x - this.g_iDragOffset_x), (this.g_iTemp2DragOffset_y - this.g_iDragOffset_y));\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets a new image and draws it to the canvas.\r\n\t * @param {bool} bGetNewImageCallType - Determines what the call type is.\r\n\t * @param {bool} bIsAlignmentUpdate - Determines if the call is an alignment update.\r\n\t */\r\n\tCanvas.prototype.getimagePNGData = function (bGetNewImageCallType, bIsAlignmentUpdate) {\r\n\r\n\t\t// If its a separation lets call the PDF version.\r\n\t\tif (this.hasSeparations()) {\r\n\t\t\tthis.getImagePngDataPDF(bGetNewImageCallType, bIsAlignmentUpdate);\r\n\t\t}\r\n\t\t// If this is an SVG document, update the SVG canvas.\r\n\t\telse if (this.isSVGApproval()) {\r\n\t\t\tthis.updateSVGCanvas(bGetNewImageCallType);\r\n\t\t}\r\n\t\t// If this is any other type of document.\r\n\t\telse {\r\n\r\n\t\t\t// If this is an image approval.\r\n\t\t\tvar szSrc = \"/ViewImage/GetImage?threeDThumbnailPath=&documentId=\" + this.g_oDoc.documentId + \"&pageNumber=0&sessionId=\" + g_szSessionId + \"&thumb=0&fileName=\" + this.g_oDoc.documentId + \"&fileExtension=png\";\r\n\t\t\tvar oCurrentCanvas = this;\r\n\r\n\t\t\t// If the image has not been setup yet.\r\n\t\t\tif (this.g_oImage.src === undefined) {\r\n\r\n\t\t\t\t// Create a new Image.\r\n\t\t\t\tthis.g_oImage = new Image();\r\n\r\n\t\t\t\tthis.g_oImage.src = szSrc;\r\n\t\t\t\tthis.g_oImage.onload = function () {\r\n\t\t\t\t\tg_oViewer.finalizeRenderingImage();\r\n\t\t\t\t\toCurrentCanvas.redraw(true);\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tthis.g_oImage.src = szSrc;\r\n\t\t\t\tthis.g_oImage.onload = function () {\r\n\t\t\t\t\toCurrentCanvas.redraw(true);\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets a new PDF image from the server.\r\n\t * @param {bool} bGetNewImageCallType - Determines the call type.\r\n\t * @param {bool} bIsAlignmentUpdate - Determines if the call is an alignment update.\r\n\t */\r\n\tCanvas.prototype.getImagePngDataPDF = function (bGetNewImageCallType, bIsAlignmentUpdate) {\r\n\r\n\t\t// If we are not animating or dragging.\r\n\t\tif (!this.g_bIsAnimating || !this.g_bIsDragging) {\r\n\r\n\t\t\t// Since we're getting a new image, clear the (if any) real-time rendered image.\r\n\t\t\tthis.clearRealtimeRenderImage();\r\n\r\n\t\t\t// Fade out the loading shine.\r\n\t\t\t$(\".shine\").fadeIn(200);\r\n\r\n\t\t\t// Get the image request.\r\n\t\t\tvar oImageRequest = this.getImageRequest(bGetNewImageCallType);\r\n\r\n\t\t\t// Set the session id of the request.\r\n\t\t\toImageRequest.SessionId = g_szSessionId;\r\n\r\n\t\t\t// Set if this is a new image call type.\r\n\t\t\toImageRequest.IsGetNewImageCallType = bGetNewImageCallType;\r\n\r\n\t\t\t// Get a new image request number for the request.\r\n\t\t\tvar iImageRequestId = Math.random();\r\n\r\n\t\t\t// If this is a full new image request.\r\n\t\t\tif (oImageRequest.IsGetNewImageCallType) {\r\n\r\n\t\t\t\t// Set the full image request id.\r\n\t\t\t\tthis.g_iFullImageRequestId = iImageRequestId;\r\n\t\t\t}\r\n\t\t\t// If this is a partial image request.\r\n\t\t\telse {\r\n\r\n\t\t\t\t// Set the partial image request id.\r\n\t\t\t\tthis.g_iPartialImageRequestId = iImageRequestId;\r\n\t\t\t}\r\n\r\n\t\t\t// Prepare the JSON.\r\n\t\t\tvar oJSON = {\r\n\t\t\t\tSessionId: g_szSessionId,\r\n\t\t\t\toImageRequest: oImageRequest,\r\n\t\t\t\tbGetImage: bGetNewImageCallType\r\n\t\t\t};\r\n\r\n\t\t\t// Post to the server.\r\n\t\t\tvar _this = this;\r\n\t\t\treturn $.post({\r\n\t\t\t\turl: \"GreenlightSvr/imagingEngine\",\r\n\t\t\t\tdata: JSON.stringify(oJSON),\r\n\t\t\t\tcontentType: \"application/json; charset=utf-8\",\r\n\t\t\t\tcache: false,\r\n\t\t\t\tdataType: \"json\",\r\n\t\t\t\tsuccess: function (oResponse) {\r\n\r\n\t\t\t\t\t// If we are still on the same approval document and page.\r\n\t\t\t\t\tif (oImageRequest.ArtworkViewerImageBox.RequestedApproval == _this.g_oDoc.documentId && oImageRequest.ArtworkViewerImageBox.RequestedPage == _this.g_iCurrentPage) {\r\n\r\n\t\t\t\t\t\t// If this is the latest request and we are in a suitable position to redraw the images.\r\n\t\t\t\t\t\tif ((oImageRequest.IsGetNewImageCallType && _this.g_iFullImageRequestId == iImageRequestId) || (!oImageRequest.IsGetNewImageCallType && _this.g_iPartialImageRequestId == iImageRequestId && !_this.g_bIsAnimating && !_this.g_bIsDragging)) {\r\n\r\n\t\t\t\t\t\t\t// If the image request was successful.\r\n\t\t\t\t\t\t\tif (oResponse.Success && oResponse.Errors.length === 0) {\r\n\t\t\t\t\t\t\t\t_this.getImagePngDataPDF_CH(oResponse.Contents, oImageRequest, iImageRequestId, bIsAlignmentUpdate);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t// If the image request was un-successful.\r\n\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\tg_oGreenlightMessages.displayErrorBubble(displayErrorContentHTML(oResponse.Errors));\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t},\r\n\t\t\t\terror: function () {\r\n\r\n\t\t\t\t\t// Fade out the shine.\r\n\t\t\t\t\t$(\".shine\").fadeOut(200);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Call-back when we have a new image returned from the server.\r\n\t * @param {object} oResponseContents - The returned image details.\r\n\t * @param {object} oImageRequest - The original image request.\r\n\t * @param {object} iImageRequestId - The original image request id.\r\n\t * @param {bool} bIsAlignmentUpdate - Determines if the call is an alignment update.\r\n\t */\r\n\tCanvas.prototype.getImagePngDataPDF_CH = function (oResponseContents, oImageRequest, iImageRequestId, bIsAlignmentUpdate) {\r\n\r\n\t\t// Extract the image details.\r\n\t\tvar oImageDetails = JSON.parse(oResponseContents);\r\n\t\tvar oCurrentCanvas = this;\r\n\t\tvar bGetNewImageCallType = oImageRequest.IsGetNewImageCallType;\r\n\t\tvar oVisibleImageSeparations = oImageRequest.ArtworkViewerImageBox.VisibleSeparations;\r\n\r\n\t\t// Calculate the drawing image positions.\r\n\t\tvar iImageDrawStart_x = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_x, oCurrentCanvas.g_iCenterShift_x + (oImageRequest.ArtworkViewerImageBox.ImagePercentages.MinX * oCurrentCanvas.g_iScaledImageWidth)));\r\n\t\tvar iImageDrawStart_y = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_y, oCurrentCanvas.g_iCenterShift_y + (oImageRequest.ArtworkViewerImageBox.ImagePercentages.MinY * oCurrentCanvas.g_iScaledImageHeight)));\r\n\t\tvar iImageWidth = Math.round(oCurrentCanvas.g_iScaledImageWidth - (oCurrentCanvas.g_iScaledImageWidth * (oImageRequest.ArtworkViewerImageBox.ImagePercentages.MinX + (1 - oImageRequest.ArtworkViewerImageBox.ImagePercentages.MaxX))));\r\n\t\tvar iImageHeight = Math.round(oCurrentCanvas.g_iScaledImageHeight - (oCurrentCanvas.g_iScaledImageHeight * (oImageRequest.ArtworkViewerImageBox.ImagePercentages.MinY + (1 - oImageRequest.ArtworkViewerImageBox.ImagePercentages.MaxY))));\r\n\r\n\t\t// If we are using a compare mode.\r\n\t\tif (g_oViewer.g_oCompareMode != eCompareMode.NoCompare) {\r\n\r\n\t\t\t// Get the compare offset if black margins have not been added.\r\n\t\t\tvar compareOffset_x = 0, compareOffset_y = 0;\r\n\t\t\tif (this.g_iZoomLevel != 1 && !bGetNewImageCallType) {\r\n\t\t\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oCurrentCanvas);\r\n\t\t\t\tcompareOffset_x = co.x;\r\n\t\t\t\tcompareOffset_y = co.y;\r\n\t\t\t}\r\n\r\n\t\t\t// Get the compare rotation of the canvas if black margins have not been added.\r\n\t\t\tvar iCompareRotation = 0;\r\n\t\t\tif (this.g_iZoomLevel != 1 && !bGetNewImageCallType) {\r\n\t\t\t\tiCompareRotation = g_oCompare.getCompareRotation(this);\r\n\t\t\t}\r\n\r\n\t\t\t// Get the image starting positions.\r\n\t\t\tvar imageDimensionsStart_x = oImageRequest.ArtworkViewerImageBox.ImagePercentages.MinX;\r\n\t\t\tvar imageDimensionsStart_y = oImageRequest.ArtworkViewerImageBox.ImagePercentages.MinY;\r\n\r\n\t\t\t// Get the image ending positions.\r\n\t\t\tvar imageDimensionsEnd_x = oImageRequest.ArtworkViewerImageBox.ImagePercentages.MaxX;\r\n\t\t\tvar imageDimensionsEnd_y = oImageRequest.ArtworkViewerImageBox.ImagePercentages.MaxY;\r\n\r\n\t\t\t// Calculate the positions based on the compare rotation.\r\n\t\t\tswitch (iCompareRotation) {\r\n\r\n\t\t\t\tcase 90:\r\n\t\t\t\t\t// Calculate the drawing image positions.\r\n\t\t\t\t\tiImageDrawStart_x = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_x / g_oViewer.c_iDPI, oCurrentCanvas.g_iCenterShift_x + compareOffset_x + (Math.abs(1 - imageDimensionsEnd_y) * oCurrentCanvas.g_iScaledImageHeight)));\r\n\t\t\t\t\tiImageDrawStart_y = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_y, oCurrentCanvas.g_iCenterShift_y + compareOffset_y + (imageDimensionsStart_x * oCurrentCanvas.g_iScaledImageWidth)));\r\n\r\n\t\t\t\t\t// Calculate the drawing width and height.\r\n\t\t\t\t\tiImageWidth = Math.round((imageDimensionsEnd_y - imageDimensionsStart_y) * oCurrentCanvas.g_iScaledImageHeight);\r\n\t\t\t\t\tiImageHeight = Math.round((imageDimensionsEnd_x - imageDimensionsStart_x) * oCurrentCanvas.g_iScaledImageWidth);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 180:\r\n\r\n\t\t\t\t\t// Calculate the drawing image positions.\r\n\t\t\t\t\tiImageDrawStart_x = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_x, oCurrentCanvas.g_iCenterShift_x + compareOffset_x + (Math.abs(1 - imageDimensionsEnd_x) * oCurrentCanvas.g_iScaledImageWidth)));\r\n\t\t\t\t\tiImageDrawStart_y = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_y, oCurrentCanvas.g_iCenterShift_y + compareOffset_y + (Math.abs(1 - imageDimensionsEnd_y) * oCurrentCanvas.g_iScaledImageHeight)));\r\n\r\n\t\t\t\t\t// Calculate the drawing width and height.\r\n\t\t\t\t\tiImageWidth = oImageRequest.ArtworkViewerImageBox.CompareImageObject.Width;\r\n\t\t\t\t\tiImageHeight = oImageRequest.ArtworkViewerImageBox.CompareImageObject.Height;\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 270:\r\n\r\n\t\t\t\t\t// Calculate the drawing image positions.\r\n\t\t\t\t\tiImageDrawStart_x = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_x, oCurrentCanvas.g_iCenterShift_x + compareOffset_x + (imageDimensionsStart_y * oCurrentCanvas.g_iScaledImageHeight)));\r\n\t\t\t\t\tiImageDrawStart_y = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_y, oCurrentCanvas.g_iCenterShift_y + compareOffset_y + (Math.abs(1 - imageDimensionsEnd_x) * oCurrentCanvas.g_iScaledImageWidth)));\r\n\r\n\t\t\t\t\t// Calculate the drawing width and height.\r\n\t\t\t\t\tiImageWidth = Math.round((imageDimensionsEnd_y - imageDimensionsStart_y) * oCurrentCanvas.g_iScaledImageHeight);\r\n\t\t\t\t\tiImageHeight = Math.round((imageDimensionsEnd_x - imageDimensionsStart_x) * oCurrentCanvas.g_iScaledImageWidth);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tdefault:\r\n\r\n\t\t\t\t\t// Calculate the drawing image positions.\r\n\t\t\t\t\tiImageDrawStart_x = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_x, oCurrentCanvas.g_iCenterShift_x + compareOffset_x + (imageDimensionsStart_x * oCurrentCanvas.g_iScaledImageWidth)));\r\n\t\t\t\t\tiImageDrawStart_y = Math.round(Math.max(oCurrentCanvas.g_iCenterShift_y, oCurrentCanvas.g_iCenterShift_y + compareOffset_y + (imageDimensionsStart_y * oCurrentCanvas.g_iScaledImageHeight)));\r\n\r\n\t\t\t\t\t// Calculate the drawing width and height.\r\n\t\t\t\t\tiImageWidth = oImageRequest.ArtworkViewerImageBox.CompareImageObject.Width;\r\n\t\t\t\t\tiImageHeight = oImageRequest.ArtworkViewerImageBox.CompareImageObject.Height;\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar oImage = new Image();\r\n\t\toImage.src = oImageDetails.ImageData;\r\n\r\n\t\t// Log the returned image if required.\r\n\t\tif (this.g_bLogImages) {\r\n\t\t\tvar w = window.open(\"\", \"_blank\", \"toolbar=0,location=0,menubar=0\");\r\n\t\t\tw.document.write(\"
\");\r\n\t\t\tw.document.write(oImage.outerHTML);\r\n\t\t\tw.document.write(\" |
\");\r\n\t\t}\r\n\r\n\t\t// Determine if this is an inital image render.\r\n\t\tvar bIsInitialImageRender = (oCurrentCanvas.g_oImage.src === undefined || oCurrentCanvas.g_oImage.src === \"\");\r\n\r\n\t\toCurrentCanvas.g_iCurrentResolution = oImageDetails.CurrentResolution;\r\n\t\toCurrentCanvas.g_szRealtimeRenderReference = oImageDetails.RealtimeRenderReference;\r\n\r\n\t\t// If this is the first time we are loading the image into the canvas OR we have deliberately asked for the return to overwrite the image SRC (e.g. when Separations are required).\r\n\t\tif (bIsInitialImageRender || bGetNewImageCallType) {\r\n\t\t\tif (bIsInitialImageRender) {\r\n\t\t\t\tg_oViewer.finalizeRenderingImage();\r\n\t\t\t\t// If this is the first time the document have been displayed, set the original resolution.\r\n\t\t\t\tif (oCurrentCanvas.hasSeparations()) {\r\n\t\t\t\t\toCurrentCanvas.g_iOriginalResolution = oCurrentCanvas.g_oDoc.pages[oCurrentCanvas.g_iCurrentPage - 1].documentResolutionPPI;\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\t// Set the actual resolution of the artwork based off the resolution of the separation images.\r\n\t\t\t\t\toCurrentCanvas.g_iOriginalResolution = oCurrentCanvas.g_oaImages[0].HeightResolution;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\toCurrentCanvas.g_oImage = oImage;\r\n\r\n\t\t\t// Update the navigation canvas for the first time.\r\n\t\t\tif (oCurrentCanvas.g_bMainCanvas && oCurrentCanvas.hasSeparations() && oCurrentCanvas.g_oNavCanvasObj != null && oCurrentCanvas.g_oNavCanvasObj.g_oImage.src === undefined) {\r\n\t\t\t\toCurrentCanvas.g_oNavCanvasObj.g_oImage = new Image();\r\n\t\t\t\toCurrentCanvas.g_oNavCanvasObj.g_oImage.src = oImage.src;\r\n\t\t\t\toCurrentCanvas.g_oNavCanvasObj.g_iScaledImageWidth = Math.round(oCurrentCanvas.g_iScaledImageWidth);\r\n\t\t\t\toCurrentCanvas.g_oNavCanvasObj.g_iScaledImageHeight = Math.round(oCurrentCanvas.g_iScaledImageHeight);\r\n\r\n\t\t\t\toCurrentCanvas.g_oNavCanvasObj.g_oImage.onload = function () {\r\n\t\t\t\t\tif (oCurrentCanvas.g_oNavCanvasObj.g_oContext) {\r\n\t\t\t\t\t\toCurrentCanvas.g_oNavCanvasObj.g_oContext.drawImage(\r\n\t\t\t\t\t\t\toImage,\r\n\t\t\t\t\t\t\tiImageDrawStart_x,\r\n\t\t\t\t\t\t\tiImageDrawStart_y,\r\n\t\t\t\t\t\t\tiImageWidth,\r\n\t\t\t\t\t\t\tiImageHeight\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\t\t\t} // Finish updating Navigation canvas.\r\n\r\n\t\t\t// Update the canvas image.\r\n\t\t\toCurrentCanvas.g_oImage.onload = function () {\r\n\r\n\t\t\t\t// Only draw if this is the latest full image request.\r\n\t\t\t\tif (bGetNewImageCallType && oCurrentCanvas.g_iFullImageRequestId != iImageRequestId) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\t// Otherwise fade out the loading shine.\r\n\t\t\t\telse {\r\n\t\t\t\t\t$(\".shine\").fadeOut(200);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// If this is a new image call.\r\n\t\t\t\tif (bGetNewImageCallType) {\r\n\r\n\t\t\t\t\t// Called because we are going to draw a full image. This is normally because we have changed separations or are spinning up a compare canvas.\r\n\t\t\t\t\t// Call the zoomed image data if we are changing separation info as this prevents the low res whole canvas view overwriting the high res zoomed view.\r\n\t\t\t\t\tif (oCurrentCanvas.g_iZoomLevel !== 1) {\r\n\r\n\t\t\t\t\t\t// If this is an alignment update.\r\n\t\t\t\t\t\tif (bIsAlignmentUpdate) {\r\n\r\n\t\t\t\t\t\t\t// We need to redraw the full image before getting the zoomed image as the alignment may have caused the margins and size to have changed.\r\n\t\t\t\t\t\t\toCurrentCanvas.g_oContext.drawImage(\r\n\t\t\t\t\t\t\t\toImage,\r\n\t\t\t\t\t\t\t\toCurrentCanvas.g_iCenterShift_x,\r\n\t\t\t\t\t\t\t\toCurrentCanvas.g_iCenterShift_y,\r\n\t\t\t\t\t\t\t\toCurrentCanvas.g_iCompareImage_x,\r\n\t\t\t\t\t\t\t\toCurrentCanvas.g_iCompareImage_y\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Get the zoomed image.\r\n\t\t\t\t\t\toCurrentCanvas.getimagePNGData(false, false);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Redraw the full image.\r\n\t\t\t\t\telse {\r\n\r\n\t\t\t\t\t\t// Only draw if this is the latest request and we are in a suitable position to redraw the images.\r\n\t\t\t\t\t\tif (!g_oSeparations.MatchVisibleSeparations(oCurrentCanvas, oVisibleImageSeparations)) {\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Redraw the full image.\r\n\t\t\t\t\t\toCurrentCanvas.g_oContext.drawImage(\r\n\t\t\t\t\t\t\toImage,\r\n\t\t\t\t\t\t\tiImageDrawStart_x,\r\n\t\t\t\t\t\t\tiImageDrawStart_y,\r\n\t\t\t\t\t\t\tiImageWidth,\r\n\t\t\t\t\t\t\tiImageHeight\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\toCurrentCanvas.redraw(false, bIsInitialImageRender);\r\n\t\t\t};\r\n\t\t}\r\n\t\t// If this is an individual part of the canvas image.\r\n\t\telse {\r\n\t\t\toImage.onload = function () {\r\n\r\n\t\t\t\t// Only draw if this is the latest partial image request and we are in a suitable position to redraw the images.\r\n\t\t\t\tif (oCurrentCanvas.g_iPartialImageRequestId != iImageRequestId || oCurrentCanvas.g_bIsAnimating || oCurrentCanvas.g_bIsDragging || oCurrentCanvas.g_iZoomLevel == 1) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\t// Otherwise fade out the loading shine.\r\n\t\t\t\telse {\r\n\t\t\t\t\t$(\".shine\").fadeOut(200);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Draw the image to the correct location.\r\n\t\t\t\toCurrentCanvas.g_oContext.drawImage(\r\n\t\t\t\t\toImage,\r\n\t\t\t\t\tiImageDrawStart_x,\r\n\t\t\t\t\tiImageDrawStart_y,\r\n\t\t\t\t\tiImageWidth,\r\n\t\t\t\t\tiImageHeight\r\n\t\t\t\t);\r\n\r\n\t\t\t\toCurrentCanvas.g_oImgData = oCurrentCanvas.g_oContext.getImageData(0, 0, oCurrentCanvas.g_oCanvas.width, oCurrentCanvas.g_oCanvas.height);\r\n\t\t\t\toCurrentCanvas.g_iTemp2DragOffset_x = oCurrentCanvas.g_iDragOffset_x;\r\n\t\t\t\toCurrentCanvas.g_iTemp2DragOffset_y = oCurrentCanvas.g_iDragOffset_y;\r\n\t\t\t\toCurrentCanvas.redraw(false, bIsInitialImageRender);\r\n\t\t\t};\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Requests the server to get the images to display on the canvas and adds the to the image array.\r\n\t * @param {bool} bUseCompareCallback - Whether to use the callback.\r\n\t * @param {double} requestId - The request id.\r\n\t * @param {bool} callAsynchronously - If the request should call async default true.\r\n\t */\r\n\tCanvas.prototype.getCanvasFiles = function (bUseCompareCallback, requestId, callAsynchronously) {\r\n\t\tif (typeof (callAsynchronously) == \"undefined\") {\r\n\t\t\tcallAsynchronously = true;\r\n\t\t}\r\n\t\t\r\n\t\t// If this is an svg document.\r\n\t\tif (this.isSVGApproval()) {\r\n\r\n\t\t\t// Use the svg loader to load the canvas files.\r\n\t\t\tg_oSVGLoader.loadSVGFile(this, this.g_oAnnotationCanvas, bUseCompareCallback, requestId);\r\n\t\t}\r\n\t\t// Otherwise load the canvas files from the server.\r\n\t\telse {\r\n\t\t\t// rather than alow a call back to occur we simply return out.\r\n\t\t\tif (this.g_oDoc.documentId == undefined || this.g_oDoc.documentId == 0) {\r\n\t\t\t\tg_oGreenlightMessages.displayErrorBubble(g_oViewer.c_szInvalidDocument);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Build up the JSON.\r\n\t\t\tvar oJSON = {\r\n\t\t\t\tSessionId: g_szSessionId,\r\n\t\t\t\tViewportWidth: this.g_oContainer.offsetWidth,\r\n\t\t\t\tDoc: deepCopyObject(this.g_oDoc),\r\n\t\t\t\tPageNumber: this.g_iCurrentPage\r\n\t\t\t};\r\n\r\n\t\t\t// Remove the pages from the copy of the doc object.\r\n\t\t\t// This will prevent us sending to much info to the server if\r\n\t\t\t// there are like 100+ pages as we only need the info from the document object.\r\n\t\t\tdelete oJSON.Doc.pages;\r\n\r\n\t\t\tvar oCanvas = this;\r\n\r\n\t\t\treturn $.post({\r\n\t\t\t\turl: \"GreenlightSvr/getCanvasFiles\",\r\n\t\t\t\tdata: JSON.stringify(oJSON),\r\n\t\t\t\tcontentType: \"application/json; charset=utf-8\",\r\n\t\t\t\tdataType: \"json\",\r\n\t\t\t\tcache: false,\r\n\t\t\t\tasync: callAsynchronously,\r\n\t\t\t\tsuccess: function (oResponse) {\r\n\r\n\t\t\t\t\tif (oResponse.Success && oResponse.Errors.length === 0) {\r\n\t\t\t\t\t\t// If we are using the compare callback.\r\n\t\t\t\t\t\tif (bUseCompareCallback) {\r\n\t\t\t\t\t\t\tg_oCompare.getCanvasFiles_CH(oCanvas, JSON.parse(oResponse.Contents), requestId);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// Otherwise use the default callback.\r\n\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\toCanvas.getCanvasFiles_CH(JSON.parse(oResponse.Contents));\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tg_oGreenlightMessages.displayErrorBubble(displayErrorContentHTML(oResponse.Errors));\r\n\t\t\t\t\t}\r\n\t\t\t\t},\r\n\t\t\t\terror: function (jqXhr, textStatus, errorThrown) {\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Adds the separations to the canvas images array.\r\n\t * @param {array} Files - Array of files from the server.\r\n\t */\r\n\tCanvas.prototype.getCanvasFiles_CH = function (Files) {\r\n\t\t// If this is an svg document, update the svg canvas instead.\r\n\t\tif (this.isSVGApproval()) {\r\n\t\t\tthis.updateSVGCanvas(true);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Populate the separation images.\r\n\t\tthis.populateSeparationImages(Files);\r\n\r\n\t\t// Get the ratio for this canvas.\r\n\t\tthis.getRatio();\r\n\r\n\t\t// If this canvas has an annotation canvas, get the ratio for the annotation canvas.\r\n\t\tif (this.g_oAnnotationCanvas != null) {\r\n\t\t\tthis.g_oAnnotationCanvas.getRatio();\r\n\t\t}\r\n\r\n\t\t// If this is the main canvas, setup the seperations div.\r\n\t\tif (this.g_bMainCanvas) {\r\n\r\n\t\t\t// If this is a PDF file then setup and show the separations div.\r\n\t\t\tg_oSeparations.SetupSeparationsDiv(this, true, []);\r\n\t\t}\r\n\t\t// If this is the compare canvas.\r\n\t\telse if (g_oCompare.g_oCompareViewer.g_iCanvasType == eCanvasType.Artwork) {\r\n\r\n\t\t\t// If both compare documents have separations.\r\n\t\t\tif (g_oCompare.g_oArtworkViewer.hasSeparations() && g_oCompare.g_oCompareViewer.hasSeparations()) {\r\n\r\n\t\t\t\t// Get the list of sync canvas from the compare module.\r\n\t\t\t\tvar oSyncCanvas = g_oCompare.getSyncCanvas(g_oViewer.g_oArtworkViewer);\r\n\r\n\t\t\t\t// Re-render the seperations.\r\n\t\t\t\tg_oSeparations.RenderSeparationElements(g_oViewer.g_oArtworkViewer, oSyncCanvas, []);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Populates the separation images.\r\n\t * @param {array} Files - The separation files.\r\n\t */\r\n\tCanvas.prototype.populateSeparationImages = function (Files) {\r\n\r\n\t\t// If this is an svg file, simply add the svg file to the list of images.\r\n\t\tif (this.isSVGApproval()) {\r\n\t\t\tthis.g_oaImages = [];\r\n\t\t\tthis.g_oaImages.push(Files);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Clear any existing separation images.\r\n\t\tthis.g_oaImages = [];\r\n\r\n\t\t// Loop through each of the files.\r\n\t\tfor (var i = 0; i < Files.length; i++) {\r\n\r\n\t\t\t// Extract the separation.\r\n\t\t\tvar oSeparation = Files[i];\r\n\r\n\t\t\t// Add the separation to the array of images.\r\n\t\t\tthis.g_oaImages.push(oSeparation);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the width and height of the image file that will be drawn to the canvas.\r\n\t */\r\n\tCanvas.prototype.getRatio = function () {\r\n\t\tvar hRatio, vRatio;\r\n\r\n\t\tthis.g_oCanvas.width = this.g_oContainer.offsetWidth * g_oViewer.c_iDPI;\r\n\t\tthis.g_oCanvas.height = this.g_oContainer.offsetHeight * g_oViewer.c_iDPI;\r\n\r\n\t\t// If this is not the nav canvas.\r\n\t\tif (this.g_oCanvas.id != \"navCanvas\" && this.g_oCanvas.id != \"navCanvasOverlay\") {\r\n\t\t\t$(this.g_oCanvas).css(\"width\", this.g_oContainer.offsetWidth);\r\n\t\t\t$(this.g_oCanvas.height).css(\"height\", this.g_oContainer.offsetHeight);\r\n\t\t}\r\n\r\n\t\t// We get the horizontal and vertical ratios and then find the min of both.\r\n\t\tif (this.g_iCanvasType == eCanvasType.Artwork) {\r\n\r\n\t\t\t// If we not are comparing, or one of the compare documents is 3D.\r\n\t\t\tif (g_oViewer.g_oCompareMode == eCompareMode.NoCompare || this.g_oCanvas.id == \"navCanvas\" || this.g_oCanvas.id == \"navCanvasOverlay\") {\r\n\r\n\t\t\t\t// Work out the horizontal and vertical ratio of the image.\r\n\t\t\t\t// Then the ratio that we'll use is the minimum of the two.\r\n\t\t\t\thRatio = (this.g_oCanvas.width - (this.c_iMargin * 2)) / (this.g_oaImages.length == 0 ? 1 : this.g_oaImages[0].ImageWidth) * this.g_iZoomLevel;\r\n\t\t\t\tvRatio = (this.g_oCanvas.height - (this.c_iMargin * 2)) / (this.g_oaImages.length == 0 ? 1 : this.g_oaImages[0].ImageHeight) * this.g_iZoomLevel;\r\n\t\t\t\tthis.g_iRatio = Math.min(hRatio, vRatio);\r\n\r\n\t\t\t\t// If we have images.\r\n\t\t\t\tif (this.g_oaImages.length !== 0) {\r\n\r\n\t\t\t\t\t// Then calculated scaledImageWidth / Height by multiplying the full image size by this ratio.\r\n\t\t\t\t\tthis.g_iScaledImageWidth = Math.round(this.g_oaImages[0].ImageWidth * this.g_iRatio);\r\n\t\t\t\t\tthis.g_iScaledImageHeight = Math.round(this.g_oaImages[0].ImageHeight * this.g_iRatio);\r\n\r\n\t\t\t\t\t// Default the compare settings.\r\n\t\t\t\t\tthis.g_iCompareImage_x = this.g_iScaledImageWidth;\r\n\t\t\t\t\tthis.g_iCompareImage_y = this.g_iScaledImageHeight;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Set the center shift.\r\n\t\t\t\tthis.g_iCenterShift_x = ((this.g_oCanvas.width - this.g_iCompareImage_x) / 2) - this.g_iDragOffset_x;\r\n\t\t\t\tthis.g_iCenterShift_y = ((this.g_oCanvas.height - this.g_iCompareImage_y) / 2) - this.g_iDragOffset_y;\r\n\t\t\t}\r\n\t\t\t// If we are comparing.\r\n\t\t\telse {\r\n\r\n\t\t\t\t// Get the ratio based on the compare documents.\r\n\t\t\t\tg_oCompare.getCompareRatio(this);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Apply the rotaton.\r\n\t\tthis.g_oContext.clearRect(0, 0, this.g_oCanvas.width, this.g_oCanvas.height);\r\n\t\tthis.g_oContext.translate(this.g_oCanvas.width / 2, this.g_oCanvas.height / 2);\r\n\t\tthis.g_oContext.rotate(this.g_iRotDegrees * Math.PI / 180);\r\n\t\tthis.g_oContext.translate(-(this.g_oCanvas.width / 2), -(this.g_oCanvas.height / 2));\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if the documenthas separations.\r\n\t * @returns {bool} Depending upon if the approval has separations.\r\n\t */\r\n\tCanvas.prototype.hasSeparations = function () {\r\n\t\tif (this.g_oDoc == null) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\telse {\r\n\t\t\treturn documentHasSeparations(this.g_oDoc.documentType, this.g_oDoc.pages.length);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Determines if the approval is a PDF approval.\r\n\t * @returns {bool} depending upon if the approval is a PDF approval.\r\n\t */\r\n\tCanvas.prototype.isSVGApproval = function () {\r\n\t\tif (this.g_oDoc == null) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\telse {\r\n\t\t\treturn this.g_oDoc.documentType === eDocumentTypes.SVG || this.g_oDoc.documentType === eDocumentTypes.CopyMagic;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Initialise the Canvas.\r\n\t */\r\n\tCanvas.prototype.initialiseCanvas = function () {\r\n\r\n\t\t// Reset the canvas.\r\n\t\tthis.resetCanvas();\r\n\r\n\t\t// Only get the canvas files if this is the main canvas and we are not comparing.\r\n\t\t// If in a compare mode, the activateCompare will get the canvas files.\r\n\t\tif (this.g_bMainCanvas && g_oViewer.g_oCompareMode == eCompareMode.NoCompare) {\r\n\t\t\tvar _this = this;\r\n\r\n\t\t\t// Ensure we have a document id.\r\n\t\t\tif (this.g_oDoc.documentId <= 0) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// If this is an archived document, show the archive module.\r\n\t\t\tif (this.g_oDoc.documentStatus == g_oArchive.g_ArchivedDocumentStatus) {\r\n\r\n\t\t\t\t// Load the archive module.\r\n\t\t\t\tg_oArchive.initialiseArchiveModule(this.g_oDoc.documentId, false);\r\n\t\t\t}\r\n\t\t\t// If this is an SVG document, load the SVG.\r\n\t\t\telse if (this.isSVGApproval()) {\r\n\r\n\t\t\t\t// Load in the SVG file.\r\n\t\t\t\tg_oSVGLoader.loadSVGFile(this, this.g_oAnnotationCanvas, false, 0);\r\n\t\t\t}\r\n\t\t\t// Otherwise get the canvas files.\r\n\t\t\telse {\r\n\r\n\t\t\t\t// Get the canvas files from the server.\r\n\t\t\t\tthis.getCanvasFiles(false, 0).done(function () {\r\n\r\n\t\t\t\t\t// Get the image data.\r\n\t\t\t\t\t_this.getimagePNGData(false, false);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the svg canvas.\r\n\t * @param {bool} bGetNewImageCallType - If this is a new image call.\r\n\t */\r\n\tCanvas.prototype.updateSVGCanvas = function (bGetNewImageCallType) {\r\n\r\n\t\t// If we are not animating or dragging.\r\n\t\tif (!this.g_bIsAnimating || !this.g_bIsDragging) {\r\n\t\t\t\r\n\t\t\t// Take a copy of the SVG to be updated.\r\n\t\t\tvar oSVG = $(this.g_oSVG.oSVG).clone();\r\n\r\n\t\t\t// Remove the unwanted items before rendering.\r\n\t\t\toSVG.find('foreignObject').remove();\r\n\t\t\toSVG.find('font').remove();\r\n\r\n\t\t\t// Check if we are in IE.\r\n\t\t\tvar bInternetExplorerBrowser = window.navigator.userAgent.indexOf(\"MSIE \") !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1;\r\n\r\n\t\t\t// If we are in internet explorer, SVG files are not supported.\r\n\t\t\tif (bInternetExplorerBrowser) {\r\n\r\n\t\t\t\t// Display an error to indicate this.\r\n\t\t\t\tg_oGreenlightMessages.displayErrorBubble(g_oSVGLoader.c_szSVGNotSupported);\r\n\r\n\t\t\t\t// Do not load the SVG.\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Serialise the SVG as a string.\r\n\t\t\tvar oSerialiser = new XMLSerializer();\r\n\t\t\tvar oSVGString = oSerialiser.serializeToString(oSVG[0]);\r\n\t\t\t\r\n\t\t\t// Replace any non breaking white spaces.\r\n\t\t\toSVGString = oSVGString.replace(new RegExp(' ', 'g'), ' ');\r\n\r\n\t\t\t// Create an empty URL to be populated.\r\n\t\t\tvar oURL;\r\n\r\n\t\t\t// Determine if this is the firefox browser.\r\n\t\t\tvar bFirefox = navigator.userAgent.toLowerCase().indexOf(\"firefox\") !== -1;\r\n\r\n\t\t\t// Outline the DOM URL element.\r\n\t\t\tvar oDOMURL;\r\n\t\t\t\r\n\t\t\t// If this is firefox.\r\n\t\t\tif (bFirefox) {\r\n\r\n\t\t\t\t// Get the dom url.\r\n\t\t\t\toDOMURL = window.URL || window.webkitURL || window;\r\n\r\n\t\t\t\t// Convert the svg to an object.\r\n\t\t\t\tvar oSVGObject = new Blob([oSVGString], { type: \"image/svg+xml;charset=utf8\" });\r\n\r\n\t\t\t\t// Convert the svg to a url.\r\n\t\t\t\toURL = oDOMURL.createObjectURL(oSVGObject);\r\n\t\t\t}\r\n\t\t\t// If this is not firefox.\r\n\t\t\telse {\r\n\r\n\t\t\t\t// Encode the URL.\r\n\t\t\t\toSVGString = encodeURIComponent(oSVGString);\r\n\r\n\t\t\t\t// Convert the svg to a url.\r\n\t\t\t\toURL = \"data:image/svg+xml;charset=utf-8,\" + oSVGString;\r\n\t\t\t}\r\n\r\n\t\t\t// Determine if this is the inital image render.\r\n\t\t\tvar bIsInitialImageRender = (this.g_oImage.src === undefined || this.g_oImage.src === \"\");\r\n\r\n\t\t\t// Reference the artwork viewer.\r\n\t\t\tvar _this = this;\r\n\r\n\t\t\t// Reset the image.\r\n\t\t\tthis.g_oImage = new Image();\r\n\r\n\t\t\t// Outline the function to load the image.\r\n\t\t\tthis.g_oImage.onload = function (e) {\r\n\r\n\t\t\t\t// Ensure that the load has completed.\r\n\t\t\t\tif (!e.target.complete) {\r\n\t\t\t\t\tsetTimeout(function () {\r\n\t\t\t\t\t\t_this.updateSVGCanvas(bGetNewImageCallType);\r\n\t\t\t\t\t}, 100);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Add the image details to the image separation list.\r\n\t\t\t\t_this.populateSeparationImages({\r\n\t\t\t\t\tImageWidth: _this.g_oImage.width,\r\n\t\t\t\t\tImageHeight: _this.g_oImage.height\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// Redraw the canvas.\r\n\t\t\t\t_this.redraw(bGetNewImageCallType, true);\r\n\r\n\t\t\t\t// Create a temporary canvas to draw the image to.\r\n\t\t\t\tvar oCanvas = document.createElement(\"canvas\");\r\n\t\t\t\toCanvas.width = _this.g_oImage.width;\r\n\t\t\t\toCanvas.height = _this.g_oImage.height;\r\n\r\n\t\t\t\t// If this is firefox, due to a firefox bug we need to try to draw the image.\r\n\t\t\t\tif (bFirefox) {\r\n\r\n\t\t\t\t\t// Try to get the context of the canvas and draw the image to it.\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tvar oFFContext = oCanvas.getContext(\"2d\");\r\n\t\t\t\t\t\toFFContext.drawImage(_this.g_oImage, 0, 0);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// If this failed, try again once loaded.\r\n\t\t\t\t\tcatch (e) {\r\n\t\t\t\t\t\tsetTimeout(function () {\r\n\t\t\t\t\t\t\t_this.updateSVGCanvas(bGetNewImageCallType);\r\n\t\t\t\t\t\t}, 100);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// Otherwise simply draw the image.\r\n\t\t\t\telse {\r\n\r\n\t\t\t\t\t// Get the context of the canvas and draw the image to it.\r\n\t\t\t\t\tvar oContext = oCanvas.getContext(\"2d\");\r\n\t\t\t\t\toContext.drawImage(_this.g_oImage, 0, 0);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Clear the image.\r\n\t\t\t\t_this.g_oImage = new Image();\r\n\t\t\t\t_this.g_oImage.src = oCanvas.toDataURL();\r\n\r\n\t\t\t\t// Log the returned image if required.\r\n\t\t\t\tif (_this.g_bLogImages) {\r\n\t\t\t\t\tvar w = window.open(\"\", \"_blank\", \"toolbar=0,location=0,menubar=0\");\r\n\t\t\t\t\tw.document.write(\"\");\r\n\t\t\t\t\tw.document.write(_this.g_oImage.outerHTML);\r\n\t\t\t\t\tw.document.write(\" |
\");\r\n\t\t\t\t}\r\n\r\n\t\t\t\t_this.g_oImage.onload = function () {\r\n\t\t\t\t\t_this.g_oImgData = _this.g_oContext.getImageData(0, 0, _this.g_oCanvas.width, _this.g_oCanvas.height);\r\n\t\t\t\t\t_this.g_iTemp2DragOffset_x = _this.g_iDragOffset_x;\r\n\t\t\t\t\t_this.g_iTemp2DragOffset_y = _this.g_iDragOffset_y;\r\n\t\t\t\t\tif (bFirefox) {\r\n\t\t\t\t\t\toDOMURL.revokeObjectURL(oURL);\r\n\t\t\t\t\t}\r\n\t\t\t\t};\r\n\r\n\t\t\t\t// If this is an inital render.\r\n\t\t\t\tif (bIsInitialImageRender) {\r\n\r\n\t\t\t\t\t// Finalise the image load.\r\n\t\t\t\t\tg_oViewer.finalizeRenderingImage();\r\n\r\n\t\t\t\t\t// We need to redraw the annotations after a delay, this is because the setupAnnotations may not have finished yet.\r\n\t\t\t\t\tsetTimeout(function () {\r\n\r\n\t\t\t\t\t\t// If the annotation module is defined, and this is an artwork canvas with an annotation canvas.\r\n\t\t\t\t\t\tif (!$.isEmptyObject(g_oAnnotations) && _this.g_iCanvasType == eCanvasType.Artwork && _this.g_oAnnotationCanvas != null) {\r\n\r\n\t\t\t\t\t\t\t// If annotation are shown.\r\n\t\t\t\t\t\t\tif (g_oSettings.g_oUserSettings.ShowAnnotations) {\r\n\r\n\t\t\t\t\t\t\t\t// Redraw the annotations.\r\n\t\t\t\t\t\t\t\t_this.g_oAnnotationCanvas.g_oContext.clearRect(0, 0, _this.g_oCanvas.width, _this.g_oCanvas.height);\r\n\t\t\t\t\t\t\t\tg_oAnnotations.redrawAnnotations(_this, _this.g_oAnnotationCanvas);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, 500);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\r\n\t\t\t// Set the source of the image.\r\n\t\t\tthis.g_oImage.src = oURL;\r\n\r\n\t\t\t// If this is the main canvas, setup the seperations div.\r\n\t\t\tif (this.g_bMainCanvas) {\r\n\r\n\t\t\t\t// If this is a PDF file then setup and show the separations div.\r\n\t\t\t\tg_oSeparations.SetupSeparationsDiv(this, bGetNewImageCallType, []);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Navigation event move function.\r\n\t * @param {event} event - The on move event object.\r\n\t */\r\n\tCanvas.prototype.navOnMove = function (event) {\r\n\t\tvar navOverlayContext = this.g_oNavCanvasOver.g_oContext;\r\n\t\tvar navCanvasOver = this.g_oNavCanvasOver;\r\n\t\tvar newCoords = getClickCoords(event, navCanvasOver);\r\n\r\n\t\tnewCoords[0] *= (navCanvasOver.g_oCanvas.width / $(\"#navCanvasOverlay\").width());\r\n\t\tnewCoords[1] *= (navCanvasOver.g_oCanvas.height / $(\"#navCanvasOverlay\").height());\r\n\r\n\t\tnewCoords[0] /= g_oViewer.c_iDPI;\r\n\t\tnewCoords[1] /= g_oViewer.c_iDPI;\r\n\r\n\t\t// Stop people dragging outside the canvas image.\r\n\t\tif ((newCoords[0] < (navCanvasOver.g_oNavigatorData[0][0] + navCanvasOver.g_oNavigatorData[1][0]) && newCoords[0] > navCanvasOver.g_oNavigatorData[0][0]) &&\r\n\t\t\t(newCoords[1] < (navCanvasOver.g_oNavigatorData[0][1] + navCanvasOver.g_oNavigatorData[1][1]) && newCoords[1] > navCanvasOver.g_oNavigatorData[0][1])) {\r\n\r\n\t\t\tthis.g_iX = newCoords[0];\r\n\t\t\tthis.g_iY = newCoords[1];\r\n\t\t\tvar newStartPoint_x = newCoords[0] - (navCanvasOver.g_oNavigatorData[3][0]) / 2;\r\n\t\t\tvar newStartPoint_y = newCoords[1] - (navCanvasOver.g_oNavigatorData[3][1]) / 2;\r\n\r\n\t\t\tnavOverlayContext.clearRect(0, 0, navCanvasOver.g_oCanvas.width, navCanvasOver.g_oCanvas.height);\r\n\t\t\tnavOverlayContext.beginPath();\r\n\t\t\tnavOverlayContext.rect(\r\n\t\t\t\tnavCanvasOver.g_oNavigatorData[0][0],\r\n\t\t\t\tnavCanvasOver.g_oNavigatorData[0][1],\r\n\t\t\t\tnavCanvasOver.g_oNavigatorData[1][0],\r\n\t\t\t\tnavCanvasOver.g_oNavigatorData[1][1]\r\n\t\t\t);\r\n\t\t\tnavOverlayContext.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\t\t\tnavOverlayContext.fill();\r\n\t\t\tnavOverlayContext.clearRect(\r\n\t\t\t\t// We will move the current viewport rectangle according to the user drag point.\r\n\t\t\t\tnewStartPoint_x,\r\n\t\t\t\tnewStartPoint_y,\r\n\t\t\t\t// We must test the width to ensure that it's less than the actual image size\r\n\t\t\t\tMath.min((navCanvasOver.g_oNavigatorData[3][0]), (navCanvasOver.g_oNavigatorData[1][0] + navCanvasOver.g_oNavigatorData[0][0] - newStartPoint_x)),\r\n\t\t\t\tMath.min((navCanvasOver.g_oNavigatorData[3][1]), (navCanvasOver.g_oNavigatorData[1][1] + navCanvasOver.g_oNavigatorData[0][1] - newStartPoint_y))\r\n\t\t\t);\r\n\t\t}\r\n\t\telse {\r\n\t\t\t$(\"#navCanvasOverlay\").off('pointerup');\r\n\t\t\t$(\"#navCanvasOverlay\").off('pointermove');\r\n\t\t\tthis.redraw(true);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Navigation Pointer up Event.\r\n\t */\r\n\tCanvas.prototype.navPointerUp = function () {\r\n\t\tthis.g_iCurrOffset_x = this.g_iDragOffset_x;\r\n\t\tthis.g_iCurrOffset_y = this.g_iDragOffset_y;\r\n\t\tthis.g_iDragOffset_x = (this.g_iX - (this.g_oNavCanvasOver.g_oCanvas.width / 2)) * this.g_iZoomLevel;\r\n\t\tthis.g_iDragOffset_y = (this.g_iY - (this.g_oNavCanvasOver.g_oCanvas.height / 2)) * this.g_iZoomLevel;\r\n\t\tthis.redraw(true);\r\n\t};\r\n\r\n\t/**\r\n\t * Pans across the artwork.\r\n\t */\r\n\tCanvas.prototype.pan = function (oSyncCanvas) {\r\n var _this = this;\r\n\r\n $(\"#\" + _this.g_oAnnotationCanvas.g_szCanvasId).css('cursor', 'all-scroll');\r\n g_oAnnotations.g_szPrevCursorStyle = \"all-scroll\";\r\n changeCanvasFunction($(\"#\" + _this.g_oAnnotationCanvas.g_szCanvasId), 'pointerup');\r\n changeCanvasFunction($(\"#\" + _this.g_oAnnotationCanvas.g_szCanvasId), 'click', function (event) {\r\n g_oAnnotations.findAnnotation(event, _this, _this.g_oAnnotationCanvas);\r\n });\r\n\t\tchangeCanvasFunction($(\"#\" + _this.g_oAnnotationCanvas.g_szCanvasId), 'pointerdown', function (event) {\r\n\r\n // Check if an annotation has been clicked.\r\n g_oAnnotations.findAnnotation(event, _this, _this.g_oAnnotationCanvas, true);\r\n\r\n // If no annotation was clicked and we are not animating, initiate the drag.\r\n if (!g_oAnnotations.g_bAnnotationsFound && !_this.g_bIsAnimating) {\r\n _this.dragInitiate(event, oSyncCanvas);\r\n }\r\n });\r\n\t};\r\n\r\n\t/**\r\n\t * Redraws the image to the canvas.\r\n\t * @param {bool} bGetNewImage - Boolean to determine if we are going to get a new image.\r\n\t * @param {bool} bIsInitialImageRender - Boolean to indicate if this is the initial image render.\r\n\t */\r\n\tCanvas.prototype.redraw = function (bGetNewImage, bIsInitialImageRender) {\r\n\r\n\t\t// Check which canvas type to sync to.\r\n\t\tif (this.g_iCanvasType == eCanvasType.Artwork && this.g_oAnnotationCanvas != null) {\r\n\t\t\tthis.g_oAnnotationCanvas.synchroniseZoomPanProperties(this);\r\n\t\t}\r\n\t\telse if (this.g_iCanvasType == eCanvasType.Annotation) {\r\n\t\t\tvar canvasToSyncFrom = g_oViewer.getLinkedArtworkCanvas(this.g_szCanvasId);\r\n\r\n\t\t\t// Check the temporary properties are set (they won't be if we've just closed the compare)\r\n\t\t\tif (canvasToSyncFrom !== null && typeof (canvasToSyncFrom.g_iDragOffset_x) !== \"undefined\") {\r\n\t\t\t\tthis.synchroniseZoomPanProperties(canvasToSyncFrom);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Draw the Artwork viewer.\r\n\t\tif (bGetNewImage || bIsInitialImageRender) {\r\n\t\t\tthis.drawImages(bGetNewImage);\r\n\t\t}\r\n\r\n\t\t// Check which canvas type before\r\n\t\tif (this.g_iCanvasType == eCanvasType.Artwork && this.g_oAnnotationCanvas != null) {\r\n\t\t\tthis.g_oAnnotationCanvas.getRatio();\r\n\t\t}\r\n\t\telse if (this.g_iCanvasType == eCanvasType.Annotation) {\r\n\t\t\tthis.getRatio();\r\n\t\t}\r\n\r\n\t\t// If the annotation module is defined we need to redraw the annotations.\r\n\t\tif (!$.isEmptyObject(g_oAnnotations)) {\r\n\r\n\t\t\t// Get the artwork and annotation canvas.\r\n\t\t\tvar oArtworkCanvas = null\r\n\t\t\tvar oAnnotationCanvas = null;\r\n\r\n\t\t\t// If this is an artwork canvas.\r\n\t\t\tif (this.g_iCanvasType == eCanvasType.Artwork) {\r\n\t\t\t\toArtworkCanvas = this;\r\n\t\t\t\toAnnotationCanvas = this.g_oAnnotationCanvas;\r\n\t\t\t}\r\n\t\t\t// If this is an annotation canvas.\r\n\t\t\telse {\r\n\t\t\t\toAnnotationCanvas = this;\r\n\t\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(this.g_szCanvasId);\r\n\t\t\t}\r\n\r\n\t\t\t// If this is not the differences canvas.\r\n\t\t\tif (oArtworkCanvas !== null && (oArtworkCanvas.g_szCanvasId !== \"DifferencesViewer\" || oArtworkCanvas.g_szCanvasId !== \"DifferencesViewer2\")) {\r\n\r\n\t\t\t\t// Redraw the annotations for the canvas if required.\r\n\t\t\t\tif (g_oSettings.g_oUserSettings.ShowAnnotations) {\r\n\t\t\t\t\tg_oAnnotations.redrawAnnotations(oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Reposition the speech bubbles.\r\n\t\t\t\tif (typeof (g_oAnnotations.repositionSpeechBubbles) != \"undefined\") {\r\n\t\t\t\t\tg_oAnnotations.repositionSpeechBubbles(oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If this is the artwork canvas.\r\n\t\tif (this.g_iCanvasType == eCanvasType.Artwork) {\r\n\r\n\t\t\t// Determine if we should allow re-rendering at zoom level 1.\r\n\t\t\t// We allow this when this is an SVG approval following changing of text.\r\n\t\t\tvar bAllowZoomLevelOneReRendering = (this.isSVGApproval() && !bIsInitialImageRender);\r\n\r\n\t\t\t// Get the image PNG data if required.\r\n\t\t\tif ((this.hasSeparations() || this.isSVGApproval()) && !this.g_bIsAnimating && !this.g_bIsDragging && bGetNewImage && (this.g_iZoomLevel !== 1 || bAllowZoomLevelOneReRendering)) {\r\n\t\t\t\tthis.getimagePNGData(false, false);\r\n\t\t\t}\r\n\r\n\t\t\t// Reset Navigation to full image.\r\n\t\t\tvar navCanvasOver = this.g_oNavCanvasOver;\r\n\t\t\tif (this.g_bMainCanvas && this.hasSeparations() && this.g_oNavCanvasOver != null && this.g_iZoomLevel === 1) {\r\n\t\t\t\tthis.calculateVisibleImagePortion(false);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t// If we are using the slider compare.\r\n\t\tif (g_oViewer.g_oCompareMode == eCompareMode.SliderHorizontal || g_oViewer.g_oCompareMode == eCompareMode.SliderVertical) {\r\n\r\n\t\t\t// Redraw the slider.\r\n\t\t\tg_oCompare.redrawCanvasSlider(this);\r\n\t\t}\r\n\t\t// If we are using the compare alignment.\r\n\t\telse if (g_oCompare.g_bAlignmentModeActive) {\r\n\r\n\t\t\t// Draw the labels.\r\n\t\t\tvar itop = $('#divApprovalStatusBar').position().top + $('#divApprovalStatusBar').height();\r\n\t\t\t$(\"#ApprovalDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#CompareAnnotationViewer\").offset().left - $(\"#ApprovalDocumentLabel\").width()).css(\"display\", \"\");\r\n\t\t\t$(\"#CompareDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#divDifferencesDivider\").offset().left - $(\"#CompareDocumentLabel\").width()).css(\"display\", \"\");\r\n\r\n\t\t\t// Redraw the alignment markers.\r\n\t\t\tg_oCompare.drawAlignmentMarkers();\r\n\t\t}\r\n\t\t// If we are using side by side, draw the labels for this mode.\r\n\t\telse if (g_oViewer.g_oCompareMode === eCompareMode.SideBySide) {\r\n\r\n\t\t\t// Draw the labels.\r\n\t\t\tvar itop = $('#divApprovalStatusBar').position().top + $('#divApprovalStatusBar').height();\r\n\r\n\t\t\t// If the compare canvas is a 3d file, we will need to use the canvas holder as the annotation canvas will be hidden.\r\n\t\t\tif (g_oCompare.g_oCompareViewer.g_oDoc.documentType == eDocumentTypes.ThreeD) {\r\n\t\t\t\t$(\"#ApprovalDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#divCompareCanvasHolder\").offset().left - $(\"#ApprovalDocumentLabel\").width()).css(\"display\", \"\");\r\n\t\t\t\t$(\"#CompareDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#divCompareCanvasHolder\").offset().left).css(\"display\", \"\");\r\n\t\t\t}\r\n\t\t\t// If this is a 2d comparison.\r\n\t\t\telse {\r\n\t\t\t\t$(\"#ApprovalDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#CompareAnnotationViewer\").offset().left - $(\"#ApprovalDocumentLabel\").width()).css(\"display\", \"\");\r\n\t\t\t\t$(\"#CompareDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#CompareAnnotationViewer\").offset().left).css(\"display\", \"\");\r\n\t\t\t}\r\n\t\t}\r\n\t\t// If we are using side by side with differences, draw the labels for this mode.\r\n\t\telse if (g_oViewer.g_oCompareMode === eCompareMode.SideBySideDiff) {\r\n\r\n\t\t\t// Draw the labels.\r\n\t\t\tvar itop = $('#divApprovalStatusBar').position().top + $('#divApprovalStatusBar').height();\r\n\t\t\t$(\"#ApprovalDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#CompareAnnotationViewer\").offset().left - $(\"#ApprovalDocumentLabel\").width()).css(\"display\", \"\");\r\n\t\t\t$(\"#CompareDocumentLabel\").css(\"top\", itop).css(\"left\", $(\"#divDifferencesDivider\").offset().left - $(\"#CompareDocumentLabel\").width()).css(\"display\", \"\");\r\n\t\t}\r\n\t\t// Otherwise clear the labels.\r\n\t\telse {\r\n\r\n\t\t\t// Clear the labels.\r\n\t\t\t$(\"#ApprovalDocumentLabel\").hide();\r\n\t\t\t$(\"#CompareDocumentLabel\").hide();\r\n\t\t}\r\n\t};\r\n\r\n\t// Helper method for redraw. Draws the highlight rectangle on the canvas.\r\n\tCanvas.prototype.drawTextHighlight = function (oContext, left, top, distx, disty, fillStyle) {\r\n\t\t\r\n\t\t// Begin the path.\r\n\t\toContext.beginPath();\r\n\r\n\t\t// Create the rectangle.\r\n\t\toContext.rect(left, top, distx, disty);\r\n\r\n\t\t// Set the fill.\r\n\t\toContext.fillStyle = fillStyle;\r\n\r\n\t\t// Fill the rectangle.\r\n\t\toContext.fill();\r\n\t};\r\n\r\n\t// Helper method for redraw. Draws the highlight rectangle on the canvas.\r\n\tCanvas.prototype.removeTextHighlight = function (oContext, left, top, distx, disty) {\r\n\t\toContext.clearRect(left, top, distx, disty);\r\n\t};\r\n\r\n\t/**\r\n\t * Reset the canvas values.\r\n\t */\r\n\tCanvas.prototype.resetCanvas = function () {\r\n\r\n\t\t// Reset the image data.\r\n\t\tthis.g_oImage = {};\r\n\r\n\t\t// Reset the properties.\r\n\t\tthis.g_iTempZoomLevel = 1;\r\n\t\tthis.g_iTempDragOffset_x = 0;\r\n\t\tthis.g_iTempDragOffset_y = 0;\r\n\t\tthis.g_iDragOffset_x = 0\r\n\t\tthis.g_iDragOffset_y = 0\r\n\t\tthis.g_iDragXDiff = 0;\r\n\t\tthis.g_iDragYDiff = 0;\r\n\t\tthis.g_iZoomDiff = 0;\r\n\t\tthis.g_iZoomLevel = 1;\r\n\t\tthis.g_bIsAnimating = false;\r\n\t\tthis.g_iRotDegrees = 0;\r\n\r\n\t\t// Reset the zoom slider if required.\r\n\t\tif (this.g_bMainCanvas) {\r\n\t\t\tthis.g_oCanvasZoom.updateZoomSlider();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Resize event.\r\n\t */\r\n\tCanvas.prototype.resize = function () {\r\n\t\ttry {\r\n\t\t\tvar content = $('#boundingrectangle');\r\n\t\t\tvar top = (window.innerHeight - content.height()) / 2;\r\n\t\t\tcontent.css('top', Math.max(0, top) + 'px');\r\n\t\t\tresizeViewerCell();\r\n\t\t\tthis.getRatio();\r\n\t\t\tif (this.g_oAnnotationCanvas != null) {\r\n\t\t\t\tthis.g_oAnnotationCanvas.getRatio();\r\n\t\t\t}\r\n\t\t\tif (this.g_bMainCanvas) {\r\n\t\t\t\tg_oSeparations.SetupSeparationsDiv(this, false, $(\"#divSeparationItems\").children(\".sep\"));\r\n\t\t\t\tg_oViewer.setupAnnotationsDiv();\r\n\t\t\t\tif (g_oViewer.g_oArtworkViewer.g_oDoc.documentType == eDocumentTypes.CopyMagic) {\r\n\t\t\t\t\tg_oSVGCopyMagic.setupCopyMagicSlideOut();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.getimagePNGData(true, false);\r\n\t\t}\r\n\t\tcatch (e) {\r\n\t\t\t// This errors when we close the viewer as .\r\n\t\t\t// it is difficult to determine when this is as the call comes from\r\n\t\t\t// the external application.\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Called to create an animated transition when rotating.\r\n\t * @param {int} iRotDegrees - The angle of rotation in degrees\r\n\t */\r\n\tCanvas.prototype.rotateAnimate = function (iRotDegrees) {\r\n\r\n\t\t// If we are going to be rotating backwards from the start, set this to the next full loop to ensure we do not go into a negative.\r\n\t\tif (iRotDegrees < 0 && this.g_iRotDegrees == 0) {\r\n\t\t\tthis.g_iRotDegrees += 360;\r\n\t\t}\r\n\r\n\t\t// Set the value of the desired rotation.\r\n\t\tthis.g_iTempRotDegrees = this.g_iRotDegrees + iRotDegrees;\r\n\r\n\t\t// Call the first frame of the rotate animate.\r\n\t\tthis.rotateAnimateFrame(iRotDegrees, 1);\r\n\t};\r\n\r\n\t/**\r\n\t * Called to draw an animated frame when rotating.\r\n\t * @param {int} iRotDegrees - The angle of rotation in degrees.\r\n\t * @param {int} iCurrentAnimationFrame - The current animation frame.\r\n\t */\r\n\tCanvas.prototype.rotateAnimateFrame = function (iRotDegrees, iCurrentAnimationFrame) {\r\n\t\t\r\n\t\t// Determine the number of desired animation frames.\r\n\t\tvar iDesiredAnimationFrames = Math.round(this.g_iAnimateFrames);\r\n\r\n\t\t// Set that the canvas is animating and disable the buttons.\r\n\t\tthis.g_bIsAnimating = true;\r\n\t\t$(\".button\").prop(\"disabled\", true);\r\n\r\n\t\t// Move the canvs by the desired frame rotation degrees.\r\n\t\tthis.g_iRotDegrees += (iRotDegrees / iDesiredAnimationFrames);\r\n\r\n\t\t// If this is the last frame.\r\n\t\tif (iCurrentAnimationFrame == iDesiredAnimationFrames) {\r\n\r\n\t\t\t// Set the rotation to the desired final rotation.\r\n\t\t\tthis.g_iRotDegrees = this.g_iTempRotDegrees;\r\n\r\n\t\t\t// Reset to 0 if we have hit a full loop.\r\n\t\t\tif (this.g_iRotDegrees == 360 || this.g_iRotDegrees == -360) {\r\n\t\t\t\tthis.g_iRotDegrees = 0;\r\n\t\t\t}\r\n\r\n\t\t\t// Set that we are no longer animating and enable the buttons.\r\n\t\t\tthis.g_bIsAnimating = false;\r\n\t\t\t$(\".button\").prop(\"disabled\", false);\r\n\t\t}\r\n\t\t// If this is not the last frame, request the next frame.\r\n\t\telse {\r\n\t\t\trequestAnimationFrame(this.rotateAnimateFrame.bind(this, iRotDegrees, ++iCurrentAnimationFrame));\r\n\t\t}\r\n\r\n\t\t// Clear the current image data and redraw now the rotation is applied.\r\n\t\tthis.clearImgData();\r\n\t\tthis.redraw(true);\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the canvas up using the passed in element.\r\n\t */\r\n\tCanvas.prototype.setup2DCanvas = function (ContainerId, CanvasClass, zIndex) {\r\n\t\tthis.g_oContainer = document.getElementById(ContainerId);\r\n\t\tthis.g_oCanvas = document.createElement('canvas');\r\n\t\t$(this.g_oCanvas).attr(\"touch-action\", \"none\");\r\n\t\tthis.g_oCanvas.id = this.g_szCanvasId;\r\n\t\t$(this.g_oCanvas).addClass(CanvasClass);\r\n\t\tthis.g_oContainer.appendChild(this.g_oCanvas);\r\n\t\tthis.g_oContext = this.g_oCanvas.getContext(\"2d\");\r\n\t\t$(this.g_oCanvas).css(\"z-index\", zIndex);\r\n\r\n\t\tresizeViewerCell();\r\n\t\tthis.initialiseCanvas();\r\n\t};\r\n\r\n\t/**\r\n\t * Synchronise this canvas with the passed in canvas.\r\n\t * @param {object} canvasToSyncFrom - The canvas we are going to sync with.\r\n\t */\r\n\tCanvas.prototype.synchroniseZoomPanProperties = function (canvasToSyncFrom) {\r\n\t\tthis.g_iDragOffset_x = canvasToSyncFrom.g_iDragOffset_x;\r\n\t\tthis.g_iDragOffset_y = canvasToSyncFrom.g_iDragOffset_y;\r\n\t\tthis.g_iTempDragOffset_x = canvasToSyncFrom.g_iTempDragOffset_x;\r\n\t\tthis.g_iTempDragOffset_y = canvasToSyncFrom.g_iTempDragOffset_y;\r\n\t\tthis.g_iTemp2DragOffset_x = canvasToSyncFrom.g_iTemp2DragOffset_x;\r\n\t\tthis.g_iTemp2DragOffset_y = canvasToSyncFrom.g_iTemp2DragOffset_y;\r\n\t\tthis.g_iZoomLevel = canvasToSyncFrom.g_iZoomLevel;\r\n\t\tthis.g_iTempZoomLevel = canvasToSyncFrom.g_iTempZoomLevel;\r\n\t\tthis.g_iZoomDiff = canvasToSyncFrom.g_iZoomDiff;\r\n\t\tthis.g_iDragXDiff = canvasToSyncFrom.g_iDragXDiff;\r\n\t\tthis.g_iDragYDiff = canvasToSyncFrom.g_iDragYDiff;\r\n\t\tthis.g_iRotDegrees = canvasToSyncFrom.g_iRotDegrees;\r\n\t\tthis.g_iTempRotDegrees = canvasToSyncFrom.g_iTempRotDegrees;\r\n\t};\r\n\r\n\t/**\r\n\t * Clears the real time render image.\r\n\t */\r\n\tCanvas.prototype.clearRealtimeRenderImage = function () {\r\n\t\tif (this.isViewerUsingRealtimeRender()) {\r\n\t\t\tvar oJSON = {\r\n\t\t\t\tSessionId: g_szSessionId,\r\n\t\t\t\tszRealtimeRenderReference: this.g_szRealtimeRenderReference\r\n\t\t\t};\r\n\r\n\t\t\tvar _this = this;\r\n\t\t\treturn $.post({\r\n\t\t\t\turl: \"GreenlightSvr/clearRealtimeRenderImage\",\r\n\t\t\t\tdata: JSON.stringify(oJSON),\r\n\t\t\t\tcontentType: \"application/json; charset=utf-8\",\r\n\t\t\t\tcache: false,\r\n\t\t\t\tdataType: \"json\",\r\n\t\t\t\tsuccess: function (oResponse, Status, jqXHR) {\r\n\t\t\t\t\t_this.g_szRealtimeRenderReference = \"\";\r\n\t\t\t\t},\r\n\t\t\t\terror: function (jqXhr, textStatus, errorThrown) {\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Checks if a click is in the confines of a graphic.\r\n\t * @param {int} x- X Coordinate\r\n\t * @param {int} y- Y Coordinate\r\n\t * @returns Boolean indicating the result.\r\n\t */\r\n\tCanvas.prototype.isClickWithinImageBounds = function (x, y, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Calculate any compare offset.\r\n\t\tvar compareOffset_x, compareOffset_y;\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tcompareOffset_x = co.x;\r\n\t\tcompareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkCanvas);\r\n\r\n\t\t// Get the canvas width and height.\r\n\t\tvar iScaledImageWidth = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iScaledImageHeight = oArtworkCanvas.g_iScaledImageHeight;\r\n\r\n\t\t// If we have a compare rotation of 90 or 270, swap the image width and height.\r\n\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\tiScaledImageWidth = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\tiScaledImageHeight = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t}\r\n\r\n\t\t// Determine if the click is within the bounds.\r\n\t\tthis.g_oContext.beginPath();\r\n\t\tvar style = this.g_oContext.fillStyle;\r\n\t\tthis.g_oContext.fillStyle = \"rgba(0,0,0,0)\";\r\n\t\tthis.g_oContext.rect(oArtworkCanvas.g_iCenterShift_x + compareOffset_x, oArtworkCanvas.g_iCenterShift_y + compareOffset_y, iScaledImageWidth, iScaledImageHeight);\r\n\t\tthis.g_oContext.closePath();\r\n\t\tthis.g_oContext.fill();\r\n\t\tthis.g_oContext.fillStyle = style\r\n\t\treturn this.g_oContext.isPointInPath(x, y);\r\n\t}\r\n\r\n\t/**\r\n\t * Checks if the viewer is using a real time render.\r\n\t */\r\n\tCanvas.prototype.isViewerUsingRealtimeRender = function () {\r\n\t\treturn this.g_szRealtimeRenderReference !== undefined && this.g_szRealtimeRenderReference !== \"\";\r\n\t}\r\n\r\n\t// Add the canvas object to the window.\r\n\twindow.Canvas = Canvas;\r\n}());"]}