{"version":3,"sources":["../js/GreenlightTechTools.js"],"names":["g_oTechTools","g_oPayload","type","width","height","lineLength","area","degrees","separations","barcodeMeasurements","TechToolsUI","oViewer","iApprovalId","oDoc","iDocumentType","this","g_oEvents","g_oViewer","g_iDocumentType","g_oAnnotationViewer","g_oArtworkViewer","g_iOrigin_x","g_iOrigin_y","g_iX","g_iY","c_szAreaMeasurementAbbreviation","c_szAngleMeasurementUnitsAbbreviation","c_szMeasurementSuffixMetric","c_dMeasurementFactorMetric","c_szMeasurementSuffixImperial","c_dMeasurementFactorImperial","c_iMeasurementUnitMetric","c_iMeasurementUnitImperial","g_szMeasurementSuffix","g_dMeasurementFactor","g_eMeasurementTypes","NONE","POINTTOPOINT","AREA","HORIZONTAL","VERTICAL","BARCODE","COLOURDENSITY","TEXT","g_iSelectedMeasurementType","g_iOriginalZoomLevel","g_eExamTypes","g_iExamTypeCode","c_szFailedToExamineImage","c_szInfoMsgNoLiveTextFound","c_szInfoMsgNoBarcodeFound","c_szInfoMsgNoSeparationsShown","c_szSeparationPercentageClassName","c_szSeparationPercentageElementName","c_szSeparationPercentage_BarcodeClassName","c_szSeparationPercentage_BarcodeElementName","c_iDisplayFontSize","c_iDPI","c_szDisplayFont","c_szFillStyle","c_szTextBaseline","c_szTextAlign","g_iApprovalId","g_iDocumentId","documentId","g_szTextMeasurementTextContent","g_szTACFieldDefault","g_oTextMeasurementWordsArray","g_oBarcodeMeasurementArray","c_iDisplayMargin","g_oTextAreaHighlightBox","iBeginX","iBeginY","iWidth","iHeight","prototype","toolTypeChange","element","$","slideUp","hasClass","css","removeStyle","g_oCompareMode","eCompareMode","SideBySide","SideBySideDiff","g_oAnnotations","g_szPrevCursorStyle","remove","i","g_oAnnotationsMade","length","g_bClosed","g_oLastUsedTool","redraw","clearToolType","parent","removeClass","changeCanvasFunction","clearBarcodeMeasurementArray","formatMeasuredDistance","measuredDistance","g_oSettings","g_oUserSettings","UseMetricUnits","round","toFixed","examineImage","oArtworkViewer","oAnnotationViewer","begin_x","begin_y","end_x","end_y","examTypeCode","iAnnotationId","g_oSeparations","ShowSpinners","oExamineImageRequest","ExamineImageRequest","DocumentName","g_oDoc","documentName","DocumentId","PageNumber","g_iCurrentPage","ConsumerId","consumerId","Dimensions","MinX","Math","max","MaxX","min","MinY","MaxY","ExamTypeCode","CurrentResolution","g_iCurrentResolution","OriginalResolution","pages","documentResolutionPPI","RealtimeRenderReference","g_szRealtimeRenderReference","AnnotationID","FullImageWidth","g_oaImages","ImageWidth","FullImageHeight","ImageHeight","oMarqueeDimensions","ImageDimensions","oJSON","SessionId","g_szSessionId","ajax","url","data","JSON","stringify","contentType","dataType","success","response","ExamineImageResponse_CH","Contents","failure","g_oGreenlightMessages","displayErrorBubble","oResponseContents","oExamineImageResponse","parse","oSeparationsArray","WordsList","currentFont","currentFontSize","szTextContent","dMinX","dMinY","dMaxX","dMaxY","iBarcodeDisplayTextCount","iTotalAreaCoverage","iPointX","g_oMarquee","g_oAnnotationActions","g_iDragRectOffset","iPointY","trueCoords","transformMarqueeCoordinatesForRotation","transformedCoordinates","transformCoordinates","iBeginPoint_X","iBeginPoint_Y","iEndPoint_X","iEndPoint_Y","iDragOffset_X","iDragOffset_Y","iCenterShift_X","iCenterShift_Y","derotateCanvasContext","g_oAnnotationCanvas","g_oContext","g_oCanvas","save","bOutOfBounds","concat","sort","sortAnnotationCoords","returnXMin","returnXMax","returnYMin","returnYMax","bDrawAnnotationHandles","g_bReadOnly","g_bMainCanvas","restore","oAnnotationHandles","szSeparationName","SanitiseSeparationName","attr","indexOf","SeparationDisabledClassName","percent","parseInt","children","prepend","push","handleX","handleY","annotationCoordinates","annotationData","IsSeparationEnabled","szCodeType","replace","szCodeData","szWidthMagnification","dBarcodeX","dBarcodeY","dBarcodeWidth","dBarcodeHeight","szMagnificationText","szDisplayText","append","annContext","fillStyle","font","textBaseline","textalign","oBarcodeMeasurement","BarcodeMeasurement","ArtworkCanvasId","g_szCanvasId","AnnotationCanvasId","SeparationName","CodeType","CodeData","DisplayText","MarqueeCoordinates","deepCopyObject","widthMagnification","X","parseFloat","Y","Width","Height","oBarcodeCoordinates","renderBarcodeMeasurement","oBarcodeAnnotationData","oHandleSize","calculateAnnotationHandleSize","eAnnotationHandleTypes","CreateNewAnnotation","iHandleDisplayCoordX","x","iHandleDisplayCoordY","y","Llx","Ury","Urx","Lly","FontName","FontSize","TextContent","SpaceAfter","drawAnnotationHandle","AnnotationColour","e","AnnotationAction","mouseMoveAnnotationHandles","mouseClickAnnotationHandles","text","show","hide","compareOffset_x","compareOffset_y","iImageWidth","g_iScaledImageWidth","iImageHeight","g_iScaledImageHeight","co","g_oCompare","calculateCompareOffsetInPx","g_oTempAnnotationArray","g_oAnnotationColSelected","g_iAnnotationType","eAnnotationTypes","TextMeasurement","LastUsedAnnotationType","syncSettings","setAnnotationRectangle","annotationPointerUp","undefined","iAnnotationID","oWordsArray","deepCopyArray","EventService","publish","g_bAnnotationsFound","displayWarningBubble","SpinnerElementName","getBarcodeMeasurementArray","canvasId","oBarcodeMeasurementArray","renderCanvasBarcodeMeasurements","szArtworkCanvasId","oArtworkCanvas","getCanvas","oAnnotationCanvas","g_iCanvasType","eCanvasType","Annotation","getLinkedArtworkCanvas","Overlay","Blink","SliderHorizontal","SliderVertical","getAnnotationCanvasId","panToBarcode","event","iBarcodePosition","preventDefault","stopPropagation","oBarcode","oBarcodeMidPoint","g_iTempDragOffset_x","g_iTempDragOffset_y","g_iDragXDiff","g_iDragOffset_x","g_iAnimateFrames","g_iDragYDiff","g_iDragOffset_y","g_oCanvasZoom","startZoomAnimate","oBarcodeMeasurements","bRenderOverlayMarquee","oAnnotationViewerContext","iScaledImageWidth","iScaledImageHeight","iCompareRotation","getCompareRotation","oRotatedOrigin","rotate","rotated_x","rotated_y","oRotatedCoordinates","g_iCenterShift_x","g_iCenterShift_y","clearRect","rect","fill","iDisplayCoordX","iDisplayCoordY","textAlign","fillText","showSeperationsSideBar","is","slideDiv","hideSeperationsSideBar","measurementMarqueeDraw","oAnnotationCanvasContext","iCoordinateDistance_x","iCoordinateDistance_y","beginPoint_x","beginPoint_y","canvasWidth","canvasHeight","canvasHalfWidth","canvasHalfHeight","artworkViewerImage","scaleFactor","scaledDistance_x","WidthResolution","scaledDistance_y","HeightResolution","g_iZoomLevel","measurePointToPoint","Line","measureArea","Rectangle","MeasureHorizontal","MeasureVertical","canvasContext","coordinateDistance_x","coordinateDistance_y","payload","hypotenuse","sqrt","angle","atan","beginPath","moveTo","lineTo","strokeStyle","setLineDash","lineWidth","stroke","closePath","szHypotenuseText","areaTextSize","measureText","iXDistance","abs","iYDistance","bDisplayTextInMarquee","oDiagonalDisplayText","translate","PI","clientWidth","clientHeight","iTextHeight","szAreaText","oAreaTextLocation","CaliperRedrawCaller","CaliperRedraw","measurement","szMeasurementText","fakeClick","redrawInPlace","BindCaliperSaveHandleEvents","coord","scaledDistance","off","onFirst","g_oSavedCalipers","HandleHover","TryHandleClick","stopImmediatePropagation","isHorizontal","newCoords","fDistanceToDraw","GetLeftmostPoint","GetNewFakeCoords","getClickCoords","setTransform","DrawHorizontalCalliper","DrawVerticalCalliper","ArtworkViewer","AnnotationViewer","h","fakeClickCoords","xCoord","calculateCentralXCoordinate","one","CaliperMeasurementEnd","MeasurementInMM","g_iCurMeas","StoreDrawPoints","StoreEvent","CaliperMeasurePointerUp","measurementText","MeasurementAlreadyExists","DrawSaveIcon","on","CaliperMeasurementRedrawPointerUp","IsCaliperRedrawMode","IsCaliper","CaliperEventsBound","iStartX","iStartY","iEndX","iEndY","iDragOffset_x","iDragOffset_y","iCenterShift_x","iCenterShift_y","iBeginPoint_x","iBeginPoint_y","iEndPoint_x","iEndPoint_y","g_iRotDegrees","measurementPointerUp","oSyncCanvas","endPoint_x","endPoint_y","oHandleData","ColourDensityMeasurement","AreaMeasurement","PointToPointMeasurement","VerticalCalliperMeasurement","HorizontalCalliperMeasurement","filter","obj","ShowAnnotations","click","g_iBeginPoint_x","g_iBeginPoint_y","g_iEndPoint_x","g_iEndPoint_y","oTransformedCoords","oRotatedAnnotationDraw","isViewerUsingRealtimeRender","tempValue","hasSeparations","NoCompare","g_oCompareViewer","docChangeEvent","oComboControl","comboControl_GetControlById","selectedDocumentIndex","oDocument","documents","greenlightDocumentId","greenlightApprovalId","documentHasSeparations","documentType","eDocumentTypes","ThreeD","documentDisplaysAsSVG","getTextMeasurementText","oData","oAnnotation","g_szTextContent","g_oMarqueeDrawArray","id","setTextMeasurementWordVisibility","oTextElementArray","bIsVisible","IsTextVisible","j","ChildTextElements","RegisterEvents","oEventService","subscribe","window"],"mappings":"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","file":"GreenlightTechTools-acee02b209.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: GreenlightTechTools.js\r\n*\r\n* Description:\tThe class containing the functionality required by the Greenlight Technical Tools for measure distances, areas, colour density, barcodes, colour separation layers and text in piece of artwork.\r\n*/\r\n\r\nvar g_oTechTools = {};\r\nvar g_oPayload = { type: null, width: null, height: null, lineLength: null, area: null, degrees: null, separations: [], barcodeMeasurements: [] };\r\n\r\n(function () {\r\n\t\"use strict\";\r\n\r\n\tfunction TechToolsUI(oViewer, iApprovalId, oDoc, iDocumentType) {\r\n\t\t/**\r\n\t\t* Object to subscribe and publish custom events\r\n\t\t*/\r\n\t\tthis.g_oEvents = {};\r\n\r\n\t\tthis.g_oViewer = oViewer;\r\n\t\tthis.g_iDocumentType = iDocumentType;\r\n\t\tthis.g_oAnnotationViewer = oViewer.g_oAnnotationViewer;\r\n\t\tthis.g_oArtworkViewer = oViewer.g_oArtworkViewer;\r\n\t\tthis.g_iOrigin_x = 0;\r\n\t\tthis.g_iOrigin_y = 0;\r\n\t\tthis.g_iX = 0;\r\n\t\tthis.g_iY = 0;\r\n\r\n\t\t// The abbreviation used to indicate an area measurement (i.e. if measurement was in feet then it would be square feet - 'sq ft'). Used in UI display strings.\r\n\t\tthis.c_szAreaMeasurementAbbreviation = \"sq\";\r\n\r\n\t\t// The abbreviation used to indicate the units used for the angle measurement. Used in UI display strings.\r\n\t\tthis.c_szAngleMeasurementUnitsAbbreviation = \"deg\";\r\n\r\n\t\t// Metric - mm\r\n\t\tthis.c_szMeasurementSuffixMetric = \"mm\";\r\n\t\tthis.c_dMeasurementFactorMetric = 25.4;\r\n\r\n\t\t// Imperial - in (Since the image is measured in dpi then it's 1:1)\r\n\t\tthis.c_szMeasurementSuffixImperial = \"in\";\r\n\t\tthis.c_dMeasurementFactorImperial = 1;\r\n\r\n\t\t// 0 = Metric, 1 = Imperial.\r\n\t\tthis.c_iMeasurementUnitMetric = 0;\r\n\t\tthis.c_iMeasurementUnitImperial = 1;\r\n\t\tthis.g_szMeasurementSuffix = this.c_szMeasurementSuffixMetric;\r\n\t\tthis.g_dMeasurementFactor = this.c_dMeasurementFactorMetric;\r\n\r\n\t\tthis.g_eMeasurementTypes = {\r\n\t\t\tNONE: -1,\r\n\t\t\tPOINTTOPOINT: 0,\r\n\t\t\tAREA: 1,\r\n\t\t\tHORIZONTAL: 2,\r\n\t\t\tVERTICAL: 3,\r\n\t\t\tBARCODE: 4,\r\n\t\t\tCOLOURDENSITY: 5,\r\n\t\t\tTEXT: 6\r\n\t\t};\r\n\r\n\t\tthis.g_iSelectedMeasurementType = this.g_eMeasurementTypes.NONE;\r\n\r\n\t\tthis.g_iOriginalZoomLevel = 1;\r\n\r\n\t\tthis.g_eExamTypes = {\r\n\t\t\tCOLOURDENSITY: 0,\r\n\t\t\tBARCODE: 1,\r\n\t\t\tTEXT: 2\r\n\t\t};\r\n\t\tthis.g_iExamTypeCode = this.g_eExamTypes.COLOURDENSITY;\r\n\r\n\t\tthis.c_szFailedToExamineImage = \"\";\r\n\t\tthis.c_szInfoMsgNoLiveTextFound = \"\";\r\n\t\tthis.c_szInfoMsgNoBarcodeFound = \"\";\r\n\t\tthis.c_szInfoMsgNoSeparationsShown = \"\";\r\n\r\n\t\tthis.c_szSeparationPercentageClassName = \"separationPercentage\";\r\n\t\tthis.c_szSeparationPercentageElementName = \".\" + this.c_szSeparationPercentageClassName;\r\n\t\tthis.c_szSeparationPercentage_BarcodeClassName = \"separationPercentage_Barcode\";\r\n\t\tthis.c_szSeparationPercentage_BarcodeElementName = \".\" + this.c_szSeparationPercentage_BarcodeClassName;\r\n\r\n\t\tthis.c_iDisplayFontSize = 15 * g_oViewer.c_iDPI;\r\n\t\tthis.c_szDisplayFont = this.c_iDisplayFontSize + \"px Varela Round\";\r\n\t\tthis.c_szFillStyle = \"#fff\";\r\n\t\tthis.c_szTextBaseline = \"bottom\";\r\n\t\tthis.c_szTextAlign = \"start\";\t// Accepted values: \"start\", \"center\", \"end\", \"left\", \"right\"\r\n\r\n\t\tthis.g_iApprovalId = iApprovalId;\r\n\t\tthis.g_iDocumentId = oDoc.documentId;\r\n\r\n\t\tthis.g_szTextMeasurementTextContent = \"\";\r\n\r\n\t\tthis.g_szTACFieldDefault = \"\";\r\n\r\n\t\tthis.g_oTextMeasurementWordsArray = []; // The stored text measurements.\r\n\t\tthis.g_oBarcodeMeasurementArray = []; // The stored barcode measurements.\r\n\t\tthis.c_iDisplayMargin = 5; // The gap (in pixels) between the Barcode details displayed above the marquee area on the annotation canvas.\r\n\r\n\t\t// The highlight of the text area measurement box.\r\n\t\tthis.g_oTextAreaHighlightBox = {\r\n\t\t\tiBeginX: 5 * g_oViewer.c_iDPI,\r\n\t\t\tiBeginY: 13 * g_oViewer.c_iDPI,\r\n\t\t\tiWidth: 5 * g_oViewer.c_iDPI,\r\n\t\t\tiHeight: 20 * g_oViewer.c_iDPI\r\n\t\t};\r\n\t}\r\n\r\n\tTechToolsUI.prototype.toolTypeChange = function (element, type) {\r\n\t\t/// \r\n\t\t/// Helper method that changes tool type when a new one is clicked.\r\n\t\t/// \r\n\t\t/// The element being clicked.\r\n\t\t/// The annotation type that is being changed.\r\n\t\t/// \r\n\t\tif (type !== g_oTechTools.g_eMeasurementTypes.HORIZONTAL && type !== g_oTechTools.g_eMeasurementTypes.VERTICAL) {\r\n\t\t\t$(\"#divTechToolsDropDown\").slideUp(200);\r\n\t\t}\r\n\r\n\t\tif ($(element).hasClass(\"techToolType\")) {\r\n\t\t\t$(\".techToolType\").css(\"background-color\", \"\");\r\n\t\t\t$(\".annotationType\").removeStyle();\r\n\t\t\tthis.g_iSelectedMeasurementType = type;\r\n\t\t}\r\n\r\n\t\t$(element).css(\"background-color\", \"grey\");\r\n\r\n\t\t// Change the cursor to a crosshair\r\n\t\t$('#AnnotationViewer').css(\"cursor\", \"crosshair\");\r\n\t\tif (g_oViewer.g_oCompareMode === eCompareMode.SideBySide || g_oViewer.g_oCompareMode === eCompareMode.SideBySideDiff) {\r\n\t\t\t$('#CompareAnnotationViewer').css(\"cursor\", \"crosshair\");\r\n\t\t}\r\n\t\tg_oAnnotations.g_szPrevCursorStyle = \"crosshair\";\r\n\r\n\t\t// Close all annotations\r\n\t\t$(\".speechbubble\").remove();\r\n\t\tfor (var i = 0; i < g_oAnnotations.g_oAnnotationsMade.length; i++) {\r\n\t\t\tg_oAnnotations.g_oAnnotationsMade[i].g_bClosed = true;\r\n\t\t}\r\n\r\n\t\tswitch (type) {\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.POINTTOPOINT:\r\n\t\t\t\tg_oAnnotations.g_oLastUsedTool = $(\"#divTechToolsPointToPoint\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.AREA:\r\n\t\t\t\tg_oAnnotations.g_oLastUsedTool = $(\"#divTechToolsArea\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.VERTICAL:\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.HORIZONTAL:\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.COLOURDENSITY:\r\n\t\t\t\tg_oAnnotations.g_oLastUsedTool = $(\"#divTechToolsDensity\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.BARCODE:\r\n\t\t\t\tg_oAnnotations.g_oLastUsedTool = $(\"#divTechToolBarcode\");\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.TEXT:\r\n\t\t\t\tg_oAnnotations.g_oLastUsedTool = $(\"#divTechToolsText\");\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tg_oTechTools.g_oAnnotationViewer.redraw(false);\r\n\t};\r\n\r\n\tTechToolsUI.prototype.clearToolType = function () {\r\n\t\t/// \r\n\t\t/// Helper method that clears the tool type when called.\r\n\t\t/// \r\n\r\n\t\t// Slide up the tech tools options.\r\n\t\t$(\"#divTechToolsDropDown\").slideUp(200);\r\n\r\n\t\t// Clear the highlighted option.\r\n\t\t$(\".techToolType\").css(\"background-color\", \"\");\r\n\r\n\t\t//Change the cursor back\r\n\t\t$('#AnnotationViewer').css(\"cursor\", \"default\");\r\n\t\tg_oAnnotations.g_szPrevCursorStyle = \"default\";\r\n\r\n\t\t$(\"#btnTechTools\").parent().removeClass(\"selectedButton\");\r\n\r\n\t\tg_oTechTools.g_iSelectedMeasurementType = g_oTechTools.g_eMeasurementTypes.NONE;\r\n\t\tchangeCanvasFunction();\r\n\r\n\t\t// Clear any previous barcode measurement data.\r\n\t\tg_oTechTools.clearBarcodeMeasurementArray();\r\n\t};\r\n\r\n\tTechToolsUI.prototype.formatMeasuredDistance = function (measuredDistance) {\r\n\t\t/// \r\n\t\t/// Formats the specified measured distance to either 2 decimal places\r\n\t\t/// if the measured units preference is set to Metric or 4 decimal places\r\n\t\t/// if the preference is set to Imperial.\r\n\t\t/// \r\n\t\t/// The measured distance to be formatted.\r\n\t\t/// Returns a string containing the formatted value.\r\n\t\tvar szFormattedText;\r\n\r\n\t\tif (g_oSettings.g_oUserSettings.UseMetricUnits) {\r\n\t\t\tszFormattedText = round(measuredDistance, 2).toFixed(2);\r\n\t\t}\r\n\t\telse {\r\n\t\t\tszFormattedText = round(measuredDistance, 4).toFixed(4);\r\n\t\t}\r\n\r\n\t\treturn szFormattedText;\r\n\t};\r\n\r\n\t/**\r\n\t * Create the examine image request and send it to the server.\r\n\t * @param {object} oArtworkViewer - The artwork viewer.\r\n\t * @param {object} oAnnotationViewer - The annotation viewer.\r\n\t * @param {int} begin_x - The starting point x coordinate.\r\n\t * @param {int} begin_y - The starting point y coordinate.\r\n\t * @param {int} end_x - The ending point x coordinate.\r\n\t * @param {int} end_y - The ending point y coordinate.\r\n\t * @param {enum} examTypeCode - Type of examine request\r\n\t * @param {any} iAnnotationId - The annotation.\r\n\t */\r\n\tTechToolsUI.prototype.examineImage = function (oArtworkViewer, oAnnotationViewer, begin_x, begin_y, end_x, end_y, examTypeCode, iAnnotationId) {\r\n\t\t\r\n\t\t// Show spinners in separations area.\r\n\t\tg_oSeparations.ShowSpinners();\r\n\r\n\t\t// Remove any existing tech tool results.\r\n\t\t$(g_oTechTools.c_szSeparationPercentageElementName).remove();\r\n\t\t$(g_oTechTools.c_szSeparationPercentage_BarcodeElementName).remove();\r\n\r\n\t\t// Create the image request.\r\n\t\tvar oExamineImageRequest = new ExamineImageRequest();\r\n\t\toExamineImageRequest.DocumentName = oArtworkViewer.g_oDoc.documentName;\r\n\t\toExamineImageRequest.DocumentId = oArtworkViewer.g_oDoc.documentId;\r\n\t\toExamineImageRequest.PageNumber = oArtworkViewer.g_iCurrentPage;\r\n\t\toExamineImageRequest.ConsumerId = oArtworkViewer.g_oDoc.consumerId;\r\n\t\toExamineImageRequest.Dimensions.MinX = Math.max(0, begin_x);\r\n\t\toExamineImageRequest.Dimensions.MaxX = Math.min(1, end_x);\r\n\t\toExamineImageRequest.Dimensions.MinY = Math.max(0, begin_y);\r\n\t\toExamineImageRequest.Dimensions.MaxY = Math.min(1, end_y);\r\n\t\toExamineImageRequest.ExamTypeCode = examTypeCode;\r\n\t\toExamineImageRequest.CurrentResolution = oArtworkViewer.g_iCurrentResolution;\r\n\t\toExamineImageRequest.OriginalResolution = oArtworkViewer.g_oDoc.pages[oArtworkViewer.g_iCurrentPage - 1].documentResolutionPPI;\r\n\t\toExamineImageRequest.RealtimeRenderReference = oArtworkViewer.g_szRealtimeRenderReference;\r\n\t\toExamineImageRequest.AnnotationID = iAnnotationId;\r\n\t\toExamineImageRequest.FullImageWidth = (typeof(oArtworkViewer.g_oaImages[0]) !== \"undefined\") ? oArtworkViewer.g_oaImages[0].ImageWidth : 0;\r\n\t\toExamineImageRequest.FullImageHeight = (typeof(oArtworkViewer.g_oaImages[0]) !== \"undefined\") ? oArtworkViewer.g_oaImages[0].ImageHeight : 0;\r\n\r\n\t\t// Create the marquee dimensions.\r\n\t\tvar oMarqueeDimensions = new ImageDimensions();\r\n\t\toMarqueeDimensions.MinX = Math.max(0, begin_x);\r\n\t\toMarqueeDimensions.MinY = Math.max(0, begin_y);\r\n\t\toMarqueeDimensions.MaxX = Math.min(1, end_x);\r\n\t\toMarqueeDimensions.MaxY = Math.min(1, end_y);\r\n\r\n\t\t/// Outline the image request to be sent up.\r\n\t\tvar oJSON = {\r\n\t\t\tSessionId: g_szSessionId,\r\n\t\t\toExamineImageRequest: oExamineImageRequest\r\n\t\t};\r\n\r\n\t\t// Send the examine image request.\r\n\t\t$.ajax({\r\n\t\t\ttype: \"POST\",\r\n\t\t\turl: \"TechTools/examineImage\",\r\n\t\t\tdata: JSON.stringify(oJSON),\r\n\t\t\tcontentType: \"application/json; charset=utf-8\",\r\n\t\t\tdataType: \"json\",\r\n\t\t\tsuccess: function (response) {\r\n\t\t\t\tg_oTechTools.ExamineImageResponse_CH(response.Contents, oExamineImageRequest, oArtworkViewer, oAnnotationViewer, oMarqueeDimensions);\r\n\t\t\t},\r\n\t\t\tfailure: function (response) {\r\n\t\t\t\tg_oGreenlightMessages.displayErrorBubble(g_oTechTools.c_szFailedToExamineImage);\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t/// \r\n\t/// The call handler for the Examine Image Request.\r\n\t/// This processes the response message and updates the UI accordingly.\r\n\t/// \r\n\t/// The response contents.\r\n\t/// The examine image request.\r\n\t/// The current canvas.\r\n\t/// The marquee dimensions.\r\n\tTechToolsUI.prototype.ExamineImageResponse_CH = function (oResponseContents, oExamineImageRequest, oArtworkViewer, oAnnotationViewer, oMarqueeDimensions) {\r\n\t\tvar oExamineImageResponse = JSON.parse(oResponseContents);\r\n\t\tvar oSeparationsArray = [];\r\n\t\toSeparationsArray = (oExamineImageRequest.ExamTypeCode === this.g_eExamTypes.TEXT) ? oExamineImageResponse.WordsList : oExamineImageResponse;\r\n\r\n\t\tg_oPayload.separations = oSeparationsArray;\r\n\t\tvar szTextContent = \"\";\r\n\t\tvar currentFont;\r\n\t\tvar currentFontSize;\r\n\t\tvar dMinX = 1;\r\n\t\tvar dMinY = 1;\r\n\t\tvar dMaxX = 0;\r\n\t\tvar dMaxY = 0;\r\n\t\tvar iBarcodeDisplayTextCount = 0;\r\n\t\tg_oPayload.barcodeMeasurements.length = 0;\r\n\t\tvar iTotalAreaCoverage = 0;\r\n\r\n\t\tif (g_oTechTools.g_oTextMeasurementWordsArray.length > 0) {\t\t// If we already have words from a previous Text Measurement...\r\n\t\t\tg_oTechTools.g_oTextMeasurementWordsArray.length = 0;\t\t// ...clear the array by resetting it's length.\r\n\t\t}\r\n\r\n\t\t// Outline the co-ordinates for the annotation handle.\r\n\t\tvar iPointX = Math.max(g_oMarquee.g_iX, g_oMarquee.g_iOrigin_x) + g_oAnnotationActions.g_iDragRectOffset;\r\n\t\tvar iPointY = Math.min(g_oMarquee.g_iY, g_oMarquee.g_iOrigin_y);\r\n\r\n\t\t// Get the transformed coordinates.\r\n\t\tvar trueCoords = g_oMarquee.transformMarqueeCoordinatesForRotation(oArtworkViewer, false, false);\r\n\t\tvar transformedCoordinates = TechToolsUI.prototype.transformCoordinates(trueCoords.iBeginPoint_X, trueCoords.iBeginPoint_Y, trueCoords.iEndPoint_X, trueCoords.iEndPoint_Y, trueCoords.iDragOffset_X, trueCoords.iDragOffset_Y, trueCoords.iCenterShift_X, trueCoords.iCenterShift_Y, oArtworkViewer);\r\n\r\n\t\t// De-rotate.\r\n\t\tg_oMarquee.derotateCanvasContext(oArtworkViewer.g_oAnnotationCanvas.g_oContext, oArtworkViewer.g_oAnnotationCanvas, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.width, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.height, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.width / 2, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.height / 2);\r\n\t\toArtworkViewer.g_oAnnotationCanvas.g_oContext.save();\r\n\r\n\t\t// Determine if the coordinates are out of bounds.\r\n\t\tvar bOutOfBounds = ((transformedCoordinates.concat().sort(sortAnnotationCoords.returnXMin)[0][0] < 0) || (transformedCoordinates.concat().sort(sortAnnotationCoords.returnXMax)[0][0] > 1) || (transformedCoordinates.concat().sort(sortAnnotationCoords.returnYMin)[0][1] < 0) || (transformedCoordinates.concat().sort(sortAnnotationCoords.returnYMax)[0][1] > 1));\r\n\r\n\t\t// Determine if annotation handles can be drawn.\r\n\t\tvar bDrawAnnotationHandles = !g_oViewer.g_bReadOnly && oArtworkViewer.g_bMainCanvas && !bOutOfBounds;\r\n\r\n\t\t// Restore the context.\r\n\t\toArtworkViewer.g_oAnnotationCanvas.g_oContext.restore();\r\n\r\n\t\t// Keep track of any annotation handles drawn as part of the render.\r\n\t\tvar oAnnotationHandles = [];\r\n\r\n\t\t// Render the results.\r\n\t\tfor (var szSeparationName in oSeparationsArray) {\r\n\t\t\tswitch (oExamineImageRequest.ExamTypeCode) {\r\n\t\t\t\r\n\t\t\t\tcase this.g_eExamTypes.COLOURDENSITY:\r\n\r\n\t\t\t\t\t// If the separation is not disabled, add the colour density measurement.\r\n\t\t\t\t\tif ($(\"#\" + g_oSeparations.SanitiseSeparationName(szSeparationName)).attr(\"class\").indexOf(g_oSeparations.SeparationDisabledClassName) === -1) {\r\n\t\t\t\t\t\tvar percent = (Math.round((1 - ((parseInt(oSeparationsArray[szSeparationName][0])) / 255)) * 10000) / 100).toFixed(0);\r\n\r\n\t\t\t\t\t\t// Add additional percentage value\r\n\t\t\t\t\t\tiTotalAreaCoverage += parseInt(percent);\r\n\t\t\t\t\t\t// Add the percentage sign\r\n\t\t\t\t\t\tpercent += \"%\";\r\n\r\n\t\t\t\t\t\t$(\"#\" + g_oSeparations.SanitiseSeparationName(szSeparationName)).children(\".innerSepDiv\").prepend(\"
\" + percent + \"
\");\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// If annotation handles can be drawn, add a single handle for this colour density measurement.\r\n\t\t\t\t\tif (bDrawAnnotationHandles && oAnnotationHandles.length == 0) {\r\n\r\n\t\t\t\t\t\t// Add coordinates to handle list.\r\n\t\t\t\t\t\toAnnotationHandles.push({\r\n\t\t\t\t\t\t\thandleX: iPointX,\r\n\t\t\t\t\t\t\thandleY: iPointY,\r\n\t\t\t\t\t\t\tannotationCoordinates: transformedCoordinates,\r\n\t\t\t\t\t\t\tannotationData: g_oPayload\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase this.g_eExamTypes.BARCODE:\r\n\r\n\t\t\t\t\t// Only draw the barcode if the separation is enabled.\r\n\t\t\t\t\tif (g_oSeparations.IsSeparationEnabled(oArtworkViewer, szSeparationName)) {\r\n\r\n\t\t\t\t\t\t// Get the barcode details.\r\n\t\t\t\t\t\tvar szCodeType = oSeparationsArray[szSeparationName][0].replace(\"_\", \" \");\t// Replace references to 'result' with oSeparations.\r\n\t\t\t\t\t\tvar szCodeData = oSeparationsArray[szSeparationName][1];\r\n\t\t\t\t\t\tvar szWidthMagnification = oSeparationsArray[szSeparationName][2];\r\n\t\t\t\t\t\tvar dBarcodeX = oSeparationsArray[szSeparationName][3];\r\n\t\t\t\t\t\tvar dBarcodeY = oSeparationsArray[szSeparationName][4];\r\n\t\t\t\t\t\tvar dBarcodeWidth = oSeparationsArray[szSeparationName][5];\r\n\t\t\t\t\t\tvar dBarcodeHeight = oSeparationsArray[szSeparationName][6];\r\n\r\n\t\t\t\t\t\t// Get the barcode text.\r\n\t\t\t\t\t\tvar szMagnificationText = (szWidthMagnification === \"0\" || szWidthMagnification === \"∞\" || szWidthMagnification === \"Infinity\") ? \"\" : \" (\" + szWidthMagnification + \"%)\";\r\n\t\t\t\t\t\tvar szDisplayText = \"(\" + szSeparationName + \") \" + szCodeType + \": \" + szCodeData + szMagnificationText;\r\n\r\n\t\t\t\t\t\t// Add the barcode text to the separation.\r\n\t\t\t\t\t\t$(\"#\" + g_oSeparations.SanitiseSeparationName(szSeparationName)).append(\"
\" + szCodeType + \": \" + szCodeData + szMagnificationText + \"
\");\r\n\r\n\t\t\t\t\t\t// Setup the annotation context for drawing.\r\n\t\t\t\t\t\tvar annContext = oAnnotationViewer.g_oContext;\r\n\t\t\t\t\t\tannContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\t\t\t\t\t\tannContext.font = g_oTechTools.c_szDisplayFont;\r\n\t\t\t\t\t\tannContext.textBaseline = g_oTechTools.c_szTextBaseline;\r\n\t\t\t\t\t\tannContext.textalign = g_oTechTools.c_szTextAlign;\r\n\r\n\t\t\t\t\t\t// Add the barcode measurement information to the stored list.\r\n\t\t\t\t\t\tvar oBarcodeMeasurement = new BarcodeMeasurement();\r\n\t\t\t\t\t\toBarcodeMeasurement.ArtworkCanvasId = oArtworkViewer.g_szCanvasId;\r\n\t\t\t\t\t\toBarcodeMeasurement.AnnotationCanvasId = oAnnotationViewer.g_szCanvasId;\r\n\t\t\t\t\t\toBarcodeMeasurement.SeparationName = szSeparationName;\r\n\t\t\t\t\t\toBarcodeMeasurement.CodeType = szCodeType;\r\n\t\t\t\t\t\toBarcodeMeasurement.CodeData = szCodeData;\r\n\t\t\t\t\t\toBarcodeMeasurement.DisplayText = szDisplayText;\r\n\t\t\t\t\t\toBarcodeMeasurement.MarqueeCoordinates = deepCopyObject(oExamineImageRequest.Dimensions);\r\n\t\t\t\t\t\toBarcodeMeasurement.widthMagnification = szWidthMagnification;\r\n\t\t\t\t\t\toBarcodeMeasurement.X = parseFloat(dBarcodeX);\r\n\t\t\t\t\t\toBarcodeMeasurement.Y = parseFloat(dBarcodeY);\r\n\t\t\t\t\t\toBarcodeMeasurement.Width = parseFloat(dBarcodeWidth);\r\n\t\t\t\t\t\toBarcodeMeasurement.Height = parseFloat(dBarcodeHeight);\r\n\t\t\t\t\t\tg_oTechTools.g_oBarcodeMeasurementArray.push(oBarcodeMeasurement);\r\n\t\t\t\t\t\tg_oPayload.barcodeMeasurements.push(oBarcodeMeasurement);\r\n\r\n\t\t\t\t\t\t// Render the barcode measurement info onto the marquee overlay.\r\n\t\t\t\t\t\tvar oBarcodeCoordinates = g_oTechTools.renderBarcodeMeasurement(oAnnotationViewer, oArtworkViewer, oBarcodeMeasurement, iBarcodeDisplayTextCount);\r\n\r\n\t\t\t\t\t\t// If annotation handles can be drawn.\r\n\t\t\t\t\t\tif (bDrawAnnotationHandles) {\r\n\r\n\t\t\t\t\t\t\t// Create the annotation data for this barcode.\r\n\t\t\t\t\t\t\tvar oBarcodeAnnotationData = deepCopyObject(g_oPayload);\r\n\t\t\t\t\t\t\toBarcodeAnnotationData.barcodeMeasurements = [oBarcodeMeasurement];\r\n\r\n\t\t\t\t\t\t\t// Calculate the annotation handle position.\r\n\t\t\t\t\t\t\tvar oHandleSize = g_oAnnotationActions.calculateAnnotationHandleSize(eAnnotationHandleTypes.CreateNewAnnotation);\r\n\t\t\t\t\t\t\tvar iHandleDisplayCoordX = oBarcodeCoordinates.x - oHandleSize[0] - (oHandleSize[0] / 4);\r\n\t\t\t\t\t\t\tvar iHandleDisplayCoordY = oBarcodeCoordinates.y - g_oTechTools.c_iDisplayFontSize - (oHandleSize[0] / 4);\r\n\r\n\t\t\t\t\t\t\t// Add coordinates to handle list.\r\n\t\t\t\t\t\t\toAnnotationHandles.push({\r\n\t\t\t\t\t\t\t\thandleX: iHandleDisplayCoordX,\r\n\t\t\t\t\t\t\t\thandleY: iHandleDisplayCoordY,\r\n\t\t\t\t\t\t\t\tannotationCoordinates: null,\r\n\t\t\t\t\t\t\t\tannotationData: oBarcodeAnnotationData\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// Increase the barcode count.\r\n\t\t\t\t\t\tiBarcodeDisplayTextCount++;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase this.g_eExamTypes.TEXT:\r\n\t\t\t\t\tg_oTechTools.g_oTextMeasurementWordsArray.push(oSeparationsArray[szSeparationName]);\r\n\r\n\t\t\t\t\tif (oExamineImageResponse.AnnotationID < 0) {\r\n\t\t\t\t\t\t// Find the outlying boundaries of all word elements.\r\n\t\t\t\t\t\tif (oSeparationsArray[szSeparationName].Llx < dMinX) {\r\n\t\t\t\t\t\t\tdMinX = oSeparationsArray[szSeparationName].Llx;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (oSeparationsArray[szSeparationName].Ury < dMinY) {\r\n\t\t\t\t\t\t\tdMinY = oSeparationsArray[szSeparationName].Ury;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (oSeparationsArray[szSeparationName].Urx > dMaxX) {\r\n\t\t\t\t\t\t\tdMaxX = oSeparationsArray[szSeparationName].Urx;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (oSeparationsArray[szSeparationName].Lly > dMaxY) {\r\n\t\t\t\t\t\t\tdMaxY = oSeparationsArray[szSeparationName].Lly;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Show a newline if there is a change in style.\r\n\t\t\t\t\t\tif (currentFont !== oSeparationsArray[szSeparationName].FontName || currentFontSize !== oSeparationsArray[szSeparationName].FontSize) {\r\n\t\t\t\t\t\t\tcurrentFont = oSeparationsArray[szSeparationName].FontName;\r\n\t\t\t\t\t\t\tcurrentFontSize = oSeparationsArray[szSeparationName].FontSize;\r\n\t\t\t\t\t\t\tif (szTextContent !== \"\") {\r\n\t\t\t\t\t\t\t\tszTextContent += \"

\";\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tszTextContent += \" \" + currentFont + \" \" + currentFontSize + \"pt
\";\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tszTextContent += oSeparationsArray[szSeparationName].TextContent;\r\n\t\t\t\t\t\t// No space after means a new line\r\n\t\t\t\t\t\tif (!oSeparationsArray[szSeparationName].SpaceAfter) {\r\n\t\t\t\t\t\t\tszTextContent += \"
\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If we have annotation handles.\r\n\t\tif (oAnnotationHandles.length > 0) {\r\n\t\t\t\r\n\t\t\t// Draw the annotation handles.\r\n\t\t\tfor (var i = 0; i < oAnnotationHandles.length; i++) {\r\n\t\t\t\tg_oAnnotationActions.drawAnnotationHandle([oAnnotationHandles[i].handleX, oAnnotationHandles[i].handleY], g_oSettings.g_oUserSettings.AnnotationColour, true, eAnnotationHandleTypes.CreateNewAnnotation, oArtworkViewer.g_oAnnotationCanvas.g_oContext);\r\n\t\t\t}\r\n\r\n\t\t\t// Set the pointer move event.\r\n\t\t\tchangeCanvasFunction('#AnnotationViewer', \"pointermove.annotationUI\", function (e) {\r\n\t\t\t\tAnnotationAction.prototype.mouseMoveAnnotationHandles(e, oArtworkViewer, g_oAnnotationActions.g_oAnnotationCanvas, oAnnotationHandles, eAnnotationHandleTypes.CreateNewAnnotation);\r\n\t\t\t});\r\n\r\n\t\t\t// Set the pointer down event.\r\n\t\t\tchangeCanvasFunction(\"#AnnotationViewer\", \"pointerdown.annotationUI\", function (e) {\r\n\t\t\t\tAnnotationAction.prototype.mouseClickAnnotationHandles(e, oArtworkViewer, g_oAnnotationActions.g_oAnnotationCanvas, oAnnotationHandles, eAnnotationHandleTypes.CreateNewAnnotation);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t//Set the TAC (Total Area Coverage)\r\n\t\tif (oExamineImageRequest.ExamTypeCode === this.g_eExamTypes.COLOURDENSITY) {\r\n\t\t\t// Set the default if first pass through, else reset to just text.\r\n\t\t\tif (this.g_szTACFieldDefault === \"\") {\r\n\t\t\t\tthis.g_szTACFieldDefault = $('#td_TAC').text();\r\n\t\t\t} else {\r\n\t\t\t\t$('#td_TAC').text(this.g_szTACFieldDefault);\r\n\t\t\t}\r\n\r\n\t\t\t//Set the value\r\n\t\t\t$('#td_TAC').text($('#td_TAC').text() + iTotalAreaCoverage + \"%\");\r\n\t\t\t$('#td_TAC').show();\r\n\r\n\t\t} else {\r\n\t\t\t$('#td_TAC').hide();\r\n\t\t}\r\n\r\n\r\n\t\t// Create annotation for selected text ONLY if we are on the current approval doc\r\n\t\tif ((oExamineImageRequest.ExamTypeCode == g_oTechTools.g_eExamTypes.TEXT) && (g_szSessionId !== 0)) {\r\n\t\t\tif (((oSeparationsArray !== undefined) && (oSeparationsArray !== null)) && oSeparationsArray.length > 0) {\r\n\t\t\t\tif (oExamineImageResponse.AnnotationID < 0) {\r\n\r\n\t\t\t\t\t// We have a new Text Measurement. Time to create a fresh annotation.\r\n\t\t\t\t\tvar iImageWidth = oArtworkViewer.g_iScaledImageWidth;\r\n\t\t\t\t\tvar iImageHeight = oArtworkViewer.g_iScaledImageHeight;\r\n\r\n\t\t\t\t\t// Calculate the compare offset of the canvas.\r\n\t\t\t\t\tvar compareOffset_x, compareOffset_y;\r\n\t\t\t\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkViewer);\r\n\t\t\t\t\tcompareOffset_x = co.x;\r\n\t\t\t\t\tcompareOffset_y = co.y;\r\n\r\n\t\t\t\t\t// These coordinates get pushed into the g_oAnnotations.g_oTempAnnotationArray by the AnnotationUI.prototype.annotationPointerUp function.\r\n\t\t\t\t\t// They need to be covered from the Adobe PDF coordinates back into pixel values.\r\n\t\t\t\t\tg_oAnnotations.g_oTempAnnotationArray.length = 0;\t// Clearing the temporary annotation coordinate array.\r\n\t\t\t\t\toAnnotationViewer.g_iOrigin_x = round((dMinX * iImageWidth) + compareOffset_x); // lower left x\r\n\t\t\t\t\toAnnotationViewer.g_iOrigin_y = round((dMinY * iImageHeight) + compareOffset_y); // upper right y\r\n\t\t\t\t\toAnnotationViewer.g_iX = round((dMaxX * iImageWidth) + compareOffset_x); // upper right x\r\n\t\t\t\t\toAnnotationViewer.g_iY = round((dMaxY * iImageHeight) + compareOffset_y); // lower left y\r\n\t\t\t\t\tg_oAnnotations.g_iApprovalId = g_oTechTools.g_iApprovalId;\r\n\t\t\t\t\tg_oAnnotations.g_oAnnotationColSelected = g_oSettings.g_oUserSettings.AnnotationColour;\r\n\t\t\t\t\tg_oAnnotations.g_iAnnotationType = eAnnotationTypes.TextMeasurement;\r\n\r\n\t\t\t\t\t// Update user preferences so that when the text measurement is complete, the next action will be another text measurement rather than the previously use annotation type.\r\n\t\t\t\t\tg_oSettings.g_oUserSettings.LastUsedAnnotationType = eAnnotationTypes.TextMeasurement;\r\n\t\t\t\t\tg_oSettings.syncSettings();\r\n\r\n\t\t\t\t\tg_oTechTools.g_szTextMeasurementTextContent = szTextContent;\r\n\r\n\t\t\t\t\tg_oAnnotations.setAnnotationRectangle(oAnnotationViewer, oArtworkViewer, oAnnotationViewer.g_oCanvas);\r\n\t\t\t\t\tg_oAnnotations.annotationPointerUp(undefined, false, oMarqueeDimensions, oArtworkViewer, oAnnotationViewer);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\t// We are re-highlighting the words for an existing Text Measurement annotation.\r\n\t\t\t\t\tvar oJSON = {\r\n\t\t\t\t\t\tiAnnotationID: oExamineImageResponse.AnnotationID,\r\n\t\t\t\t\t\toWordsArray: deepCopyArray(g_oTechTools.g_oTextMeasurementWordsArray)\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\tEventService.publish(\"setExistingTextMeasurementAnnotationWordsList\", oJSON);\r\n\t\t\t\t\tg_oTechTools.g_szTextMeasurementTextContent = \"\";\r\n\t\t\t\t\tg_oTechTools.g_oTextMeasurementWordsArray.length = 0;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if (!g_oAnnotations.g_bAnnotationsFound) {\r\n\t\t\t\tg_oGreenlightMessages.displayWarningBubble(g_oTechTools.c_szInfoMsgNoLiveTextFound);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If this is a text measurement.\r\n\t\tif (oExamineImageRequest.ExamTypeCode == g_oTechTools.g_eExamTypes.TEXT) {\r\n\r\n\t\t\t// Redraw the canvas.\r\n\t\t\toAnnotationViewer.redraw(false);\r\n\t\t}\r\n\t\t// If this is a barcode measurement type, and we have found no barcodes in the area.\r\n\t\telse if (oExamineImageRequest.ExamTypeCode == g_oTechTools.g_eExamTypes.BARCODE && iBarcodeDisplayTextCount == 0) {\r\n\r\n\t\t\t// Display the warning bubble and redraw the canvas.\r\n\t\t\tg_oGreenlightMessages.displayWarningBubble(g_oTechTools.c_szInfoMsgNoBarcodeFound);\r\n\t\t\toAnnotationViewer.redraw(false);\r\n\t\t}\r\n\r\n\t\t// Hide the seperation spinners.\r\n\t\t$(g_oSeparations.SpinnerElementName).hide();\r\n\t};\r\n\r\n\t// Gets the barcode measurements for a canvas.\r\n\tTechToolsUI.prototype.getBarcodeMeasurementArray = function (canvasId) {\r\n\r\n\t\t// Create a new array to store the barcode measurements.\r\n\t\tvar oBarcodeMeasurementArray = [];\r\n\r\n\t\t// Loop through each of the stored barcode measurements.\r\n\t\tfor (var i = 0; i < g_oTechTools.g_oBarcodeMeasurementArray.length; i++) {\r\n\r\n\t\t\t// If the barcode measurement is on this canvas.\r\n\t\t\tif (g_oTechTools.g_oBarcodeMeasurementArray[i].ArtworkCanvasId == canvasId || g_oTechTools.g_oBarcodeMeasurementArray[i].AnnotationCanvasId == canvasId) {\r\n\r\n\t\t\t\t// Add the barcode measurement to the list.\r\n\t\t\t\toBarcodeMeasurementArray.push(g_oTechTools.g_oBarcodeMeasurementArray[i]);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the barcode measurements array.\r\n\t\treturn oBarcodeMeasurementArray;\r\n\t}\r\n\r\n\t// Renders the barcode measurements for a canvas.\r\n\tTechToolsUI.prototype.renderCanvasBarcodeMeasurements = function (szArtworkCanvasId) {\r\n\r\n\t\t// Get the artwork and annotation canvas.\r\n\t\tvar oArtworkCanvas = g_oViewer.getCanvas(szArtworkCanvasId);\r\n\t\tvar oAnnotationCanvas = oArtworkCanvas.g_oAnnotationCanvas;\r\n\r\n\t\t// If the canvas passed in was an annotation canvas.\r\n\t\tif (oArtworkCanvas.g_iCanvasType == eCanvasType.Annotation) {\r\n\r\n\t\t\t// Get the artwork and annotation canvas.\r\n\t\t\toAnnotationCanvas = g_oViewer.getCanvas(szArtworkCanvasId);\r\n\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(oAnnotationCanvas.g_szCanvasId);\r\n\t\t}\r\n\r\n\t\t// Get a list of any active barcode measurements for the canvas.\r\n\t\tvar oBarcodeMeasurementArray = g_oTechTools.getBarcodeMeasurementArray(szArtworkCanvasId);\r\n\r\n\t\t// If we are using the barcode measurement tool, and barcodes have been found for this canvas.\r\n\t\tif ((g_oTechTools.g_iSelectedMeasurementType === g_oTechTools.g_eMeasurementTypes.BARCODE) && (oBarcodeMeasurementArray.length > 0)) {\r\n\r\n\t\t\t// If we are in an overlay compare mode.\r\n\t\t\tif (g_oViewer.g_oCompareMode == eCompareMode.Overlay ||\r\n\t\t\t\tg_oViewer.g_oCompareMode == eCompareMode.Blink ||\r\n\t\t\t\tg_oViewer.g_oCompareMode == eCompareMode.SliderHorizontal ||\r\n\t\t\t\tg_oViewer.g_oCompareMode == eCompareMode.SliderVertical) {\r\n\r\n\t\t\t\t// Do not redraw this barcode unless this is the current annotation canvas.\r\n\t\t\t\tif (oAnnotationCanvas.g_szCanvasId != g_oCompare.getAnnotationCanvasId()) {\r\n\r\n\t\t\t\t\t// Do not render the barocdes.\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Redraw any barcode measurements for the canvas.\r\n\t\t\tfor (var i = 0; i < oBarcodeMeasurementArray.length; i++) {\r\n\t\t\t\tg_oTechTools.renderBarcodeMeasurement(oAnnotationCanvas, oArtworkCanvas, oBarcodeMeasurementArray[i], i, i === 0);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Pans to a specific barcode measurement.\r\n\tTechToolsUI.prototype.panToBarcode = function (event, iBarcodePosition) {\r\n\t\tevent.preventDefault();\r\n\t\tevent.stopPropagation();\r\n\r\n\t\t// Get the requested barcode to pan to.\r\n\t\tvar oBarcode = g_oTechTools.g_oBarcodeMeasurementArray[iBarcodePosition];\r\n\r\n\t\t// Get the artwork and annotation viewer for the barcode.\r\n\t\tvar oArtworkViewer = g_oViewer.getCanvas(oBarcode.ArtworkCanvasId);\r\n\t\tvar oAnnotationViewer = g_oViewer.getCanvas(oBarcode.AnnotationCanvasId);\r\n\r\n\t\t/* Compare offset needs to be considered.\r\n\t\t// Calulate the compare offset on the artwork canvas.\r\n\t\tvar compareOffset_x, compareOffset_y;\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkViewer);\r\n\t\tcompareOffset_x = co.x;\r\n\t\tcompareOffset_y = co.y;\r\n\t\t*/\r\n\r\n\t\t// Setup the pan to the barcode.\r\n\t\tvar oBarcodeMidPoint = [oBarcode.MarqueeCoordinates.MinX + ((oBarcode.MarqueeCoordinates.MaxX - oBarcode.MarqueeCoordinates.MinX) / 2), oBarcode.MarqueeCoordinates.MinY + ((oBarcode.MarqueeCoordinates.MaxY - oBarcode.MarqueeCoordinates.MinY) / 2)];\r\n\t\toArtworkViewer.g_iTempDragOffset_x = (oBarcodeMidPoint[0] * oArtworkViewer.g_iScaledImageWidth) - (oArtworkViewer.g_iScaledImageWidth / 2);\r\n\t\toArtworkViewer.g_iTempDragOffset_y = (oBarcodeMidPoint[1] * oArtworkViewer.g_iScaledImageHeight) - (oArtworkViewer.g_iScaledImageHeight / 2);\r\n\t\toArtworkViewer.g_iDragXDiff = (oArtworkViewer.g_iDragOffset_x - oArtworkViewer.g_iTempDragOffset_x) / oAnnotationViewer.g_iAnimateFrames;\r\n\t\toArtworkViewer.g_iDragYDiff = (oArtworkViewer.g_iDragOffset_y - oArtworkViewer.g_iTempDragOffset_y) / oAnnotationViewer.g_iAnimateFrames;\r\n\r\n\t\t// Pan to the barcode.\r\n\t\toArtworkViewer.g_oCanvasZoom.startZoomAnimate();\r\n\t}\r\n\r\n\t// Clears any current barcode measurements.\r\n\tTechToolsUI.prototype.clearBarcodeMeasurementArray = function () {\r\n\r\n\t\t// Clear any previous barcode measurement data.\r\n\t\tg_oTechTools.g_oBarcodeMeasurementArray.length = 0;\r\n\t\tg_oPayload.barcodeMeasurements.length = 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Renders a requested barcode measurement.\r\n\t * @param {object} oAnnotationViewer - The annotation viewer.\r\n\t * @param {object} oArtworkViewer - The artwork viewer.\r\n\t * @param {object} oBarcodeMeasurements - The barcode measurement object.\r\n\t * @param {int} iBarcodeDisplayTextCount - The number of barcode measurements.\r\n\t * @param {bool} bRenderOverlayMarquee - Whether to render the overlay marquee.\r\n\t */\r\n\tTechToolsUI.prototype.renderBarcodeMeasurement = function (oAnnotationViewer, oArtworkViewer, oBarcodeMeasurements, iBarcodeDisplayTextCount, bRenderOverlayMarquee) {\r\n\r\n\t\t// Get the annotation context.\r\n\t\tvar oAnnotationViewerContext = oAnnotationViewer.g_oContext;\r\n\r\n\t\t// Take a copy of the barcode measurements object.\r\n\t\tvar oBarcodeMeasurement = deepCopyObject(oBarcodeMeasurements);\r\n\r\n\t\t// Get the scaled image width and height.\r\n\t\tvar iScaledImageWidth = oArtworkViewer.g_iScaledImageWidth;\r\n\t\tvar iScaledImageHeight = oArtworkViewer.g_iScaledImageHeight;\r\n\r\n\t\t// Calculate the compare offset of the canvas.\r\n\t\tvar compareOffset_x, compareOffset_y;\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkViewer);\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(oArtworkViewer);\r\n\r\n\t\t// If we have a compare rotation.\r\n\t\tif (iCompareRotation > 0) {\r\n\r\n\t\t\t// Rotate the origin by the compare rotation.\r\n\t\t\tvar oRotatedOrigin = oArtworkViewer.rotate(oBarcodeMeasurement.MarqueeCoordinates.MinX, oBarcodeMeasurement.MarqueeCoordinates.MinY, 0.5, 0.5, iCompareRotation);\r\n\t\t\toBarcodeMeasurement.MarqueeCoordinates.MinX = oRotatedOrigin.rotated_x;\r\n\t\t\toBarcodeMeasurement.MarqueeCoordinates.MinY = oRotatedOrigin.rotated_y;\r\n\r\n\t\t\t// Rotate the co-ordinates by the compare rotation.\r\n\t\t\tvar oRotatedCoordinates = oArtworkViewer.rotate(oBarcodeMeasurement.MarqueeCoordinates.MaxX, oBarcodeMeasurement.MarqueeCoordinates.MaxY, 0.5, 0.5, iCompareRotation);\r\n\t\t\toBarcodeMeasurement.MarqueeCoordinates.MaxX = oRotatedCoordinates.rotated_x;\r\n\t\t\toBarcodeMeasurement.MarqueeCoordinates.MaxY = oRotatedCoordinates.rotated_y;\r\n\r\n\t\t\t// If we have a compare rotation of 90 or 270, swap the image width and height.\r\n\t\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\t\tiScaledImageWidth = oArtworkViewer.g_iScaledImageHeight;\r\n\t\t\t\tiScaledImageHeight = oArtworkViewer.g_iScaledImageWidth;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Re-render the annotation viewer overlay to display the marquee selection. Used when panning the barcode measurement.\r\n\t\tif (bRenderOverlayMarquee !== undefined && bRenderOverlayMarquee !== null && bRenderOverlayMarquee) {\r\n\r\n\t\t\t// Generate the canvas coordinates for the rectangle marquee.\r\n\t\t\tg_oMarquee.g_iOrigin_x = (oBarcodeMeasurement.MarqueeCoordinates.MinX * iScaledImageWidth) + oArtworkViewer.g_iCenterShift_x + compareOffset_x;\r\n\t\t\tg_oMarquee.g_iOrigin_y = (oBarcodeMeasurement.MarqueeCoordinates.MinY * iScaledImageHeight) + oArtworkViewer.g_iCenterShift_y + compareOffset_y;\r\n\t\t\tg_oMarquee.g_iX = (oBarcodeMeasurement.MarqueeCoordinates.MaxX * iScaledImageWidth) + oArtworkViewer.g_iCenterShift_x + compareOffset_x;\r\n\t\t\tg_oMarquee.g_iY = (oBarcodeMeasurement.MarqueeCoordinates.MaxY * iScaledImageHeight) + oArtworkViewer.g_iCenterShift_y + compareOffset_y;\r\n\r\n\t\t\t// De-rotate the canvas back to 0 degree orientation so that the clearing an resetting the overlay will cover the desired area.\r\n\t\t\tg_oMarquee.derotateCanvasContext(oAnnotationViewerContext, oAnnotationViewer, oAnnotationViewer.g_oCanvas.width, oAnnotationViewer.g_oCanvas.height, oAnnotationViewer.g_oCanvas.width / 2, oAnnotationViewer.g_oCanvas.height / 2);\r\n\r\n\t\t\t// Clear the previous overlay.\r\n\t\t\toAnnotationViewerContext.clearRect(0, 0, oAnnotationViewer.g_oCanvas.width, oAnnotationViewer.g_oCanvas.height);\r\n\r\n\t\t\t// Create a new opaque overlay.\r\n\t\t\toAnnotationViewerContext.rect(0, 0, oAnnotationViewer.g_oCanvas.width, oAnnotationViewer.g_oCanvas.height);\r\n\t\t\toAnnotationViewerContext.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\t\t\toAnnotationViewerContext.fill();\r\n\r\n\t\t\t// Reset the canvas context back to the current rotation.\r\n\t\t\toAnnotationViewerContext.restore();\r\n\r\n\t\t\t// Clear the rectangle marquee in the current orientation.\r\n\t\t\toAnnotationViewerContext.clearRect(g_oMarquee.g_iOrigin_x, g_oMarquee.g_iOrigin_y, g_oMarquee.g_iX - g_oMarquee.g_iOrigin_x, g_oMarquee.g_iY - g_oMarquee.g_iOrigin_y);\r\n\t\t}\r\n\r\n\t\t// Determine the display coordinates.\r\n\t\tvar iDisplayCoordX = Math.min(g_oMarquee.g_iX, g_oMarquee.g_iOrigin_x);\r\n\t\tvar iDisplayCoordY = Math.min(g_oMarquee.g_iY, g_oMarquee.g_iOrigin_y);\r\n\r\n\t\t// De-rotate.\r\n\t\toArtworkViewer.g_oAnnotationCanvas.g_oContext.save();\r\n\t\tg_oMarquee.derotateCanvasContext(oArtworkViewer.g_oAnnotationCanvas.g_oContext, oArtworkViewer.g_oAnnotationCanvas, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.width, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.height, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.width / 2, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.height / 2);\r\n\r\n\t\t// Need to adjust the Y starting coordinate to take into account multiple lines of text to be displayed.\r\n\t\tiDisplayCoordY = iDisplayCoordY - (iBarcodeDisplayTextCount * (g_oTechTools.c_iDisplayFontSize + g_oTechTools.c_iDisplayMargin));\r\n\r\n\t\t// Now restore the canvas flipping it back to its original orientation.\r\n\t\toAnnotationViewerContext.restore();\r\n\r\n\t\t// Prepare for writing the text.\r\n\t\toAnnotationViewerContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\t\toAnnotationViewerContext.font = g_oTechTools.c_szDisplayFont;\r\n\t\toAnnotationViewerContext.textBaseline = g_oTechTools.c_szTextBaseline;\r\n\t\toAnnotationViewerContext.textAlign = g_oTechTools.c_szTextAlign;\r\n\r\n\t\t// Write the text.\r\n\t\toAnnotationViewerContext.fillText(oBarcodeMeasurement.DisplayText, iDisplayCoordX, iDisplayCoordY);\r\n\r\n\t\t// Return the coordinates we have drawn the barcode to.\r\n\t\treturn { x: iDisplayCoordX, y: iDisplayCoordY };\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the separations side bar.\r\n\t */\r\n\tTechToolsUI.prototype.showSeperationsSideBar = function () {\r\n\r\n\t\t// If a slide is required.\r\n\t\tif (!$(\"#divSepDiv\").is(\":visible\")) {\r\n\r\n\t\t\t// Slide the div.\r\n\t\t\tslideDiv($(\"#divSepContainer\"), false, true);\r\n\r\n\t\t\t// Update the user settings.\r\n\t\t\tg_oSettings.syncSettings();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the separations side bar.\r\n\t */\r\n\tTechToolsUI.prototype.hideSeperationsSideBar = function () {\r\n\r\n\t\t// If a slide is required.\r\n\t\tif ($(\"#divSepDiv\").is(\":visible\")) {\r\n\r\n\t\t\t// Slide the div.\r\n\t\t\tslideDiv($(\"#divSepContainer\"), false, true);\r\n\r\n\t\t\t// Update the user settings.\r\n\t\t\tg_oSettings.syncSettings();\r\n\t\t}\r\n\t};\r\n\r\n\t/// \r\n\t/// Handles the different type of measurements and updates the UI with the required details dependant on the selected measurement type.\r\n\t/// The long list of parameters are not all required by this method but form an interface used by the MarqueeService which draws the\r\n\t/// marquee on the canvas and then calls implementation specific functions (i.e. this function).\r\n\t/// \r\n\t/// The annotation canvas context.\r\n\t/// The X coordinate distance (the distance between the begin and end points).\r\n\t/// The Y coordinate distance (the distance between the begin and end points).\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// Width of the canvas.\r\n\t/// Height of the canvas.\r\n\t/// The half width of the canvas.\r\n\t/// The half height of the canvas.\r\n\tTechToolsUI.prototype.measurementMarqueeDraw = function (oArtworkViewer, oAnnotationViewer, oAnnotationCanvasContext, iCoordinateDistance_x, iCoordinateDistance_y, beginPoint_x, beginPoint_y, canvasWidth, canvasHeight, canvasHalfWidth, canvasHalfHeight) {\r\n\t\t\r\n\t\tif (g_oTechTools.g_iSelectedMeasurementType === g_oTechTools.g_eMeasurementTypes.BARCODE) {\t\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// Set the measurement units and display suffixes.\r\n\t\tif (g_oSettings.g_oUserSettings.UseMetricUnits) {\r\n\t\t\tg_oTechTools.g_szMeasurementSuffix = g_oTechTools.c_szMeasurementSuffixMetric;\r\n\t\t\tg_oTechTools.g_dMeasurementFactor = g_oTechTools.c_dMeasurementFactorMetric;\r\n\t\t}\r\n\t\telse {\r\n\t\t\tg_oTechTools.g_szMeasurementSuffix = g_oTechTools.c_szMeasurementSuffixImperial;\r\n\t\t\tg_oTechTools.g_dMeasurementFactor = g_oTechTools.c_dMeasurementFactorImperial;\r\n\t\t}\r\n\r\n\t\tvar artworkViewerImage = oArtworkViewer.g_oaImages[0];\r\n\t\tvar scaleFactor = artworkViewerImage.ImageWidth / oArtworkViewer.g_iScaledImageWidth;\r\n\r\n\t\tvar scaledDistance_x = (iCoordinateDistance_x * scaleFactor / artworkViewerImage.WidthResolution) * g_oTechTools.g_dMeasurementFactor;\r\n\t\tvar scaledDistance_y = (iCoordinateDistance_y * scaleFactor / artworkViewerImage.HeightResolution) * g_oTechTools.g_dMeasurementFactor;\r\n\r\n\t\tg_oTechTools.g_iOriginalZoomLevel = oArtworkViewer.g_iZoomLevel;\r\n\r\n\t\tswitch (g_oTechTools.g_iSelectedMeasurementType) {\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.POINTTOPOINT:\r\n\t\t\t\tg_oTechTools.measurePointToPoint(oArtworkViewer, oAnnotationViewer, oAnnotationCanvasContext, beginPoint_x, beginPoint_y, scaledDistance_x, scaledDistance_y, iCoordinateDistance_x, iCoordinateDistance_y, g_oPayload);\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.Line;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.AREA:\r\n\t\t\t\tg_oTechTools.measureArea(oArtworkViewer, oAnnotationViewer, oAnnotationCanvasContext, beginPoint_x, beginPoint_y, scaledDistance_x, scaledDistance_y, iCoordinateDistance_x, iCoordinateDistance_y, g_oPayload);\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.Rectangle;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.HORIZONTAL:\r\n\t\t\t\tMeasureHorizontal(oArtworkViewer, oAnnotationViewer, oAnnotationCanvasContext, beginPoint_x, beginPoint_y, scaledDistance_x, iCoordinateDistance_x, iCoordinateDistance_y, canvasWidth, canvasHeight, canvasHalfWidth, canvasHalfHeight);\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.VERTICAL:\r\n\t\t\t\tMeasureVertical(oArtworkViewer, oAnnotationViewer, oAnnotationCanvasContext, beginPoint_x, beginPoint_y, scaledDistance_y, iCoordinateDistance_x, iCoordinateDistance_y, canvasWidth, canvasHeight, canvasHalfWidth, canvasHalfHeight);\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.BARCODE:\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.COLOURDENSITY:\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.TEXT:\r\n\t\t\tdefault:\r\n\t\t\t// Do nothing.\r\n\t\t}\r\n\t};\r\n\r\n\t\t/** \r\n\t\t* Function to calculate the point to point measurement and render it in the UI.\r\n\t\t* @param canvasContext - The canvas context.\r\n\t\t* @param {number} beginPoint_x - The start X coordinate.\r\n\t\t* @param {number} beginPoint_y - The start Y coordinate.\r\n\t\t* @param {number} scaledDistance_x - The X coordinate distance (the distance between the begin and end points) scaled by the image width.\r\n\t\t* @param {number} scaledDistance_y - The Y coordinate distance (the distance between the begin and end points) scaled by the image height.\r\n\t\t* @param {number} coordinateDistance_x - The X coordinate distance (the distance between the begin and end points).\r\n\t\t* @param {number} coordinateDistance_y - The Y coordinate distance (the distance between the begin and end points).\r\n\t */\r\n\tTechToolsUI.prototype.measurePointToPoint = function (oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, scaledDistance_x, scaledDistance_y, coordinateDistance_x, coordinateDistance_y, payload) {\r\n\t\tcanvasContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\t\tcanvasContext.font = g_oTechTools.c_szDisplayFont;\r\n\t\tcanvasContext.textBaseline = g_oTechTools.c_szTextBaseline;\r\n\t\tcanvasContext.textAlign = g_oTechTools.c_szTextAlign;\r\n\r\n\t\tif (scaledDistance_x > 0) {\r\n\t\t\tcanvasContext.fillText(g_oTechTools.formatMeasuredDistance(scaledDistance_x) + \" \" + g_oTechTools.g_szMeasurementSuffix, beginPoint_x, beginPoint_y);\r\n\t\t\tpayload.width = g_oTechTools.formatMeasuredDistance(scaledDistance_x) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\t\t}\r\n\t\tvar iTextHeight = 30; // this value is larger than actually required as the text appears on a diagonal, meaning some overlap is possible.\r\n\t\t// Point 2 point measurement\r\n\t\tvar hypotenuse = Math.sqrt((scaledDistance_x * scaledDistance_x) + (scaledDistance_y * scaledDistance_y));\r\n\r\n\t\t// 57.2958 is not a magic number. It is a radian!\r\n\t\tvar angle = Math.atan(coordinateDistance_y / coordinateDistance_x) * 57.2958;\r\n\r\n\t\t// Reverse the angle to make sure the measurement figure is correctly oriented\r\n\t\tif (((g_oMarquee.g_iX < g_oMarquee.g_iOrigin_x) && (g_oMarquee.g_iY > g_oMarquee.g_iOrigin_y))\r\n\t\t\t||\r\n\t\t\t((g_oMarquee.g_iX > g_oMarquee.g_iOrigin_x) && (g_oMarquee.g_iY < g_oMarquee.g_iOrigin_y))) {\r\n\t\t\tangle -= angle * 2;\r\n\t\t};\r\n\r\n\t\tcanvasContext.beginPath();\r\n\t\tcanvasContext.moveTo(g_oMarquee.g_iOrigin_x, g_oMarquee.g_iOrigin_y);\r\n\t\tcanvasContext.lineTo(g_oMarquee.g_iX, g_oMarquee.g_iY);\r\n\t\tcanvasContext.strokeStyle = ((scaledDistance_x === 0 || scaledDistance_y === 0) ? \"rgba(255,255,255,1)\" : \"rgba(0,0,0,1)\");\r\n\t\tcanvasContext.setLineDash([5, 3]);\r\n\t\tcanvasContext.lineWidth = 2;\r\n\t\tcanvasContext.stroke();\r\n\t\tcanvasContext.closePath();\r\n\t\t// render the diagonal distance text\r\n\t\tif (coordinateDistance_y > 1 && coordinateDistance_x > 1) {\r\n\t\t\tvar szHypotenuseText = g_oTechTools.formatMeasuredDistance(hypotenuse) + \" \" + g_oTechTools.g_szMeasurementSuffix + \" \" + Math.round(angle) + \" \" + g_oTechTools.c_szAngleMeasurementUnitsAbbreviation + \".\";\r\n\t\t\tpayload.lineLength = g_oTechTools.formatMeasuredDistance(hypotenuse) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\t\t\tpayload.degrees = Math.round(angle) + \" \" + g_oTechTools.c_szAngleMeasurementUnitsAbbreviation;\r\n\t\t\tvar areaTextSize = canvasContext.measureText(szHypotenuseText);\r\n\r\n\t\t\t// check to see if there is enough space in the rectangle to display the text.\r\n\t\t\tvar iXDistance = Math.abs(g_oMarquee.g_iX - g_oMarquee.g_iOrigin_x);\r\n\t\t\tvar iYDistance = Math.abs(g_oMarquee.g_iY - g_oMarquee.g_iOrigin_y);\r\n\t\t\tvar bDisplayTextInMarquee = Math.sqrt((iXDistance * iXDistance) + (iYDistance * iYDistance)) > areaTextSize.width\r\n\t\t\t\t&& Math.abs(iYDistance) > iTextHeight\r\n\t\t\t\t&& Math.abs(iXDistance) > iTextHeight;\r\n\r\n\t\t\t// gather the begin point into an object for easy access & modification later.\r\n\t\t\tvar oDiagonalDisplayText = { x: beginPoint_x, y: beginPoint_y };\r\n\r\n\t\t\t// if there is enough space to display the text then set up the canvas rotation to display it diagonally.\r\n\t\t\tif (bDisplayTextInMarquee) {\r\n\t\t\t\t// rotate\r\n\t\t\t\tcanvasContext.translate(beginPoint_x + (coordinateDistance_x / 2), beginPoint_y + (coordinateDistance_y / 2));\r\n\t\t\t\tcanvasContext.rotate(angle * Math.PI / 180);\r\n\t\t\t\tcanvasContext.translate(-(beginPoint_x + (coordinateDistance_x / 2)), -(beginPoint_y + (coordinateDistance_y / 2)));\r\n\t\t\t}\r\n\t\t\t// Otherwise, identify where we need to place the text to ensure maximum viewing.\r\n\t\t\telse {\r\n\t\t\t\t// if we are to the right of the center of the canvas...\r\n\t\t\t\tif (oDiagonalDisplayText.x > oArtworkViewer.g_oCanvas.clientWidth / 2) {\r\n\t\t\t\t\t// ... display on the left side ...\r\n\t\t\t\t\toDiagonalDisplayText.x -= iXDistance / 2 + areaTextSize.width / 2 + 20; // extra text appears on this side, so we include extra distance to avoid overlap with this text.\r\n\t\t\t\t}\r\n\t\t\t\t// ... otherwise if we are left of the center, display on the right side.\r\n\t\t\t\telse {\r\n\t\t\t\t\toDiagonalDisplayText.x += iXDistance / 2 + areaTextSize.width / 2 + 10;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// if this would still leave the text outside of the bounds of the canvas reset and place it at the bottom or Top.\r\n\t\t\t\tif (oDiagonalDisplayText.x + ((coordinateDistance_x / 2) - (areaTextSize.width / 2)) + areaTextSize.width > oArtworkViewer.g_oCanvas.clientWidth) {\r\n\t\t\t\t\toDiagonalDisplayText = { x: beginPoint_x, y: beginPoint_y };\r\n\t\t\t\t\tif (oDiagonalDisplayText.y > oArtworkViewer.g_oCanvas.clientHeight / 2) {\r\n\t\t\t\t\t\toDiagonalDisplayText.y -= iYDistance / 2 + iTextHeight / 2 + 10;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\toDiagonalDisplayText.y += iYDistance / 2 + iTextHeight / 2 + 10;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvar szHypotenuseText = g_oTechTools.formatMeasuredDistance(hypotenuse) + \" \" + g_oTechTools.g_szMeasurementSuffix + \" \" + Math.round(angle) + \" \" + g_oTechTools.c_szAngleMeasurementUnitsAbbreviation + \".\";\r\n\t\t\t\r\n\t\t\tvar areaTextSize = canvasContext.measureText(szHypotenuseText);\r\n\t\t\tcanvasContext.beginPath();\r\n\t\t\tcanvasContext.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\t\t\tcanvasContext.rect(oDiagonalDisplayText.x + ((coordinateDistance_x / 2) - (areaTextSize.width / 2)) - g_oTechTools.g_oTextAreaHighlightBox.iBeginX, oDiagonalDisplayText.y + (coordinateDistance_y / 2) - g_oTechTools.g_oTextAreaHighlightBox.iBeginY, areaTextSize.width + g_oTechTools.g_oTextAreaHighlightBox.iWidth, g_oTechTools.g_oTextAreaHighlightBox.iHeight);\r\n\t\t\tcanvasContext.fill();\r\n\t\t\tcanvasContext.fillStyle = \"#f3961c\";\r\n\t\t\tcanvasContext.fillText(szHypotenuseText, oDiagonalDisplayText.x + ((coordinateDistance_x / 2) - (areaTextSize.width / 2)), oDiagonalDisplayText.y + (coordinateDistance_y / 2) + 5);\r\n\r\n\t\t\t// only de-rotate the canvas if we previously rotated it.\r\n\t\t\tif (bDisplayTextInMarquee) {\r\n\t\t\t\t// de-rotate\r\n\t\t\t\tcanvasContext.translate(beginPoint_x + (coordinateDistance_x / 2), beginPoint_y + (coordinateDistance_y / 2));\r\n\t\t\t\tcanvasContext.rotate(-angle * Math.PI / 180);\r\n\t\t\t\tcanvasContext.translate(-(beginPoint_x + (coordinateDistance_x / 2)), -(beginPoint_y + (coordinateDistance_y / 2)));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcanvasContext.translate(beginPoint_x, beginPoint_y);\r\n\t\tcanvasContext.rotate(-90 * Math.PI / 180);\r\n\t\tcanvasContext.translate(-beginPoint_x, -beginPoint_y);\r\n\t\tcanvasContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\r\n\t\tif (scaledDistance_y > 0) {\r\n\t\t\tcanvasContext.fillText(g_oTechTools.formatMeasuredDistance(scaledDistance_y) + \" \" + g_oTechTools.g_szMeasurementSuffix, beginPoint_x - coordinateDistance_y, beginPoint_y);\r\n\t\t\tpayload.height = g_oTechTools.formatMeasuredDistance(scaledDistance_y) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\t\t}\r\n\t};\r\n\r\n\t/// \r\n\t/// Function to calculate the area measurement and render it in the UI.\r\n\t/// \r\n\t/// The canvas context.\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// The X coordinate distance (the distance between the begin and end points) scaled by the image width.\r\n\t/// The Y coordinate distance (the distance between the begin and end points) scaled by the image height.\r\n\t/// The X coordinate distance (the distance between the begin and end points).\r\n\t/// The Y coordinate distance (the distance between the begin and end points).\r\n\tTechToolsUI.prototype.measureArea = function (oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, scaledDistance_x, scaledDistance_y, coordinateDistance_x, coordinateDistance_y, payload) {\r\n\t\tcanvasContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\t\tcanvasContext.font = g_oTechTools.c_szDisplayFont;\r\n\t\tcanvasContext.textBaseline = g_oTechTools.c_szTextBaseline;\r\n\t\tcanvasContext.textAlign = g_oTechTools.c_szTextAlign;\r\n\r\n\t\tvar iTextHeight = 20;\r\n\r\n\t\t// if we are just drawing a line\r\n\t\tif (scaledDistance_x === 0 || scaledDistance_y === 0) {\r\n\t\t\tcanvasContext.beginPath();\r\n\t\t\tcanvasContext.moveTo(g_oMarquee.g_iOrigin_x, g_oMarquee.g_iOrigin_y);\r\n\t\t\tcanvasContext.lineTo(g_oMarquee.g_iX, g_oMarquee.g_iY);\r\n\t\t\tcanvasContext.strokeStyle = \"rgba(255,255,255,1)\";\r\n\t\t\tcanvasContext.setLineDash([5, 3]);\r\n\t\t\tcanvasContext.lineWidth = 2;\r\n\t\t\tcanvasContext.stroke();\r\n\t\t\tcanvasContext.closePath();\r\n\t\t};\r\n\r\n\t\t// X-Axis measurement text...if it is a non-zero measurement.\r\n\t\tif (scaledDistance_x > 0) {\r\n\t\t\tcanvasContext.fillText(g_oTechTools.formatMeasuredDistance(scaledDistance_x) + \" \" + g_oTechTools.g_szMeasurementSuffix, beginPoint_x, beginPoint_y);\r\n\t\t\tpayload.width = g_oTechTools.formatMeasuredDistance(scaledDistance_x) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\t\t};\r\n\r\n\t\t// Area measurement text.\r\n\t\tvar area = g_oTechTools.formatMeasuredDistance(scaledDistance_x) * g_oTechTools.formatMeasuredDistance(scaledDistance_y);\r\n\t\tvar szAreaText = g_oTechTools.formatMeasuredDistance(area) + \" \" + g_oTechTools.c_szAreaMeasurementAbbreviation + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\t\tvar areaTextSize = canvasContext.measureText(szAreaText);\r\n\r\n\t\tpayload.area = szAreaText;\r\n\r\n\t\tcanvasContext.beginPath();\r\n\t\tcanvasContext.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\r\n\t\t// Only display the area measurement if it is a non-zero measurement.\r\n\t\tif (area > 0) {\r\n\t\t\t// check to see if there is enough space in the rectangle to display the text.\r\n\t\t\tvar iXDistance = Math.abs(g_oMarquee.g_iX - g_oMarquee.g_iOrigin_x);\r\n\t\t\tvar iYDistance = Math.abs(g_oMarquee.g_iY - g_oMarquee.g_iOrigin_y);\r\n\t\t\tvar bDisplayTextInMarquee = (iXDistance > areaTextSize.width)\r\n\t\t\t\t&& (iYDistance > iTextHeight)\r\n\t\t\t\t&& (iXDistance > iTextHeight);\r\n\t\t\tvar oAreaTextLocation = { x: beginPoint_x, y: beginPoint_y };\r\n\r\n\t\t\tif (!bDisplayTextInMarquee) {\r\n\t\t\t\t// if we are to the left of the center of the canvas, place the text on the right, and vice versa.\r\n\t\t\t\tif (oAreaTextLocation.x > oArtworkViewer.g_oCanvas.clientWidth / 2) {\r\n\t\t\t\t\toAreaTextLocation.x -= iXDistance / 2 + areaTextSize.width / 2 + 20;\r\n\t\t\t\t} else {\r\n\t\t\t\t\toAreaTextLocation.x += iXDistance / 2 + areaTextSize.width / 2 + 10;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// if this would still leave the text outside of the bounds of the canvas reset and place it at the bottom or Top.\r\n\t\t\t\tif (oAreaTextLocation.x + ((coordinateDistance_x / 2) - (areaTextSize.width / 2)) + areaTextSize.width > oArtworkViewer.g_oCanvas.clientWidth) {\r\n\t\t\t\t\toAreaTextLocation = { x: beginPoint_x, y: beginPoint_y };\r\n\t\t\t\t\tif (oAreaTextLocation.y > oArtworkViewer.g_oCanvas.clientHeight / 2) {\r\n\t\t\t\t\t\toAreaTextLocation.y -= iYDistance / 2 + iTextHeight / 2 + 10;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\toAreaTextLocation.y += iYDistance / 2 + iTextHeight / 2 + 10;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tcanvasContext.rect(oAreaTextLocation.x + ((coordinateDistance_x / 2) - (areaTextSize.width / 2)) - g_oTechTools.g_oTextAreaHighlightBox.iBeginX,\r\n\t\t\t\toAreaTextLocation.y + (coordinateDistance_y / 2) - g_oTechTools.g_oTextAreaHighlightBox.iBeginY,\r\n\t\t\t\tareaTextSize.width + g_oTechTools.g_oTextAreaHighlightBox.iWidth,\r\n\t\t\t\tg_oTechTools.g_oTextAreaHighlightBox.iHeight\r\n\t\t\t);\r\n\t\t\tcanvasContext.fill();\r\n\t\t\tcanvasContext.fillStyle = \"#f3961c\";\r\n\t\t\tcanvasContext.fillText(szAreaText, oAreaTextLocation.x + ((coordinateDistance_x / 2) - (areaTextSize.width / 2)), oAreaTextLocation.y + (coordinateDistance_y / 2) + 5);\r\n\t\t}\r\n\r\n\t\t// rotate the canvas for the Y axis text.\r\n\t\tcanvasContext.translate(beginPoint_x, beginPoint_y);\r\n\t\tcanvasContext.rotate(-90 * Math.PI / 180);\r\n\t\tcanvasContext.translate(-beginPoint_x, -beginPoint_y);\r\n\t\tcanvasContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\r\n\t\t// Y-Axis measurement text...if it is a non-zero measurement.\r\n\t\tif (scaledDistance_y > 0) {\r\n\t\t\tcanvasContext.fillText(g_oTechTools.formatMeasuredDistance(scaledDistance_y) + \" \" + g_oTechTools.g_szMeasurementSuffix, beginPoint_x - coordinateDistance_y, beginPoint_y);\r\n\t\t\tpayload.height = g_oTechTools.formatMeasuredDistance(scaledDistance_y) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Helper method to call the caliper redraw method without using 800 parameters\r\n\t * @param {object} event The event\r\n\t * @param {object} data Object containing all the needed parameters\r\n\t */\r\n\tTechToolsUI.prototype.CaliperRedrawCaller = function (event, data) {\r\n\t\tCaliperRedraw(event, data.type, data.oArtworkViewer, data.oAnnotationViewer, data.canvasContext, data.canvasWidth, data.canvasHeight,\r\n\t\t\tdata.beginPoint_x, data.beginPoint_y, data.coordinateDistance_x, data.coordinateDistance_y, data.measurement, data.szMeasurementText, data.fakeClick, data.redrawInPlace);\r\n\t};\r\n\r\n\t/**\r\n\t * Redraws the caliper based on where the mouse is\r\n\t * @param {object} event The event\r\n\t * @param {number} type Enum of the type of measurement\r\n\t * @param {object} oArtworkViewer The artwork viewer\r\n\t * @param {object} oAnnotationViewer The annotation viewer\r\n\t * @param {object} canvasContext The 2DContext object\r\n\t * @param {number} canvasWidth The width of the canvas\r\n\t * @param {number} canvasHeight The height of the canvas\r\n\t * @param {number} beginPoint_x The start point of the draw\r\n\t * @param {number} beginPoint_y The start point of the draw\r\n\t * @param {number} coordinateDistance_x How far away on the X axis is the point\r\n\t * @param {number} coordinateDistance_y How far away on the Y axis is the point\r\n\t * @param {number} measurement The measurement itself\r\n\t * @param {string} szMeasurementText The measurement in a user friendly format\r\n\t * @param {boolean} fakeClick Whether we're faking a click\r\n\t * @param {boolean} redrawInPlace Whether we're redrawing the caliper in place\r\n\t */\r\n\tvar CaliperRedraw = function (event, type, oArtworkViewer, oAnnotationViewer, canvasContext,\r\n\t\tcanvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_x, coordinateDistance_y, measurement, szMeasurementText, fakeClick, redrawInPlace) {\r\n\t\tvar isHorizontal = type === g_oTechTools.g_eMeasurementTypes.HORIZONTAL;\r\n\t\tmeasurement = measurement || null;\r\n\t\tfakeClick = fakeClick || null;\r\n\r\n\t\tcanvasContext.save();\r\n\r\n\t\tvar fDistanceToDraw = isHorizontal ? coordinateDistance_x : coordinateDistance_y;\r\n\t\tif (measurement) {\r\n\t\t\tfDistanceToDraw = measurement;\r\n\t\t}\r\n\t\tfDistanceToDraw = fDistanceToDraw * (oArtworkViewer.g_iZoomLevel / g_oTechTools.g_iOriginalZoomLevel);\r\n\r\n\t\t// force our own coords if faking the click\r\n\t\tvar newCoords;\r\n\t\tif (!fakeClick) {\r\n\t\t\tnewCoords = getClickCoords(event, oAnnotationViewer);\r\n\t\t}\r\n\t\telse {\r\n\t\t\tif (redrawInPlace) {\r\n\t\t\t\tnewCoords = g_oSavedCalipers.GetLeftmostPoint(event); \r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tnewCoords = GetNewFakeCoords(oArtworkViewer, oAnnotationViewer, fDistanceToDraw, isHorizontal, redrawInPlace);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Unrotate the canvas context\r\n\t\tcanvasContext.setTransform(1, 0, 0, 1, 0, 0);\r\n\r\n\t\tvar x = isHorizontal ? newCoords[0] : beginPoint_x;\r\n\t\tvar y = isHorizontal ? beginPoint_y : newCoords[1];\r\n\r\n\t\t// Doesn't recurse anymore?\r\n\t\tif (isHorizontal) {\r\n\t\t\tDrawHorizontalCalliper(canvasContext, canvasWidth, canvasHeight, x, y, fDistanceToDraw, coordinateDistance_y, szMeasurementText);\r\n\t\t}\r\n\t\telse {\r\n\t\t\tDrawVerticalCalliper(canvasContext, canvasWidth, canvasHeight, x, y, fDistanceToDraw, szMeasurementText);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the faked coordinates to draw the caliper in a predetermined location\r\n\t * @param {object} ArtworkViewer The artworkviewer\r\n\t * @param {object} AnnotationViewer The annotationviewer\r\n\t * @param {number} fDistanceToDraw how large the caliper is to be\r\n\t * @param {bool} isHorizontal whether it's a horizontal caliper\r\n\t * @returns {number[]} faked click coordinates\r\n\t */\r\n\tvar GetNewFakeCoords = function (ArtworkViewer, AnnotationViewer, fDistanceToDraw, isHorizontal) {\r\n\t\tif (!isHorizontal) {\r\n\t\t\tvar h = $(\"#divContainer\").height() + 10;\r\n\t\t\treturn fakeClickCoords(0, h, AnnotationViewer);\r\n\t\t}\r\n\r\n\t\tvar xCoord = calculateCentralXCoordinate(fDistanceToDraw);\r\n\t\tswitch (g_oViewer.g_oCompareMode) {\r\n\t\t\tcase eCompareMode.SideBySide:\r\n\t\t\t\txCoord /= 2;\r\n\t\t\t\tbreak;\r\n\t\t\tcase eCompareMode.SideBySideDiff:\r\n\t\t\t\txCoord /= 3;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tif (ArtworkViewer.g_szCanvasId === \"CompareViewer\") {\r\n\t\t\txCoord *= 3;\r\n\t\t}\r\n\r\n\t\treturn fakeClickCoords(xCoord, 0, AnnotationViewer);\r\n\t};\r\n\r\n\t/**\r\n\t * Binds the relevant events for the caliper save handle event\r\n\t * @param {object} oAnnotationViewer The annotation viewer object\r\n\t * @param {object} canvasContext The canvas context for the artwork\r\n\t * @param {number[]} coord The start coordinates\r\n\t * @param {number} type Enum of the type of caliper\r\n\t * @param {number} scaledDistance The scaled distance\r\n\t */\r\n\tvar BindCaliperSaveHandleEvents = function (oAnnotationViewer, canvasContext, coord, type, scaledDistance) {\r\n\t\t$(oAnnotationViewer.g_oCanvas).off('.calipersave');\r\n\r\n\t\t$(oAnnotationViewer.g_oCanvas).onFirst('pointermove.calipersave', function (e) {\r\n\t\t\tg_oSavedCalipers.HandleHover(e, canvasContext, coord, type, scaledDistance);\r\n\t\t});\r\n\r\n\t\t$(oAnnotationViewer.g_oCanvas).onFirst('pointerdown.calipersave', function (e) {\r\n\t\t\t// If we detect and handle the click\r\n\t\t\tif (g_oSavedCalipers.TryHandleClick(e, canvasContext, coord, type, scaledDistance)) {\r\n\t\t\t\t// Prevent other handlers from firing.\r\n\t\t\t\te.stopImmediatePropagation();\r\n\t\t\t\t// Make sure the pointerup event doesn't trigger.\r\n\t\t\t\t$(oAnnotationViewer.g_oCanvas).off('pointerup.caliperdraw');\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t/**\r\n\t * Event for when the a caliper is stopped being dragged\r\n\t * @param {object} e The event\r\n\t * @param {object} oArtworkViewer The artwork canvas object\r\n\t * @param {object} oAnnotationViewer The annotation canvas object\r\n\t * @param {object} canvasContext The 2dCanvasContext object\r\n\t * @param {number[]} coord The coordinates\r\n\t * @param {number} type Enum of the type of caliper\r\n\t * @param {number} scaledDistance The calculated distance\r\n\t */\r\n\tvar CaliperMeasurementRedrawPointerUp = function (e, oArtworkViewer, oAnnotationViewer, canvasContext, coord, type, scaledDistance) {\r\n\t\t$(oAnnotationViewer.g_oCanvas).off('pointermove');\r\n\t\t$(oAnnotationViewer.g_oCanvas).off('pointerdown.calipersave');\r\n\t\tif (!oArtworkViewer.g_bMainCanvas || g_oSavedCalipers.MeasurementAlreadyExists(type, scaledDistance)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar newCoords = getClickCoords(e, oAnnotationViewer);\r\n\t\tif (type === g_oTechTools.g_eMeasurementTypes.HORIZONTAL) {\r\n\t\t\tnewCoords[1] = coord[1];\r\n\t\t}\r\n\t\telse {\r\n\t\t\tnewCoords[0] = coord[0];\r\n\t\t}\r\n\r\n\t\tg_oSavedCalipers.DrawSaveIcon(canvasContext, newCoords, type, scaledDistance);\r\n\r\n\t\tg_oSavedCalipers.StoreDrawPoints(newCoords[0], newCoords[1]);\r\n\t\tg_oSavedCalipers.StoreEvent(e);\r\n\r\n\t\tBindCaliperSaveHandleEvents(oAnnotationViewer, canvasContext, newCoords, type, scaledDistance);\r\n\t};\r\n\r\n\t/// \r\n\t/// Function to calculate the Horizontal Calliper measurement and render it in the UI.\r\n\t/// \r\n\t/// The canvas context.\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// The X coordinate distance (the distance between the begin and end points) scaled by the image width.\r\n\t/// The X coordinate distance (the distance between the begin and end points).\r\n\t/// The Y coordinate distance (the distance between the begin and end points).\r\n\t/// Width of the canvas.\r\n\t/// Height of the canvas.\r\n\t/// The half width of the canvas.\r\n\t/// The half height of the canvas.\r\n\tvar MeasureHorizontal = function (oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, scaledDistance_x, coordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, canvasHalfWidth, canvasHalfHeight) {\r\n\t\tvar szMeasurementText = g_oTechTools.formatMeasuredDistance(scaledDistance_x) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\r\n\t\tDrawHorizontalCalliper(canvasContext, canvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_x, coordinateDistance_y, szMeasurementText);\r\n\r\n\t\t$(oAnnotationViewer.g_oCanvas).off('pointerup');\r\n\t\t$(oAnnotationViewer.g_oCanvas).one('pointerup', function (e) {\r\n\t\t\tCaliperMeasurementEnd(e, oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, MeasurementInMM(scaledDistance_x),\r\n\t\t\t\tcoordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, szMeasurementText, g_oTechTools.g_eMeasurementTypes.HORIZONTAL);\r\n\t\t});\r\n\t};\r\n\r\n\t/// \r\n\t/// Helper method to draw the Horizontal Calliper overlay in the UI.\r\n\t/// \r\n\t/// The canvas context.\r\n\t/// Width of the canvas.\r\n\t/// Height of the canvas.\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// The X coordinate distance (the distance between the begin and end points).\r\n\t/// The Y coordinate distance (the distance between the begin and end points).\r\n\t/// The measurement text.\r\n\tvar DrawHorizontalCalliper = function (canvasContext, canvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_x, coordinateDistance_y, szMeasurementText) {\r\n\t\tcanvasContext.clearRect(0, 0, canvasWidth, canvasHeight);\r\n\t\tcanvasContext.beginPath();\r\n\t\tcanvasContext.rect(0, 0, canvasWidth, canvasHeight);\r\n\t\tcanvasContext.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\t\tcanvasContext.fill();\r\n\t\tcanvasContext.clearRect(beginPoint_x, 0, coordinateDistance_x, canvasHeight);\r\n\r\n\t\tcanvasContext.translate(beginPoint_x, beginPoint_y);\r\n\t\tcanvasContext.rotate(-90 * Math.PI / 180);\r\n\t\tcanvasContext.translate(-beginPoint_x, -beginPoint_y);\r\n\t\tcanvasContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\t\tcanvasContext.font = g_oTechTools.c_szDisplayFont;\r\n\t\tcanvasContext.textBaseline = g_oTechTools.c_szTextBaseline;\r\n\t\tcanvasContext.textAlign = g_oTechTools.c_szTextAlign;\r\n\t\tcanvasContext.fillText(szMeasurementText, beginPoint_x, beginPoint_y);\r\n\t\tcanvasContext.restore();\r\n\t};\r\n\r\n\t/// \r\n\t/// Function to calculate the Vertical Calliper measurement and render it in the UI.\r\n\t/// \r\n\t/// The canvas context.\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// The Y coordinate distance (the distance between the begin and end points) scaled by the image height.\r\n\t/// The X coordinate distance (the distance between the begin and end points).\r\n\t/// The Y coordinate distance (the distance between the begin and end points).\r\n\t/// Width of the canvas.\r\n\t/// Height of the canvas.\r\n\t/// The half width of the canvas.\r\n\t/// The half height of the canvas.\r\n\tvar MeasureVertical = function (oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, scaledDistance_y, coordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, canvasHalfWidth, canvasHalfHeight) {\r\n\t\tvar szMeasurementText = g_oTechTools.formatMeasuredDistance(scaledDistance_y) + \" \" + g_oTechTools.g_szMeasurementSuffix;\r\n\r\n\t\tDrawVerticalCalliper(canvasContext, canvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_y, szMeasurementText);\r\n\r\n\t\t$(oAnnotationViewer.g_oCanvas).off(\"pointerup\");\r\n\t\t$(oAnnotationViewer.g_oCanvas).one('pointerup', function (e) {\r\n\t\t\tCaliperMeasurementEnd(e, oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, MeasurementInMM(scaledDistance_y),\r\n\t\t\t\tcoordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, szMeasurementText, g_oTechTools.g_eMeasurementTypes.VERTICAL);\r\n\t\t});\r\n\t};\r\n\r\n\t/**\r\n\t * The event for when a caliper measuremen\r\n\t * @param {object} e The event\r\n\t * @param {object} oArtworkViewer The artwork viewer object\r\n\t * @param {object} oAnnotationViewer The annotation viewer object\r\n\t * @param {object} canvasContext The 2dCanvasContext object\r\n\t * @param {number} beginPoint_x The x coordinate of the point dragged from\r\n\t * @param {number} beginPoint_y The y coordinate of the point dragged from\r\n\t * @param {number} measurement The measurement itself\r\n\t * @param {number} coordinateDistance_x How far on the x axis it was drawn\r\n\t * @param {number} coordinateDistance_y How far on the y axis it was drawn\r\n\t * @param {number} canvasWidth The width of the canvas\r\n\t * @param {number} canvasHeight The height of the canvas\r\n\t * @param {string} szMeasurementText The measurement in the user's format as a string\r\n\t * @param {number} type Enum of the type of measurement\r\n\t */\r\n\tvar CaliperMeasurementEnd = function (e, oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, measurement,\r\n\t\tcoordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, szMeasurementText, type) {\r\n\t\tg_oSavedCalipers.g_iCurMeas = measurement;\r\n\t\tg_oSavedCalipers.StoreDrawPoints(beginPoint_x, beginPoint_y);\r\n\t\tg_oSavedCalipers.StoreEvent(e);\r\n\t\tg_oTechTools.CaliperMeasurePointerUp(oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, measurement,\r\n\t\t\tcoordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, szMeasurementText, type);\r\n\t};\r\n\r\n\t/**\r\n\t * Event for when a caliper measurement is finished being drawn. Binds the events for redrawing it\r\n\t * @param {object} oArtworkViewer The artwork viewer object\r\n\t * @param {object} oAnnotationViewer The annotation viewer object\r\n\t * @param {object} canvasContext The 2dCanvasContext object\r\n\t * @param {number} beginPoint_x The x coordinate of the point dragged from\r\n\t * @param {number} beginPoint_y The y coordinate of the point dragged from\r\n\t * @param {number} scaledDistance The distance dragged\r\n\t * @param {number} coordinateDistance_x How far on the x axis it was drawn\r\n\t * @param {number} coordinateDistance_y How far on the y axis it was drawn\r\n\t * @param {number} canvasWidth The width of the canvas\r\n\t * @param {number} canvasHeight The height of the canvas\r\n\t * @param {string} measurementText The measurement in the user's format as a string\r\n\t * @param {number} type Enum of the type of measurement\r\n\t */\r\n\tTechToolsUI.prototype.CaliperMeasurePointerUp = function (oArtworkViewer, oAnnotationViewer, canvasContext, beginPoint_x, beginPoint_y, scaledDistance,\r\n\t\tcoordinateDistance_x, coordinateDistance_y, canvasWidth, canvasHeight, measurementText, type) {\r\n\t\t$(oAnnotationViewer.g_oCanvas).off('pointerdown');\r\n\r\n\t\t$(oAnnotationViewer.g_oCanvas).off('pointermove');\r\n\t\t$(\".annotationViewer\").off('pointermove');\r\n\r\n\t\tif (oArtworkViewer.g_bMainCanvas && !g_oSavedCalipers.MeasurementAlreadyExists(type, scaledDistance)) {\r\n\t\t\tg_oSavedCalipers.DrawSaveIcon(canvasContext, [beginPoint_x, beginPoint_y], type, scaledDistance);\r\n\t\t\tBindCaliperSaveHandleEvents(oAnnotationViewer, canvasContext, [beginPoint_x, beginPoint_y], type, scaledDistance);\r\n\t\t}\r\n\r\n\t\t$(oAnnotationViewer.g_oCanvas).on('pointerdown.caliperdraw', function (e) {\r\n\t\t\t// Hide the toolbar if it's still there\r\n\t\t\t$(\"#divTechToolsDropDown\").slideUp(200);\r\n\r\n\t\t\tCaliperRedraw(e, type, oArtworkViewer, oAnnotationViewer, canvasContext,\r\n\t\t\t\tcanvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_x, coordinateDistance_y, null, measurementText, false, false);\r\n\r\n\t\t\t$(oAnnotationViewer.g_oCanvas).off('pointerup');\r\n\t\t\t$(oAnnotationViewer.g_oCanvas).on('pointerup.caliperdraw', function (e) {\r\n\t\t\t\tCaliperMeasurementRedrawPointerUp(e, oArtworkViewer, oAnnotationViewer, canvasContext, [beginPoint_x, beginPoint_y], type, scaledDistance);\r\n\t\t\t});\r\n\r\n\t\t\t$(oAnnotationViewer.g_oCanvas).off('pointermove');\r\n\t\t\t$(oAnnotationViewer.g_oCanvas).on('pointermove.caliperdraw', function (e) {\r\n\t\t\t\tCaliperRedraw(e, type, oArtworkViewer, oAnnotationViewer, canvasContext,\r\n\t\t\t\t\tcanvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_x, coordinateDistance_y, null, measurementText, false, false);\r\n\t\t\t});\r\n\t\t});\r\n\t};\r\n\r\n\t/**\r\n\t * Returns whether currently dragging the mouse will redraw a caliper\r\n\t * @returns {bool} True if currently caliper redraw events are bound.\r\n\t */\r\n\tTechToolsUI.prototype.IsCaliperRedrawMode = function () {\r\n\t\treturn this.IsCaliper(this.g_iSelectedMeasurementType) && g_oSavedCalipers.CaliperEventsBound($(\"#AnnotationViewer\"), \"pointerdown\");\r\n\t};\r\n\r\n\t/**\r\n\t * Returns whether the given measurement type is a caliper\r\n\t * @param {number} type Enum of the measurement type\r\n\t * @returns {bool} True if caliper measurement.\r\n\t */\r\n\tTechToolsUI.prototype.IsCaliper = function (type) {\r\n\t\treturn type === this.g_eMeasurementTypes.HORIZONTAL || type === this.g_eMeasurementTypes.VERTICAL;\r\n\t};\r\n\r\n\t/// \r\n\t/// Helper method to draw the Horizontal Calliper overlay in the UI.\r\n\t/// \r\n\t/// The canvas context.\r\n\t/// Width of the canvas.\r\n\t/// Height of the canvas.\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// The Y coordinate distance (the distance between the begin and end points).\r\n\t/// The measurement text.\r\n\tvar DrawVerticalCalliper = function (canvasContext, canvasWidth, canvasHeight, beginPoint_x, beginPoint_y, coordinateDistance_y, szMeasurementText) {\r\n\t\tcanvasContext.clearRect(0, 0, canvasWidth, canvasHeight);\r\n\t\tcanvasContext.beginPath();\r\n\t\tcanvasContext.rect(0, 0, canvasWidth, canvasHeight);\r\n\t\tcanvasContext.fillStyle = \"rgba(0,0,0,0.75)\";\r\n\t\tcanvasContext.fill();\r\n\t\tcanvasContext.clearRect(0, beginPoint_y, canvasWidth, coordinateDistance_y);\r\n\r\n\t\tcanvasContext.fillStyle = g_oTechTools.c_szFillStyle;\r\n\t\tcanvasContext.font = g_oTechTools.c_szDisplayFont;\r\n\t\tcanvasContext.textBaseline = g_oTechTools.c_szTextBaseline;\r\n\t\tcanvasContext.textAlign = g_oTechTools.c_szTextAlign;\r\n\t\tcanvasContext.fillText(szMeasurementText, beginPoint_x, beginPoint_y);\r\n\t\tcanvasContext.restore();\r\n\t};\r\n\r\n\t/**\r\n\t * Transforms coordinates based on rotation and offsets.\r\n\t * @param {int} iStartX - The starting x coordinate.\r\n\t * @param {int} iStartY - The starting y coordinate.\r\n\t * @param {int} iEndX - The ending x coordinate.\r\n\t * @param {int} iEndY - The ending y coordinate.\r\n\t * @param {int} iDragOffset_x - The drag offset of the x axis.\r\n\t * @param {int} iDragOffset_y - The drag offset of the y axis.\r\n\t * @param {int} iCenterShift_x - The centershift on the x axis.\r\n\t * @param {int} iCenterShift_y - The centershift on the y axis.\r\n\t * @param {object} oArtworkViewer - The artwork viewer.\r\n\t * @returns {array} - Transformed coordinates.\r\n\t */\r\n\tTechToolsUI.prototype.transformCoordinates = function (iStartX, iStartY, iEndX, iEndY, iDragOffset_x, iDragOffset_y, iCenterShift_x, iCenterShift_y, oArtworkViewer) {\r\n\t\tvar iBeginPoint_x = iStartX;\r\n\t\tvar iBeginPoint_y = iStartY;\r\n\t\tvar iEndPoint_x = iEndX;\r\n\t\tvar iEndPoint_y = iEndY;\r\n\r\n\t\t// Calculate the positions based on the canvas rotation.\r\n\t\tswitch (oArtworkViewer.g_iRotDegrees) {\r\n\t\t\tcase 90:\r\n\t\t\t\tiBeginPoint_x += iDragOffset_x * 2;\r\n\t\t\t\tiBeginPoint_x -= iDragOffset_y;\r\n\t\t\t\tiBeginPoint_y += iDragOffset_y * 2;\r\n\t\t\t\tiBeginPoint_y += iDragOffset_x;\r\n\t\t\t\tiEndPoint_x += iDragOffset_x * 2;\r\n\t\t\t\tiEndPoint_x -= iDragOffset_y;\r\n\t\t\t\tiEndPoint_y += iDragOffset_y * 2;\r\n\t\t\t\tiEndPoint_y += iDragOffset_x;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 180:\r\n\t\t\t\tiBeginPoint_x += iDragOffset_x * 3;\r\n\t\t\t\tiBeginPoint_y += iDragOffset_y * 3;\r\n\t\t\t\tiEndPoint_x += iDragOffset_x * 3;\r\n\t\t\t\tiEndPoint_y += iDragOffset_y * 3;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 270:\r\n\t\t\t\tiBeginPoint_x += iDragOffset_x * 2;\r\n\t\t\t\tiBeginPoint_x += iDragOffset_y;\r\n\t\t\t\tiBeginPoint_y += iDragOffset_y * 2;\r\n\t\t\t\tiBeginPoint_y -= iDragOffset_x;\r\n\t\t\t\tiEndPoint_x += iDragOffset_x * 2;\r\n\t\t\t\tiEndPoint_x += iDragOffset_y;\r\n\t\t\t\tiEndPoint_y += iDragOffset_y * 2;\r\n\t\t\t\tiEndPoint_y -= iDragOffset_x;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\tiBeginPoint_x += iDragOffset_x;\r\n\t\t\t\tiBeginPoint_y += iDragOffset_y;\r\n\t\t\t\tiEndPoint_x += iDragOffset_x;\r\n\t\t\t\tiEndPoint_y += iDragOffset_y;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\t// Calculate the compare offset of the canvas.\r\n\t\tvar compareOffset_x, compareOffset_y;\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkViewer);\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(oArtworkViewer);\r\n\r\n\t\t// Ensure the image width is scaled to the image size.\r\n\t\tvar iImageWidth = oArtworkViewer.g_iScaledImageWidth;\r\n\t\tvar iImageHeight = oArtworkViewer.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\tiImageWidth = oArtworkViewer.g_iScaledImageHeight;\r\n\t\t\tiImageHeight = oArtworkViewer.g_iScaledImageWidth;\r\n\t\t}\r\n\r\n\t\t// Update the begin and end points.\r\n\t\tiBeginPoint_x -= (iCenterShift_x + iDragOffset_x + compareOffset_x);\r\n\t\tiBeginPoint_y -= (iCenterShift_y + iDragOffset_y + compareOffset_y);\r\n\t\tiEndPoint_x -= (iCenterShift_x + iDragOffset_x + compareOffset_x);\r\n\t\tiEndPoint_y -= (iCenterShift_y + iDragOffset_y + compareOffset_y);\r\n\r\n\t\t// Ratio the begin and end points.\r\n\t\tiBeginPoint_x /= iImageWidth;\r\n\t\tiBeginPoint_y /= iImageHeight;\r\n\t\tiEndPoint_x /= iImageWidth;\r\n\t\tiEndPoint_y /= iImageHeight;\r\n\r\n\t\treturn [[iBeginPoint_x, iBeginPoint_y], [iEndPoint_x, iEndPoint_y]];\r\n\t}\r\n\r\n\t/// \r\n\t/// Helper method that is called when the pointer up event is fired during a technical tools measurement action.\r\n\t/// \r\n\t/// The event.\r\n\t/// The start X coordinate.\r\n\t/// The start Y coordinate.\r\n\t/// The end X coordinate.\r\n\t/// The end Y coordinate.\r\n\t/// The X-axis drag offset.\r\n\t/// The Y-axis drag offset.\r\n\t/// The X-axis centre shift. The distance from the edge of the screen to the edge of image.\r\n\t/// The Y-axis centre shift. The distance from the edge of the screen to the edge of image.\r\n\t/// Width of the image.\r\n\t/// Height of the image.\r\n\tTechToolsUI.prototype.measurementPointerUp = function (event, oArtworkViewer, oSyncCanvas, beginPoint_x, beginPoint_y, endPoint_x, endPoint_y, iDragOffset_x, iDragOffset_y, iCenterShift_x, iCenterShift_y, iImageWidth, iImageHeight) {\r\n\t\t\r\n\t\t// Outline the co-ordinates for the annotation handle.\r\n\t\tvar iPointX = Math.max(g_oMarquee.g_iX, g_oMarquee.g_iOrigin_x) + g_oAnnotationActions.g_iDragRectOffset;\r\n\t\tvar iPointY = Math.min(g_oMarquee.g_iY, g_oMarquee.g_iOrigin_y);\r\n\r\n\t\t// Get the transformed coordinates.\r\n\t\tvar trueCoords = g_oMarquee.transformMarqueeCoordinatesForRotation(oArtworkViewer, false);\r\n\t\tvar transformedCoordinates = TechToolsUI.prototype.transformCoordinates(trueCoords.iBeginPoint_X, trueCoords.iBeginPoint_Y, trueCoords.iEndPoint_X, trueCoords.iEndPoint_Y, iDragOffset_x, iDragOffset_y, iCenterShift_x, iCenterShift_y, oArtworkViewer);\r\n\r\n\t\t// Determine if the coordinates are out of bounds.\r\n\t\tvar bOutOfBounds = transformedCoordinates.concat().sort(sortAnnotationCoords.returnXMin)[0][0] < 0\r\n\t\t\t|| transformedCoordinates.concat().sort(sortAnnotationCoords.returnXMax)[0][0] > 1\r\n\t\t\t|| transformedCoordinates.concat().sort(sortAnnotationCoords.returnYMin)[0][1] < 0\r\n\t\t\t|| transformedCoordinates.concat().sort(sortAnnotationCoords.returnYMax)[0][1] > 1;\r\n\r\n\t\t// De-rotate.\r\n\t\toArtworkViewer.g_oAnnotationCanvas.g_oContext.save();\r\n\t\tg_oMarquee.derotateCanvasContext(oArtworkViewer.g_oAnnotationCanvas.g_oContext, oArtworkViewer.g_oAnnotationCanvas, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.width, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.height, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.width / 2, oArtworkViewer.g_oAnnotationCanvas.g_oCanvas.height / 2);\r\n\r\n\t\t// Draw the annotation handle.\r\n\t\tif (g_oTechTools.g_iSelectedMeasurementType != g_oTechTools.g_eMeasurementTypes.TEXT &&\r\n\t\t\tg_oTechTools.g_iSelectedMeasurementType != g_oTechTools.g_eMeasurementTypes.VERTICAL &&\r\n\t\t\tg_oTechTools.g_iSelectedMeasurementType != g_oTechTools.g_eMeasurementTypes.HORIZONTAL &&\r\n\t\t\tg_oTechTools.g_iSelectedMeasurementType != g_oTechTools.g_eMeasurementTypes.COLOURDENSITY && // We draw this later\r\n\t\t\tg_oTechTools.g_iSelectedMeasurementType != g_oTechTools.g_eMeasurementTypes.BARCODE) { // We draw this later\r\n\r\n\t\t\tif (!g_oViewer.g_bReadOnly && oArtworkViewer.g_bMainCanvas && !bOutOfBounds) {\r\n\r\n\t\t\t\t// Draw the annotation handle.\r\n\t\t\t\tg_oAnnotationActions.drawAnnotationHandle([iPointX, iPointY], g_oSettings.g_oUserSettings.AnnotationColour, true, eAnnotationHandleTypes.CreateNewAnnotation, oArtworkViewer.g_oAnnotationCanvas.g_oContext);\r\n\r\n\t\t\t\t// Create the handle data object array for the single handle.\r\n\t\t\t\tvar oHandleData = [{\r\n\t\t\t\t\thandleX: iPointX,\r\n\t\t\t\t\thandleY: iPointY,\r\n\t\t\t\t\tannotationCoordinates: transformedCoordinates,\r\n\t\t\t\t\tannotationData: g_oPayload\r\n\t\t\t\t}];\r\n\r\n\t\t\t\t// Set the pointer move event.\r\n\t\t\t\tchangeCanvasFunction('#AnnotationViewer', \"pointermove.annotationUI\", function (e) {\r\n\t\t\t\t\tAnnotationAction.prototype.mouseMoveAnnotationHandles(e, oArtworkViewer, g_oAnnotationActions.g_oAnnotationCanvas, oHandleData, eAnnotationHandleTypes.CreateNewAnnotation);\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// Set the pointer down event.\r\n\t\t\t\tchangeCanvasFunction(\"#AnnotationViewer\", \"pointerdown.annotationUI\", function (e) {\r\n\t\t\t\t\tAnnotationAction.prototype.mouseClickAnnotationHandles(e, oArtworkViewer, g_oAnnotationActions.g_oAnnotationCanvas, oHandleData, eAnnotationHandleTypes.CreateNewAnnotation);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Revert.\r\n\t\toArtworkViewer.g_oAnnotationCanvas.g_oContext.restore();\r\n\r\n\t\tswitch (g_oTechTools.g_iSelectedMeasurementType) {\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.COLOURDENSITY:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.ColourDensityMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.BARCODE:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.BarcodeMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.AREA:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.AreaMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.POINTTOPOINT:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.PointToPointMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.TEXT:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.TextMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.VERTICAL:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.VerticalCalliperMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTechTools.g_eMeasurementTypes.HORIZONTAL:\r\n\t\t\t\tg_oPayload.type = eAnnotationTypes.HorizontalCalliperMeasurement;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\t// If we are measuring a barcode, text or colour density.\r\n\t\tif ((g_oTechTools.g_iSelectedMeasurementType === g_oTechTools.g_eMeasurementTypes.BARCODE) ||\r\n\t\t\t(g_oTechTools.g_iSelectedMeasurementType === g_oTechTools.g_eMeasurementTypes.COLOURDENSITY) ||\r\n\t\t\t(g_oTechTools.g_iSelectedMeasurementType === g_oTechTools.g_eMeasurementTypes.TEXT)) {\r\n\r\n\t\t\t// We want a densitometer reading, text measurement or barcode scan instead!\r\n\t\t\tvar examTypeCode = g_oTechTools.g_eExamTypes.COLOURDENSITY;\r\n\r\n\t\t\t// Determine the selected measurement type.\r\n\t\t\tswitch (g_oTechTools.g_iSelectedMeasurementType) {\r\n\r\n\t\t\t\tcase g_oTechTools.g_eMeasurementTypes.BARCODE:\r\n\t\t\t\t\texamTypeCode = g_oTechTools.g_eExamTypes.BARCODE;\r\n\r\n\t\t\t\t\t// Clear any previous barcode measurement data for this canvas.\r\n\t\t\t\t\tg_oTechTools.g_oBarcodeMeasurementArray = g_oTechTools.g_oBarcodeMeasurementArray.filter(function (obj) {\r\n\t\t\t\t\t\treturn obj.ArtworkCanvasId != oArtworkViewer.g_szCanvasId;\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase g_oTechTools.g_eMeasurementTypes.TEXT:\r\n\t\t\t\t\texamTypeCode = g_oTechTools.g_eExamTypes.TEXT;\r\n\t\t\t\t\tif (!g_oSettings.g_oUserSettings.ShowAnnotations) {\r\n\t\t\t\t\t\t$(\"#HideAnnotations\").click();\t\t// We're creating a new annotation...so show the annotations if currently hidden.\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\t// Leave the exam type code as zero.\r\n\t\t\t}\r\n\r\n\t\t\t// Take a copy of the begin and end points.\r\n\t\t\tvar g_iBeginPoint_x = beginPoint_x;\r\n\t\t\tvar g_iBeginPoint_y = beginPoint_y;\r\n\t\t\tvar g_iEndPoint_x = endPoint_x;\r\n\t\t\tvar g_iEndPoint_y = endPoint_y;\r\n\r\n\t\t\t// Calculate the positions based on the canvas rotation.\r\n\t\t\tvar oTransformedCoords = TechToolsUI.prototype.transformCoordinates(beginPoint_x, beginPoint_y, endPoint_x, endPoint_y, iDragOffset_x, iDragOffset_y, iCenterShift_x, iCenterShift_y, oArtworkViewer);\r\n\t\t\tbeginPoint_x = oTransformedCoords[0][0];\r\n\t\t\tbeginPoint_y = oTransformedCoords[0][1];\r\n\t\t\tendPoint_x = oTransformedCoords[1][0];\r\n\t\t\tendPoint_y = oTransformedCoords[1][1];\r\n\r\n\t\t\t// Get the compare rotation of the canvas (again)\r\n\t\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkViewer);\r\n\r\n\t\t\t// If this is a real time render for the colour density tool.\r\n\t\t\t// Barcode real time renders are created at the time of scanning.\r\n\t\t\tif (g_oViewer.g_oArtworkViewer.isViewerUsingRealtimeRender() && g_oTechTools.g_iSelectedMeasurementType == g_oTechTools.g_eMeasurementTypes.COLOURDENSITY) {\r\n\r\n\t\t\t\t// Update the points to be relative to the real time render image, rather than the whole image.\r\n\t\t\t\tbeginPoint_x = g_iBeginPoint_x / oArtworkViewer.g_oCanvas.width;\r\n\t\t\t\tbeginPoint_y = g_iBeginPoint_y / oArtworkViewer.g_oCanvas.height;\r\n\t\t\t\tendPoint_x = g_iEndPoint_x / oArtworkViewer.g_oCanvas.width;\r\n\t\t\t\tendPoint_y = g_iEndPoint_y / oArtworkViewer.g_oCanvas.height;\r\n\r\n\t\t\t\t// These cases orientate the begin/end X & Y coordinates to the server image which won't have been rotated.\r\n\t\t\t\tswitch (g_oTechTools.g_oArtworkViewer.g_iRotDegrees) {\r\n\t\t\t\t\tcase 90:\r\n\t\t\t\t\t\tvar tempValue = beginPoint_x;\r\n\t\t\t\t\t\tbeginPoint_x = beginPoint_y;\r\n\t\t\t\t\t\tbeginPoint_y = 1 - tempValue;\r\n\r\n\t\t\t\t\t\ttempValue = endPoint_x;\r\n\t\t\t\t\t\tendPoint_x = endPoint_y;\r\n\t\t\t\t\t\tendPoint_y = 1 - tempValue;\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 180:\r\n\t\t\t\t\t\tbeginPoint_x = 1 - beginPoint_x;\r\n\t\t\t\t\t\tbeginPoint_y = 1 - beginPoint_y;\r\n\r\n\t\t\t\t\t\tendPoint_x = 1 - endPoint_x;\r\n\t\t\t\t\t\tendPoint_y = 1 - endPoint_y;\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 270:\r\n\t\t\t\t\t\tvar tempValue = beginPoint_x;\r\n\t\t\t\t\t\tbeginPoint_x = 1 - beginPoint_y;\r\n\t\t\t\t\t\tbeginPoint_y = tempValue;\r\n\r\n\t\t\t\t\t\ttempValue = endPoint_x;\r\n\t\t\t\t\t\tendPoint_x = 1 - endPoint_y;\r\n\t\t\t\t\t\tendPoint_y = tempValue;\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t// Do nothing as it's in the correct orientation.\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// If the canvas has compare rotation.\r\n\t\t\tif (iCompareRotation > 0) {\r\n\r\n\t\t\t\t// Rotate the begin points.\r\n\t\t\t\tvar oRotatedAnnotationDraw = oArtworkViewer.rotate(beginPoint_x, beginPoint_y, 0.5, 0.5, -iCompareRotation);\r\n\t\t\t\tbeginPoint_x = oRotatedAnnotationDraw.rotated_x;\r\n\t\t\t\tbeginPoint_y = oRotatedAnnotationDraw.rotated_y;\r\n\r\n\t\t\t\t// Rotate the end points.\r\n\t\t\t\tvar oRotatedAnnotationDraw = oArtworkViewer.rotate(endPoint_x, endPoint_y, 0.5, 0.5, -iCompareRotation);\r\n\t\t\t\tendPoint_x = oRotatedAnnotationDraw.rotated_x;\r\n\t\t\t\tendPoint_y = oRotatedAnnotationDraw.rotated_y;\r\n\t\t\t}\r\n\r\n\t\t\t// If this is a density barcode or text measurement, and we cannot show the side bar.\r\n\t\t\tif (g_oTechTools.g_iSelectedMeasurementType == g_oTechTools.g_eMeasurementTypes.COLOURDENSITY ||\r\n\t\t\t\tg_oTechTools.g_iSelectedMeasurementType == g_oTechTools.g_eMeasurementTypes.BARCODE ||\r\n\t\t\t\tg_oTechTools.g_iSelectedMeasurementType == g_oTechTools.g_eMeasurementTypes.TEXT) {\r\n\r\n\t\t\t\t// If we cannot show the side bar due to not having separations.\r\n\t\t\t\tif ((!g_oViewer.g_oArtworkViewer.hasSeparations()) ||\r\n\t\t\t\t\t(g_oViewer.g_oCompareMode != eCompareMode.NoCompare && !g_oCompare.g_oCompareViewer.hasSeparations())) {\r\n\r\n\t\t\t\t\t// Display a warning message.\r\n\t\t\t\t\tg_oGreenlightMessages.displayWarningBubble(g_oTechTools.c_szInfoMsgNoSeparationsShown);\r\n\r\n\t\t\t\t\t// Redraw the canvas.\r\n\t\t\t\t\toArtworkViewer.g_oAnnotationCanvas.redraw(false);\r\n\r\n\t\t\t\t\t// Do not examine the image.\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Examine the image.\r\n\t\t\tg_oTechTools.examineImage(\r\n\t\t\t\toArtworkViewer,\r\n\t\t\t\toArtworkViewer.g_oAnnotationCanvas,\r\n\t\t\t\tMath.min(beginPoint_x, endPoint_x),\r\n\t\t\t\tMath.min(beginPoint_y, endPoint_y),\r\n\t\t\t\tMath.max(beginPoint_x, endPoint_x),\r\n\t\t\t\tMath.max(beginPoint_y, endPoint_y),\r\n\t\t\t\texamTypeCode\r\n\t\t\t);\r\n\r\n\t\t\t// Show the separations slide out if we're NOT looking for text.\r\n\t\t\tif (($(\"#divSepDiv\").css(\"display\") === \"none\") &&\r\n\t\t\t\t(g_oTechTools.g_iSelectedMeasurementType !== g_oTechTools.g_eMeasurementTypes.TEXT)) {\r\n\r\n\t\t\t\t// Show the separations side bar.\r\n\t\t\t\tg_oTechTools.showSeperationsSideBar(g_oTechTools.g_iSelectedMeasurementType !== g_oTechTools.g_eMeasurementTypes.BARCODE);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Called when the document has been changed.\r\n\t */\r\n\tTechToolsUI.prototype.docChangeEvent = function () {\r\n\r\n\t\t// Clear any previous barcode measurement data.\r\n\t\tg_oTechTools.clearBarcodeMeasurementArray();\r\n\r\n\t\t// Get the index of the approval document combo control.\r\n\t\tvar oComboControl = comboControl_GetControlById(\"approvalNameComboControl\", false);\r\n\r\n\t\t// If the combo control has been found and a document has been selected.\r\n\t\tif (oComboControl != null && oComboControl.selectedDocumentIndex != -1) {\r\n\r\n\t\t\t// Get the selected document.\r\n\t\t\tvar oDocument = oComboControl.documents[oComboControl.selectedDocumentIndex];\r\n\r\n\t\t\t// Set the document details.\r\n\t\t\tg_oTechTools.g_iDocumentId = oDocument.greenlightDocumentId;\r\n\t\t\tg_oTechTools.g_iApprovalId = oDocument.greenlightApprovalId;\r\n\t\t}\r\n\t\telse {\r\n\t\t\tg_oTechTools.g_iDocumentId = 0;\r\n\t\t\tg_oTechTools.g_iApprovalId = 0;\r\n\t\t}\r\n\t\t\r\n\t\t// If the document is a PDF.\r\n\t\tif (documentHasSeparations(g_oTechTools.g_oArtworkViewer.g_oDoc.documentType, g_oTechTools.g_oArtworkViewer.g_oDoc.pages.length)) {\r\n\r\n\t\t\t// Enable PDF specific measurements.\r\n\t\t\t$(\"#tblTechTools\").show();\r\n\t\t\t$(\"#btnTechTools\").show();\r\n\t\t\t$(\"#divTechToolsBarcode\").show();\r\n\t\t\t$(\"#divTechToolsDensity\").show();\r\n\t\t\t$(\"#divTechToolsText\").show();\r\n\t\t}\r\n\t\t// If this is a threeD or svg document.\r\n\t\telse if (g_oTechTools.g_oArtworkViewer.g_oDoc.documentType == eDocumentTypes.ThreeD || documentDisplaysAsSVG(g_oTechTools.g_oArtworkViewer.g_oDoc.documentType)) {\r\n\r\n\t\t\t// Disable the tech tools.\r\n\t\t\t$(\"#tblTechTools\").hide();\r\n\t\t\t$(\"#btnTechTools\").hide();\r\n\t\t\t$(\"#divTechToolsBarcode\").hide();\r\n\t\t\t$(\"#divTechToolsDensity\").hide();\r\n\t\t\t$(\"#divTechToolsText\").hide();\r\n\t\t}\r\n\t\t// If the document is any other type of document.\r\n\t\telse {\r\n\r\n\t\t\t// Disable PDF specific measurements.\r\n\t\t\t$(\"#tblTechTools\").show();\r\n\t\t\t$(\"#btnTechTools\").show();\r\n\t\t\t$(\"#divTechToolsBarcode\").hide();\r\n\t\t\t$(\"#divTechToolsDensity\").hide();\r\n\t\t\t$(\"#divTechToolsText\").hide();\r\n\t\t}\r\n\t};\r\n\r\n\t/// \r\n\t/// Called when the Text Measurement annotation needs to collect the text content.\r\n\t/// If this is a result of the creation of a new Text Measurement Annotation then\r\n\t/// the text content and text measurement words array will be populated with the\r\n\t/// info returned by the examineImage_CH function.\r\n\t/// If the text content and text measurement words array are empty then this event\r\n\t/// has been called by a pre-existing text measurement annotation that needs to\r\n\t/// know which words it should highlight. The words array is not stored in the\r\n\t/// database and is worked out when the annotation is loaded from the database.\r\n\t/// \r\n\t/// \r\n\t/// The annotation object to be populated with the text measurement words.\r\n\t/// \r\n\tTechToolsUI.prototype.getTextMeasurementText = function (oData) {\r\n\t\t// Extract the objects from the published data.\r\n\t\tvar oAnnotation = oData.oAnnotation;\r\n\t\tvar oArtworkCanvas = oData.oArtworkCanvas;\r\n\t\tvar oAnnotationCanvas = oData.oAnnotationCanvas;\r\n\r\n\t\t// If we already have words from a previous Text Measurement (which we shouldn't but you never know)...\r\n\t\tif (oAnnotation.g_oTextMeasurementWordsArray.length > 0 ||\r\n\t\t\t(oAnnotation.g_szTextContent !== undefined && oAnnotation.g_szTextContent.length > 0)) {\r\n\t\t\toAnnotation.g_oTextMeasurementWordsArray.length = 0;\t// ...clear the array by resetting it's length.\r\n\t\t}\r\n\r\n\t\tif (g_oTechTools.g_szTextMeasurementTextContent.length === 0) {\r\n\t\t\t// If we're populating a previously saved annotation we have to re-retrieve the measured text...\r\n\t\t\tvar begin_x = oAnnotation.g_oMarqueeDrawArray[0][0];\r\n\t\t\tvar begin_y = oAnnotation.g_oMarqueeDrawArray[0][1];\r\n\t\t\tvar end_x = oAnnotation.g_oMarqueeDrawArray[1][0];\r\n\t\t\tvar end_y = oAnnotation.g_oMarqueeDrawArray[1][1];\r\n\t\t\tvar iAnnotationId = oAnnotation.id;\r\n\t\t\tg_oTechTools.examineImage(oArtworkCanvas, oAnnotationCanvas, begin_x, begin_y, end_x, end_y, g_oTechTools.g_eExamTypes.TEXT, iAnnotationId);\r\n\t\t}\r\n\t\telse {\r\n\t\t\t// ...Else just serve up the text measurement content we currently have.\r\n\t\t\toAnnotation.g_szTextContent = g_oTechTools.g_szTextMeasurementTextContent;\r\n\t\t\toAnnotation.g_oTextMeasurementWordsArray = deepCopyArray(g_oTechTools.g_oTextMeasurementWordsArray);\r\n\r\n\t\t\t// Clear the Tech Tools text measurement variables for the next annotation that needs to retrieve the measurement text.\r\n\t\t\tg_oTechTools.g_szTextMeasurementTextContent = \"\";\r\n\t\t\tg_oTechTools.g_oTextMeasurementWordsArray.length = 0;\r\n\t\t}\r\n\t};\r\n\r\n\t/// \r\n\t/// Helper function to iterate through the TextElement object array and set all the IsTextVisible\r\n\t/// properties to the specified value.\r\n\t/// \r\n\t/// The text element array.\r\n\t/// The boolean value that the IsTextVisible property is to be set to.\r\n\tTechToolsUI.prototype.setTextMeasurementWordVisibility = function (oTextElementArray, bIsVisible) {\r\n\t\tfor (var i = 0; i < oTextElementArray.length; i++) {\r\n\t\t\toTextElementArray.IsTextVisible = bIsVisible;\r\n\r\n\t\t\tfor (var j = 0; j < oTextElementArray[i].ChildTextElements.length; j++) {\r\n\t\t\t\toTextElementArray[i].ChildTextElements[j].IsTextVisible = bIsVisible;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Registers the approvals events.\r\n\t * @param {object} oEventService - The event service we are registering the events to.\r\n\t */\r\n\tTechToolsUI.prototype.RegisterEvents = function (oEventService) {\r\n\t\tg_oTechTools.g_oEvents = oEventService;\r\n\t\tg_oTechTools.g_oEvents.subscribe(\"changeDoc\", g_oTechTools.docChangeEvent);\r\n\t\tg_oTechTools.g_oEvents.subscribe(\"getTextMeasurementText\", g_oTechTools.getTextMeasurementText);\r\n\t};\r\n\r\n\t// Add the Tech Tools UI object to the window.\r\n\twindow.TechToolsUI = TechToolsUI;\r\n}());"]}