/// <summary> /// Moves the position to the end of wrapped line. /// </summary> /// <param name="displayContext">The display context.</param> public static TextPosition ToEndOfWrappedLine( this TextPosition bufferPosition, IDisplayContext displayContext) { // Get the wrapped line and layout. Layout layout; int wrappedLineIndex; LayoutLine wrappedLine = bufferPosition.GetWrappedLine( displayContext, out layout, out wrappedLineIndex); // Move to the end of the wrapped line. If this isn't the last, we // need to shift back one character. int unicodeIndex = wrappedLine.StartIndex + wrappedLine.Length; if (wrappedLineIndex != layout.LineCount - 1) { unicodeIndex--; } // Because the wrappedLine works with UTF-8 encoding, we need to // convert it back to a C# string. string lineText = displayContext.LineBuffer.GetLineText(bufferPosition.LinePosition); int characterIndex = PangoUtility.TranslatePangoToStringIndex( lineText, unicodeIndex); // Create a new buffer position from the elements and return it. return(new TextPosition(bufferPosition.LinePosition, characterIndex)); }
public void ToStringOnMiddleOfTwoByteString() { // Arrange const int stringIndex = 8; const string text = "éâäàçê"; // Act int pangoIndex = PangoUtility.TranslatePangoToStringIndex(text, stringIndex); // Assert Assert.AreEqual(4, pangoIndex); }
public void ToStringOnMiddleOfSimpleString() { // Arrange const int stringIndex = 4; const string text = "simple"; // Act int pangoIndex = PangoUtility.TranslatePangoToStringIndex(text, stringIndex); // Assert Assert.AreEqual(4, pangoIndex); }
public void ToStringOnEmptyString() { // Arrange const int stringIndex = 0; const string text = ""; // Act int pangoIndex = PangoUtility.TranslatePangoToStringIndex(text, stringIndex); // Assert Assert.AreEqual(0, pangoIndex); }
/// <summary> /// Gets the string index for a given X coordinate (in Pango units). /// </summary> /// <param name="layoutLine">The layout line.</param> /// <param name="x">The x.</param> /// <param name="stringIndex">Index of the string.</param> /// <param name="trailing">The trailing.</param> /// <returns></returns> public static bool XToTranslatedIndex( this LayoutLine layoutLine, int x, out int stringIndex, out int trailing) { int pangoIndex; bool results = layoutLine.XToIndex(x, out pangoIndex, out trailing); stringIndex = PangoUtility.TranslatePangoToStringIndex( layoutLine.Layout.Text, pangoIndex); return(results); }
/// <summary> /// Gets the buffer position from a given point. /// </summary> /// <param name="widgetPoint">The widget point.</param> /// <param name="displayContext">The display context.</param> /// <returns></returns> public static TextPosition GetTextPosition( PointD widgetPoint, EditorViewController controller) { IDisplayContext displayContext = controller.DisplayContext; double y = widgetPoint.Y + displayContext.BufferOffsetY; int lineIndex = displayContext.Renderer.GetLineLayoutRange(y); Layout layout = displayContext.Renderer.GetLineLayout( lineIndex, LineContexts.None); // Shift the buffer-relative coordinates to layout-relative coordinates. double layoutY = y; if (lineIndex > 0) { layoutY -= displayContext.Renderer.GetLineLayoutHeight(0, lineIndex - 1); } int pangoLayoutY = Units.FromPixels((int)layoutY); // Shift the buffer-relative coordinates to handle padding. LineBlockStyle style = displayContext.Renderer.GetLineStyle( lineIndex, LineContexts.None); double layoutX = widgetPoint.X - style.Left; // Determines where in the layout is the point. int pangoLayoutX = Units.FromPixels((int)layoutX); int unicodeIndex; int trailing; layout.XyToIndex(pangoLayoutX, pangoLayoutY, out unicodeIndex, out trailing); // When dealing with UTF-8 characters, we have to convert the // Unicode index into a C# index. string lineText = displayContext.LineBuffer.GetLineText(lineIndex); unicodeIndex = NormalizeEmptyStrings(lineText, unicodeIndex); int characterIndex = PangoUtility.TranslatePangoToStringIndex( lineText, unicodeIndex); // If the source text is empty, then we disable the trailing. if (lineText.Length == 0) { trailing = 0; } // Return the buffer position. return(new TextPosition(lineIndex, characterIndex + trailing)); }
/// <summary> /// Translates the X, Y coordinates to a character index. /// </summary> /// <param name="layout">The layout.</param> /// <param name="x">The x.</param> /// <param name="y">The y.</param> /// <param name="stringIndex">The resulting index into the string.</param> /// <param name="trailing">The trailing.</param> /// <returns></returns> public static bool XyToTranslatedIndex( this Layout layout, int x, int y, out int stringIndex, out int trailing) { // Grab the results fromt he Pango index. int pangoIndex; bool results = layout.XyToIndex(x, y, out pangoIndex, out trailing); // Translate the Pango index. stringIndex = PangoUtility.TranslatePangoToStringIndex( layout.Text, pangoIndex); // Return the results. return(results); }
/// <summary> /// Moves the position to the beginning of wrapped line. /// </summary> /// <param name="displayContext">The display context.</param> public static TextPosition ToBeginningOfWrappedLine( this TextPosition bufferPosition, IDisplayContext displayContext) { // Wrapped lines (via Pango) work with UTF-8 encoding, not the // normal C# string indexes. We need to get the index and convert // it to a character string since that is what this library uses. LayoutLine wrappedLine = bufferPosition.GetWrappedLine(displayContext); int unicodeIndex = wrappedLine.StartIndex; // Because the wrappedLine works with UTF-8 encoding, we need to // convert it back to a C# string. string lineText = displayContext.LineBuffer.GetLineText(bufferPosition.LinePosition); int characterIndex = PangoUtility.TranslatePangoToStringIndex( lineText, unicodeIndex); // Create a new buffer position from the elements and return it. return(new TextPosition(bufferPosition.LinePosition, characterIndex)); }
public static void Down(EditorViewController controller) { // Extract a number of useful variable for this method. IDisplayContext displayContext = controller.DisplayContext; TextPosition position = displayContext.Caret.Position; EditorViewRenderer buffer = displayContext.Renderer; // Figure out the layout and wrapped line we are currently on. Layout layout; int wrappedLineIndex; LayoutLine wrappedLine = position.GetWrappedLine( displayContext, out layout, out wrappedLineIndex); // Figure out the X coordinate of the line. If there is an action context, // use that. Otherwise, calculate it from the character index of the position. int lineX = GetLineX(controller, wrappedLine, position); // Figure out which wrapped line we'll be moving the caret to. int lineIndex = position.LinePosition.GetLineIndex(buffer.LineBuffer); if (wrappedLine.IsLastLineInLayout()) { // If we are the last line in the buffer, just do nothing. if (position.IsLastLineInBuffer(buffer)) { return; } // Move to the next line. lineIndex++; layout = buffer.GetLineLayout(lineIndex, LineContexts.None); wrappedLine = layout.Lines[0]; } else { // Just move down in the layout. wrappedLineIndex++; wrappedLine = layout.Lines[wrappedLineIndex]; } // Adjust the X coordinate for the current line. lineX -= GetLeftStylePaddingPango(controller, lineIndex); // The wrapped line has the current wrapped line, so use the lineX // to figure out which character to use. int trailing; int unicodeIndex; wrappedLine.XToIndex(lineX, out unicodeIndex, out trailing); // Calculate the character position, but we have to map UTF-8 // characters because Pango uses that instead of C# strings. string lineText = controller.DisplayContext.LineBuffer.GetLineText(lineIndex); unicodeIndex = NormalizeEmptyStrings(lineText, unicodeIndex); int characterIndex = PangoUtility.TranslatePangoToStringIndex( lineText, unicodeIndex); if (lineText.Length > 0 && trailing > 0) { characterIndex++; } // Draw the new location of the caret. var caretPosition = new TextPosition( new LinePosition(lineIndex), new CharacterPosition(characterIndex)); displayContext.ScrollToCaret(caretPosition); }