void PerformHorizontalFlowArrange( int ownerClientLeft, int ownerClientWidth, int ownerClientTop) { if (lineCollection == null) { return; } if ((layerFlags & FLOWLAYER_HAS_MULTILINE) != 0) { PerformHorizontalFlowArrangeForMultilineText(ownerClientLeft, ownerClientWidth, ownerClientTop); return; } int ownerClientRight = ownerClientLeft + ownerClientWidth; int default_line_height = EditableTextLine.DEFAULT_LINE_HEIGHT; int curX = 0; int curY = 0; bool lastestIsBlock = false; int maxHeightInRow = 2; int maxWidth = 0; int curY_fromTop = ownerClientTop; #if DEBUG long startTick = DateTime.Now.Ticks; #endif FlowReLocator flowRelocator = FlowReLocator.GetNewFlowRelocator(); flowRelocator.Load(this); EditableRun lastNotNullElement = null; int childCount = 0; while (flowRelocator.ReadNextRun()) { EditableRun currentRun = flowRelocator.CurrentRun; if (currentRun != null) { lastNotNullElement = currentRun; childCount++; #if DEBUG vinv_dbug_BeginSetElementBound(currentRun); #endif int v_desired_width = currentRun.Width; int v_desired_height = currentRun.Height; if (lastestIsBlock || currentRun.IsBlockElement || (curX + v_desired_width > ownerClientRight)) { if (!flowRelocator.IsFirstRunOfLine) { flowRelocator.CloseCurrentLine(curX, maxHeightInRow); if (maxWidth < curX) { maxWidth = curX; } curY = curY_fromTop + maxHeightInRow; curY_fromTop = curY; maxHeightInRow = default_line_height; flowRelocator.SetCurrentLineTop(curY); } curX = ownerClientLeft; flowRelocator.Accept(); lastestIsBlock = currentRun.IsBlockElement; if (v_desired_height > maxHeightInRow) { maxHeightInRow = v_desired_height; } EditableRun.DirectSetLocation(currentRun, curX, 0); if (lastestIsBlock) { v_desired_width = flowRelocator.OwnerElementWidth; } EditableRun.DirectSetSize(currentRun, v_desired_width, v_desired_height); curX += v_desired_width; } else { flowRelocator.Accept(); lastestIsBlock = currentRun.IsBlockElement; if (v_desired_height > maxHeightInRow) { maxHeightInRow = v_desired_height; } EditableRun.DirectSetLocation(currentRun, curX, 0); EditableRun.DirectSetSize( currentRun, v_desired_width, v_desired_height); curX += v_desired_width; } #if DEBUG vinv_dbug_EndSetElementBound(currentRun); #endif } else { switch (flowRelocator.FeederState) { case 1: { if (maxWidth < curX) { maxWidth = curX; } flowRelocator.CloseCurrentLineWithLineBreak(curX, maxHeightInRow); curX = ownerClientLeft; curY = curY_fromTop + maxHeightInRow; curY_fromTop = curY; maxHeightInRow = default_line_height; flowRelocator.SetCurrentLineTop(curY); } break; case 4: { if (maxWidth < curX) { maxWidth = curX; } flowRelocator.SetCurrentLineSize(curX, maxHeightInRow); curX = ownerClientLeft; } break; } } } if (curX > maxWidth) { maxWidth = curX; } int finalHeight = curY_fromTop + maxHeightInRow; ValidateArrangement(); FlowReLocator.FreeFlowRelocator(flowRelocator); }
void PerformHorizontalFlowArrangeForMultilineText( int ownerClientLeft, int ownerClientWidth, int ownerClientTop) { #if DEBUG long startTick = DateTime.Now.Ticks; #endif List <EditableTextLine> lines = (List <EditableTextLine>) this.lineCollection; int ownerClientRight = ownerClientLeft + ownerClientWidth; int curX = 0; int curY = 0; bool lastestIsBlock = false; int maxWidth = 0; int curY_fromTop = ownerClientTop; int maxHeightInRow = EditableTextLine.DEFAULT_LINE_HEIGHT; int lineCount = lines.Count; for (int i = 0; i < lineCount; ++i) { EditableTextLine line = lines[i]; curX = ownerClientLeft; lastestIsBlock = false; line.SetTop(curY_fromTop); if (!line.NeedArrange) { maxHeightInRow = line.ActualLineHeight; if (line.ActualLineWidth > maxWidth) { maxWidth = line.ActualLineWidth; } } else { maxHeightInRow = EditableTextLine.DEFAULT_LINE_HEIGHT; EditableTextLine newLine = null; line.ValidateContentArrangement(); bool isFirstRunInThisLine = true; foreach (EditableRun currentRun in line) { #if DEBUG vinv_dbug_BeginSetElementBound(currentRun); #endif int v_desired_width = currentRun.Width; int v_desired_height = currentRun.Height; if (isFirstRunInThisLine) { lastestIsBlock = currentRun.IsBlockElement; if (v_desired_height > maxHeightInRow) { maxHeightInRow = v_desired_height; } EditableRun.DirectSetLocation(currentRun, curX, 0); if (v_desired_height > maxHeightInRow) { maxHeightInRow = v_desired_height; } if (lastestIsBlock) { v_desired_width = ownerClientWidth; } EditableRun.DirectSetSize(currentRun, v_desired_width, v_desired_height); currentRun.MarkValidContentArrangement(); curX += v_desired_width; isFirstRunInThisLine = false; } else { if (lastestIsBlock || currentRun.IsBlockElement || (curX + v_desired_width > ownerClientRight)) { newLine = new EditableTextLine(this); newLine.AddLast(currentRun); curY = curY_fromTop + maxHeightInRow; curY_fromTop = curY; maxHeightInRow = EditableTextLine.DEFAULT_LINE_HEIGHT; EditableRun nextR = currentRun.NextTextRun; while (nextR != null) { line.UnsafeRemoveVisualElement(nextR); newLine.AddLast(nextR); nextR = nextR.NextTextRun; } if (i + 1 == lineCount) { lines.Add(newLine); } else { lines.Insert(i + 1, newLine); } lineCount++; break; } else { lastestIsBlock = currentRun.IsBlockElement; if (v_desired_height > maxHeightInRow) { maxHeightInRow = v_desired_height; } EditableRun.DirectSetLocation(currentRun, curX, 0); EditableRun.DirectSetSize(currentRun, v_desired_width, v_desired_height); currentRun.MarkValidContentArrangement(); curX += v_desired_width; } } #if DEBUG vinv_dbug_EndSetElementBound(currentRun); #endif } if (curX > maxWidth) { maxWidth = curX; } } line.SetPostArrangeLineSize(maxWidth, maxHeightInRow); curY = curY_fromTop + maxHeightInRow; curY_fromTop = curY; } ValidateArrangement(); }