private static bool GetLine(Paragraph paragraph, TextLine line, Win32DCSafeHandle hdc, FontCache fontCache, FlowContext flowContext, float left, float right, float height, Stack <int> lineRunsIndex, Stack <int> lineRunsCharIndex, int lineIndents) { float num = right - left; float num2 = left; bool newLine = false; int num3 = 0; do { lineRunsIndex.Push(flowContext.Context.TextRunIndex); lineRunsCharIndex.Push(flowContext.Context.TextRunCharacterIndex); TextRun subRunForLine = paragraph.GetSubRunForLine(flowContext.Context, ref newLine); if (subRunForLine == null) { break; } line.LogicalRuns.Add(subRunForLine); int width = subRunForLine.GetWidth(hdc, fontCache); num3 = Math.Max(subRunForLine.GetWidth(hdc, fontCache, isAtLineEnd: true) - width, num3); num2 += (float)width; if (!(num2 + (float)num3 > right)) { continue; } bool flag = flowContext.WordTrim; if (!flowContext.LineLimit && flag) { if ((float)line.GetHeight(hdc, fontCache) >= height) { flag = false; } line.ResetHeight(); } if (!subRunForLine.IsPlaceholderTextRun) { FoldLine(paragraph, line, hdc, fontCache, flowContext, flag, lineRunsIndex, lineRunsCharIndex, num - (float)num3, lineIndents); break; } lineRunsIndex.Push(flowContext.Context.TextRunIndex); lineRunsCharIndex.Push(flowContext.Context.TextRunCharacterIndex); bool flag2 = true; TextRun subRunForLine2 = paragraph.GetSubRunForLine(flowContext.Context, ref newLine); if (subRunForLine2 != null) { flag2 = (subRunForLine.TextRunProperties.IndexInParagraph < subRunForLine2.TextRunProperties.IndexInParagraph); } flowContext.Context.TextRunIndex = lineRunsIndex.Pop(); flowContext.Context.TextRunCharacterIndex = lineRunsCharIndex.Pop(); if (flag2) { FoldLine(paragraph, line, hdc, fontCache, flowContext, flag, lineRunsIndex, lineRunsCharIndex, num - (float)num3, lineIndents); break; } }while (!newLine); if (line.LogicalRuns.Count == 0) { return(false); } return(true); }
private CaretInfo MapLocation(Graphics g, TextBoxContext location, bool relativeToRun, bool moveCaretToNextLine, out TextRun run) { Win32DCSafeHandle win32DCSafeHandle = null; bool flag = false; try { if (g == null) { flag = true; g = Graphics.FromHwnd(IntPtr.Zero); } win32DCSafeHandle = new Win32DCSafeHandle(g.GetHdc(), ownsHandle: false); return(MapLocation(win32DCSafeHandle, location, relativeToRun, moveCaretToNextLine, out run)); } finally { if (!win32DCSafeHandle.IsInvalid) { g.ReleaseHdc(); } if (flag) { g.Dispose(); g = null; } } }
private void TextScriptPlace(Win32DCSafeHandle hdc, bool fontSelected, FontCache fontCache) { int num = 0; GlyphShapeData glyphScriptShapeData = m_cachedGlyphData.GlyphScriptShapeData; if (fontSelected) { num = Win32.ScriptPlace(hdc, ref m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref SCRIPT_ANALYSIS, m_cachedGlyphData.RawAdvances, m_cachedGlyphData.RawGOffsets, ref m_cachedGlyphData.ABC); } else { num = Win32.ScriptPlace(IntPtr.Zero, ref m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref SCRIPT_ANALYSIS, m_cachedGlyphData.RawAdvances, m_cachedGlyphData.RawGOffsets, ref m_cachedGlyphData.ABC); if (num == -2147483638) { fontCache.SelectFontObject(hdc, m_cachedFont.Hfont); num = Win32.ScriptPlace(hdc, ref m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref SCRIPT_ANALYSIS, m_cachedGlyphData.RawAdvances, m_cachedGlyphData.RawGOffsets, ref m_cachedGlyphData.ABC); } } if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } if (m_cachedGlyphData.ABC.Width > 0 && m_text.Length == 1 && TextBox.IsWhitespaceControlChar(m_text[0])) { m_cachedGlyphData.ABC.SetToZeroWidth(); } }
internal void Draw(Win32DCSafeHandle hdc, int lineThickness, uint rgbColor) { if (lineThickness < 1) { lineThickness = 1; } Win32.LOGBRUSH lplb = default(Win32.LOGBRUSH); lplb.lbColor = rgbColor; lplb.lbHatch = 0; lplb.lbStyle = 0u; Win32ObjectSafeHandle win32ObjectSafeHandle = Win32.ExtCreatePen(66048u, (uint)lineThickness, ref lplb, 0u, null); Win32ObjectSafeHandle win32ObjectSafeHandle2 = Win32ObjectSafeHandle.Zero; try { win32ObjectSafeHandle2 = Win32.SelectObject(hdc, win32ObjectSafeHandle); Win32.MoveToEx(hdc, m_startPoint.X, m_startPoint.Y, IntPtr.Zero); Win32.LineTo(hdc, m_endPoint.X, m_endPoint.Y); } finally { if (!win32ObjectSafeHandle2.IsInvalid) { Win32.SelectObject(hdc, win32ObjectSafeHandle2).SetHandleAsInvalid(); win32ObjectSafeHandle2.SetHandleAsInvalid(); } if (!win32ObjectSafeHandle.IsInvalid) { win32ObjectSafeHandle.Close(); win32ObjectSafeHandle = null; } } }
internal static void DrawClippedTextRun(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, int x, int baselineY, uint fontColorOverride, Rectangle clipRect, Underline underline) { uint crColor = 0u; IntPtr intPtr = IntPtr.Zero; try { underline?.Draw(hdc, (int)((double)run.UnderlineHeight * 0.085), fontColorOverride); RECT structure = default(RECT); structure.left = clipRect.Left; structure.right = clipRect.Right; structure.top = clipRect.Top; structure.bottom = clipRect.Bottom; crColor = Win32.SetTextColor(hdc, fontColorOverride); GlyphData glyphData = run.GetGlyphData(hdc, fontCache); GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData; CachedFont cachedFont = run.GetCachedFont(hdc, fontCache); fontCache.SelectFontObject(hdc, cachedFont.Hfont); intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, intPtr, fDeleteOld: false); int num = Win32.ScriptTextOut(hdc, ref cachedFont.ScriptCache, x, baselineY, 4u, intPtr, ref run.SCRIPT_ANALYSIS, IntPtr.Zero, 0, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphData.Advances, null, glyphData.GOffsets); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } } finally { if (intPtr != IntPtr.Zero) { Marshal.FreeHGlobal(intPtr); } crColor = Win32.SetTextColor(hdc, crColor); } }
private static int FindFoldTextPosition_TextRunTrim(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, float maxWidth, SCRIPT_LOGATTR?nextCharLogAttr) { string text = run.Text; int i = FindFoldTextPosition_CharacterTrim(run, hdc, fontCache, maxWidth); if (i == text.Length && i > 0 && !run.ScriptLogAttr[i - 1].IsWhiteSpace && nextCharLogAttr.HasValue && !nextCharLogAttr.Value.IsWhiteSpace && !nextCharLogAttr.Value.IsSoftBreak) { i--; } int num = i; if (i > 0) { if (i < text.Length) { while (i > 0 && !run.ScriptLogAttr[i].IsWhiteSpace && !run.ScriptLogAttr[i].IsSoftBreak) { i--; } if (i <= 0) { return(-1); } for (; i < num + 1 && run.ScriptLogAttr[i].IsWhiteSpace; i++) { } } return(i); } return(-1); }
internal static void ExtDrawTextRun(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, int x, int baselineY, Underline underline) { uint crColor = 0u; try { uint colorInt = run.ColorInt; underline?.Draw(hdc, (int)((double)run.UnderlineHeight * 0.085), colorInt); crColor = Win32.SetTextColor(hdc, colorInt); CachedFont cachedFont = run.GetCachedFont(hdc, fontCache); fontCache.SelectFontObject(hdc, cachedFont.Hfont); int[] lpDx = null; uint fuOptions = 0u; if (run.ScriptAnalysis.fRTL == 1) { fuOptions = 128u; } if (!Win32.ExtTextOut(hdc, x, baselineY, fuOptions, IntPtr.Zero, run.Text, (uint)run.Text.Length, lpDx)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } finally { crColor = Win32.SetTextColor(hdc, crColor); } }
internal int GetDescent(Win32DCSafeHandle hdc, FontCache fontCache) { if (!m_initialized) { Initialize(hdc, fontCache); } return(m_textMetric.tmDescent); }
internal int GetLeading(Win32DCSafeHandle hdc, FontCache fontCache) { if (!m_initialized) { Initialize(hdc, fontCache); } return(m_textMetric.tminternalLeading); }
private void LoadGlyphData(Win32DCSafeHandle hdc, FontCache fontCache) { if (!m_clone && m_cachedGlyphData.NeedGlyphPlaceData) { m_cachedGlyphData.NeedGlyphPlaceData = false; m_cachedGlyphData.ScaleFactor = m_cachedFont.ScaleFactor; TextScriptPlace(hdc, fontSelected: false, fontCache); } }
internal int GetPrefixWidth(Win32DCSafeHandle hdc, FontCache fontCache) { if (m_prefix == null) { return(0); } CalculateDimensions(hdc, fontCache, useVisualRunsIfAvailable: true); return(m_prefixWidth); }
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()); } } }
internal int GetWidth(Win32DCSafeHandle hdc, FontCache fontCache, bool isAtLineEnd) { if (m_cachedGlyphData == null) { ShapeAndPlace(hdc, fontCache); } else { LoadGlyphData(hdc, fontCache); } return(m_cachedGlyphData.GetTotalWidth(isAtLineEnd)); }
internal GlyphData GetGlyphData(Win32DCSafeHandle hdc, FontCache fontCache) { if (m_cachedGlyphData == null) { ShapeAndPlace(hdc, fontCache); } else { LoadGlyphData(hdc, fontCache); } return(m_cachedGlyphData); }
internal void SelectFontObject(Win32DCSafeHandle hdc, Win32ObjectSafeHandle hFont) { if (hdc != m_selectedHdc) { m_selectedHdc = hdc; m_selectedFont = Win32ObjectSafeHandle.Zero; } if (hFont != m_selectedFont) { Win32.SelectObject(hdc, hFont).SetHandleAsInvalid(); m_selectedFont = hFont; } }
private void Initialize(Win32DCSafeHandle hdc, FontCache fontCache) { fontCache.SelectFontObject(hdc, m_hfont); Win32.GetTextMetrics(hdc, out m_textMetric); if (ScaleFactor != 1f) { m_textMetric.tmHeight = Scale(m_textMetric.tmHeight); m_textMetric.tmAscent = Scale(m_textMetric.tmAscent); m_textMetric.tmDescent = Scale(m_textMetric.tmDescent); m_textMetric.tminternalLeading = Scale(m_textMetric.tminternalLeading); } m_initialized = true; }
private static int FindWidthToBreakPosition(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, float maxWidth, out int width) { string text = run.Text; int[] logicalWidths = run.GetLogicalWidths(hdc, fontCache); int i = 0; for (width = 0; i < text.Length && ((float)(width + logicalWidths[i]) <= maxWidth || (!run.ScriptLogAttr[i].IsWhiteSpace && !run.ScriptLogAttr[i].IsSoftBreak)); i++) { width += logicalWidths[i]; } return(i); }
private static int FindFoldTextPosition_CharacterTrim(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, float maxWidth) { string text = run.Text; int[] logicalWidths = run.GetLogicalWidths(hdc, fontCache); int i = 0; for (int num = 0; i < text.Length && (float)(num + logicalWidths[i]) <= maxWidth; i++) { num += logicalWidths[i]; } return(i); }
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); }
internal static void Render(TextBox textBox, List <Paragraph> paragraphs, Graphics g, FontCache fontCache, PointF offset, RectangleF layoutRectangle) { float dpiX = g.DpiX; Win32DCSafeHandle win32DCSafeHandle = new Win32DCSafeHandle(g.GetHdc(), ownsHandle: false); try { Render(textBox, paragraphs, win32DCSafeHandle, fontCache, offset, layoutRectangle, dpiX); } finally { fontCache.ResetGraphics(); if (!win32DCSafeHandle.IsInvalid) { g.ReleaseHdc(); } } }
internal static List <Paragraph> Flow(TextBox textBox, Graphics g, FontCache fontCache, FlowContext flowContext, bool keepLines, out float height) { List <Paragraph> list = null; float dpiX = g.DpiX; Win32DCSafeHandle win32DCSafeHandle = new Win32DCSafeHandle(g.GetHdc(), ownsHandle: false); try { return(Flow(textBox, win32DCSafeHandle, dpiX, fontCache, flowContext, keepLines, out height)); } finally { fontCache.ResetGraphics(); if (!win32DCSafeHandle.IsInvalid) { g.ReleaseHdc(); } } }
internal static void Render(TextBox textBox, List <Paragraph> paragraphs, Win32DCSafeHandle hdc, FontCache fontCache, PointF offset, RectangleF layoutRectangle, float dpiX, bool unitsInMM) { if (paragraphs == null || paragraphs.Count == 0) { return; } Rectangle layoutRectangle2; Point point; if (!unitsInMM) { layoutRectangle2 = new Rectangle((int)layoutRectangle.X, (int)layoutRectangle.Y, (int)layoutRectangle.Width, (int)layoutRectangle.Height); point = new Point((int)offset.X, (int)offset.Y); } else { layoutRectangle2 = new Rectangle(ConvertToPixels(layoutRectangle.X, dpiX), ConvertToPixels(layoutRectangle.Y, dpiX), ConvertToPixels(layoutRectangle.Width, dpiX), ConvertToPixels(layoutRectangle.Height, dpiX)); point = new Point(ConvertToPixels(offset.X, dpiX), ConvertToPixels(offset.Y, dpiX)); } uint fMode = Win32.SetTextAlign(hdc, 24u); int iBkMode = Win32.SetBkMode(hdc, 1); Win32ObjectSafeHandle win32ObjectSafeHandle = Win32.SelectObject(hdc, Win32ObjectSafeHandle.Zero); try { fontCache.WritingMode = textBox.TextBoxProps.WritingMode; int offsetY = point.Y; for (int i = 0; i < paragraphs.Count; i++) { RenderParagraph(textBox, paragraphs[i], hdc, fontCache, point.X, ref offsetY, layoutRectangle2, dpiX); } } finally { fMode = Win32.SetTextAlign(hdc, fMode); iBkMode = Win32.SetBkMode(hdc, iBkMode); if (!win32ObjectSafeHandle.IsInvalid) { Win32.SelectObject(hdc, win32ObjectSafeHandle).SetHandleAsInvalid(); win32ObjectSafeHandle.SetHandleAsInvalid(); } } }
internal int[] GetLogicalWidths(Win32DCSafeHandle hdc, FontCache fontCache) { GlyphData glyphData = GetGlyphData(hdc, fontCache); int[] array = new int[m_text.Length]; int num = Win32.ScriptGetLogicalWidths(ref SCRIPT_ANALYSIS, m_text.Length, glyphData.GlyphScriptShapeData.GlyphCount, glyphData.ScaledAdvances, glyphData.GlyphScriptShapeData.Clusters, glyphData.GlyphScriptShapeData.VisAttrs, array); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } if (glyphData.Scaled) { for (int i = 0; i < array.Length; i++) { array[i] = glyphData.Scale(array[i]); } } return(array); }
internal int GetHeight(Win32DCSafeHandle hdc, FontCache fontCache) { if (!m_calculatedHeight) { m_calculatedHeight = true; for (int i = 0; i < m_logicalRuns.Count; i++) { TextRun textRun = m_logicalRuns[i]; int ascent = textRun.GetAscent(hdc, fontCache); if (ascent > m_ascent) { m_ascent = ascent; } int descent = textRun.GetDescent(hdc, fontCache); if (descent > m_descent) { m_descent = descent; } } if (m_prefix != null) { for (int j = 0; j < m_prefix.Count; j++) { TextRun textRun2 = m_prefix[j]; int ascent2 = textRun2.GetAscent(hdc, fontCache); if (ascent2 > m_ascent) { m_ascent = ascent2; } int descent2 = textRun2.GetDescent(hdc, fontCache); if (descent2 > m_descent) { m_descent = descent2; } } } } return(m_ascent + m_descent); }
internal Underline(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, Rectangle layoutRectangle, int x, int baselineY, RPLFormat.WritingModes writingMode) { int width = run.GetWidth(hdc, fontCache); int num = (int)((double)(int)((double)run.UnderlineHeight * 0.085) * 1.5); switch (writingMode) { case RPLFormat.WritingModes.Horizontal: m_startPoint = new Point(layoutRectangle.X + x, layoutRectangle.Y + baselineY + num); m_endPoint = new Point(Math.Min(m_startPoint.X + width, layoutRectangle.Right), m_startPoint.Y); break; case RPLFormat.WritingModes.Vertical: m_startPoint = new Point(layoutRectangle.Right - baselineY - num - 1, layoutRectangle.Y + x); m_endPoint = new Point(m_startPoint.X, Math.Min(m_startPoint.Y + width, layoutRectangle.Bottom)); break; case RPLFormat.WritingModes.Rotate270: m_startPoint = new Point(layoutRectangle.X + baselineY + num, layoutRectangle.Bottom - x); m_endPoint = new Point(m_startPoint.X, Math.Max(m_startPoint.Y - width, layoutRectangle.Top)); break; } }
private void SetupGraphics(float dpi) { m_graphics.PageUnit = GraphicsUnit.Pixel; m_graphics.PageScale = 1f; m_hdc = new Win32DCSafeHandle(m_graphics.GetHdc(), ownsHandle: false); m_oldXForm = default(Win32.XFORM); if (m_matrix != null) { m_xForm = new Win32.XFORM(m_matrix, m_pageUnits, dpi); m_oldMode = Win32.SetGraphicsMode(m_hdc, 2); if (!Win32.GetWorldTransform(m_hdc, ref m_oldXForm)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } if (!Win32.SetWorldTransform(m_hdc, ref m_xForm)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { m_xForm = Win32.XFORM.Identity; } }
internal static void DrawTextRun(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, int x, int baselineY, Underline underline) { uint crColor = 0u; try { uint colorInt = run.ColorInt; underline?.Draw(hdc, (int)((double)run.UnderlineHeight * 0.085), colorInt); crColor = Win32.SetTextColor(hdc, colorInt); GlyphData glyphData = run.GetGlyphData(hdc, fontCache); GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData; CachedFont cachedFont = run.GetCachedFont(hdc, fontCache); fontCache.SelectFontObject(hdc, cachedFont.Hfont); int num = Win32.ScriptTextOut(hdc, ref cachedFont.ScriptCache, x, baselineY, 4u, IntPtr.Zero, ref run.SCRIPT_ANALYSIS, IntPtr.Zero, 0, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphData.Advances, null, glyphData.GOffsets); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } } finally { crColor = Win32.SetTextColor(hdc, crColor); } }
internal static void Render(TextBox textBox, List <Paragraph> paragraphs, Win32DCSafeHandle hdc, FontCache fontCache, PointF offset, RectangleF layoutRectangle, float dpiX) { Render(textBox, paragraphs, hdc, fontCache, offset, layoutRectangle, dpiX, unitsInMM: true); }
private static void RenderHighlightedTextRun(TextBox textBox, Paragraph paragraph, TextRun run, TextRun prevRun, Win32DCSafeHandle hdc, Graphics g, FontCache fontCache, float dpiX, int x, int offsetY, int baselineY, int lineHeight, Rectangle layoutRectangle, int runWidth, int prevRunWidth, int prevRunX, bool lastRunInLine, bool lastLineInParagraph) { uint? num = null; Rectangle?rectangle = null; bool flag = false; Color color = run.HighlightColor; if (!color.IsEmpty) { int num2 = (run.HighlightStart >= 0) ? run.HighlightStart : 0; int num3 = (run.HighlightEnd >= 0) ? run.HighlightEnd : runWidth; if (lastRunInLine) { bool flag2 = run.ScriptAnalysis.fLayoutRTL == 1; if (lastLineInParagraph && runWidth != 0) { if (num2 != num3 && ((flag2 && run.HighlightStart < 0) || (!flag2 && run.HighlightEnd < 0))) { if (flag2) { num2 -= 5; int abcA = run.GetGlyphData(hdc, fontCache).ABC.abcA; if (abcA < 0) { num2 += abcA; } } else { num3 += 5; int abcC = run.GetGlyphData(hdc, fontCache).ABC.abcC; if (abcC < 0) { num3 -= abcC; } } } } else if (runWidth == 0) { if (flag2) { num2 -= 5; } else { num3 += 5; } } } if (num2 != num3) { if (num2 == 0 && prevRun != null && (prevRun.GetGlyphData(hdc, fontCache).ABC.abcC <= 0 || run.GetGlyphData(hdc, fontCache).ABC.abcA < 0)) { flag = true; } if (run.AllowColorInversion && NeedsColorInversion(color, textBox.TextBoxProps.BackgroundColor)) { color = InvertColor(textBox.TextBoxProps.BackgroundColor); } using (Brush brush = new SolidBrush(color)) { rectangle = ((!textBox.HorizontalText) ? new Rectangle?(new Rectangle(layoutRectangle.Right - offsetY, layoutRectangle.Y + x + num2, lineHeight, num3 - num2)) : new Rectangle?(new Rectangle(layoutRectangle.X + x + num2, layoutRectangle.Y + offsetY - lineHeight, num3 - num2, lineHeight))); g.FillRectangle(brush, rectangle.Value); } if (run.AllowColorInversion && NeedsColorInversion(color, run.TextRunProperties.Color)) { Color color2 = InvertColor(run.TextRunProperties.Color); num = (uint)((color2.B << 16) | (color2.G << 8) | color2.R); } } run.HighlightColor = Color.Empty; } if (runWidth > 0) { textBox.TextBoxProps.DrawTextRun(run, paragraph, hdc, dpiX, fontCache, x, offsetY, baselineY, lineHeight, layoutRectangle); if (num.HasValue) { textBox.TextBoxProps.DrawClippedTextRun(run, paragraph, hdc, dpiX, fontCache, x, offsetY, baselineY, lineHeight, layoutRectangle, num.Value, rectangle.Value); } } if (flag) { Rectangle empty = Rectangle.Empty; empty = (textBox.HorizontalText ? new Rectangle(layoutRectangle.X + x, layoutRectangle.Y + offsetY - lineHeight, prevRunWidth, lineHeight) : new Rectangle(layoutRectangle.Right - offsetY, layoutRectangle.Y + x, lineHeight, prevRunWidth)); Color color3 = prevRun.TextRunProperties.Color; if (!run.AllowColorInversion || !NeedsColorInversion(color, color3)) { num = prevRun.ColorInt; } else { color3 = InvertColor(color3); num = (uint)((color3.B << 16) | (color3.G << 8) | color3.R); } textBox.TextBoxProps.DrawClippedTextRun(prevRun, paragraph, hdc, dpiX, fontCache, prevRunX, offsetY, baselineY, lineHeight, layoutRectangle, num.Value, empty); } }
private static void RenderParagraph(TextBox textBox, Paragraph paragraph, Win32DCSafeHandle hdc, FontCache fontCache, int offsetX, ref int offsetY, Rectangle layoutRectangle, float dpiX) { List <TextLine> textLines = paragraph.TextLines; IParagraphProps paragraphProps = paragraph.ParagraphProps; bool flag = textBox.TextBoxProps.Direction == RPLFormat.Directions.LTR; RPLFormat.TextAlignments textAlignments = paragraphProps.Alignment; if (textAlignments == RPLFormat.TextAlignments.General) { textAlignments = textBox.TextBoxProps.DefaultAlignment; if (!flag) { switch (textAlignments) { case RPLFormat.TextAlignments.Right: textAlignments = RPLFormat.TextAlignments.Left; break; case RPLFormat.TextAlignments.Left: textAlignments = RPLFormat.TextAlignments.Right; break; } } } int num = ConvertToPixels(paragraphProps.LeftIndent, dpiX); int num2 = ConvertToPixels(paragraphProps.RightIndent, dpiX); int num3 = ConvertToPixels(paragraphProps.HangingIndent, dpiX); if (num3 < 0) { if (flag) { num -= num3; } else { num2 -= num3; } } if (paragraphProps.ListLevel > 0) { int num4 = paragraphProps.ListLevel * ConvertToPixels(10.583333f, dpiX); if (flag) { num += num4; } else { num2 += num4; } } if (textLines == null || textLines.Count == 0) { offsetY += ConvertToPixels(paragraphProps.SpaceBefore, dpiX); offsetY += ConvertToPixels(paragraphProps.SpaceAfter, dpiX); return; } Graphics graphics = null; try { for (int i = 0; i < textLines.Count; i++) { TextLine textLine = textLines[i]; int ascent = textLine.GetAscent(hdc, fontCache); textLine.GetDescent(hdc, fontCache); int height = textLine.GetHeight(hdc, fontCache); if (textLine.FirstLine) { offsetY += ConvertToPixels(paragraphProps.SpaceBefore, dpiX); } int baselineY = offsetY + ascent; offsetY += height; int num5 = offsetX; switch (textAlignments) { case RPLFormat.TextAlignments.Left: num5 = num; break; case RPLFormat.TextAlignments.Center: { int num6 = 0; num6 = ((!textBox.HorizontalText) ? layoutRectangle.Height : layoutRectangle.Width); num5 = num + (num6 - num - num2) / 2 - textLine.GetWidth(hdc, fontCache) / 2; break; } default: num5 = ((!textBox.HorizontalText) ? (layoutRectangle.Height - num2 - textLine.GetWidth(hdc, fontCache)) : (layoutRectangle.Width - num2 - textLine.GetWidth(hdc, fontCache))); break; } if (textLine.Prefix != null && textLine.Prefix.Count > 0) { int num7 = (!flag) ? (num5 + textLine.GetWidth(hdc, fontCache) + ConvertToPixels(4.233333f, dpiX)) : (num5 - ConvertToPixels(4.233333f, dpiX) - textLine.GetPrefixWidth(hdc, fontCache)); if (num3 < 0) { if (flag && textAlignments == RPLFormat.TextAlignments.Left) { num7 += num3; } else if (!flag && textAlignments == RPLFormat.TextAlignments.Right) { num7 -= num3; } } for (int j = 0; j < textLine.Prefix.Count; j++) { TextRun textRun = textLine.Prefix[j]; textBox.TextBoxProps.DrawTextRun(textRun, paragraph, hdc, dpiX, fontCache, num7, offsetY, baselineY, height, layoutRectangle); num7 += textRun.GetWidth(hdc, fontCache); } } if (textLine.FirstLine && num3 != 0) { if (flag) { switch (textAlignments) { case RPLFormat.TextAlignments.Left: num5 += num3; break; case RPLFormat.TextAlignments.Center: num5 += num3 / 2; break; } } else { switch (textAlignments) { case RPLFormat.TextAlignments.Right: num5 -= num3; break; case RPLFormat.TextAlignments.Center: num5 -= num3 / 2; break; } } } int prevRunWidth = 0; int prevRunX = 0; TextRun prevRun = null; int count = textLine.VisualRuns.Count; for (int k = 0; k < count; k++) { TextRun textRun2 = textLine.VisualRuns[k]; int width = textRun2.GetWidth(hdc, fontCache, k == count - 1); if (!textRun2.IsHighlightTextRun) { if (width > 0) { textBox.TextBoxProps.DrawTextRun(textRun2, paragraph, hdc, dpiX, fontCache, num5, offsetY, baselineY, height, layoutRectangle); } } else { bool flag2 = (flag && k + 1 == count) || (!flag && k == 0); if (width > 0 || flag2) { if (graphics == null) { graphics = Graphics.FromHdc(hdc.Handle); } RenderHighlightedTextRun(textBox, paragraph, textRun2, prevRun, hdc, graphics, fontCache, dpiX, num5, offsetY, baselineY, height, layoutRectangle, width, prevRunWidth, prevRunX, flag2, textLine.LastLine); } } prevRunX = num5; prevRunWidth = width; num5 += width; prevRun = textRun2; } if (textLine.LastLine) { offsetY += ConvertToPixels(paragraphProps.SpaceAfter, dpiX); } } } finally { if (graphics != null) { graphics.Dispose(); graphics = null; } } }