internal void Render(Graphics g, RectangleF rectangle, PointF offset, IEnumerable <RTSelectionHighlight> highlights, bool unitsInMM) { List <Paragraph> rTParagraphs = RTParagraphs; if (rTParagraphs == null || rTParagraphs.Count == 0) { return; } using (RevertingDeviceContext revertingDeviceContext = new RevertingDeviceContext(g, Dpi)) { Win32DCSafeHandle hdc = revertingDeviceContext.Hdc; if (highlights != null) { _ = RTTextbox.TextBoxProps.Direction; foreach (RTSelectionHighlight highlight in highlights) { if (!HighlightStartLessThanOrEqualToEnd(highlight.SelectionStart, highlight.SelectionEnd)) { TextBoxContext selectionStart = highlight.SelectionStart; highlight.SelectionStart = highlight.SelectionEnd; highlight.SelectionEnd = selectionStart; } TextRun run; CaretInfo caretInfo = MapLocation(hdc, highlight.SelectionStart, relativeToRun: true, moveCaretToNextLine: true, out run); TextRun run2; CaretInfo caretInfo2 = MapLocation(hdc, highlight.SelectionEnd, relativeToRun: true, moveCaretToNextLine: true, out run2); if (caretInfo != null && caretInfo2 != null && run != null && run2 != null) { SetHighlighting(rTParagraphs, hdc, highlight, run, run2, caretInfo.Position.X, caretInfo2.Position.X); } } } Rectangle rect = (!unitsInMM) ? Rectangle.Round(rectangle) : new Rectangle(TextBox.ConvertToPixels(rectangle.X, m_dpi), TextBox.ConvertToPixels(rectangle.Y, m_dpi), TextBox.ConvertToPixels(rectangle.Width, m_dpi), TextBox.ConvertToPixels(rectangle.Height, m_dpi)); revertingDeviceContext.XForm.Transform(ref rect); Win32ObjectSafeHandle win32ObjectSafeHandle = Win32.CreateRectRgn(rect.Left - 1, rect.Top - 1, rect.Right + 1, rect.Bottom + 1); if (!win32ObjectSafeHandle.IsInvalid) { try { if (Win32.SelectClipRgn(hdc, win32ObjectSafeHandle) == 0) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } finally { win32ObjectSafeHandle.Close(); } } TextBox.Render(RTTextbox, rTParagraphs, hdc, FontCache, offset, rectangle, m_dpi, unitsInMM); if (Win32.SelectClipRgn(hdc, Win32ObjectSafeHandle.Zero) == 0) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } }
private CaretInfo MapLocation(Win32DCSafeHandle hdc, TextBoxContext location, bool relativeToRun, bool moveCaretToNextLine, out TextRun run) { CaretInfo caretInfo = null; run = null; int lineYOffset; int lineHeight; int textRunCharacterIndex; bool isFirstLine; bool isLastLine; Point paragraphAndRunCoordinates = GetParagraphAndRunCoordinates(hdc, location, moveCaretToNextLine, out lineYOffset, out lineHeight, out run, out textRunCharacterIndex, out isFirstLine, out isLastLine); if (run != null) { GlyphData glyphData = run.GlyphData; GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData; int piX = 0; if (glyphData != null && run.CharacterCount > 0) { int num = Win32.ScriptCPtoX(textRunCharacterIndex, fTrailing: false, run.CharacterCount, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, glyphData.Advances, ref run.SCRIPT_ANALYSIS, ref piX); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } } caretInfo = new CaretInfo(); CachedFont cachedFont = run.GetCachedFont(hdc, FontCache); caretInfo.Height = cachedFont.GetHeight(hdc, FontCache); caretInfo.Ascent = cachedFont.GetAscent(hdc, FontCache); caretInfo.Descent = cachedFont.GetDescent(hdc, FontCache); caretInfo.LineHeight = lineHeight; caretInfo.LineYOffset = lineYOffset; caretInfo.IsFirstLine = isFirstLine; caretInfo.IsLastLine = isLastLine; _ = RTParagraphs; int y = paragraphAndRunCoordinates.Y - caretInfo.Ascent; if (relativeToRun) { caretInfo.Position = new Point(piX, y); } else { caretInfo.Position = new Point(paragraphAndRunCoordinates.X + piX, y); } } return(caretInfo); }