/// <summary> /// Calculate the character index and offset by characters for the given word and given offset.<br/> /// If the location is below the word line then set the selection to the end.<br/> /// If the location is to the right of the word then set the selection to the end.<br/> /// If the offset is to the left of the word set the selection to the beginning.<br/> /// Otherwise calculate the width of each substring to find the char the location is on. /// </summary> /// <param name="control">used to create graphics to measure string</param> /// <param name="word">the word to calculate its index and offset</param> /// <param name="loc">the location to calculate for</param> /// <param name="selectionIndex">return the index of the char under the location</param> /// <param name="selectionOffset">return the offset of the char under the location</param> /// <param name="inclusive">is to include the first character in the calculation</param> private static void CalculateWordCharIndexAndOffset(Control control, CssRect word, Point loc, bool inclusive, out int selectionIndex, out float selectionOffset) { selectionIndex = 0; selectionOffset = 0f; var offset = loc.X - word.Left; if (word.Text == null) { // not a text word - set full selection selectionIndex = -1; selectionOffset = -1; } else if (offset > word.Width - word.OwnerBox.ActualWordSpacing || loc.Y > DomUtils.GetCssLineBoxByWord(word).LineBottom) { // mouse under the line, to the right of the word - set to the end of the word selectionIndex = word.Text.Length; selectionOffset = word.Width; } else if (offset > 0) { // calculate partial word selection var font = word.OwnerBox.ActualFont; using (var g = new WinGraphics(control.CreateGraphics(), false)) { int charFit; int charFitWidth; var maxWidth = offset + (inclusive ? 0 : 1.5f * word.LeftGlyphPadding); g.MeasureString(word.Text, font, maxWidth, out charFit, out charFitWidth); selectionIndex = charFit; selectionOffset = charFitWidth; } } }
/// <summary> /// Calculate the character index and offset by characters for the given word and given offset.<br/> /// If the location is below the word line then set the selection to the end.<br/> /// If the location is to the right of the word then set the selection to the end.<br/> /// If the offset is to the left of the word set the selection to the beginning.<br/> /// Otherwise calculate the width of each substring to find the char the location is on. /// </summary> /// <param name="control">used to create graphics to measure string</param> /// <param name="word">the word to calculate its index and offset</param> /// <param name="loc">the location to calculate for</param> /// <param name="selectionIndex">return the index of the char under the location</param> /// <param name="selectionOffset">return the offset of the char under the location</param> /// <param name="inclusive">is to include the first character in the calculation</param> private static void CalculateWordCharIndexAndOffset(Control control, CssRect word, Point loc, bool inclusive, out int selectionIndex, out float selectionOffset) { selectionIndex = 0; selectionOffset = 0f; var offset = loc.X - word.Left; if (word.Text == null) { // not a text word - set full selection selectionIndex = -1; selectionOffset = -1; } else if (offset > word.Width - word.OwnerBox.ActualWordSpacing || loc.Y > DomUtils.GetCssLineBoxByWord(word).LineBottom) { // mouse under the line, to the right of the word - set to the end of the word selectionIndex = word.Text.Length; selectionOffset = word.Width; } else if (offset > 0) { // calculate partial word selection var font = word.OwnerBox.ActualFont; using (var g = new WinGraphics(control.CreateGraphics())) { int charFit; int charFitWidth; var maxWidth = offset + ( inclusive ? 0 : 1.5f*word.LeftGlyphPadding ); g.MeasureString(word.Text, font, maxWidth, out charFit, out charFitWidth); selectionIndex = charFit; selectionOffset = charFitWidth; } } }