private static bool FlowParagraph(Paragraph paragraph, RPLFormat.Directions direction, Win32DCSafeHandle hdc, float dpiX, FontCache fontCache, FlowContext flowContext, bool keepLines, SizeF flowContextSize, ref int contentOffset) { List <TextLine> list = new List <TextLine>(); TextBoxContext context = flowContext.Context; int num = paragraph.OffsetY; paragraph.ProcessedEmptyParagraph = false; bool flag = false; IParagraphProps paragraphProps = paragraph.ParagraphProps; if (!flowContext.Updatable || !paragraph.Updated) { flag = (context.TextRunIndex == 0 && context.TextRunCharacterIndex == 0); } if (flag) { num += TextBox.ConvertToPixels(paragraphProps.SpaceBefore, dpiX); if ((float)num >= flowContextSize.Height) { paragraph.Height = num - paragraph.OffsetY; return(false); } } int num2 = contentOffset; float leftIndent = 0f; float rightIndent = 0f; float hangingIndent = 0f; paragraph.GetParagraphIndents(direction, dpiX, out leftIndent, out rightIndent, out hangingIndent); Stack <int> stack = null; Stack <int> stack2 = null; TextLine textLine = null; while (true) { float num3 = leftIndent; float num4 = rightIndent; if (flag) { if (direction == RPLFormat.Directions.LTR) { num3 += hangingIndent; } else { num4 += hangingIndent; } } stack = new Stack <int>(); stack2 = new Stack <int>(); textLine = new TextLine(); if (flag) { textLine.Prefix = CreateLinePrefix(paragraph, direction); textLine.FirstLine = true; } if (!GetLine(paragraph, textLine, hdc, fontCache, flowContext, num3, flowContextSize.Width - num4, flowContextSize.Height - (float)num, stack, stack2, (int)(num3 + num4))) { if (list.Count > 0) { list[list.Count - 1].LastLine = true; } num += TextBox.ConvertToPixels(paragraphProps.SpaceAfter, dpiX); break; } if (keepLines) { textLine.ScriptLayout(hdc, fontCache); } num += textLine.GetHeight(hdc, fontCache); list.Add(textLine); num2 = num; if ((float)num >= flowContextSize.Height) { break; } flag = false; } paragraph.Height = num - paragraph.OffsetY; if ((float)num > flowContextSize.Height) { if (list.Count > 0 && (float)num2 > flowContextSize.Height) { TextLine textLine2 = list[list.Count - 1]; int textRunIndex = 0; int textRunCharacterIndex = 0; while (stack.Count > 0) { textRunIndex = stack.Pop(); } while (stack2.Count > 0) { textRunCharacterIndex = stack2.Pop(); } if (flowContext.LineLimit) { context.TextRunIndex = textRunIndex; context.TextRunCharacterIndex = textRunCharacterIndex; list.RemoveAt(list.Count - 1); flowContext.OmittedLineHeight = TextBox.ConvertToMillimeters(textLine2.GetHeight(hdc, fontCache), dpiX); if (textLine2.FirstLine) { num2 -= TextBox.ConvertToPixels(paragraphProps.SpaceBefore, dpiX); } } else { TextBoxContext textBoxContext = context.Clone(); textBoxContext.TextRunIndex = textRunIndex; textBoxContext.TextRunCharacterIndex = textRunCharacterIndex; flowContext.ClipContext = textBoxContext; } num2 -= textLine2.GetHeight(hdc, fontCache); } paragraph.AdvanceToNextRun(context, skipEmptyRuns: false); paragraph.AdvanceToNextRun(flowContext.ClipContext, skipEmptyRuns: false); if (list.Count > 0) { if (flowContext.ClipContext == null && paragraph.AtEndOfParagraph(context)) { contentOffset = num; } else { contentOffset = num2; } paragraph.TextLines = list; return(true); } paragraph.TextLines = null; if (paragraph.AtEndOfParagraph(context)) { contentOffset = num; } return(false); } paragraph.AdvanceToNextRun(context); paragraph.TextLines = list; contentOffset = num; return(true); }
internal static List <Paragraph> Flow(TextBox textBox, Win32DCSafeHandle hdc, float dpiX, FontCache fontCache, FlowContext flowContext, bool keepLines, out float height) { if (flowContext.Height <= 0f || flowContext.Width <= 0f) { height = 0f; return(null); } int num = TextBox.ConvertToPixels(flowContext.ContentOffset, dpiX); int contentOffset = num; TextBoxContext context = flowContext.Context; RPLFormat.Directions direction = textBox.TextBoxProps.Direction; List <Paragraph> list = new List <Paragraph>(); Win32ObjectSafeHandle win32ObjectSafeHandle = Win32.SelectObject(hdc, Win32ObjectSafeHandle.Zero); SizeF flowContextSize; if (!textBox.VerticalText) { flowContextSize = new SizeF(TextBox.ConvertToPixels(flowContext.Width, dpiX), TextBox.ConvertToPixels(flowContext.Height, dpiX)); } else { flowContext.VerticalCanGrow = textBox.TextBoxProps.CanGrow; flowContextSize = new SizeF(TextBox.ConvertToPixels(flowContext.Height, dpiX), TextBox.ConvertToPixels(flowContext.Width, dpiX)); } fontCache.WritingMode = textBox.TextBoxProps.WritingMode; try { while (context.ParagraphIndex < textBox.Paragraphs.Count) { Paragraph paragraph = textBox.Paragraphs[context.ParagraphIndex]; paragraph.OffsetY = num; bool num2 = FlowParagraph(paragraph, direction, hdc, dpiX, fontCache, flowContext, keepLines, flowContextSize, ref contentOffset); num += paragraph.Height; if (!keepLines) { paragraph.TextLines = null; } if (!num2) { break; } list.Add(paragraph); if ((float)num >= flowContextSize.Height) { if (paragraph.AtEndOfParagraph(context)) { context.IncrementParagraph(); } break; } context.IncrementParagraph(); } if ((float)num < flowContextSize.Height) { flowContext.AtEndOfTextBox = true; } } finally { if (!win32ObjectSafeHandle.IsInvalid) { Win32.SelectObject(hdc, win32ObjectSafeHandle).SetHandleAsInvalid(); win32ObjectSafeHandle.SetHandleAsInvalid(); } } height = TextBox.ConvertToMillimeters(num, dpiX); flowContext.ContentOffset = TextBox.ConvertToMillimeters(contentOffset, dpiX); return(list); }
internal static float FlowVertical(TextBox textBox, Graphics g, FontCache fontCache, FlowContext flowContext, out float width, out float nextWidth) { width = (nextWidth = 0f); List <Paragraph> list = null; int num = 0; int val = int.MaxValue; int num2 = 0; float height = 0f; int num3 = 0; List <TextLine> list2 = null; float dpiX = g.DpiX; Win32DCSafeHandle win32DCSafeHandle = new Win32DCSafeHandle(g.GetHdc(), ownsHandle: false); if (textBox.VerticalText) { flowContext.VerticalCanGrow = textBox.TextBoxProps.CanGrow; num3 = TextBox.ConvertToPixels(flowContext.Height, dpiX); } else { num3 = TextBox.ConvertToPixels(flowContext.Width, dpiX); } try { list = Flow(textBox, win32DCSafeHandle, dpiX, fontCache, flowContext, keepLines: true, out height); if (list != null) { for (int i = 0; i < list.Count; i++) { list2 = list[i].TextLines; if (list2 != null) { float leftIndent = 0f; float rightIndent = 0f; float hangingIndent = 0f; float num4 = 0f; RPLFormat.Directions direction = textBox.TextBoxProps.Direction; list[i].GetParagraphIndents(direction, dpiX, out leftIndent, out rightIndent, out hangingIndent); num4 = leftIndent + rightIndent; if (list2[0].FirstLine) { num4 += hangingIndent; } num2 = Math.Max(num2, (int)num4); for (int j = 0; j < list2.Count; j++) { num = Math.Max(num, list2[j].GetWidth(win32DCSafeHandle, fontCache, useVisualRunsIfAvailable: false) + (int)num4); val = Math.Min(val, list2[j].GetWidth(win32DCSafeHandle, fontCache, useVisualRunsIfAvailable: false) + (int)num4); } list[i].TextLines = null; } } } val = Math.Max(val, num2); if (num > 0) { int num5 = 0; if (flowContext.VerticalCanGrow && flowContext.ForcedCharTrim) { num5 = flowContext.CharTrimmedRunWidth; } else { num5 = (num - val) / 2; if (num5 == 0) { num5 = num / 2; } else { num5 += val; if (num5 >= num3) { num5 /= 2; } } } width = TextBox.ConvertToMillimeters(num, dpiX); nextWidth = TextBox.ConvertToMillimeters(num5, dpiX); return(height); } return(height); } finally { fontCache.ResetGraphics(); if (!win32DCSafeHandle.IsInvalid) { g.ReleaseHdc(); } } }