{"version":3,"sources":["../js/Text/GreenlightTextTools.js"],"names":["g_oTextTools","TextTools","this","g_eToolTypes","TextHighlight","ParagraphHighlight","RemoveTextHighlight","AreaTextHighlight","g_bHighlightInProgress","g_bHighlightIsCharacterAccuracy","g_bHighlightOnCompareCanvas","g_eActiveToolType","g_eActiveAnnotationType","g_oAnnotationText","g_oCurrentText","g_oStartingText","g_oEndingText","g_szHighlightColour","g_iExistingAnnotationId","prototype","initialiseTextTool","eToolType","eAnnotationType","bCharacterLevelAccuracy","bCompareCanvas","colour","setHighlightColour","$","remove","g_oAnnotations","closeActiveAnnotations","length","displayHighlightInfo","g_oSettings","g_oUserSettings","ShowAnnotations","click","changeCanvasFunction","prop","g_oTextTools_TextHighlight","initialiseHighlight","g_oTextTools_ParagraphHighlight","g_oTextTools_RemoveTextHighlight","g_oTextTools_AreaTextHighlight","endhighlight","oArtworkCanvas","oAnnotationCanvas","bSaveAnnotation","g_oGreenlightMessages","closeBubbles","g_oTextCompare","g_bTextCompareInProgress","bAutoSelect","g_oTextCompare_AutoSelection","isAutoSelectionEnabled","addTextData","updateTextData","rebuildAnnotationList","createAnnotation","updateNewAnnotation","updateAnnotation","convertMousePositionToPercentages","event","coords","getClick","transformedClick","transformClickForRotation","co","g_oCompare","calculateCompareOffsetInPx","compareOffset_x","x","compareOffset_y","y","g_iScaledImageWidth","g_iScaledImageHeight","i","g_oActiveBubbles","closeBubble","id","displayInfoBubble","getHighlightInfo","szHighlightInfo","c_szTextHighlight","c_szParagraphHighlight","c_szRemoveTextHighlight","c_szAreaTextHighlight","isTextHighlightLeftToRight","c_szTextHighlightLeftToRight","c_szTextHighlightRightToLeft","c_szTextHighlightExit","c_szTextHighlightSeeMore","c_szTextHighlightClickDragRelease","c_szTextHighlightChangeDirection","showMoreHighlightInfo","hide","slideToggle","toggleHighlightDirection","HighlightPreference","eHighlightType","LeftToRight","RightToLeft","updateSettingHighlightPreference","getFirstTextInParagraph","iParagraph","getFirstCharacterInParagraph","getFirstWordInParagraph","oTextData","g_oTextData","getTextData","g_oDoc","documentId","g_iCurrentPage","textData","paragraph","Paragraphs","Order","line","Lines","word","Words","character","Characters","getLastTextInParagraph","getLastCharacterInParagraph","getLastWordInParagraph","isLastCharacterInWord","findText","point_x","point_y","findText_Character","findText_Word","findParagraph","iLine","findLine","iWord","findWord","iCharacter","findChararacter","isPointWithinBounds","X1","X2","Y1","Y2","bounds_x1","bounds_x2","bounds_y1","bounds_y2","findClosestText","findClosestText_Character","findClosestText_Word","oText","iClosestDistance","j","k","iDistance","distancePointToBounds","l","bounds_x_middle","bounds_y_middle","Math","min","sqrt","pow","showAllParagraphs","highlightParagraph","showAllLines","highlightLine","showAllWords","highlightWord","removeHighlights","g_oContext","save","g_oMarquee","derotateCanvasContext","g_oCanvas","width","height","clearRect","restore","highlightSections","oSections","highlightSections_Character","highlightSections_Word","oWords","getSectionsWords","sort","sortWords","distinctWords","oWord","oPreviousWord","iX1","iX2","iY1","iY2","highlightElement","oCharacters","getSectionsCharacters","sortCharacters","distinctCharacters","oCharacter","oPreviousCharacter","highlightCharacter","concat","getSectionWords","startingText","endingText","leftToRight","textHighlightCorrectOrder","characterLevelAccuracy","oStart","oParagraph","isWordInSection","push","getSectionCharacters","isCharacterInSection","a","b","splice","getSectionsBounds_Words","oSectionsBounds","x1","x2","y1","y2","oSectionBounds","getSectionBounds_Words","max","getSectionsBounds_Characters","getSectionBounds_Characters","getWordListBounds","oWordList","getCharacterListBounds","oCharacterList","getWordText","Content","getCharacterText","getWordListText","szText","getCharacterListText","getSectionsText_Words","szPrepend","szAppend","szSectionsText","getSectionText_Words","szSectionText","bPreviousWordHighlighted","bWordInSection","SpaceAfter","split","reverse","join","getSectionsText_Characters","getSectionText_Characters","getWordBoldSetting","Bold","getWordItalicSetting","Italic","getCharacterBoldSetting","getCharacterItalicSetting","getCharacterLastInWord","getWordCharacters","splitSections","splitSections_Characters","splitSections_Words","oSplitSections","oSectionWords","mergeSections","mergeSections_Characters","mergeSections_Words","oMergedSections","oMergedSection","isWordInList","isCharacterInList","isWordInSection_LeftToRight","isWordInSection_RightToLeft","isCharacterInSection_LeftToRight","isCharacterInSection_RightToLeft","bCharacterInSection","grep","oWordListItem","oCharacterListItem","oLine","iScaledImageWidth","iScaledImageHeight","iCompareRotation","getCompareRotation","oRotatedLetterLower","rotate","rotated_x","rotated_y","oRotatedLetterUpper","startX","g_iCenterShift_x","startY","g_iCenterShift_y","distX","distY","drawTextHighlight","indexOf","oHexColour","getHexColour","oRGB","convertColourHexToRGB","r","g","oTextAnnotation","generateTextAnnotation","g_oAnnotationsMade","createAnnotationDiv","eAnnotationDivType","Popup","redrawAnnotations","repositionSpeechBubbles","focus","oAnnotationText","Annotation","g_iApprovalId","getNextAnnotationId","g_iAnnotationType","g_oDrawArray","g_szTextContent","g_szTextHighlightContent","JSON","stringify","g_iParentAnnotationId","g_iNumber","apply","map","o","g_szColour","g_oAnnotationColSelected","g_iDocumentId","g_iAuthor","g_oUserDetails","UserId","g_szAuthorEmail","EmailAddress","g_bSaved","status","isEmptyObject","pages","documentPageNumber","g_iDocumentPageId","documentPageId","eAnnotationTypes","TextClassification","g_oAnnotationData","g_oAnnotationTextClassification","populateDefaultAnnotationData","ann","g_oDrawCoordSetArray","xCoordinate","yCoordinate","AnnotationSave","window"],"mappings":"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","file":"GreenlightTextTools-5571b88334.js","sourcesContent":["/*\r\n * Copyright (c) 2021 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: GreenlightTextTools.js\r\n *\r\n * Description:\tThe class containing the functionality required by the Greenlight for text tools.\r\n * \r\n */\r\n\r\n// The text tools object.\r\nvar g_oTextTools = {};\r\n\r\n(function () {\r\n\t\"use strict\";\r\n\r\n\t/**\r\n\t * Load the text content for the page.\r\n\t */\r\n\tfunction TextTools() {\r\n\r\n\t\t// The tools available for use.\r\n\t\tthis.g_eToolTypes = {\r\n\t\t\tTextHighlight: 1,\r\n\t\t\tParagraphHighlight: 2,\r\n\t\t\tRemoveTextHighlight: 3,\r\n\t\t\tAreaTextHighlight: 4\r\n\t\t};\r\n\r\n\t\t// Keeps track of if a highlight is in progress.\r\n\t\tthis.g_bHighlightInProgress = false;\r\n\r\n\t\t// Keep track of the highlight accuracy.\r\n\t\tthis.g_bHighlightIsCharacterAccuracy = false;\r\n\r\n\t\t// Keeps track of if the highlight is on the compare canvas.\r\n\t\tthis.g_bHighlightOnCompareCanvas = false;\r\n\r\n\t\t// Keep track of the active tool type.\r\n\t\tthis.g_eActiveToolType = null;\r\n\r\n\t\t// Keep track of the active annotation type.\r\n\t\tthis.g_eActiveAnnotationType = null;\r\n\r\n\t\t// The annotation text for the highlight.\r\n\t\tthis.g_oAnnotationText = [];\r\n\r\n\t\t// The current text on highlight.\r\n\t\tthis.g_oCurrentText = null;\r\n\r\n\t\t// The starting text on highlight.\r\n\t\tthis.g_oStartingText = null;\r\n\r\n\t\t// The ending text on highlight.\r\n\t\tthis.g_oEndingText = null;\r\n\r\n\t\t// The colour to use for highlighting.\r\n\t\tthis.g_szHighlightColour = \"\";\r\n\r\n\t\t// The annotation to add text to.\r\n\t\tthis.g_iExistingAnnotationId = null;\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises a text tool.\r\n\t * @param {enum} eToolType - The tool to be initialised.\r\n\t * @param {enum} eAnnotationType - The annotation type.\r\n\t * @param {bool} bCharacterLevelAccuracy - If the tool should be at character or word level accuracy.\r\n\t * @param {bool} bCompareCanvas - If this is on the compare canvas.\r\n\t * @param {string} colour - The colour to be used.\r\n\t */\r\n\tTextTools.prototype.initialiseTextTool = function (eToolType, eAnnotationType, bCharacterLevelAccuracy, bCompareCanvas, colour) {\r\n\t\t\r\n\t\t// Set that a highlight is in progress.\r\n\t\tg_oTextTools.g_bHighlightInProgress = true;\r\n\r\n\t\t// Update the highlight settings.\r\n\t\tg_oTextTools.g_eActiveToolType = eToolType;\r\n\t\tg_oTextTools.g_eActiveAnnotationType = eAnnotationType;\r\n\t\tg_oTextTools.g_bHighlightOnCompareCanvas = bCompareCanvas;\r\n\t\tg_oTextTools.g_bHighlightIsCharacterAccuracy = bCharacterLevelAccuracy;\r\n\r\n\t\t// Update the highlight colour.\r\n\t\tg_oTextTools.setHighlightColour(colour);\r\n\r\n\t\t// If this is an edit for a new annotation, remove the div without deleting the annotation.\r\n\t\tif (g_oTextTools.g_iExistingAnnotationId < 0) {\r\n\t\t\t$(\"#\" + g_oTextTools.g_iExistingAnnotationId).remove();\r\n\t\t}\r\n\r\n\t\t// Close any other open annotations.\r\n\t\tg_oAnnotations.closeActiveAnnotations();\r\n\r\n\t\t// Hide the existing annotations from the annotation list.\r\n\t\t$(\".annotationListItem\").remove();\r\n\r\n\t\t// Display an info bubble for highlighting text if required.\r\n\t\tif ($(\".speechbubble__texthighlight\").length == 0) {\r\n\t\t\tg_oTextTools.displayHighlightInfo();\r\n\t\t}\r\n\r\n\t\t// Reshow annotations if they are hidden.\r\n\t\tif (!g_oSettings.g_oUserSettings.ShowAnnotations) {\r\n\t\t\t$(\"#HideAnnotations\").click();\r\n\t\t}\r\n\r\n\t\t// Clear all bindings.\r\n\t\tchangeCanvasFunction();\r\n\r\n\t\t// Ensure we are on the main canvas.\r\n\t\tif ($(\"#chkAnnotationToggle\").prop(\"checked\")) {\r\n\t\t\t$(\"#chkAnnotationToggle\").click();\r\n\t\t}\r\n\r\n\t\t// Initialise the tool.\r\n\t\tswitch (g_oTextTools.g_eActiveToolType) {\r\n\t\t\tcase g_oTextTools.g_eToolTypes.TextHighlight:\r\n\t\t\t\tg_oTextTools_TextHighlight.initialiseHighlight();\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextTools.g_eToolTypes.ParagraphHighlight:\r\n\t\t\t\tg_oTextTools_ParagraphHighlight.initialiseHighlight();\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextTools.g_eToolTypes.RemoveTextHighlight:\r\n\t\t\t\tg_oTextTools_RemoveTextHighlight.initialiseHighlight();\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextTools.g_eToolTypes.AreaTextHighlight:\r\n\t\t\t\tg_oTextTools_AreaTextHighlight.initialiseHighlight();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Ends a text highlight.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @param {bool} bSaveAnnotation - If the highlight annotation should be saved.\r\n\t */\r\n\tTextTools.prototype.endhighlight = function (oArtworkCanvas, oAnnotationCanvas, bSaveAnnotation) {\r\n\r\n\t\t// Set that a highlight is not in progress.\r\n\t\tg_oTextTools.g_bHighlightInProgress = false;\r\n\r\n\t\t// Close any open info bubbles.\r\n\t\tg_oGreenlightMessages.closeBubbles(\"Info\");\r\n\r\n\t\t// If we do not want to save the annotation, stop the process here.\r\n\t\tif (!bSaveAnnotation) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If this is part of a text compare, send the annotation text back to the text compare.\r\n\t\tif (g_oTextCompare.g_bTextCompareInProgress) {\r\n\r\n\t\t\t// Reset the canvas function.\r\n\t\t\tchangeCanvasFunction();\r\n\r\n\t\t\t// Should we auto select the text on the compare document.\r\n\t\t\tvar bAutoSelect = g_oTextCompare_AutoSelection.isAutoSelectionEnabled();\r\n\r\n\t\t\t// If this is a new annotation.\r\n\t\t\tif (g_oTextTools.g_iExistingAnnotationId == null) {\r\n\t\t\t\tg_oTextCompare.addTextData(g_oTextTools.g_oAnnotationText, g_oTextTools.g_bHighlightOnCompareCanvas, bAutoSelect, true);\r\n\t\t\t}\r\n\t\t\t// If this is an existing annotation.\r\n\t\t\telse {\r\n\t\t\t\tg_oTextCompare.updateTextData(g_oTextTools.g_oAnnotationText, g_oTextTools.g_bHighlightOnCompareCanvas, bAutoSelect);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Re-build the annotation list.\r\n\t\tg_oAnnotations.rebuildAnnotationList(oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Check we have highlight content.\r\n\t\tif (g_oTextTools.g_oAnnotationText.length == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If this is a new annotation.\r\n\t\tif (g_oTextTools.g_iExistingAnnotationId == null) {\r\n\r\n\t\t\t// Create the annotation.\r\n\t\t\tg_oTextTools.createAnnotation(oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t\t// If this is an edit of a new annotation.\r\n\t\telse if (g_oTextTools.g_iExistingAnnotationId < 0) {\r\n\r\n\t\t\t// Update the new annotation.\r\n\t\t\tg_oTextTools.updateNewAnnotation(oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t\t// If this is an existing annotation.\r\n\t\telse {\r\n\r\n\t\t\t// Update the annotation.\r\n\t\t\tg_oTextTools.updateAnnotation(oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Converts a mouse position to percentages.\r\n\t * @param {object} event - The event.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The mouse percentages.\r\n\t */\r\n\tTextTools.prototype.convertMousePositionToPercentages = function (event, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the click coordinates.\r\n\t\tvar coords = g_oAnnotations.getClick(event, oAnnotationCanvas);\r\n\r\n\t\t// Get the transformed coordinates.\r\n\t\tvar transformedClick = g_oAnnotations.transformClickForRotation(coords[0], coords[1], oArtworkCanvas);\r\n\t\tcoords[0] = transformedClick[0];\r\n\t\tcoords[1] = transformedClick[1];\r\n\r\n\t\t// Calculate the compare offset of the canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Convert the coordinates to percentages.\r\n\t\tcoords[0] = (coords[0] - compareOffset_x) / oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tcoords[1] = (coords[1] - compareOffset_y) / oArtworkCanvas.g_iScaledImageHeight;\r\n\r\n\t\t// Return the result.\r\n\t\treturn {\r\n\t\t\tx: coords[0],\r\n\t\t\ty: coords[1]\r\n\t\t};\r\n\t};\r\n\r\n\t/**\r\n\t * Displays the highlight info.\r\n\t */\r\n\tTextTools.prototype.displayHighlightInfo = function () {\r\n\t\t\r\n\t\t// Hide any existing bubbles.\r\n\t\tfor (var i = 0; i < g_oActiveBubbles.length; i++) {\r\n\t\t\tg_oGreenlightMessages.closeBubble(g_oActiveBubbles[i].id, true, true);\r\n\t\t}\r\n\t\t\r\n\t\t// Display the info bubble with the correct text.\r\n\t\tg_oGreenlightMessages.displayInfoBubble(g_oTextTools.getHighlightInfo(), true);\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text highlight info.\r\n\t */\r\n\tTextTools.prototype.getHighlightInfo = function () {\r\n\t\t\r\n\t\t// Outline the highlight info to be returned.\r\n\t\tvar szHighlightInfo = \"\";\r\n\r\n\t\t// Open the main info div.\r\n\t\tszHighlightInfo += '
';\r\n\r\n\t\t// Add the text based on the tool type.\r\n\t\tszHighlightInfo += '
';\r\n\t\tswitch (g_oTextTools.g_eActiveToolType) {\r\n\t\t\tcase g_oTextTools.g_eToolTypes.TextHighlight:\r\n\t\t\t\tszHighlightInfo += g_oTextTools.c_szTextHighlight;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextTools.g_eToolTypes.ParagraphHighlight:\r\n\t\t\t\tszHighlightInfo += g_oTextTools.c_szParagraphHighlight;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextTools.g_eToolTypes.RemoveTextHighlight:\r\n\t\t\t\tszHighlightInfo += g_oTextTools.c_szRemoveTextHighlight;\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextTools.g_eToolTypes.AreaTextHighlight:\r\n\t\t\t\tszHighlightInfo += g_oTextTools.c_szAreaTextHighlight;\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\tszHighlightInfo += g_oTextTools.isTextHighlightLeftToRight() ? ' ' + g_oTextTools.c_szTextHighlightLeftToRight : ' ' + g_oTextTools.c_szTextHighlightRightToLeft;\r\n\t\tszHighlightInfo += '
';\r\n\r\n\t\t// Add the close message.\r\n\t\tszHighlightInfo += '
' + g_oTextTools.c_szTextHighlightExit + '
';\r\n\r\n\t\t// Add the see more message.\r\n\t\tszHighlightInfo += '
' + g_oTextTools.c_szTextHighlightSeeMore + '
';\r\n\r\n\t\t// Add the see more info to be shown.\r\n\t\tszHighlightInfo += '
';\r\n\t\tszHighlightInfo += '
' + g_oTextTools.c_szTextHighlightClickDragRelease + '
';\r\n\t\tszHighlightInfo += '
' + g_oTextTools.c_szTextHighlightChangeDirection + '
';\r\n\t\tszHighlightInfo += '
';\r\n\r\n\t\t// Close the main info div.\r\n\t\tszHighlightInfo += '
';\r\n\r\n\t\t// Return the highlight info.\r\n\t\treturn szHighlightInfo;\r\n\t};\r\n\r\n\t/**\r\n\t * Shows more highlight information.\r\n\t */\r\n\tTextTools.prototype.showMoreHighlightInfo = function () {\r\n\r\n\t\t// Hide the show more content div.\r\n\t\t$(\"#divTextHighlightShowMoreInfo\").hide();\r\n\r\n\t\t// Show the extra content.\r\n\t\t$(\"#divTextHighlightMoreInfo\").slideToggle();\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the highlight direction.\r\n\t */\r\n\tTextTools.prototype.toggleHighlightDirection = function () {\r\n\r\n\t\t// Toggle the highlight direction.\r\n\t\tg_oSettings.g_oUserSettings.HighlightPreference = g_oSettings.g_oUserSettings.HighlightPreference == eHighlightType.LeftToRight ? eHighlightType.RightToLeft : eHighlightType.LeftToRight;\r\n\r\n\t\t// Update the setting.\r\n\t\tg_oSettings.updateSettingHighlightPreference(true);\r\n\r\n\t\t// Update the info bubble.\r\n\t\tg_oTextTools.displayHighlightInfo();\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the first text in a paragraph.\r\n\t * @param {int} iParagraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getFirstTextInParagraph = function (iParagraph, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\treturn g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getFirstCharacterInParagraph(iParagraph, oArtworkCanvas) : g_oTextTools.getFirstWordInParagraph(iParagraph, oArtworkCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the first word in a paragraph.\r\n\t * @param {int} iParagraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getFirstWordInParagraph = function (iParagraph, oArtworkCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the first word of the paragraph.\r\n\t\treturn {\r\n\t\t\tparagraph: oTextData.Paragraphs[iParagraph].Order,\r\n\t\t\tline: oTextData.Paragraphs[iParagraph].Lines[0].Order,\r\n\t\t\tword: oTextData.Paragraphs[iParagraph].Lines[0].Words[0].Order\r\n\t\t};\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the first character in a paragraph.\r\n\t * @param {int} iParagraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getFirstCharacterInParagraph = function (iParagraph, oArtworkCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the first character of the paragraph.\r\n\t\treturn {\r\n\t\t\tparagraph: oTextData.Paragraphs[iParagraph].Order,\r\n\t\t\tline: oTextData.Paragraphs[iParagraph].Lines[0].Order,\r\n\t\t\tword: oTextData.Paragraphs[iParagraph].Lines[0].Words[0].Order,\r\n\t\t\tcharacter: oTextData.Paragraphs[iParagraph].Lines[0].Words[0].Characters[0].Order\r\n\t\t};\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the last text in a paragraph.\r\n\t * @param {int} iParagraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getLastTextInParagraph = function (iParagraph, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\treturn g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getLastCharacterInParagraph(iParagraph, oArtworkCanvas) : g_oTextTools.getLastWordInParagraph(iParagraph, oArtworkCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the last word in a paragraph.\r\n\t * @param {int} iParagraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getLastWordInParagraph = function (iParagraph, oArtworkCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the last word of the paragraph.\r\n\t\treturn {\r\n\t\t\tparagraph: oTextData.Paragraphs[iParagraph].Order,\r\n\t\t\tline: oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Order,\r\n\t\t\tword: oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words[oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words.length - 1].Order,\r\n\t\t};\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the last character in a paragraph.\r\n\t * @param {int} iParagraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getLastCharacterInParagraph = function (iParagraph, oArtworkCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the last character of the paragraph.\r\n\t\treturn {\r\n\t\t\tparagraph: oTextData.Paragraphs[iParagraph].Order,\r\n\t\t\tline: oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Order,\r\n\t\t\tword: oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words[oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words.length - 1].Order,\r\n\t\t\tcharacter: oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words[oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words.length - 1].Characters[oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words[oTextData.Paragraphs[iParagraph].Lines[oTextData.Paragraphs[iParagraph].Lines.length - 1].Words.length - 1].Characters.length - 1].Order,\r\n\t\t};\r\n\t};\r\n\r\n\t/**\r\n\t * Checks if the character is the last in the word.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {int} character - The character.\r\n\t * @param {object} oTextData - The text data.\r\n\t */\r\n\tTextTools.prototype.isLastCharacterInWord = function (paragraph, line, word, character, oTextData) {\r\n\t\treturn oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters.length == character + 1;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds text within a point.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The found text.\r\n\t */\r\n\tTextTools.prototype.findText = function (point_x, point_y, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\treturn g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.findText_Character(point_x, point_y, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.findText_Word(point_x, point_y, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Finds text within a point at a word level.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The found text.\r\n\t */\r\n\tTextTools.prototype.findText_Word = function (point_x, point_y, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Try to find a paragragh.\r\n\t\tvar iParagraph = g_oTextTools.findParagraph(point_x, point_y, oTextData);\r\n\r\n\t\t// If a paragraph has been found.\r\n\t\tif (iParagraph != -1) {\r\n\r\n\t\t\t// Try to find a line in the paragraph.\r\n\t\t\tvar iLine = g_oTextTools.findLine(point_x, point_y, iParagraph, oTextData);\r\n\r\n\t\t\t// If a line has been found.\r\n\t\t\tif (iLine != -1) {\r\n\r\n\t\t\t\t// Try to find a word in the line.\r\n\t\t\t\tvar iWord = g_oTextTools.findWord(point_x, point_y, iParagraph, iLine, oTextData);\r\n\r\n\t\t\t\t// If a word has been found.\r\n\t\t\t\tif (iWord != -1) {\r\n\r\n\t\t\t\t\t// Return the text.\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tparagraph: iParagraph,\r\n\t\t\t\t\t\tline: iLine,\r\n\t\t\t\t\t\tword: iWord\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// No text found.\r\n\t\treturn null;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds text within a point at a character level.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The found text.\r\n\t */\r\n\tTextTools.prototype.findText_Character = function (point_x, point_y, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Try to find a paragragh.\r\n\t\tvar iParagraph = g_oTextTools.findParagraph(point_x, point_y, oTextData);\r\n\r\n\t\t// If a paragraph has been found.\r\n\t\tif (iParagraph != -1) {\r\n\r\n\t\t\t// Try to find a line in the paragraph.\r\n\t\t\tvar iLine = g_oTextTools.findLine(point_x, point_y, iParagraph, oTextData);\r\n\r\n\t\t\t// If a line has been found.\r\n\t\t\tif (iLine != -1) {\r\n\r\n\t\t\t\t// Try to find a word in the line.\r\n\t\t\t\tvar iWord = g_oTextTools.findWord(point_x, point_y, iParagraph, iLine, oTextData);\r\n\r\n\t\t\t\t// If a word has been found.\r\n\t\t\t\tif (iWord != -1) {\r\n\r\n\t\t\t\t\t// Try to find a character in the word.\r\n\t\t\t\t\tvar iCharacter = g_oTextTools.findChararacter(point_x, point_y, iParagraph, iLine, iWord, oTextData);\r\n\r\n\t\t\t\t\t// If a character has been found.\r\n\t\t\t\t\tif (iCharacter != -1) {\r\n\r\n\t\t\t\t\t\t// Return the text.\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\tparagraph: iParagraph,\r\n\t\t\t\t\t\t\tline: iLine,\r\n\t\t\t\t\t\t\tword: iWord,\r\n\t\t\t\t\t\t\tcharacter: iCharacter\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// No text found.\r\n\t\treturn null;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds a paragraph.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @returns {int} - The found paragraph.\r\n\t */\r\n\tTextTools.prototype.findParagraph = function (point_x, point_y, oTextData) {\r\n\r\n\t\t// Outline the paragraph to be returned.\r\n\t\tvar iParagraph = -1;\r\n\r\n\t\t// Check for each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// If this point is within the bounds of the paragraph.\r\n\t\t\tif (g_oTextTools.isPointWithinBounds(point_x, point_y, oTextData.Paragraphs[i].X1, oTextData.Paragraphs[i].X2, oTextData.Paragraphs[i].Y1, oTextData.Paragraphs[i].Y2)) {\r\n\r\n\t\t\t\t// Set that the paragraph has been found.\r\n\t\t\t\tiParagraph = i;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the found paragraph.\r\n\t\treturn iParagraph;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds a line,\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @returns {int} - The found line.\r\n\t */\r\n\tTextTools.prototype.findLine = function (point_x, point_y, paragraph, oTextData) {\r\n\r\n\t\t// Outline the line to be returned.\r\n\t\tvar iLine = -1;\r\n\r\n\t\t// Check for each of the lines.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs[paragraph].Lines.length; i++) {\r\n\r\n\t\t\t// If this point is within the bounds of the line.\r\n\t\t\tif (g_oTextTools.isPointWithinBounds(point_x, point_y, oTextData.Paragraphs[paragraph].Lines[i].X1, oTextData.Paragraphs[paragraph].Lines[i].X2, oTextData.Paragraphs[paragraph].Lines[i].Y1, oTextData.Paragraphs[paragraph].Lines[i].Y2)) {\r\n\r\n\t\t\t\t// Set that the line has been found.\r\n\t\t\t\tiLine = i;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the found line.\r\n\t\treturn iLine;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds a word.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @returns {int} - The found word.\r\n\t */\r\n\tTextTools.prototype.findWord = function (point_x, point_y, paragraph, line, oTextData) {\r\n\r\n\t\t// Outline the word to be returned.\r\n\t\tvar iWord = -1;\r\n\r\n\t\t// Check for each of the words.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs[paragraph].Lines[line].Words.length; i++) {\r\n\r\n\t\t\t// If this point is within the bounds of the word.\r\n\t\t\tif (g_oTextTools.isPointWithinBounds(point_x, point_y, oTextData.Paragraphs[paragraph].Lines[line].Words[i].X1, oTextData.Paragraphs[paragraph].Lines[line].Words[i].X2, oTextData.Paragraphs[paragraph].Lines[line].Words[i].Y1, oTextData.Paragraphs[paragraph].Lines[line].Words[i].Y2)) {\r\n\r\n\t\t\t\t// Set that the word has been found.\r\n\t\t\t\tiWord = i;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the found word.\r\n\t\treturn iWord;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds a character.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {doube} point_y - The y position.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @returns {int} - The found character.\r\n\t */\r\n\tTextTools.prototype.findChararacter = function (point_x, point_y, paragraph, line, word, oTextData) {\r\n\r\n\t\t// Outline the character to be returned.\r\n\t\tvar iCharacter = -1;\r\n\r\n\t\t// Check for each of the characters.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters.length; i++) {\r\n\r\n\t\t\t// If this point is within the bounds of the character.\r\n\t\t\tif (g_oTextTools.isPointWithinBounds(point_x, point_y, oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters[i].X1, oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters[i].X2, oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters[i].Y1, oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters[i].Y2)) {\r\n\r\n\t\t\t\t// Set that the character has been found.\r\n\t\t\t\tiCharacter = i;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the found character.\r\n\t\treturn iCharacter;\r\n\t};\r\n\r\n\t/**\r\n\t * Checks if a point is within bounds.\r\n\t * @param {double} point_x - The x position.\r\n\t * @param {double} point_y - The y position.\r\n\t * @param {double} bounds_x1 - The bounds x1.\r\n\t * @param {double} bounds_x2 - The bounds x2.\r\n\t * @param {double} bounds_y1 - The bounds y1.\r\n\t * @param {double} bounds_y2 - The bounds y2.\r\n\t * @returns {bool} - If the point is within the bounds.\r\n\t */\r\n\tTextTools.prototype.isPointWithinBounds = function (point_x, point_y, bounds_x1, bounds_x2, bounds_y1, bounds_y2) {\r\n\t\treturn point_x >= bounds_x1 && point_x <= bounds_x2 && point_y >= bounds_y1 && point_y <= bounds_y2;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds the closest text to a point.\r\n\t * @param {double} point_x - The point x.\r\n\t * @param {double} point_y - The point y.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.findClosestText = function (point_x, point_y, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\treturn g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.findClosestText_Character(point_x, point_y, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.findClosestText_Word(point_x, point_y, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Finds the closest word to a point.\r\n\t * @param {double} point_x - The point x.\r\n\t * @param {double} point_y - The point y.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.findClosestText_Word = function (point_x, point_y, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the text to be returned, and the closest distance.\r\n\t\tvar oText = null;\r\n\t\tvar iClosestDistance = -1;\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Check for each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Check for each of the lines.\r\n\t\t\tfor (var j = 0; j < oTextData.Paragraphs[i].Lines.length; j++) {\r\n\r\n\t\t\t\t// Check for each of the words.\r\n\t\t\t\tfor (var k = 0; k < oTextData.Paragraphs[i].Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t// Get the distance to the bounds.\r\n\t\t\t\t\tvar iDistance = g_oTextTools.distancePointToBounds(point_x, point_y, oTextData.Paragraphs[i].Lines[j].Words[k].X1, oTextData.Paragraphs[i].Lines[j].Words[k].X2, oTextData.Paragraphs[i].Lines[j].Words[k].Y1, oTextData.Paragraphs[i].Lines[j].Words[k].Y2);\r\n\r\n\t\t\t\t\t// If this point is closer to the bounds.\r\n\t\t\t\t\tif (oText == null || iDistance < iClosestDistance) {\r\n\r\n\t\t\t\t\t\t// Set that the word is the closest.\r\n\t\t\t\t\t\toText = {\r\n\t\t\t\t\t\t\tparagraph: i,\r\n\t\t\t\t\t\t\tline: j,\r\n\t\t\t\t\t\t\tword: k\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\t// Update the closest distance.\r\n\t\t\t\t\t\tiClosestDistance = iDistance;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the closest word.\r\n\t\treturn oText;\r\n\t};\r\n\r\n\t/**\r\n\t * Finds the closest character to a point.\r\n\t * @param {double} point_x - The point x.\r\n\t * @param {double} point_y - The point y.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.findClosestText_Character = function (point_x, point_y, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the text to be returned, and the closest distance.\r\n\t\tvar oText = null;\r\n\t\tvar iClosestDistance = -1;\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Check for each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Check for each of the lines.\r\n\t\t\tfor (var j = 0; j < oTextData.Paragraphs[i].Lines.length; j++) {\r\n\r\n\t\t\t\t// Check for each of the words.\r\n\t\t\t\tfor (var k = 0; k < oTextData.Paragraphs[i].Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t// Check for each of the characters.\r\n\t\t\t\t\tfor (var l = 0; l < oTextData.Paragraphs[i].Lines[j].Words[k].Characters.length; l++) {\r\n\r\n\t\t\t\t\t\t// Get the distance to the bounds.\r\n\t\t\t\t\t\tvar iDistance = g_oTextTools.distancePointToBounds(point_x, point_y, oTextData.Paragraphs[i].Lines[j].Words[k].Characters[l].X1, oTextData.Paragraphs[i].Lines[j].Words[k].Characters[l].X2, oTextData.Paragraphs[i].Lines[j].Words[k].Characters[l].Y1, oTextData.Paragraphs[i].Lines[j].Words[k].Characters[l].Y2);\r\n\r\n\t\t\t\t\t\t// If this point is closer to the bounds.\r\n\t\t\t\t\t\tif (oText == null || iDistance < iClosestDistance) {\r\n\r\n\t\t\t\t\t\t\t// Set that the character is the closest.\r\n\t\t\t\t\t\t\toText = {\r\n\t\t\t\t\t\t\t\tparagraph: i,\r\n\t\t\t\t\t\t\t\tline: j,\r\n\t\t\t\t\t\t\t\tword: k,\r\n\t\t\t\t\t\t\t\tcharacter: l\r\n\t\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\t\t// Update the closest distance.\r\n\t\t\t\t\t\t\tiClosestDistance = iDistance;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the closest character.\r\n\t\treturn oText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the distance from a point to a bounds.\r\n\t * @param {any} point_x - The point x.\r\n\t * @param {any} point_y - The point y.\r\n\t * @param {any} bounds_x1 - The x1 bounds.\r\n\t * @param {any} bounds_x2 - The x2 bounds.\r\n\t * @param {any} bounds_y1 - The y1 bounds.\r\n\t * @param {any} bounds_y2 - The y2 bounds.\r\n\t */\r\n\tTextTools.prototype.distancePointToBounds = function (point_x, point_y, bounds_x1, bounds_x2, bounds_y1, bounds_y2) {\r\n\r\n\t\t// Outline the mid points for comparison.\r\n\t\tvar bounds_x_middle = bounds_x1 + ((bounds_x2 - bounds_x1) / 2);\r\n\t\tvar bounds_y_middle = bounds_y1 + ((bounds_y2 - bounds_y1) / 2);\r\n\r\n\t\t// Return the distance to the closest point on the bounds.\r\n\t\treturn Math.min(\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x1), 2) + Math.pow((point_y - bounds_y1), 2)), // Top Left Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x2), 2) + Math.pow((point_y - bounds_y1), 2)), // Top Right Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x1), 2) + Math.pow((point_y - bounds_y2), 2)), // Bottom Left Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x2), 2) + Math.pow((point_y - bounds_y2), 2)), // Bottom Right Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x_middle), 2) + Math.pow((point_y - bounds_y1), 2)), // Top Middle Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x_middle), 2) + Math.pow((point_y - bounds_y2), 2)), // Bottom Middle Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x1), 2) + Math.pow((point_y - bounds_y_middle), 2)), // Middle Left Point\r\n\t\t\tMath.sqrt(Math.pow((point_x - bounds_x2), 2) + Math.pow((point_y - bounds_y_middle), 2)) // Middle Right Point\r\n\t\t);\r\n\t};\r\n\r\n\t/**\r\n\t * Shows all paragraphs.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.showAllParagraphs = function (oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Highlight each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\t\t\tg_oTextTools.highlightParagraph(i, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows all lines.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.showAllLines = function (oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Highlight each of the lines.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\t\t\tfor (var j = 0; j < oTextData.Paragraphs[i].Lines.length; j++) {\r\n\t\t\t\tg_oTextTools.highlightLine(i, j, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows all words.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.showAllWords = function (oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Highlight each of the words.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\t\t\tfor (var j = 0; j < oTextData.Paragraphs[i].Lines.length; j++) {\r\n\t\t\t\tfor (var k = 0; k < oTextData.Paragraphs[i].Lines[j].Words.length; k++) {\r\n\t\t\t\t\tg_oTextTools.highlightWord(i, j, k, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Removes all highlights.\r\n\t * @param {oAnnotationCanvas} - The annotation canvas to remove highlights for.\r\n\t */\r\n\tTextTools.prototype.removeHighlights = function (oAnnotationCanvas) {\r\n\t\toAnnotationCanvas.g_oContext.save();\r\n\t\tg_oMarquee.derotateCanvasContext(oAnnotationCanvas.g_oContext, oAnnotationCanvas, oAnnotationCanvas.g_oCanvas.width, oAnnotationCanvas.g_oCanvas.height, oAnnotationCanvas.g_oCanvas.width / 2, oAnnotationCanvas.g_oCanvas.height / 2);\r\n\t\toAnnotationCanvas.g_oContext.clearRect(0, 0, oAnnotationCanvas.g_oCanvas.width, oAnnotationCanvas.g_oCanvas.height);\r\n\t\toAnnotationCanvas.g_oContext.restore();\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a list of sections.\r\n\t * @param {object} oSections - The sections to highlight.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightSections = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\tg_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.highlightSections_Character(oSections, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.highlightSections_Word(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a list of sections at word level.\r\n\t * @param {object} oSections - The sections to highlight.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightSections_Word = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Get the sections words.\r\n\t\tvar oWords = g_oTextTools.getSectionsWords(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Sort the sections words.\r\n\t\toWords = oWords.sort(g_oTextTools.sortWords);\r\n\r\n\t\t// Remove the duplicate words.\r\n\t\toWords = g_oTextTools.distinctWords(oWords);\r\n\r\n\t\t// Highlight each of the words.\r\n\t\tfor (var i = 0; i < oWords.length; i++) {\r\n\r\n\t\t\t// If we have highlighted the previous word on this paragraph line.\r\n\t\t\tif (i > 0 && oWords[i].word == oWords[i - 1].word + 1 && oWords[i].line == oWords[i - 1].line && oWords[i].paragraph == oWords[i - 1].paragraph) {\r\n\r\n\t\t\t\t// Get the previous word.\r\n\t\t\t\tvar oWord = oTextData.Paragraphs[oWords[i].paragraph].Lines[oWords[i].line].Words[oWords[i].word];\r\n\t\t\t\tvar oPreviousWord = oTextData.Paragraphs[oWords[i - 1].paragraph].Lines[oWords[i - 1].line].Words[oWords[i - 1].word];\r\n\r\n\t\t\t\t// Determine the coordinates to be used for the space based on the text direction.\r\n\t\t\t\tvar iX1 = oPreviousWord.X2 < oWord.X1 ? oPreviousWord.X2 : oPreviousWord.X1;\r\n\t\t\t\tvar iX2 = oPreviousWord.X2 < oWord.X1 ? oWord.X1 : oWord.X2;\r\n\t\t\t\tvar iY1 = oPreviousWord.Y1 < oWord.Y2 ? oPreviousWord.Y2 : oPreviousWord.Y1;\r\n\t\t\t\tvar iY2 = oPreviousWord.Y1 < oWord.Y2 ? oWord.Y1 : oWord.Y2;\r\n\r\n\t\t\t\t// Highlight the space between the two words.\r\n\t\t\t\tg_oTextTools.highlightElement(iX1, iX2, iY1, iY2, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\r\n\t\t\t// Highlight the word.\r\n\t\t\tg_oTextTools.highlightWord(oWords[i].paragraph, oWords[i].line, oWords[i].word, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a list of sections at character level.\r\n\t * @param {object} oSections - The sections to highlight.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightSections_Character = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Get the sections characters.\r\n\t\tvar oCharacters = g_oTextTools.getSectionsCharacters(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Sort the sections characters.\r\n\t\toCharacters = oCharacters.sort(g_oTextTools.sortCharacters);\r\n\r\n\t\t// Remove the duplicate characters.\r\n\t\toCharacters = g_oTextTools.distinctCharacters(oCharacters);\r\n\r\n\t\t// Highlight each of the characters.\r\n\t\tfor (var i = 0; i < oCharacters.length; i++) {\r\n\t\t\t\r\n\t\t\t// If we have highlighted the last character of the previous word on this paragraph line, and this is the first character of the next word.\r\n\t\t\tif (i > 0 && oCharacters[i].word == oCharacters[i - 1].word + 1 && oCharacters[i].line == oCharacters[i - 1].line && oCharacters[i].paragraph == oCharacters[i - 1].paragraph && g_oTextTools.isLastCharacterInWord(oCharacters[i - 1].paragraph, oCharacters[i - 1].line, oCharacters[i - 1].word, oCharacters[i - 1].character, oTextData) && oCharacters[i].character == 0) {\r\n\t\t\t\t\r\n\t\t\t\t// Get the current and previous characters.\r\n\t\t\t\tvar oCharacter = oTextData.Paragraphs[oCharacters[i].paragraph].Lines[oCharacters[i].line].Words[oCharacters[i].word].Characters[oCharacters[i].character];\r\n\t\t\t\tvar oPreviousCharacter = oTextData.Paragraphs[oCharacters[i - 1].paragraph].Lines[oCharacters[i - 1].line].Words[oCharacters[i - 1].word].Characters[oCharacters[i - 1].character];\r\n\r\n\t\t\t\t// Determine the coordinates to be used for the space based on the text direction.\r\n\t\t\t\tvar iX1 = oPreviousCharacter.X2 < oCharacter.X1 ? oPreviousCharacter.X2 : oPreviousCharacter.X1;\r\n\t\t\t\tvar iX2 = oPreviousCharacter.X2 < oCharacter.X1 ? oCharacter.X1 : oCharacter.X2;\r\n\t\t\t\tvar iY1 = oPreviousCharacter.Y1 < oCharacter.Y2 ? oPreviousCharacter.Y2 : oPreviousCharacter.Y1;\r\n\t\t\t\tvar iY2 = oPreviousCharacter.Y1 < oCharacter.Y2 ? oCharacter.Y1 : oCharacter.Y2;\r\n\r\n\t\t\t\t// Highlight the space between the two words.\r\n\t\t\t\tg_oTextTools.highlightElement(iX1, iX2, iY1, iY2, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\r\n\t\t\t// Highlight the character.\r\n\t\t\tg_oTextTools.highlightCharacter(oCharacters[i].paragraph, oCharacters[i].line, oCharacters[i].word, oCharacters[i].character, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the words for a list of sections.\r\n\t * @param {object} oSections - The sections to get the words for.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas,\r\n\t * @returns {object} - List of words.\r\n\t */\r\n\tTextTools.prototype.getSectionsWords = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the words to be returned.\r\n\t\tvar oWords = [];\r\n\r\n\t\t// Loop through each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Add the words for the section.\r\n\t\t\toWords = oWords.concat(g_oTextTools.getSectionWords(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas, oAnnotationCanvas));\r\n\t\t}\r\n\r\n\t\t// Return the words.\r\n\t\treturn oWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Checks if the text highlight is in the correct order.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the highlight is left to right.\r\n\t * @param {bool} characterLevelAccuracy - If this is to a character level accuracy.\r\n\t */\r\n\tTextTools.prototype.textHighlightCorrectOrder = function (startingText, endingText, leftToRight, characterLevelAccuracy) {\r\n\r\n\t\t// Wrong order if the end paragraph is before the start paragraph.\r\n\t\tif (endingText.paragraph < startingText.paragraph) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Wrong order if we are on the same paragraph and the end line is before the start line.\r\n\t\tif (endingText.paragraph == startingText.paragraph && endingText.line < startingText.line) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Wrong order if we are left to right, on the same paragraph line, but the end word is before the start word.\r\n\t\tif (leftToRight && endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word < startingText.word) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Wrong order if we are right to left, on the same paragraph line, but the start word is before the end word.\r\n\t\tif (!leftToRight && endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && startingText.word < endingText.word) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Wrong order if we are character left to right, on the same paragraph line word, but the end character is before the start character.\r\n\t\tif (characterLevelAccuracy && leftToRight && endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && startingText.word == endingText.word && endingText.character < startingText.character) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Wrong order if we are character right to left, on the same paragraph line word, but the start character is before the end character.\r\n\t\tif (characterLevelAccuracy && !leftToRight && endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && startingText.word == endingText.word && startingText.character < endingText.character) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t// Text is in the correct order.\r\n\t\treturn true;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the words for a section.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the highlight is left to right.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The list of words.\r\n\t */\r\n\tTextTools.prototype.getSectionWords = function (startingText, endingText, leftToRight, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the words to be returned.\r\n\t\tvar oWords = [];\r\n\r\n\t\t// Check the text is in the correct order.\r\n\t\tif (!g_oTextTools.textHighlightCorrectOrder(startingText, endingText, leftToRight, false)) {\r\n\r\n\t\t\t// Swap the order if required.\r\n\t\t\tvar oStart = startingText;\r\n\t\t\tstartingText = endingText;\r\n\t\t\tendingText = oStart;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the paragraphs in the document.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Extract the paragraph.\r\n\t\t\tvar oParagraph = oTextData.Paragraphs[i];\r\n\r\n\t\t\t// Check the paragraph is part of this selection.\r\n\t\t\tif (i >= startingText.paragraph && i <= endingText.paragraph) {\r\n\r\n\t\t\t\t// Loop through each line in the paragraph.\r\n\t\t\t\tfor (var j = 0; j < oParagraph.Lines.length; j++) {\r\n\r\n\t\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\t\tfor (var k = 0; k < oParagraph.Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t\t// If the word is in the section.\r\n\t\t\t\t\t\tif (g_oTextTools.isWordInSection(i, j, k, startingText, endingText, leftToRight)) {\r\n\r\n\t\t\t\t\t\t\t// Add this word to our list.\r\n\t\t\t\t\t\t\toWords.push({ paragraph: i, line: j, word: k });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the section words.\r\n\t\treturn oWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the characters for a list of sections.\r\n\t * @param {object} oSections - The sections to get the characters for.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - List of characters.\r\n\t */\r\n\tTextTools.prototype.getSectionsCharacters = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the characters to be returned.\r\n\t\tvar oCharacters = [];\r\n\r\n\t\t// Loop through each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Add the characters for the section.\r\n\t\t\toCharacters = oCharacters.concat(g_oTextTools.getSectionCharacters(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas, oAnnotationCanvas));\r\n\t\t}\r\n\r\n\t\t// Return the characters.\r\n\t\treturn oCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the characters for a section.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the highlight is left to right.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The list of characters.\r\n\t */\r\n\tTextTools.prototype.getSectionCharacters = function (startingText, endingText, leftToRight, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the characters to be returned.\r\n\t\tvar oCharacters = [];\r\n\r\n\t\t// Check the text is in the correct order.\r\n\t\tif (!g_oTextTools.textHighlightCorrectOrder(startingText, endingText, leftToRight, true)) {\r\n\r\n\t\t\t// Swap the order if required.\r\n\t\t\tvar oStart = startingText;\r\n\t\t\tstartingText = endingText;\r\n\t\t\tendingText = oStart;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the paragraphs in the document.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Extract the paragraph.\r\n\t\t\tvar oParagraph = oTextData.Paragraphs[i];\r\n\r\n\t\t\t// Check the paragraph is part of this selection.\r\n\t\t\tif (i >= startingText.paragraph && i <= endingText.paragraph) {\r\n\r\n\t\t\t\t// Loop through each line in the paragraph.\r\n\t\t\t\tfor (var j = 0; j < oParagraph.Lines.length; j++) {\r\n\r\n\t\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\t\tfor (var k = 0; k < oParagraph.Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t\t// Loop through each characters in the word.\r\n\t\t\t\t\t\tfor (var l = 0; l < oParagraph.Lines[j].Words[k].Characters.length; l++) {\r\n\r\n\t\t\t\t\t\t\t// If the character is in the section.\r\n\t\t\t\t\t\t\tif (g_oTextTools.isCharacterInSection(i, j, k, l, startingText, endingText, leftToRight)) {\r\n\r\n\t\t\t\t\t\t\t\t// Add this character to our list.\r\n\t\t\t\t\t\t\t\toCharacters.push({ paragraph: i, line: j, word: k, character: l });\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the section characters.\r\n\t\treturn oCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Performs a sort on words.\r\n\t * @param {object} a - The first word.\r\n\t * @param {object} b - The second word.\r\n\t * @returns {int} - The sort.\r\n\t */\r\n\tTextTools.prototype.sortWords = function (a, b) {\r\n\t\tif (a.paragraph < b.paragraph) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.paragraph > b.paragraph) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse if (a.line < b.line) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.line > b.line) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse if (a.word < b.word) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.word > b.word) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Performs a sort on characters.\r\n\t * @param {object} a - The first character.\r\n\t * @param {object} b - The second character.\r\n\t * @returns {int} - The sort.\r\n\t */\r\n\tTextTools.prototype.sortCharacters = function (a, b) {\r\n\t\tif (a.paragraph < b.paragraph) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.paragraph > b.paragraph) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse if (a.line < b.line) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.line > b.line) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse if (a.word < b.word) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.word > b.word) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse if (a.character < b.character) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\telse if (a.character > b.character) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\telse {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Distincts a list of words.\r\n\t * @param {object} oWords - The list of words.\r\n\t * @returns {object} - Distinct list of words.\r\n\t */\r\n\tTextTools.prototype.distinctWords = function (oWords) {\r\n\r\n\t\t// Loop through each of the words.\r\n\t\tfor (var i = 0; i < oWords.length; i++) {\r\n\r\n\t\t\t// If this word is the same as the previous word.\r\n\t\t\tif (i > 0 && oWords[i].word == oWords[i - 1].word && oWords[i].line == oWords[i - 1].line && oWords[i].paragraph == oWords[i - 1].paragraph) {\r\n\r\n\t\t\t\t// Remove it from the list.\r\n\t\t\t\toWords.splice(i, 1);\r\n\t\t\t\ti--;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the words.\r\n\t\treturn oWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Distincts a list of characters.\r\n\t * @param {object} oCharacters - The list of characters.\r\n\t * @returns {object} - Distinct list of characters.\r\n\t */\r\n\tTextTools.prototype.distinctCharacters = function (oCharacters) {\r\n\r\n\t\t// Loop through each of the characters.\r\n\t\tfor (var i = 0; i < oCharacters.length; i++) {\r\n\r\n\t\t\t// If this word is the same as the previous character.\r\n\t\t\tif (i > 0 && oCharacters[i].character == oCharacters[i - 1].character && oCharacters[i].word == oCharacters[i - 1].word && oCharacters[i].line == oCharacters[i - 1].line && oCharacters[i].paragraph == oCharacters[i - 1].paragraph) {\r\n\r\n\t\t\t\t// Remove it from the list.\r\n\t\t\t\toCharacters.splice(i, 1);\r\n\t\t\t\ti--;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the characters.\r\n\t\treturn oCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bounds for a list of sections at word level.\r\n\t * @param {object} oSections - The list of sections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The sections bounds.\r\n\t */\r\n\tTextTools.prototype.getSectionsBounds_Words = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\t\r\n\t\t// Outline the bounds to be returned.\r\n\t\tvar oSectionsBounds = {\r\n\t\t\tx1: 1,\r\n\t\t\tx2: 0,\r\n\t\t\ty1: 1,\r\n\t\t\ty2: 0\r\n\t\t};\r\n\r\n\t\t// Loop through each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Get the bounds for the section.\r\n\t\t\tvar oSectionBounds = g_oTextTools.getSectionBounds_Words(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Update the sections bounds.\r\n\t\t\toSectionsBounds.x1 = Math.min(oSectionsBounds.x1, oSectionBounds.x1);\r\n\t\t\toSectionsBounds.x2 = Math.max(oSectionsBounds.x2, oSectionBounds.x2);\r\n\t\t\toSectionsBounds.y1 = Math.min(oSectionsBounds.y1, oSectionBounds.y1);\r\n\t\t\toSectionsBounds.y2 = Math.max(oSectionsBounds.y2, oSectionBounds.y2);\r\n\t\t}\r\n\r\n\t\t// Return the bounds of the section.\r\n\t\treturn oSectionsBounds;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bounds for a list of sections at character level.\r\n\t * @param {object} oSections - The list of sections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The sections bounds.\r\n\t */\r\n\tTextTools.prototype.getSectionsBounds_Characters = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the bounds to be returned.\r\n\t\tvar oSectionsBounds = {\r\n\t\t\tx1: 1,\r\n\t\t\tx2: 0,\r\n\t\t\ty1: 1,\r\n\t\t\ty2: 0\r\n\t\t};\r\n\r\n\t\t// Loop through each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Get the bounds for the section.\r\n\t\t\tvar oSectionBounds = g_oTextTools.getSectionBounds_Characters(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Update the sections bounds.\r\n\t\t\toSectionsBounds.x1 = Math.min(oSectionsBounds.x1, oSectionBounds.x1);\r\n\t\t\toSectionsBounds.x2 = Math.max(oSectionsBounds.x2, oSectionBounds.x2);\r\n\t\t\toSectionsBounds.y1 = Math.min(oSectionsBounds.y1, oSectionBounds.y1);\r\n\t\t\toSectionsBounds.y2 = Math.max(oSectionsBounds.y2, oSectionBounds.y2);\r\n\t\t}\r\n\r\n\t\t// Return the bounds of the section.\r\n\t\treturn oSectionsBounds;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bounds of a word list.\r\n\t * @param {object} oWordList - The list of words.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getWordListBounds = function (oWordList, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Determine the section bounds.\r\n\t\tvar oSectionBounds = {\r\n\t\t\tx1: 1,\r\n\t\t\tx2: 0,\r\n\t\t\ty1: 1,\r\n\t\t\ty2: 0\r\n\t\t};\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the words.\r\n\t\tfor (var i = 0; i < oWordList.length; i++) {\r\n\r\n\t\t\t// Extract the current word.\r\n\t\t\tvar oWord = oTextData.Paragraphs[oWordList[i].paragraph].Lines[oWordList[i].line].Words[oWordList[i].word];\r\n\r\n\t\t\t// Update the section bounds.\r\n\t\t\toSectionBounds.x1 = Math.min(oSectionBounds.x1, oWord.X1, oWord.X2);\r\n\t\t\toSectionBounds.x2 = Math.max(oSectionBounds.x2, oWord.X1, oWord.X2);\r\n\t\t\toSectionBounds.y1 = Math.min(oSectionBounds.y1, oWord.Y1, oWord.Y2);\r\n\t\t\toSectionBounds.y2 = Math.max(oSectionBounds.y2, oWord.Y1, oWord.Y2);\r\n\t\t}\r\n\r\n\t\t// Return the bounds of the section.\r\n\t\treturn oSectionBounds;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bounds of a character list.\r\n\t * @param {object} oCharacterList - The list of characters.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getCharacterListBounds = function (oCharacterList, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Determine the section bounds.\r\n\t\tvar oSectionBounds = {\r\n\t\t\tx1: 1,\r\n\t\t\tx2: 0,\r\n\t\t\ty1: 1,\r\n\t\t\ty2: 0\r\n\t\t};\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the characters.\r\n\t\tfor (var i = 0; i < oCharacterList.length; i++) {\r\n\r\n\t\t\t// Extract the current character.\r\n\t\t\tvar oWord = oTextData.Paragraphs[oCharacterList[i].paragraph].Lines[oCharacterList[i].line].Words[oCharacterList[i].word].Characters[oCharacterList[i].character];\r\n\r\n\t\t\t// Update the section bounds.\r\n\t\t\toSectionBounds.x1 = Math.min(oSectionBounds.x1, oWord.X1, oWord.X2);\r\n\t\t\toSectionBounds.x2 = Math.max(oSectionBounds.x2, oWord.X1, oWord.X2);\r\n\t\t\toSectionBounds.y1 = Math.min(oSectionBounds.y1, oWord.Y1, oWord.Y2);\r\n\t\t\toSectionBounds.y2 = Math.max(oSectionBounds.y2, oWord.Y1, oWord.Y2);\r\n\t\t}\r\n\r\n\t\t// Return the bounds of the section.\r\n\t\treturn oSectionBounds;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bounds for a section.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the highlight is left to right.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The section bounds.\r\n\t */\r\n\tTextTools.prototype.getSectionBounds_Words = function (startingText, endingText, leftToRight, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Determine the section bounds.\r\n\t\tvar oSectionBounds = {\r\n\t\t\tx1: 1,\r\n\t\t\tx2: 0,\r\n\t\t\ty1: 1,\r\n\t\t\ty2: 0\r\n\t\t};\r\n\r\n\t\t// Switch the order of the start and end if required.\r\n\t\tif ((endingText.paragraph < startingText.paragraph) || (endingText.paragraph == startingText.paragraph && endingText.line < startingText.line) || (endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word < startingText.word)) {\r\n\t\t\tvar oStart = startingText;\r\n\t\t\tstartingText = endingText;\r\n\t\t\tendingText = oStart;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Extract the paragraph.\r\n\t\t\tvar oParagraph = oTextData.Paragraphs[i];\r\n\r\n\t\t\t// Check the paragraph is part of this selection.\r\n\t\t\tif (i >= startingText.paragraph && i <= endingText.paragraph) {\r\n\r\n\t\t\t\t// Loop through each line in the paragraph.\r\n\t\t\t\tfor (var j = 0; j < oParagraph.Lines.length; j++) {\r\n\r\n\t\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\t\tfor (var k = 0; k < oParagraph.Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t\t// Determine if the word is within the section.\r\n\t\t\t\t\t\tvar bWordInSection = g_oTextTools.isWordInSection(i, j, k, startingText, endingText, leftToRight);\r\n\r\n\t\t\t\t\t\t// If the word is in the section.\r\n\t\t\t\t\t\tif (bWordInSection) {\r\n\r\n\t\t\t\t\t\t\t// Update the section bounds.\r\n\t\t\t\t\t\t\toSectionBounds.x1 = Math.min(oSectionBounds.x1, oParagraph.Lines[j].Words[k].X1, oParagraph.Lines[j].Words[k].X2);\r\n\t\t\t\t\t\t\toSectionBounds.x2 = Math.max(oSectionBounds.x2, oParagraph.Lines[j].Words[k].X1, oParagraph.Lines[j].Words[k].X2);\r\n\t\t\t\t\t\t\toSectionBounds.y1 = Math.min(oSectionBounds.y1, oParagraph.Lines[j].Words[k].Y1, oParagraph.Lines[j].Words[k].Y2);\r\n\t\t\t\t\t\t\toSectionBounds.y2 = Math.max(oSectionBounds.y2, oParagraph.Lines[j].Words[k].Y1, oParagraph.Lines[j].Words[k].Y2);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the bounds of the section.\r\n\t\treturn oSectionBounds;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bounds for a section.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the highlight is left to right.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The section bounds.\r\n\t */\r\n\tTextTools.prototype.getSectionBounds_Characters = function (startingText, endingText, leftToRight, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Determine the section bounds.\r\n\t\tvar oSectionBounds = {\r\n\t\t\tx1: 1,\r\n\t\t\tx2: 0,\r\n\t\t\ty1: 1,\r\n\t\t\ty2: 0\r\n\t\t};\r\n\r\n\t\t// Switch the order of the start and end if required.\r\n\t\tif ((endingText.paragraph < startingText.paragraph) ||\r\n\t\t\t(endingText.paragraph == startingText.paragraph && endingText.line < startingText.line) ||\r\n\t\t\t(endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word < startingText.word) ||\r\n\t\t\t(endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word == startingText.word && endingText.character < startingText.character)) {\r\n\t\t\tvar oStart = startingText;\r\n\t\t\tstartingText = endingText;\r\n\t\t\tendingText = oStart;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Extract the paragraph.\r\n\t\t\tvar oParagraph = oTextData.Paragraphs[i];\r\n\r\n\t\t\t// Check the paragraph is part of this selection.\r\n\t\t\tif (i >= startingText.paragraph && i <= endingText.paragraph) {\r\n\r\n\t\t\t\t// Loop through each line in the paragraph.\r\n\t\t\t\tfor (var j = 0; j < oParagraph.Lines.length; j++) {\r\n\r\n\t\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\t\tfor (var k = 0; k < oParagraph.Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t\t// Loop through each of the characters on the line.\r\n\t\t\t\t\t\tfor (var l = 0; l < oParagraph.Lines[j].Words[k].Characters.length; l++) {\r\n\r\n\t\t\t\t\t\t\t// Determine if the character is within the section.\r\n\t\t\t\t\t\t\tvar bCharacterInSection = g_oTextTools.isCharacterInSection(i, j, k, l, startingText, endingText, leftToRight);\r\n\r\n\t\t\t\t\t\t\t// If the character is in the section.\r\n\t\t\t\t\t\t\tif (bCharacterInSection) {\r\n\r\n\t\t\t\t\t\t\t\t// Update the section bounds.\r\n\t\t\t\t\t\t\t\toSectionBounds.x1 = Math.min(oSectionBounds.x1, oParagraph.Lines[j].Words[k].Characters[l].X1, oParagraph.Lines[j].Words[k].Characters[l].X2);\r\n\t\t\t\t\t\t\t\toSectionBounds.x2 = Math.max(oSectionBounds.x2, oParagraph.Lines[j].Words[k].Characters[l].X1, oParagraph.Lines[j].Words[k].Characters[l].X2);\r\n\t\t\t\t\t\t\t\toSectionBounds.y1 = Math.min(oSectionBounds.y1, oParagraph.Lines[j].Words[k].Characters[l].Y1, oParagraph.Lines[j].Words[k].Characters[l].Y2);\r\n\t\t\t\t\t\t\t\toSectionBounds.y2 = Math.max(oSectionBounds.y2, oParagraph.Lines[j].Words[k].Characters[l].Y1, oParagraph.Lines[j].Words[k].Characters[l].Y2);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the bounds of the section.\r\n\t\treturn oSectionBounds;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the word text for a word.\r\n\t * @param {object} oWord - the word.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getWordText = function (oWord, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the word text.\r\n\t\treturn oTextData.Paragraphs[oWord.paragraph].Lines[oWord.line].Words[oWord.word].Content;\r\n\t};\r\n\r\n\tTextTools.prototype.getCharacterText = function (oCharacter, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the character text.\r\n\t\treturn oTextData.Paragraphs[oCharacter.paragraph].Lines[oCharacter.line].Words[oCharacter.word].Characters[oCharacter.character].Content;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text for a word list.\r\n\t * @param {object} oWordList - The word list.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getWordListText = function (oWordList, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\t\r\n\t\t// Outline the text to be returned.\r\n\t\tvar szText = \"\";\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the words in the list.\r\n\t\tfor (var i = 0; i < oWordList.length; i++) {\r\n\r\n\t\t\t// If this is not the first word, add a space.\r\n\t\t\tif (i > 0) {\r\n\t\t\t\tszText += \" \";\r\n\t\t\t}\r\n\r\n\t\t\t// Add the word.\r\n\t\t\tszText += oTextData.Paragraphs[oWordList[i].paragraph].Lines[oWordList[i].line].Words[oWordList[i].word].Content;\r\n\t\t}\r\n\r\n\t\t// Return the text.\r\n\t\treturn szText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text for a character list.\r\n\t * @param {object} oCharacterList - The character list.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getCharacterListText = function (oCharacterList, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the text to be returned.\r\n\t\tvar szText = \"\";\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the characters in the list.\r\n\t\tfor (var i = 0; i < oCharacterList.length; i++) {\r\n\r\n\t\t\t// Add the character.\r\n\t\t\tszText += oTextData.Paragraphs[oCharacterList[i].paragraph].Lines[oCharacterList[i].line].Words[oCharacterList[i].word].Characters[oCharacterList[i].character].Content;\r\n\r\n\t\t\t// If this is the last character in the word, and we have more characters to add, add a space.\r\n\t\t\tif (g_oTextTools.isLastCharacterInWord(oCharacterList[i].paragraph, oCharacterList[i].line, oCharacterList[i].word, oCharacterList[i].character, oTextData) && i + 1 < oCharacterList.length) {\r\n\t\t\t\tszText += \" \";\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the text.\r\n\t\treturn szText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text for a list of sections.\r\n\t * @param {object} oSections - The list of sections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The sections text.\r\n\t */\r\n\tTextTools.prototype.getSectionsText_Words = function (oSections, oArtworkCanvas, szPrepend, szAppend) {\r\n\r\n\t\t// Determine the text to be returned.\r\n\t\tvar szSectionsText = \"\";\r\n\r\n\t\t// Add the prepend.\r\n\t\tszSectionsText += szPrepend;\r\n\r\n\t\t// Loop through each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Add the text for the section.\r\n\t\t\tszSectionsText += g_oTextTools.getSectionText_Words(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas);\r\n\t\t}\r\n\r\n\t\t// Add the append.\r\n\t\tszSectionsText += szAppend;\r\n\r\n\t\t// Return the result.\r\n\t\treturn szSectionsText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text for a section.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the section is left to right.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The section text.\r\n\t */\r\n\tTextTools.prototype.getSectionText_Words = function (startingText, endingText, leftToRight, oArtworkCanvas) {\r\n\r\n\t\t// Determine the text to be returned.\r\n\t\tvar szSectionText = \"\";\r\n\r\n\t\t// Switch the order of the start and end if required.\r\n\t\tif ((endingText.paragraph < startingText.paragraph) || (endingText.paragraph == startingText.paragraph && endingText.line < startingText.line) || (endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word < startingText.word)) {\r\n\t\t\tvar oStart = startingText;\r\n\t\t\tstartingText = endingText;\r\n\t\t\tendingText = oStart;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Extract the paragraph.\r\n\t\t\tvar oParagraph = oTextData.Paragraphs[i];\r\n\r\n\t\t\t// If this paragraph is within our selection.\r\n\t\t\tif (i >= startingText.paragraph && i <= endingText.paragraph) {\r\n\r\n\t\t\t\t// If this paragraph was not the first paragraph, add a space before the text on the next paragraph.\r\n\t\t\t\tif (i > startingText.paragraph) {\r\n\t\t\t\t\tszSectionText += \" \";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Loop through each line in the paragraph.\r\n\t\t\t\tfor (var j = 0; j < oParagraph.Lines.length; j++) {\r\n\r\n\t\t\t\t\t// If this line was not the first line, add a space before the text on the next line.\r\n\t\t\t\t\tif (i > startingText.paragraph || j > startingText.line) {\r\n\t\t\t\t\t\tszSectionText += \" \";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Keep track of if the previous word has been highlighted.\r\n\t\t\t\t\tvar bPreviousWordHighlighted = false;\r\n\r\n\t\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\t\tfor (var k = 0; k < oParagraph.Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t\t// Determine if the word is within the section.\r\n\t\t\t\t\t\tvar bWordInSection = g_oTextTools.isWordInSection(i, j, k, startingText, endingText, leftToRight);\r\n\r\n\t\t\t\t\t\t// If the word is in the section.\r\n\t\t\t\t\t\tif (bWordInSection) {\r\n\r\n\t\t\t\t\t\t\t// If the previous word was highlighted and has a space after.\r\n\t\t\t\t\t\t\tif (bPreviousWordHighlighted && oParagraph.Lines[j].Words[k - 1].SpaceAfter) {\r\n\r\n\t\t\t\t\t\t\t\t// Add the space to the text.\r\n\t\t\t\t\t\t\t\tszSectionText += \" \";\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Add the text to the word.\r\n\t\t\t\t\t\t\tszSectionText += oParagraph.Lines[j].Words[k].Content;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Update the previous word highlight flag.\r\n\t\t\t\t\t\tbPreviousWordHighlighted = bWordInSection;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If this is a right to left highlight, reverse the section text.\r\n\t\tif (!leftToRight) {\r\n\t\t\tszSectionText = szSectionText.split(\" \").reverse().join(\" \");\r\n\t\t}\r\n\r\n\t\t// Return the text of the section.\r\n\t\treturn szSectionText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text for a list of sections.\r\n\t * @param {object} oSections - The list of sections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The sections text.\r\n\t */\r\n\tTextTools.prototype.getSectionsText_Characters = function (oSections, oArtworkCanvas, szPrepend, szAppend) {\r\n\r\n\t\t// Determine the text to be returned.\r\n\t\tvar szSectionsText = \"\";\r\n\r\n\t\t// Add the prepend.\r\n\t\tszSectionsText += szPrepend;\r\n\r\n\t\t// Loop through each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Add the text for the section.\r\n\t\t\tszSectionsText += g_oTextTools.getSectionText_Characters(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas);\r\n\t\t}\r\n\r\n\t\t// Add the append.\r\n\t\tszSectionsText += szAppend;\r\n\r\n\t\t// Return the result.\r\n\t\treturn szSectionsText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text for a section.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the section is left to right.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The section text.\r\n\t */\r\n\tTextTools.prototype.getSectionText_Characters = function (startingText, endingText, leftToRight, oArtworkCanvas) {\r\n\r\n\t\t// Determine the text to be returned.\r\n\t\tvar szSectionText = \"\";\r\n\r\n\t\t// Switch the order of the start and end if required.\r\n\t\tif ((endingText.paragraph < startingText.paragraph) ||\r\n\t\t\t(endingText.paragraph == startingText.paragraph && endingText.line < startingText.line) ||\r\n\t\t\t(endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word < startingText.word) ||\r\n\t\t\t(endingText.paragraph == startingText.paragraph && endingText.line == startingText.line && endingText.word == startingText.word && endingText.character < startingText.character)) {\r\n\t\t\tvar oStart = startingText;\r\n\t\t\tstartingText = endingText;\r\n\t\t\tendingText = oStart;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Loop through each of the paragraphs.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Extract the paragraph.\r\n\t\t\tvar oParagraph = oTextData.Paragraphs[i];\r\n\r\n\t\t\t// If this paragraph is within our selection.\r\n\t\t\tif (i >= startingText.paragraph && i <= endingText.paragraph) {\r\n\r\n\t\t\t\t// If this paragraph was not the first paragraph, add a space before the text on the next paragraph.\r\n\t\t\t\tif (i > startingText.paragraph) {\r\n\t\t\t\t\tszSectionText += \" \";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Loop through each line in the paragraph.\r\n\t\t\t\tfor (var j = 0; j < oParagraph.Lines.length; j++) {\r\n\r\n\t\t\t\t\t// If this line was not the first line, add a space before the text on the next line.\r\n\t\t\t\t\tif (i > startingText.paragraph || j > startingText.line) {\r\n\t\t\t\t\t\tszSectionText += \" \";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\t\tfor (var k = 0; k < oParagraph.Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t\t// If this word was not the first word, add a space before the text on the next word.\r\n\t\t\t\t\t\tif (i > startingText.paragraph || j > startingText.line || k > startingText.word) {\r\n\t\t\t\t\t\t\tszSectionText += \" \";\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Loop through each of the characters in the word.\r\n\t\t\t\t\t\tfor (var l = 0; l < oParagraph.Lines[j].Words[k].Characters.length; l++) {\r\n\r\n\t\t\t\t\t\t\t// Determine if the character is within the section.\r\n\t\t\t\t\t\t\tvar bCharacterInSection = g_oTextTools.isCharacterInSection(i, j, k, l, startingText, endingText, leftToRight);\r\n\r\n\t\t\t\t\t\t\t// If the character is in the section.\r\n\t\t\t\t\t\t\tif (bCharacterInSection) {\r\n\r\n\t\t\t\t\t\t\t\t// Add the text to the word.\r\n\t\t\t\t\t\t\t\tszSectionText += oParagraph.Lines[j].Words[k].Characters[l].Content;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If this is a right to left highlight, reverse the section text.\r\n\t\tif (!leftToRight) {\r\n\t\t\tszSectionText = szSectionText.split(\" \").reverse().join(\" \");\r\n\t\t}\r\n\r\n\t\t// Return the text of the section.\r\n\t\treturn szSectionText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bold setting for a word.\r\n\t * @param {object} oWord - The word.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getWordBoldSetting = function (oWord, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the word bold setting.\r\n\t\treturn oTextData.Paragraphs[oWord.paragraph].Lines[oWord.line].Words[oWord.word].Bold;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the italic setting for a word.\r\n\t * @param {object} oWord - The word.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getWordItalicSetting = function (oWord, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the word italic setting.\r\n\t\treturn oTextData.Paragraphs[oWord.paragraph].Lines[oWord.line].Words[oWord.word].Italic;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the bold setting for a character.\r\n\t * @param {object} oCharacter - The character.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getCharacterBoldSetting = function (oCharacter, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the character bold setting.\r\n\t\treturn oTextData.Paragraphs[oCharacter.paragraph].Lines[oCharacter.line].Words[oCharacter.word].Characters[oCharacter.character].Bold;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the italic setting for a character.\r\n\t * @param {object} oCharacter - The character.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getCharacterItalicSetting = function (oCharacter, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return the character italic setting.\r\n\t\treturn oTextData.Paragraphs[oCharacter.paragraph].Lines[oCharacter.line].Words[oCharacter.word].Characters[oCharacter.character].Italic;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets if the character is the last in the word.\r\n\t * @param {object} oCharacter - The character.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getCharacterLastInWord = function (oCharacter, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Return if the character is the last in the word.\r\n\t\treturn g_oTextTools.isLastCharacterInWord(oCharacter.paragraph, oCharacter.line, oCharacter.word, oCharacter.character, oTextData);\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the characters for a word.\r\n\t * @param {any} oWord - The word.\r\n\t * @param {any} oArtworkCanvas - The artwork canvas.\r\n\t * @param {any} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.getWordCharacters = function (oWord, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Get the word.\r\n\t\tvar oWord = oTextData.Paragraphs[oWord.paragraph].Lines[oWord.line].Words[oWord.word];\r\n\r\n\t\t// Return the characters.\r\n\t\treturn oWord.Characters;\r\n\t};\r\n\r\n\t/**\r\n\t * Splits the sections content based on the accuracy.\r\n\t * @param {object} oSections - The sections data.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.splitSections = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\treturn g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.splitSections_Characters(oSections, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.splitSections_Words(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Splits the sections content at word level.\r\n\t * @param {object} oSections - The sections data.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.splitSections_Words = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the split sections to be build up.\r\n\t\tvar oSplitSections = [];\r\n\r\n\t\t// Loop over each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Split the section into individual words.\r\n\t\t\tvar oSectionWords = g_oTextTools.getSectionWords(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Loop over each of the section words and create a section for the individual word.\r\n\t\t\tfor (var j = 0; j < oSectionWords.length; j++) {\r\n\t\t\t\toSplitSections.push({\r\n\t\t\t\t\tstartingText: {\r\n\t\t\t\t\t\tparagraph: oSectionWords[j].paragraph,\r\n\t\t\t\t\t\tline: oSectionWords[j].line,\r\n\t\t\t\t\t\tword: oSectionWords[j].word\r\n\t\t\t\t\t},\r\n\t\t\t\t\tendingText: {\r\n\t\t\t\t\t\tparagraph: oSectionWords[j].paragraph,\r\n\t\t\t\t\t\tline: oSectionWords[j].line,\r\n\t\t\t\t\t\tword: oSectionWords[j].word\r\n\t\t\t\t\t},\r\n\t\t\t\t\tleftToRight: true\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the split content.\r\n\t\treturn oSplitSections;\r\n\t};\r\n\r\n\t/**\r\n\t * Splits the sections content at character level.\r\n\t * @param {object} oSections - The sections data.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.splitSections_Characters = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the split sections to be build up.\r\n\t\tvar oSplitSections = [];\r\n\r\n\t\t// Loop over each of the sections.\r\n\t\tfor (var i = 0; i < oSections.length; i++) {\r\n\r\n\t\t\t// Split the section into individual characters.\r\n\t\t\tvar oSectionWords = g_oTextTools.getSectionCharacters(oSections[i].startingText, oSections[i].endingText, oSections[i].leftToRight, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Loop over each of the section characters and create a section for the individual item.\r\n\t\t\tfor (var j = 0; j < oSectionWords.length; j++) {\r\n\t\t\t\toSplitSections.push({\r\n\t\t\t\t\tstartingText: {\r\n\t\t\t\t\t\tparagraph: oSectionWords[j].paragraph,\r\n\t\t\t\t\t\tline: oSectionWords[j].line,\r\n\t\t\t\t\t\tword: oSectionWords[j].word,\r\n\t\t\t\t\t\tcharacter: oSectionWords[j].character\r\n\t\t\t\t\t},\r\n\t\t\t\t\tendingText: {\r\n\t\t\t\t\t\tparagraph: oSectionWords[j].paragraph,\r\n\t\t\t\t\t\tline: oSectionWords[j].line,\r\n\t\t\t\t\t\tword: oSectionWords[j].word,\r\n\t\t\t\t\t\tcharacter: oSectionWords[j].character\r\n\t\t\t\t\t},\r\n\t\t\t\t\tleftToRight: true\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the split sections.\r\n\t\treturn oSplitSections;\r\n\t};\r\n\r\n\t/**\r\n\t * Merges the sections based on the accuracy.\r\n\t * @param {array} oSections - The sections to be merged.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.mergeSections = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\treturn g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.mergeSections_Characters(oSections, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.mergeSections_Words(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Merges the sections at a word level.\r\n\t * @param {array} oSections - The sections to be merged.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.mergeSections_Words = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the merged sections to be build up.\r\n\t\tvar oMergedSections = [];\r\n\r\n\t\t// Extract the split text data.\r\n\t\tvar oWords = g_oTextTools.getSectionsWords(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Sort the words.\r\n\t\toWords = oWords.sort(g_oTextTools.sortWords);\r\n\r\n\t\t// Remove the duplicate words.\r\n\t\toWords = g_oTextTools.distinctWords(oWords);\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Keep track of the current merged section being created.\r\n\t\tvar oMergedSection = null;\r\n\r\n\t\t// Loop through each of the paragraphs on the page.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Loop through each line in the paragraph.\r\n\t\t\tfor (var j = 0; j < oTextData.Paragraphs[i].Lines.length; j++) {\r\n\r\n\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\tfor (var k = 0; k < oTextData.Paragraphs[i].Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t// If we are on the first word, skip to the first word in the list.\r\n\t\t\t\t\tif (i == 0 && j == 0 && k == 0) {\r\n\t\t\t\t\t\ti = oWords[0].paragraph;\r\n\t\t\t\t\t\tj = oWords[0].line;\r\n\t\t\t\t\t\tk = oWords[0].word;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Check if the word is in the list.\r\n\t\t\t\t\tif (g_oTextTools.isWordInList(i, j, k, oWords)) {\r\n\r\n\t\t\t\t\t\t// If we are building up a merged section, add the word to the ending text.\r\n\t\t\t\t\t\tif (oMergedSection != null) {\r\n\t\t\t\t\t\t\toMergedSection.endingText = {\r\n\t\t\t\t\t\t\t\tparagraph: i, line: j, word: k\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// Otherwise, create a new merged section.\r\n\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\toMergedSection = {\r\n\t\t\t\t\t\t\t\tstartingText: { paragraph: i, line: j, word: k },\r\n\t\t\t\t\t\t\t\tendingText: { paragraph: i, line: j, word: k },\r\n\t\t\t\t\t\t\t\tleftToRight: true\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// If the word is not in the list.\r\n\t\t\t\t\telse {\r\n\r\n\t\t\t\t\t\t// If we have a merged section being built up, add it to the merged sections.\r\n\t\t\t\t\t\tif (oMergedSection != null) {\r\n\t\t\t\t\t\t\toMergedSections.push(oMergedSection);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Reset the merged section.\r\n\t\t\t\t\t\toMergedSection = null;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// If we are on the last word in the list, we can stop the search.\r\n\t\t\t\t\tif (i == oWords[oWords.length - 1].paragraph && j == oWords[oWords.length - 1].line && k == oWords[oWords.length - 1].word) {\r\n\r\n\t\t\t\t\t\t// If we have a merged section being built up, add it to the merged sections.\r\n\t\t\t\t\t\tif (oMergedSection != null) {\r\n\t\t\t\t\t\t\toMergedSections.push(oMergedSection);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Return the merged sections.\r\n\t\t\t\t\t\treturn oMergedSections;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the merged sections.\r\n\t\treturn oMergedSections;\r\n\t};\r\n\r\n\t/**\r\n\t * Merges the sections at a character level.\r\n\t * @param {array} oSections - The sections to be merged.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.mergeSections_Characters = function (oSections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Outline the merged sections to be build up.\r\n\t\tvar oMergedSections = [];\r\n\r\n\t\t// Extract the split text data.\r\n\t\tvar oCharacters = g_oTextTools.getSectionsCharacters(oSections, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Sort the characters.\r\n\t\toCharacters = oCharacters.sort(g_oTextTools.sortCharacters);\r\n\r\n\t\t// Remove the duplicate characters.\r\n\t\toCharacters = g_oTextTools.distinctCharacters(oCharacters);\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Keep track of the current merged section being created.\r\n\t\tvar oMergedSection = null;\r\n\r\n\t\t// Loop through each of the paragraphs on the page.\r\n\t\tfor (var i = 0; i < oTextData.Paragraphs.length; i++) {\r\n\r\n\t\t\t// Loop through each line in the paragraph.\r\n\t\t\tfor (var j = 0; j < oTextData.Paragraphs[i].Lines.length; j++) {\r\n\r\n\t\t\t\t// Loop through each of the words on the line.\r\n\t\t\t\tfor (var k = 0; k < oTextData.Paragraphs[i].Lines[j].Words.length; k++) {\r\n\r\n\t\t\t\t\t// Loop through each of the characters in the word.\r\n\t\t\t\t\tfor (var l = 0; l < oTextData.Paragraphs[i].Lines[j].Words[k].Characters.length; l++) {\r\n\r\n\t\t\t\t\t\t// If we are on the first character, skip to the first character in the list.\r\n\t\t\t\t\t\tif (i == 0 && j == 0 && k == 0 && l == 0) {\r\n\t\t\t\t\t\t\ti = oCharacters[0].paragraph;\r\n\t\t\t\t\t\t\tj = oCharacters[0].line;\r\n\t\t\t\t\t\t\tk = oCharacters[0].word;\r\n\t\t\t\t\t\t\tl = oCharacters[0].character;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Check if the character is in the list.\r\n\t\t\t\t\t\tif (g_oTextTools.isCharacterInList(i, j, k, l, oCharacters)) {\r\n\r\n\t\t\t\t\t\t\t// If we are building up a merged section, add the character to the ending text.\r\n\t\t\t\t\t\t\tif (oMergedSection != null) {\r\n\t\t\t\t\t\t\t\toMergedSection.endingText = {\r\n\t\t\t\t\t\t\t\t\tparagraph: i, line: j, word: k, character: l\r\n\t\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t// Otherwise, create a new merged section.\r\n\t\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t\toMergedSection = {\r\n\t\t\t\t\t\t\t\t\tstartingText: { paragraph: i, line: j, word: k, character: l },\r\n\t\t\t\t\t\t\t\t\tendingText: { paragraph: i, line: j, word: k, character: l },\r\n\t\t\t\t\t\t\t\t\tleftToRight: true\r\n\t\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// If the character is not in the list.\r\n\t\t\t\t\t\telse {\r\n\r\n\t\t\t\t\t\t\t// If we have a merged section being built up, add it to the merged sections.\r\n\t\t\t\t\t\t\tif (oMergedSection != null) {\r\n\t\t\t\t\t\t\t\toMergedSections.push(oMergedSection);\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Reset the merged section.\r\n\t\t\t\t\t\t\toMergedSection = null;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// If we are on the last character in the list, we can stop the looping.\r\n\t\t\t\t\t\tif (i == oCharacters[oCharacters.length - 1].paragraph && j == oCharacters[oCharacters.length - 1].line && k == oCharacters[oCharacters.length - 1].word && l == oCharacters[oCharacters.length - 1].character) {\r\n\r\n\t\t\t\t\t\t\t// If we have a merged section being built up, add it to the merged sections.\r\n\t\t\t\t\t\t\tif (oMergedSection != null) {\r\n\t\t\t\t\t\t\t\toMergedSections.push(oMergedSection);\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Return the merged sections.\r\n\t\t\t\t\t\t\treturn oMergedSections;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the merged sections.\r\n\t\treturn oMergedSections;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a word is within a section.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the section is left to right.\r\n\t * @returns {bool} - If the word is within the section.\r\n\t */\r\n\tTextTools.prototype.isWordInSection = function (paragraph, line, word, startingText, endingText, leftToRight) {\r\n\r\n\t\t// Determine if the word is within the section based on the direction.\r\n\t\treturn leftToRight ? g_oTextTools.isWordInSection_LeftToRight(paragraph, line, word, startingText, endingText) : g_oTextTools.isWordInSection_RightToLeft(paragraph, line, word, startingText, endingText);\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a character is within a section.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {int} character - The character.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @param {bool} leftToRight - If the section is left to right.\r\n\t * @returns {bool} - If the character is within the section.\r\n\t */\r\n\tTextTools.prototype.isCharacterInSection = function (paragraph, line, word, character, startingText, endingText, leftToRight) {\r\n\r\n\t\t// Determine if the character is within the section based on the direction.\r\n\t\treturn leftToRight ? g_oTextTools.isCharacterInSection_LeftToRight(paragraph, line, word, character, startingText, endingText) : g_oTextTools.isCharacterInSection_RightToLeft(paragraph, line, word, character, startingText, endingText);\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a word is in a left to right section.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @returns {bool} - If the word is within the section.\r\n\t */\r\n\tTextTools.prototype.isWordInSection_LeftToRight = function (paragraph, line, word, startingText, endingText) {\r\n\t\t\r\n\t\t// Determine if the word is within the section.\r\n\t\tvar bWordInSection = false;\r\n\r\n\t\t// Ensure the word is after the starting text.\r\n\t\tif ((paragraph > startingText.paragraph) ||\r\n\t\t\t(paragraph == startingText.paragraph && line > startingText.line) ||\r\n\t\t\t(paragraph == startingText.paragraph && line == startingText.line && word >= startingText.word)) {\r\n\r\n\t\t\t// Ensure the word is before the ending text.\r\n\t\t\tif ((paragraph < endingText.paragraph) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line < endingText.line) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line == endingText.line && word <= endingText.word)) {\r\n\r\n\t\t\t\t// Set that the word is within the section.\r\n\t\t\t\tbWordInSection = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return if the word is in the section.\r\n\t\treturn bWordInSection;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a character is in a left to right section.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {int} character - The character.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @returns {bool} - If the character is within the section.\r\n\t */\r\n\tTextTools.prototype.isCharacterInSection_LeftToRight = function (paragraph, line, word, character, startingText, endingText) {\r\n\r\n\t\t// Determine if the character is within the section.\r\n\t\tvar bCharacterInSection = false;\r\n\r\n\t\t// Ensure the character is after the starting text.\r\n\t\tif ((paragraph > startingText.paragraph) ||\r\n\t\t\t(paragraph == startingText.paragraph && line > startingText.line) ||\r\n\t\t\t(paragraph == startingText.paragraph && line == startingText.line && word > startingText.word) ||\r\n\t\t\t(paragraph == startingText.paragraph && line == startingText.line && word == startingText.word && character >= startingText.character)) {\r\n\r\n\t\t\t// Ensure the character is before the ending text.\r\n\t\t\tif ((paragraph < endingText.paragraph) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line < endingText.line) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line == endingText.line && word < endingText.word) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line == endingText.line && word == endingText.word && character <= endingText.character)) {\r\n\r\n\t\t\t\t// Set that the character is within the section.\r\n\t\t\t\tbCharacterInSection = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return if the character is in the section.\r\n\t\treturn bCharacterInSection;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a word is in a right to left section.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @returns {bool} - If the word is within the section.\r\n\t */\r\n\tTextTools.prototype.isWordInSection_RightToLeft = function (paragraph, line, word, startingText, endingText) {\r\n\t\t\r\n\t\t// Determine if the word is within the section.\r\n\t\tvar bWordInSection = false;\r\n\r\n\t\t// Ensure the word is after the starting text.\r\n\t\tif ((paragraph > startingText.paragraph) ||\r\n\t\t\t(paragraph == startingText.paragraph && line > startingText.line) ||\r\n\t\t\t(paragraph == startingText.paragraph && line == startingText.line && word <= startingText.word)) {\r\n\r\n\t\t\t// Ensure the word is before the ending text.\r\n\t\t\tif ((paragraph < endingText.paragraph) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line < endingText.line) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line == endingText.line && word >= endingText.word)) {\r\n\r\n\t\t\t\t// Set that the word is within the section.\r\n\t\t\t\tbWordInSection = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If the starting text and ending text are on the same line, we need to check the switched direction for words inbetween.\r\n\t\tif (startingText.paragraph == endingText.paragraph && startingText.line == endingText.line &&\r\n\t\t\tparagraph == endingText.paragraph && line == endingText.line && word >= startingText.word && word <= endingText.word) {\r\n\r\n\t\t\t// Set that the word is within the section.\r\n\t\t\tbWordInSection = true;\r\n\t\t}\r\n\r\n\t\t// Return if the word is in the section.\r\n\t\treturn bWordInSection;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a character is in a right to left section.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {int} character - The character.\r\n\t * @param {object} startingText - The starting text.\r\n\t * @param {object} endingText - The ending text.\r\n\t * @returns {bool} - If the character is within the section.\r\n\t */\r\n\tTextTools.prototype.isCharacterInSection_RightToLeft = function (paragraph, line, word, character, startingText, endingText) {\r\n\r\n\t\t// Determine if the character is within the section.\r\n\t\tvar bCharacterInSection = false;\r\n\r\n\t\t// Ensure the character is after the starting text.\r\n\t\tif ((paragraph > startingText.paragraph) ||\r\n\t\t\t(paragraph == startingText.paragraph && line > startingText.line) ||\r\n\t\t\t(paragraph == startingText.paragraph && line == startingText.line && word < startingText.word) ||\r\n\t\t\t(paragraph == startingText.paragraph && line == startingText.line && word == startingText.word && character <= startingText.character)) {\r\n\r\n\t\t\t// Ensure the character is before the ending text.\r\n\t\t\tif ((paragraph < endingText.paragraph) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line < endingText.line) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line == endingText.line && word > endingText.word) ||\r\n\t\t\t\t(paragraph == endingText.paragraph && line == endingText.line && word == endingText.word && character >= endingText.character)) {\r\n\r\n\t\t\t\t// Set that the character is within the section.\r\n\t\t\t\tbCharacterInSection = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If the starting text and ending text are on the same line, we need to check the switched direction for characters inbetween.\r\n\t\tif (startingText.paragraph == endingText.paragraph && startingText.line == endingText.line && startingText.word == endingText.word &&\r\n\t\t\tparagraph == endingText.paragraph && line == endingText.line && word == endingText.word &&\r\n\t\t\tcharacter >= startingText.character && character <= endingText.character) {\r\n\r\n\t\t\t// Set that the character is within the section.\r\n\t\t\tbCharacterInSection = true;\r\n\t\t}\r\n\r\n\t\t// Return if the character is in the section.\r\n\t\treturn bCharacterInSection;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a word is in a list of words.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {array} oWordList - The word list.\r\n\t */\r\n\tTextTools.prototype.isWordInList = function (paragraph, line, word, oWordList) {\r\n\t\treturn $.grep(oWordList, function (oWordListItem) {\r\n\t\t\treturn oWordListItem.paragraph == paragraph && oWordListItem.line == line && oWordListItem.word == word;\r\n\t\t}).length > 0;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if a character is in a list of characters.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {int} character - The character.\r\n\t * @param {array} oCharacterList - The character list.\r\n\t */\r\n\tTextTools.prototype.isCharacterInList = function (paragraph, line, word, character, oCharacterList) {\r\n\t\treturn $.grep(oCharacterList, function (oCharacterListItem) {\r\n\t\t\treturn oCharacterListItem.paragraph == paragraph && oCharacterListItem.line == line && oCharacterListItem.word == word && oCharacterListItem.character == character;\r\n\t\t}).length > 0;\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a paragraph.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightParagraph = function (paragraph, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Extract the paragrpah to be highlighted.\r\n\t\tvar oParagraph = oTextData.Paragraphs[paragraph];\r\n\r\n\t\t// Highlight the element.\r\n\t\tg_oTextTools.highlightElement(oParagraph.X1, oParagraph.X2, oParagraph.Y1, oParagraph.Y2, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a line.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightLine = function (paragraph, line, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Extract the line to be highlighted.\r\n\t\tvar oLine = oTextData.Paragraphs[paragraph].Lines[line];\r\n\r\n\t\t// Highlight the element.\r\n\t\tg_oTextTools.highlightElement(oLine.X1, oLine.X2, oLine.Y1, oLine.Y2, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a word.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightWord = function (paragraph, line, word, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\t\tvar oWord = oTextData.Paragraphs[paragraph].Lines[line].Words[word];\r\n\r\n\t\t// Highlight the element.\r\n\t\tg_oTextTools.highlightElement(oWord.X1, oWord.X2, oWord.Y1, oWord.Y2, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a character.\r\n\t * @param {int} paragraph - The paragraph.\r\n\t * @param {int} line - The line.\r\n\t * @param {int} word - The word.\r\n\t * @param {int} character - The character.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightCharacter = function (paragraph, line, word, character, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\t\tvar oCharacter = oTextData.Paragraphs[paragraph].Lines[line].Words[word].Characters[character];\r\n\r\n\t\t// Highlight the element.\r\n\t\tg_oTextTools.highlightElement(oCharacter.X1, oCharacter.X2, oCharacter.Y1, oCharacter.Y2, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights an element.\r\n\t * @param {double} X1 - The x1 of the element.\r\n\t * @param {double} X2 - The x2 of the element.\r\n\t * @param {double} Y1 - The y1 of the element.\r\n\t * @param {double} Y2 - The y2 of the element.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.highlightElement = function (X1, X2, Y1, Y2, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the canvas scaled image width and height.\r\n\t\tvar iScaledImageWidth = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iScaledImageHeight = oArtworkCanvas.g_iScaledImageHeight;\r\n\r\n\t\t// Calculate the compare offset on the artwork canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkCanvas);\r\n\r\n\t\t// If we have a compare rotation.\r\n\t\tif (iCompareRotation > 0) {\r\n\r\n\t\t\t// If we have a compare rotation of 90 or 270, swap the scaled image width and height.\r\n\t\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\t\tiScaledImageWidth = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\t\tiScaledImageHeight = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t\t}\r\n\r\n\t\t\t// Rotate the lower left positions.\r\n\t\t\tvar oRotatedLetterLower = oAnnotationCanvas.rotate(X1, Y1, 0.5, 0.5, iCompareRotation);\r\n\t\t\tX1 = oRotatedLetterLower.rotated_x;\r\n\t\t\tY1 = oRotatedLetterLower.rotated_y;\r\n\r\n\t\t\t// Rotate the upper right positions.\r\n\t\t\tvar oRotatedLetterUpper = oAnnotationCanvas.rotate(X2, Y2, 0.5, 0.5, iCompareRotation);\r\n\t\t\tX2 = oRotatedLetterUpper.rotated_x;\r\n\t\t\tY2 = oRotatedLetterUpper.rotated_y;\r\n\t\t}\r\n\r\n\t\t// Calculate the start positions and distance.\r\n\t\tvar startX = (X1 * iScaledImageWidth) + oArtworkCanvas.g_iCenterShift_x + compareOffset_x;\r\n\t\tvar startY = (Y2 * iScaledImageHeight) + oArtworkCanvas.g_iCenterShift_y + compareOffset_y;\r\n\t\tvar distX = ((X2 - X1) * iScaledImageWidth);\r\n\t\tvar distY = ((Y1 - Y2) * iScaledImageHeight);\r\n\r\n\t\t// Draw the highlight.\r\n\t\toAnnotationCanvas.drawTextHighlight(oAnnotationCanvas.g_oContext, startX, startY, distX, distY, g_oTextTools.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the highlight colour.\r\n\t * @param {string} colour - The colour to be used.\r\n\t */\r\n\tTextTools.prototype.setHighlightColour = function (colour) {\r\n\r\n\t\t// If this is already an RGBA colour.\r\n\t\tif (colour.indexOf(\"rgba(\") == 0) {\r\n\t\t\tg_oTextTools.g_szHighlightColour = colour;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Ensure we are in a hex colour.\r\n\t\tvar oHexColour = g_oAnnotations.getHexColour(colour);\r\n\r\n\t\t// Convert the hex colour to RGB.\r\n\t\tvar oRGB = convertColourHexToRGB(oHexColour);\r\n\r\n\t\t// Update the highlight colour.\r\n\t\tg_oTextTools.g_szHighlightColour = \"rgba(\" + oRGB.r + \", \" + oRGB.g + \", \" + oRGB.b + \", \" + 0.5 + \")\";\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a text highlight annotation.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.createAnnotation = function (oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Generate a text annotation.\r\n\t\tvar oTextAnnotation = g_oTextTools.generateTextAnnotation(g_oTextTools.g_oAnnotationText, g_oTextTools.g_eActiveAnnotationType, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Add the annotation to the annotations list.\r\n\t\tg_oAnnotations.g_oAnnotationsMade.push(oTextAnnotation);\r\n\r\n\t\t// Create the annotation div.\r\n\t\toTextAnnotation.createAnnotationDiv(eAnnotationDivType.Popup, true, null, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Redraw the annotations.\r\n\t\toAnnotationCanvas.g_oContext.clearRect(0, 0, oAnnotationCanvas.g_oCanvas.width, oAnnotationCanvas.g_oCanvas.height);\r\n\t\tg_oAnnotations.redrawAnnotations(oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Reposition the speech bubbles.\r\n\t\tg_oAnnotations.repositionSpeechBubbles(oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Focus the JQTE text editor for the new annotation.\r\n\t\t$(\".jqte_editor\").focus();\r\n\t};\r\n\r\n\t/**\r\n\t * Generates a text annotation.\r\n\t * @param {object} oAnnotationText - The annotation text.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t * @returns {object} - The text annotation.\r\n\t */\r\n\tTextTools.prototype.generateTextAnnotation = function (oAnnotationText, eAnnotationType, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Create a new annotation for the text.\r\n\t\tvar oTextAnnotation = new Annotation(g_oAnnotations.g_iApprovalId);\r\n\r\n\t\t// Set the id of the annotation.\r\n\t\toTextAnnotation.id = g_oAnnotations.getNextAnnotationId();\r\n\r\n\t\t// Set the annotation type.\r\n\t\toTextAnnotation.g_iAnnotationType = eAnnotationType;\r\n\r\n\t\t// Set the draw array from the bounds.\r\n\t\tvar oSectionBounds = g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getSectionsBounds_Characters(oAnnotationText, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.getSectionsBounds_Words(oAnnotationText, oArtworkCanvas, oAnnotationCanvas);\r\n\t\toTextAnnotation.g_oDrawArray = [[oSectionBounds.x1, oSectionBounds.y1], [oSectionBounds.x2, oSectionBounds.y2]];\r\n\r\n\t\t// Set the text for the annotation.\r\n\t\toTextAnnotation.g_szTextContent = g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getSectionsText_Characters(oAnnotationText, oArtworkCanvas, \"
\", \"
\") : g_oTextTools.getSectionsText_Words(oAnnotationText, oArtworkCanvas, \"
\", \"
\");\r\n\r\n\t\t// Set the text highlight content for the annotation.\r\n\t\toTextAnnotation.g_szTextHighlightContent = JSON.stringify(oAnnotationText);\r\n\r\n\t\t// Populate the properties of the annotation.\r\n\t\toTextAnnotation.g_iParentAnnotationId = 0;\r\n\t\toTextAnnotation.g_iNumber = Math.max(1, Math.max.apply(Math, g_oAnnotations.g_oAnnotationsMade.map(function (o) { return o.g_iNumber; })) + 1);\r\n\t\toTextAnnotation.g_szColour = g_oAnnotations.getHexColour(g_oAnnotations.g_oAnnotationColSelected);\r\n\t\toTextAnnotation.g_iDocumentId = oArtworkCanvas.g_oDoc.documentId;\r\n\t\toTextAnnotation.g_iAuthor = g_oUserDetails.UserId;\r\n\t\toTextAnnotation.g_szAuthorEmail = g_oUserDetails.EmailAddress;\r\n\t\toTextAnnotation.g_bSaved = false;\r\n\t\toTextAnnotation.status = \"a\";\r\n\r\n\t\t// If we have more than one page, grab the page id by looping through the pages.\r\n\t\tif (!$.isEmptyObject(oArtworkCanvas.g_oDoc.pages)) {\r\n\t\t\tfor (var i = 0; i < oArtworkCanvas.g_oDoc.pages.length; i++) {\r\n\t\t\t\tif (oArtworkCanvas.g_oDoc.pages[i].documentPageNumber == oArtworkCanvas.g_iCurrentPage) {\r\n\t\t\t\t\toTextAnnotation.g_iDocumentPageId = oArtworkCanvas.g_oDoc.pages[i].documentPageId;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If this is a text classification annotation, populate the annotation data.\r\n\t\tif (eAnnotationType == eAnnotationTypes.TextClassification) {\r\n\t\t\toTextAnnotation.g_oAnnotationData = g_oAnnotationTextClassification.populateDefaultAnnotationData();\r\n\t\t}\r\n\r\n\t\t// Return the generated SVG text annotation.\r\n\t\treturn oTextAnnotation;\r\n\t};\r\n\r\n\t/**\r\n\t * Updates a text highlight annotation.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.updateAnnotation = function (oArtworkCanvas, oAnnotationCanvas) {\r\n\t\t\r\n\t\t// Find the annotation in the list.\r\n\t\tvar oTextAnnotation = $.grep(g_oAnnotations.g_oAnnotationsMade, function (ann) {\r\n\t\t\treturn ann.id == g_oTextTools.g_iExistingAnnotationId;\r\n\t\t})[0];\r\n\r\n\t\t// Set the draw array from the bounds, and update the coordinates.\r\n\t\tvar oSectionBounds = g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getSectionsBounds_Characters(g_oTextTools.g_oAnnotationText, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.getSectionsBounds_Words(g_oTextTools.g_oAnnotationText, oArtworkCanvas, oAnnotationCanvas);\r\n\t\toTextAnnotation.g_oDrawArray = [[oSectionBounds.x1, oSectionBounds.y1], [oSectionBounds.x2, oSectionBounds.y2]];\r\n\t\toTextAnnotation.g_oDrawCoordSetArray[0].xCoordinate = oSectionBounds.x1;\r\n\t\toTextAnnotation.g_oDrawCoordSetArray[0].yCoordinate = oSectionBounds.y1;\r\n\t\toTextAnnotation.g_oDrawCoordSetArray[1].xCoordinate = oSectionBounds.x2;\r\n\t\toTextAnnotation.g_oDrawCoordSetArray[1].xCoordinate = oSectionBounds.y2;\r\n\r\n\t\t// Update the text content for the annotation.\r\n\t\toTextAnnotation.g_szTextContent = g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getSectionsText_Characters(g_oTextTools.g_oAnnotationText, oArtworkCanvas, \"
\", \"
\") : g_oTextTools.getSectionsText_Words(g_oTextTools.g_oAnnotationText, oArtworkCanvas, \"
\", \"
\");\r\n\r\n\t\t// Set the text highlight content for the annotation.\r\n\t\toTextAnnotation.g_szTextHighlightContent = JSON.stringify(g_oTextTools.g_oAnnotationText);\r\n\r\n\t\t// Set the correct annotation status.\r\n\t\toTextAnnotation.status = oTextAnnotation.status == \"a\" ? \"a\" : \"u\";\r\n\r\n\t\t// Save the annotation.\r\n\t\toTextAnnotation.AnnotationSave(eAnnotationDivType.Popup, oArtworkCanvas, oAnnotationCanvas, true);\r\n\t};\r\n\r\n\t/**\r\n\t * Updates a new text highlight annotation.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextTools.prototype.updateNewAnnotation = function (oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Find the annotation in the list.\r\n\t\tvar oTextAnnotation = $.grep(g_oAnnotations.g_oAnnotationsMade, function (ann) {\r\n\t\t\treturn ann.id == g_oTextTools.g_iExistingAnnotationId;\r\n\t\t})[0];\r\n\r\n\t\t// Set the draw array from the bounds.\r\n\t\tvar oSectionBounds = g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getSectionsBounds_Characters(g_oTextTools.g_oAnnotationText, oArtworkCanvas, oAnnotationCanvas) : g_oTextTools.getSectionsBounds_Words(g_oTextTools.g_oAnnotationText, oArtworkCanvas, oAnnotationCanvas);\r\n\t\toTextAnnotation.g_oDrawArray = [[oSectionBounds.x1, oSectionBounds.y1], [oSectionBounds.x2, oSectionBounds.y2]];\r\n\r\n\t\t// Update the text content for the annotation.\r\n\t\toTextAnnotation.g_szTextContent = g_oTextTools.g_bHighlightIsCharacterAccuracy ? g_oTextTools.getSectionsText_Characters(g_oTextTools.g_oAnnotationText, oArtworkCanvas, \"
\", \"
\") : g_oTextTools.getSectionsText_Words(g_oTextTools.g_oAnnotationText, oArtworkCanvas, \"
\", \"
\");\r\n\r\n\t\t// Set the text highlight content for the annotation.\r\n\t\toTextAnnotation.g_szTextHighlightContent = JSON.stringify(g_oTextTools.g_oAnnotationText);\r\n\r\n\t\t// Create the annotation div.\r\n\t\toTextAnnotation.createAnnotationDiv(eAnnotationDivType.Popup, true, null, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Redraw the annotations.\r\n\t\toAnnotationCanvas.g_oContext.clearRect(0, 0, oAnnotationCanvas.g_oCanvas.width, oAnnotationCanvas.g_oCanvas.height);\r\n\t\tg_oAnnotations.redrawAnnotations(oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Reposition the speech bubbles.\r\n\t\tg_oAnnotations.repositionSpeechBubbles(oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Determines if the text highlight is left to right.\r\n\t * @returns {bool} - If the text highlight is left to right.\r\n\t */\r\n\tTextTools.prototype.isTextHighlightLeftToRight = function () {\r\n\t\treturn g_oSettings.g_oUserSettings.HighlightPreference == eHighlightType.LeftToRight;\r\n\t};\r\n\r\n\t// Add the Text Tools UI object to the window.\r\n\twindow.TextTools = TextTools;\r\n}());"]}