/// <summary>Finds the index of the nearest character to x pixels.</summary> /// <param name="x">The number of pixels from the left edge of this text element.</param> /// <returns>The index of the nearest letter.</returns> public int LetterIndex(int x) { if (ChildNodes == null) { return(0); } int widthSoFar = 0; int lettersSoFar = 0; for (int i = 0; i < ChildNodes.Count; i++) { WordElement word = (WordElement)ChildNodes[i]; // Grab the words computed style: Css.ComputedStyle wordStyle = word.Style.Computed; // Bump up the current width: widthSoFar += wordStyle.PixelWidth; if (x <= widthSoFar) { int localWidthOffset = x - (widthSoFar - wordStyle.PixelWidth); lettersSoFar += wordStyle.Text.LetterIndex(localWidthOffset); break; } else { lettersSoFar += word.LetterCount(); } } return(lettersSoFar); }
/// <summary>Gets the word containing the letter at the given index.</summary> /// <param name="index">The index of the letter to find in this text element.</param> /// <param name="localOffset">The index of the letter in the word.</param> /// <returns>The nearest word element found.</returns> public WordElement GetWordWithLetter(int index, out int localOffset) { localOffset = 0; if (ChildNodes == null) { return(null); } int lettersSoFar = 0; for (int i = 0; i < ChildNodes.Count; i++) { WordElement word = (WordElement)ChildNodes[i]; int letterCount = word.LetterCount(); lettersSoFar += letterCount; if (index <= lettersSoFar) { localOffset = index - (lettersSoFar - letterCount); return(word); } } localOffset = lettersSoFar; return(null); }
/// <summary>Finds the index of the nearest character to x pixels.</summary> /// <param name="x">The number of pixels from the left edge of this text element.</param> /// <param name="y">The number of pixels from the top edge of this text element.</param> /// <returns>The index of the nearest letter.</returns> public int LetterIndex(int x, int y) { if (ChildNodes == null) { return(0); } int widthSoFar = 0; int lettersSoFar = 0; for (int i = 0; i < ChildNodes.Count; i++) { WordElement word = (WordElement)ChildNodes[i]; // Grab the words computed style: Css.ComputedStyle wordStyle = word.Style.Computed; // Find where the bottom of the line is at: int lineBottom = wordStyle.PixelHeight + wordStyle.ParentOffsetTop; if (lineBottom < y) { // Not at the right line yet. lettersSoFar += word.LetterCount(); continue; } // Crank over the width: widthSoFar += wordStyle.PixelWidth; if (x <= widthSoFar) { int localWidthOffset = x - (widthSoFar - wordStyle.PixelWidth); lettersSoFar += wordStyle.Text.LetterIndex(localWidthOffset); break; } else { lettersSoFar += word.LetterCount(); } } return(lettersSoFar); }
/// <summary>Gets the relative position in pixels of the letter at the given index.</summary> /// <param name="index">The index of the letter in this text element.</param> /// <returns>The number of pixels from the left and top edges of this text element the letter is as a vector.</returns> public Vector2 GetPosition(ref int index) { if (index == 0 || ChildNodes == null) { return(Vector2.zero); } int localOffset; WordElement word = GetWordWithLetter(index, out localOffset); if (word == null) { index -= localOffset; return(Vector2.zero); } Css.ComputedStyle computed = word.Style.Computed; float left = computed.ParentOffsetLeft + computed.Text.LocalPositionOf(localOffset); float top = computed.ParentOffsetTop; return(new Vector2(left, top)); }
internal void Lettering(List <Element> into, Element parent) { if (ChildNodes == null) { return; } int count = ChildNodes.Count; for (int i = 0; i < count; i++) { // Grab the child node: Element child = ChildNodes[i]; // Get the element type: Type type = child.GetType(); if (type == typeof(TextElement)) { // Apply to each word: child.Lettering(into, parent); } else if (type == typeof(WordElement)) { // Split the word into its chars: WordElement word = (WordElement)child; // Grab the text object: TextRenderingProperty textProperty = word.Style.Computed.Text; if (textProperty == null || textProperty.Text == null) { continue; } // Get the characters: char[] characters = textProperty.Text.ToCharArray(); // How many chars? int characterCount = characters.Length; // Add each letter as a new element: for (int c = 0; c < characterCount; c++) { // The character(s) as a string: string charString; // Grab the character: char character = characters[c]; // Surrogate pair? if (char.IsHighSurrogate(character) && c != characters.Length - 1) { // Low surrogate follows: char lowChar = characters[c + 1]; c++; // Get the charcode: int code = char.ConvertToUtf32(character, lowChar); // Turn it back into a string: charString = char.ConvertFromUtf32(code); } else { charString = "" + character; } // Create a word ele: WordElement result = new WordElement(Document, parent, charString); // Add it: into.Add(result); } } else { // Direct add: into.Add(child); } } }
internal void Lettering(List<Element> into,Element parent){ if(ChildNodes==null){ return; } int count=ChildNodes.Count; for(int i=0;i<count;i++){ // Grab the child node: Element child=ChildNodes[i]; // Get the element type: Type type=child.GetType(); if(type == typeof(TextElement)){ // Apply to each word: child.Lettering(into,parent); }else if(type == typeof(WordElement)){ // Split the word into its chars: WordElement word=(WordElement)child; // Grab the text object: TextRenderingProperty textProperty=word.Style.Computed.Text; if(textProperty==null || textProperty.Text==null){ continue; } // Get the characters: char[] characters=textProperty.Text.ToCharArray(); // How many chars? int characterCount=characters.Length; // Add each letter as a new element: for(int c=0;c<characterCount;c++){ // The character(s) as a string: string charString; // Grab the character: char character=characters[c]; // Surrogate pair? if(char.IsHighSurrogate(character) && c!=characters.Length-1){ // Low surrogate follows: char lowChar=characters[c+1]; c++; // Get the charcode: int code=char.ConvertToUtf32(character,lowChar); // Turn it back into a string: charString=char.ConvertFromUtf32(code); }else{ charString=""+character; } // Create a word ele: WordElement result=new WordElement(Document,parent,charString); // Add it: into.Add(result); } }else{ // Direct add: into.Add(child); } } }