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); } }
internal void TerminateAt(int index) { m_text = m_text.Remove(index, m_text.Length - index); SCRIPT_LOGATTR[] array = new SCRIPT_LOGATTR[index]; Array.Copy(ScriptLogAttr, 0, array, 0, array.Length); ScriptLogAttr = array; m_cachedGlyphData = null; }
internal TextRun(string text, ITextRunProps props, TexRunShapeData shapeData) : this(text, props) { if (shapeData != null) { SCRIPT_ANALYSIS = shapeData.Analysis; ScriptLogAttr = shapeData.ScriptLogAttr; m_cachedFont = shapeData.Font; m_itemizedScriptId = shapeData.ItemizedScriptId; m_runState = shapeData.State; if (shapeData.GlyphData != null) { m_cachedGlyphData = new GlyphData(shapeData.GlyphData); } } }
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 TextBoxContext MapPoint(Graphics g, PointF pt, out bool atEndOfLine) { TextBoxContext textBoxContext = null; atEndOfLine = false; textBoxContext = GetParagraphAndRunIndex(g, (int)pt.X, (int)pt.Y, out TextRun run, out int runX, out atEndOfLine); if (run != null) { GlyphData glyphData = run.GlyphData; GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData; if (glyphData != null && run.CharacterCount > 0) { int piCP = 0; int piTrailing = 0; int num = Win32.ScriptXtoCP(runX, run.CharacterCount, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, glyphData.Advances, ref run.SCRIPT_ANALYSIS, ref piCP, ref piTrailing); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } if (run.ScriptAnalysis.fLayoutRTL == 1) { if (piCP == -1) { textBoxContext.TextRunCharacterIndex += run.CharacterCount; } else if (pt.X <= 0f) { TextBoxContext textBoxContext2 = textBoxContext; textBoxContext2.TextRunCharacterIndex = textBoxContext2.TextRunCharacterIndex; } else { textBoxContext.TextRunCharacterIndex += piCP + piTrailing; } } else { textBoxContext.TextRunCharacterIndex += piCP + piTrailing; } } } if (textBoxContext == null) { textBoxContext = new TextBoxContext(); } return(textBoxContext); }
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 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 void ShapeAndPlace(Win32DCSafeHandle hdc, FontCache fontCache) { bool verticalFont = false; if (fontCache.AllowVerticalFont) { verticalFont = HasEastAsianChars; } if (m_cachedFont == null) { m_cachedFont = fontCache.GetFont(m_textRunProps, GetCharset(), verticalFont); FallbackFont = false; } CachedFont cachedFont = m_cachedFont; bool flag = false; bool flag2 = false; string text = m_text; int num = Convert.ToInt32((double)text.Length * 1.5 + 16.0); m_cachedGlyphData = new GlyphData(num, text.Length); GlyphShapeData glyphScriptShapeData = m_cachedGlyphData.GlyphScriptShapeData; int num2 = Win32.ScriptShape(IntPtr.Zero, ref m_cachedFont.ScriptCache, text, text.Length, num, ref SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); if (num2 == -2147483638) { flag = true; fontCache.SelectFontObject(hdc, m_cachedFont.Hfont); num2 = Win32.ScriptShape(hdc, ref m_cachedFont.ScriptCache, text, text.Length, num, ref SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } if (num2 == -2147024882) { num = text.Length * 3; m_cachedGlyphData = new GlyphData(num, text.Length); glyphScriptShapeData = m_cachedGlyphData.GlyphScriptShapeData; num2 = Win32.ScriptShape(hdc, ref m_cachedFont.ScriptCache, text, text.Length, num, ref SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } if (!FallbackFont) { if (num2 == -2147220992) { int num3 = 0; m_cachedFont = fontCache.GetFallbackFont(script: (!m_itemizedScriptId.HasValue) ? ScriptAnalysis.eScript : m_itemizedScriptId.Value, textRunProps: m_textRunProps, charset: GetCharset(), verticalFont: verticalFont); fontCache.SelectFontObject(hdc, m_cachedFont.Hfont); flag = true; flag2 = true; num2 = Win32.ScriptShape(hdc, ref m_cachedFont.ScriptCache, text, text.Length, num, ref SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } else if (HasEastAsianChars) { if (!flag) { fontCache.SelectFontObject(hdc, m_cachedFont.Hfont); flag = true; } Win32.SCRIPT_FONTPROPERTIES sfp = default(Win32.SCRIPT_FONTPROPERTIES); sfp.cBytes = 16; num2 = Win32.ScriptGetFontProperties(hdc, ref m_cachedFont.ScriptCache, ref sfp); short wgDefault = sfp.wgDefault; int num4 = 0; num4 = ((!m_itemizedScriptId.HasValue) ? ScriptAnalysis.eScript : m_itemizedScriptId.Value); for (int i = 0; i < glyphScriptShapeData.GlyphCount; i++) { if (glyphScriptShapeData.Glyphs[i] == wgDefault) { m_cachedFont = fontCache.GetFallbackFont(m_textRunProps, GetCharset(), num4, verticalFont); m_cachedFont.DefaultGlyph = wgDefault; fontCache.SelectFontObject(hdc, m_cachedFont.Hfont); flag = true; flag2 = true; num2 = Win32.ScriptShape(hdc, ref m_cachedFont.ScriptCache, text, text.Length, num, ref SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); break; } } } } if (num2 == -2147220992) { m_cachedFont = cachedFont; if (!flag || flag2) { Win32.SelectObject(hdc, m_cachedFont.Hfont).SetHandleAsInvalid(); flag = true; } flag2 = false; SetUndefinedScript(); num2 = Win32.ScriptShape(hdc, ref m_cachedFont.ScriptCache, text, text.Length, num, ref SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } if (Win32.Failed(num2)) { Marshal.ThrowExceptionForHR(num2); } if (flag2) { FallbackFont = true; } m_cachedGlyphData.TrimToGlyphCount(); m_cachedGlyphData.ScaleFactor = m_cachedFont.ScaleFactor; TextScriptPlace(hdc, flag, fontCache); }