public static void DrawTextRun(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, int x, int baselineY, Underline underline) { uint crColor = 0u; try { uint colorInt = run.ColorInt; if (underline != null) { 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, (int[])null, glyphData.GOffsets); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } } finally { crColor = Win32.SetTextColor(hdc, crColor); } }
private void TextScriptPlace(Win32DCSafeHandle hdc, bool fontSelected, FontCache fontCache) { int num = 0; GlyphShapeData glyphScriptShapeData = this.m_cachedGlyphData.GlyphScriptShapeData; if (fontSelected) { num = Win32.ScriptPlace(hdc, ref this.m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref this.SCRIPT_ANALYSIS, this.m_cachedGlyphData.RawAdvances, this.m_cachedGlyphData.RawGOffsets, ref this.m_cachedGlyphData.ABC); } else { num = Win32.ScriptPlace(IntPtr.Zero, ref this.m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref this.SCRIPT_ANALYSIS, this.m_cachedGlyphData.RawAdvances, this.m_cachedGlyphData.RawGOffsets, ref this.m_cachedGlyphData.ABC); if (num == -2147483638) { fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont); num = Win32.ScriptPlace(hdc, ref this.m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref this.SCRIPT_ANALYSIS, this.m_cachedGlyphData.RawAdvances, this.m_cachedGlyphData.RawGOffsets, ref this.m_cachedGlyphData.ABC); } } if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } if (this.m_cachedGlyphData.ABC.Width > 0 && this.m_text.Length == 1 && TextBox.IsWhitespaceControlChar(this.m_text[0])) { this.m_cachedGlyphData.ABC.SetToZeroWidth(); } }
public TextBoxContext MapPoint(Graphics g, PointF pt, out bool atEndOfLine) { TextBoxContext textBoxContext = null; atEndOfLine = false; TextRun textRun = default(TextRun); int iX = default(int); textBoxContext = this.GetParagraphAndRunIndex(g, (int)pt.X, (int)pt.Y, out textRun, out iX, out atEndOfLine); if (textRun != null) { GlyphData glyphData = textRun.GlyphData; GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData; if (glyphData != null && textRun.CharacterCount > 0) { int num = 0; int num2 = 0; int num3 = Win32.ScriptXtoCP(iX, textRun.CharacterCount, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, glyphData.Advances, ref textRun.SCRIPT_ANALYSIS, ref num, ref num2); if (Win32.Failed(num3)) { Marshal.ThrowExceptionForHR(num3); } if (textRun.ScriptAnalysis.fLayoutRTL == 1) { if (num == -1) { textBoxContext.TextRunCharacterIndex += textRun.CharacterCount; } else if (pt.X <= 0.0) { TextBoxContext textBoxContext2 = textBoxContext; textBoxContext2.TextRunCharacterIndex = textBoxContext2.TextRunCharacterIndex; } else { textBoxContext.TextRunCharacterIndex += num + num2; } } else { textBoxContext.TextRunCharacterIndex += num + num2; } } } if (textBoxContext == null) { textBoxContext = new TextBoxContext(); } return(textBoxContext); }
private CaretInfo MapLocation(Win32DCSafeHandle hdc, TextBoxContext location, bool relativeToRun, bool moveCaretToNextLine, out TextRun run) { CaretInfo caretInfo = null; run = null; int lineYOffset = default(int); int lineHeight = default(int); int iCP = default(int); bool isFirstLine = default(bool); bool isLastLine = default(bool); Point paragraphAndRunCoordinates = this.GetParagraphAndRunCoordinates(hdc, location, moveCaretToNextLine, out lineYOffset, out lineHeight, out run, out iCP, out isFirstLine, out isLastLine); if (run != null) { GlyphData glyphData = run.GlyphData; GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData; int num = 0; if (glyphData != null && run.CharacterCount > 0) { int num2 = Win32.ScriptCPtoX(iCP, false, run.CharacterCount, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, glyphData.Advances, ref run.SCRIPT_ANALYSIS, ref num); if (Win32.Failed(num2)) { Marshal.ThrowExceptionForHR(num2); } } caretInfo = new CaretInfo(); CachedFont cachedFont = run.GetCachedFont(hdc, this.FontCache); caretInfo.Height = cachedFont.GetHeight(hdc, this.FontCache); caretInfo.Ascent = cachedFont.GetAscent(hdc, this.FontCache); caretInfo.Descent = cachedFont.GetDescent(hdc, this.FontCache); caretInfo.LineHeight = lineHeight; caretInfo.LineYOffset = lineYOffset; caretInfo.IsFirstLine = isFirstLine; caretInfo.IsLastLine = isLastLine; List <Paragraph> rTParagraph = this.RTParagraphs; int y = paragraphAndRunCoordinates.Y - caretInfo.Ascent; if (relativeToRun) { caretInfo.Position = new Point(num, y); } else { caretInfo.Position = new Point(paragraphAndRunCoordinates.X + num, y); } } return(caretInfo); }
static ScriptProperties() { IntPtr ptr = default(IntPtr); int num = default(int); int num2 = Win32.ScriptGetProperties(out ptr, out num); if (Win32.Failed(num2)) { Marshal.ThrowExceptionForHR(num2); } ScriptProperties.ScriptsProps = new ScriptProperties[num]; for (int i = 0; i < num; i++) { IntPtr ptr2 = Marshal.ReadIntPtr(ptr, i * IntPtr.Size); long value = Marshal.ReadInt64(ptr2); ScriptProperties.ScriptsProps[i] = new ScriptProperties(value); } }
public int[] GetLogicalWidths(Win32DCSafeHandle hdc, FontCache fontCache) { GlyphData glyphData = this.GetGlyphData(hdc, fontCache); int[] array = new int[this.m_text.Length]; int num = Win32.ScriptGetLogicalWidths(ref this.SCRIPT_ANALYSIS, this.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); }
public 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 { if (underline != null) { underline.Draw(hdc, (int)((double)run.UnderlineHeight * 0.085), fontColorOverride); } RECT rECT = default(RECT); rECT.left = clipRect.Left; rECT.right = clipRect.Right; rECT.top = clipRect.Top; rECT.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(rECT)); Marshal.StructureToPtr(rECT, intPtr, 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, (int[])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 void AnalyzeForBreakPositions(List <TextRun> itemRuns, string itemsText) { if (itemsText.Length != 0) { SCRIPT_ANALYSIS sCRIPT_ANALYSIS = itemRuns[0].SCRIPT_ANALYSIS; SCRIPT_LOGATTR[] array = new SCRIPT_LOGATTR[itemsText.Length]; int num = Win32.ScriptBreak(itemsText, itemsText.Length, ref sCRIPT_ANALYSIS, array); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } int num2 = 0; for (int i = 0; i < itemRuns.Count; i++) { TextRun textRun = itemRuns[i]; int length = textRun.Text.Length; SCRIPT_LOGATTR[] array2 = new SCRIPT_LOGATTR[length]; Array.Copy(array, num2, array2, 0, length); textRun.ScriptLogAttr = array2; num2 += length; } } }
public void ScriptItemize(RPLFormat.Directions direction) { SCRIPT_ITEM[] array = null; int num = 0; StringBuilder stringBuilder = new StringBuilder(); string nextTextBlock; while ((nextTextBlock = this.GetNextTextBlock()) != null) { if (nextTextBlock.Length > 0) { SCRIPT_CONTROL sCRIPT_CONTROL = default(SCRIPT_CONTROL); sCRIPT_CONTROL.dword1 = 16777216u; ScriptState scriptState = new ScriptState(); scriptState.uBidiLevel = ((direction != 0) ? 1 : 0); SCRIPT_STATE as_SCRIPT_STATE = scriptState.GetAs_SCRIPT_STATE(); SCRIPT_ITEM[] array2 = new SCRIPT_ITEM[nextTextBlock.Length + 1]; int num2 = 0; int num3 = Win32.ScriptItemize(nextTextBlock, nextTextBlock.Length, array2.Length, ref sCRIPT_CONTROL, ref as_SCRIPT_STATE, array2, ref num2); if (Win32.Failed(num3)) { Marshal.ThrowExceptionForHR(num3); } if (array == null) { array = array2; num = num2; } else { SCRIPT_ITEM[] array3 = new SCRIPT_ITEM[num + array2.Length]; Array.Copy(array, 0, array3, 0, num); for (int i = 0; i < array2.Length; i++) { SCRIPT_ITEM sCRIPT_ITEM = array2[i]; sCRIPT_ITEM.iCharPos += stringBuilder.Length; array3[num + i] = sCRIPT_ITEM; } array = array3; num += num2; } stringBuilder.Append(nextTextBlock); } } if (num > 0) { List <SCRIPT_ITEM> list = new List <SCRIPT_ITEM>(); int num4 = -1; bool flag = false; for (int j = 0; j < num; j++) { int bidiLevel = ScriptState.GetBidiLevel(array[j].analysis.state.word1); int bidiLevel2 = ScriptState.GetBidiLevel(array[j + 1].analysis.state.word1); if (bidiLevel == bidiLevel2 && this.CanMergeItemizedRuns(array[j].iCharPos, array[j + 1].iCharPos - 1, stringBuilder)) { if (num4 < 0) { num4 = j; } } else { if (num4 >= 0) { list.Add(array[num4]); } list.Add(array[j]); num4 = -1; } } if (num4 >= 0) { list.Add(array[num4]); } list.Add(array[num]); array = null; num = list.Count - 1; if (num == 1) { for (int k = 0; k < this.m_runs.Count; k++) { this.m_runs[k].SCRIPT_ANALYSIS = list[0].analysis; } Paragraph.AnalyzeForBreakPositions(this.m_runs, stringBuilder.ToString()); } else { List <TextRun> list2 = new List <TextRun>(); for (int l = 0; l < num; l++) { int iCharPos = list[l].iCharPos; int endingParaCharIndex = list[l + 1].iCharPos - 1; List <TextRun> collection = this.ExtractRuns(iCharPos, endingParaCharIndex, list[l].analysis); list2.AddRange(collection); } this.m_runs = list2; } } }
public void ShapeAndPlace(Win32DCSafeHandle hdc, FontCache fontCache) { bool verticalFont = false; if (fontCache.AllowVerticalFont) { verticalFont = this.HasEastAsianChars; } if (this.m_cachedFont == null) { this.m_cachedFont = fontCache.GetFont(this.m_textRunProps, this.GetCharset(), verticalFont); this.FallbackFont = false; } CachedFont cachedFont = this.m_cachedFont; bool flag = false; bool flag2 = false; string text = this.m_text; int num = Convert.ToInt32((double)text.Length * 1.5 + 16.0); this.m_cachedGlyphData = new GlyphData(num, text.Length); GlyphShapeData glyphScriptShapeData = this.m_cachedGlyphData.GlyphScriptShapeData; int num2 = Win32.ScriptShape(IntPtr.Zero, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); if (num2 == -2147483638) { flag = true; fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont); num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } if (num2 == -2147024882) { num = text.Length * 3; this.m_cachedGlyphData = new GlyphData(num, text.Length); glyphScriptShapeData = this.m_cachedGlyphData.GlyphScriptShapeData; num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } if (!this.FallbackFont) { if (num2 == -2147220992) { int num3 = 0; num3 = ((!this.m_itemizedScriptId.HasValue) ? this.ScriptAnalysis.eScript : this.m_itemizedScriptId.Value); this.m_cachedFont = fontCache.GetFallbackFont(this.m_textRunProps, this.GetCharset(), num3, verticalFont); fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont); flag = true; flag2 = true; num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } else if (this.HasEastAsianChars) { if (!flag) { fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont); flag = true; } Win32.SCRIPT_FONTPROPERTIES sCRIPT_FONTPROPERTIES = default(Win32.SCRIPT_FONTPROPERTIES); sCRIPT_FONTPROPERTIES.cBytes = 16; num2 = Win32.ScriptGetFontProperties(hdc, ref this.m_cachedFont.ScriptCache, ref sCRIPT_FONTPROPERTIES); short wgDefault = sCRIPT_FONTPROPERTIES.wgDefault; int num4 = 0; num4 = ((!this.m_itemizedScriptId.HasValue) ? this.ScriptAnalysis.eScript : this.m_itemizedScriptId.Value); int num5 = 0; while (num5 < glyphScriptShapeData.GlyphCount) { if (glyphScriptShapeData.Glyphs[num5] != wgDefault) { num5++; continue; } this.m_cachedFont = fontCache.GetFallbackFont(this.m_textRunProps, this.GetCharset(), num4, verticalFont); this.m_cachedFont.DefaultGlyph = wgDefault; fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont); flag = true; flag2 = true; num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); break; } } } if (num2 == -2147220992) { this.m_cachedFont = cachedFont; if (!flag || flag2) { Win32ObjectSafeHandle win32ObjectSafeHandle = Win32.SelectObject(hdc, this.m_cachedFont.Hfont); win32ObjectSafeHandle.SetHandleAsInvalid(); flag = true; } flag2 = false; this.SetUndefinedScript(); num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount); } if (Win32.Failed(num2)) { Marshal.ThrowExceptionForHR(num2); } if (flag2) { this.FallbackFont = true; } this.m_cachedGlyphData.TrimToGlyphCount(); this.m_cachedGlyphData.ScaleFactor = this.m_cachedFont.ScaleFactor; this.TextScriptPlace(hdc, flag, fontCache); }
public void ScriptLayout(Win32DCSafeHandle hdc, FontCache fontCache) { if (this.m_visualRuns == null) { int count = this.m_logicalRuns.Count; if (count != 0) { byte[] array = new byte[count]; int[] array2 = new int[count]; for (int i = 0; i < count; i++) { array[i] = (byte)this.m_logicalRuns[i].ScriptAnalysis.s.uBidiLevel; } int num = Win32.ScriptLayout(count, array, null, array2); if (Win32.Failed(num)) { Marshal.ThrowExceptionForHR(num); } this.m_visualRuns = new List <TextRun>(count); for (int j = 0; j < count; j++) { this.m_visualRuns.Add(null); } for (int k = 0; k < count; k++) { this.m_visualRuns[array2[k]] = this.m_logicalRuns[k]; } int num2 = 0; int l = -1; for (int m = 0; m < count; m++) { TextRun textRun = this.m_visualRuns[m]; textRun.UnderlineHeight = 0; if (textRun.TextRunProperties.TextDecoration == RPLFormat.TextDecorations.Underline) { if (l < 0) { l = m; } int height = textRun.GetHeight(hdc, fontCache); if (height > num2) { num2 = height; } } else if (l >= 0) { for (; l < m; l++) { this.m_visualRuns[l].UnderlineHeight = num2; } num2 = 0; l = -1; } } if (l >= 0) { for (; l < count; l++) { this.m_visualRuns[l].UnderlineHeight = num2; } } } } }