void JoinWithNextLine() { if (IsLastLine) { return; } // TextLineBox lowerLine = _textFlowLayer.GetTextLine(_currentLineNumber + 1); this.LocalSuspendLineReArrange(); int cx = 0; Run lastTextRun = this.LastRun; if (lastTextRun != null) { cx = lastTextRun.Right; } foreach (Run r in lowerLine._runs) { this.AddLast(r); Run.DirectSetLocation(r, cx, 0); cx += r.Width; } this.LocalResumeLineReArrange(); this.EndWithLineBreak = lowerLine.EndWithLineBreak; _textFlowLayer.Remove(lowerLine._currentLineNumber); }
public void AddLineBreakAfter(Run afterTextRun) { if (afterTextRun == null) { this.EndWithLineBreak = true; TextLineBox newline = _textFlowLayer.InsertNewLine(_currentLineNumber + 1); // if (_textFlowLayer.LineCount - 1 != newline.LineNumber) { newline.EndWithLineBreak = true; } } else if (afterTextRun.NextRun == null) { this.EndWithLineBreak = true; TextLineBox newline = _textFlowLayer.InsertNewLine(_currentLineNumber + 1); // if (_textFlowLayer.LineCount - 1 != newline.LineNumber) { newline.EndWithLineBreak = true; } } else { using (RunListPool.Borrow(out List <Run> tempTextRuns)) { if (afterTextRun != null) { foreach (Run t in GetRunIterForward(afterTextRun.NextRun)) { tempTextRuns.Add(t); } } bool thisEndWithLineBreak = this.EndWithLineBreak; this.EndWithLineBreak = true; this.LocalSuspendLineReArrange(); TextLineBox newTextline = _textFlowLayer.InsertNewLine(_currentLineNumber + 1); newTextline.EndWithLineBreak = thisEndWithLineBreak; // int j = tempTextRuns.Count; newTextline.LocalSuspendLineReArrange(); int cx = 0; for (int i = 0; i < j; ++i) { Run t = tempTextRuns[i]; this.Remove(t); newTextline.AddLast(t); Run.DirectSetLocation(t, cx, 0); cx += t.Width; } newTextline.LocalResumeLineReArrange(); this.LocalResumeLineReArrange(); } } }
public TempTextLineCopyContext(TextLineBox textline, out Typography.Text.TextBufferSpan buffSpan) { _tempStBuilder = StringBuilderPool <StringBuilderPoolOwner> .GetFreeStringBuilder(); textline.CopyLineContent(_tempStBuilder); int len = _tempStBuilder.Length; char[] charBuffer = new char[len]; _tempStBuilder.CopyTo(0, charBuffer, 0, len); buffSpan = new Typography.Text.TextBufferSpan(charBuffer); }
public void MoveToLine(int lineNumber) { _currentLine = _textFlowLayer.GetTextLine(lineNumber); _currentLineY = _currentLine.Top; //if current line is a blank line //not first run => currentTextRun= null _currentTextRun = _currentLine.FirstRun; _rCharOffset = 0; _rPixelOffset = 0; caret_char_index = 0; _caretXPos = 0; }
public TextFlowWalkerBase(TextFlowLayer flowlayer) { #if DEBUG this.dbug_MyId = dbugTotalId; dbugTotalId++; #endif _textFlowLayer = flowlayer; //flowlayer.Reflow += flowlayer_Reflow; _currentLine = flowlayer.GetTextLine(0); if (_currentLine.FirstRun != null) { _currentTextRun = _currentLine.FirstRun; } }
public VisualPointInfo FindTextRunOnPosition(int x, int y) { if (y < 0) { return(null); } else { int j = _lineEditor.LineCount; if (j > 0) { TextLineBox textLine = _lineEditor.GetTextLineAtPos(y); if (textLine != null) { return(textLine.GetTextPointInfoFromCaretPoint(x)); } } return(null); } }
public Rectangle dbugGetRectAreaOf(int beginlineNum, int beginColumnNum, int endLineNum, int endColumnNum) { TextFlowLayer flowLayer = _textLayer; TextLineBox beginLine = flowLayer.GetTextLineAtPos(beginlineNum); if (beginLine == null) { return(Rectangle.Empty); } if (beginlineNum == endLineNum) { VisualPointInfo beginPoint = beginLine.GetTextPointInfoFromCharIndex(beginColumnNum); VisualPointInfo endPoint = beginLine.GetTextPointInfoFromCharIndex(endColumnNum); return(new Rectangle(beginPoint.X, beginLine.Top, endPoint.X, beginLine.ActualLineHeight)); } else { VisualPointInfo beginPoint = beginLine.GetTextPointInfoFromCharIndex(beginColumnNum); TextLineBox endLine = flowLayer.GetTextLineAtPos(endLineNum); VisualPointInfo endPoint = endLine.GetTextPointInfoFromCharIndex(endColumnNum); return(new Rectangle(beginPoint.X, beginLine.Top, endPoint.X, beginLine.ActualLineHeight)); } }
void AddLineBreakBefore(Run beforeTextRun) { if (beforeTextRun == null) { this.EndWithLineBreak = true; _textFlowLayer.InsertNewLine(_currentLineNumber + 1); } else { //TODO: use pool using (RunListPool.Borrow(out List <Run> tempTextRuns)) { if (beforeTextRun != null) { foreach (Run t in GetRunIterForward(beforeTextRun)) { tempTextRuns.Add(t); } } this.EndWithLineBreak = true; TextLineBox newTextline = _textFlowLayer.InsertNewLine(_currentLineNumber + 1); // this.LocalSuspendLineReArrange(); newTextline.LocalSuspendLineReArrange(); int j = tempTextRuns.Count; for (int i = 0; i < j; ++i) { Run t = tempTextRuns[i]; this.Remove(t); newTextline.AddLast(t); } this.LocalResumeLineReArrange(); newTextline.LocalResumeLineReArrange(); } } }
public void Copy(VisualSelectionRange selectionRange, TextRangeCopy output) { EditableVisualPointInfo startPoint = selectionRange.StartPoint; EditableVisualPointInfo endPoint = selectionRange.EndPoint; if (startPoint.Run != null) { if (startPoint.Run == endPoint.Run) { CopyRun elem = startPoint.Run.Copy( startPoint.RunLocalSelectedIndex, endPoint.LineCharIndex - startPoint.LineCharIndex); if (elem != null) { output.AppendRun(elem); } } else { GetStartAndStopLine(startPoint, endPoint, out TextLineBox startLine, out TextLineBox stopLine); if (startLine == stopLine) { CopyRun rightPart = startPoint.Run.Copy(startPoint.RunLocalSelectedIndex); if (rightPart != null) { output.AppendRun(rightPart); } if (startPoint.Run.NextRun != endPoint.Run) { foreach (Run run in _textFlowLayer.TextRunForward( startPoint.Run.NextRun, endPoint.Run.PrevRun)) { output.AppendRun(run); } } CopyRun leftPart = endPoint.Run.LeftCopy(endPoint.RunLocalSelectedIndex); if (leftPart != null) { output.AppendRun(leftPart); } } else { int startLineId = startPoint.LineId; int stopLineId = endPoint.LineId; startLine.RightCopy(startPoint, output); for (int i = startLineId + 1; i < stopLineId; i++) { //begine new line output.AppendNewLine(); TextLineBox line = _textFlowLayer.GetTextLine(i); line.Copy(output); } if (endPoint.LineCharIndex > -1) { output.AppendNewLine(); stopLine.LeftCopy(endPoint, output); } } } } else { GetStartAndStopLine(startPoint, endPoint, out TextLineBox startLine, out TextLineBox stopLine); if (startLine == stopLine) { if (startPoint.LineCharIndex == -1) { foreach (Run t in _textFlowLayer.TextRunForward( startPoint.Run, endPoint.Run.PrevRun)) { output.AppendRun(t); } CopyRun postCutTextRun = endPoint.Run.Copy(endPoint.RunLocalSelectedIndex + 1); if (postCutTextRun != null) { output.AppendRun(postCutTextRun); } } else { CopyRun rightPart = startPoint.Run.Copy(startPoint.RunLocalSelectedIndex + 1); if (rightPart != null) { output.AppendRun(rightPart); } foreach (Run t in _textFlowLayer.TextRunForward( startPoint.Run.NextRun, endPoint.Run.PrevRun)) { output.AppendRun(t.CreateCopy()); } CopyRun leftPart = endPoint.Run.LeftCopy(startPoint.RunLocalSelectedIndex); if (leftPart != null) { output.AppendRun(leftPart); } } } else { int startLineId = startPoint.LineId; int stopLineId = endPoint.LineId; startLine.RightCopy(startPoint, output); for (int i = startLineId + 1; i < stopLineId; i++) { output.AppendNewLine(); TextLineBox line = _textFlowLayer.GetTextLine(i); line.Copy(output); } stopLine.LeftCopy(endPoint, output); } } }
void GetStartAndStopLine(EditableVisualPointInfo startPoint, EditableVisualPointInfo endPoint, out TextLineBox startLine, out TextLineBox stopLine) { startLine = (startPoint.LineId == _currentLineNumber) ? this : _textFlowLayer.GetTextLine(startPoint.LineId); stopLine = (endPoint.LineId == _currentLineNumber) ? this : _textFlowLayer.GetTextLine(endPoint.LineId); }
internal SelectionRangeInfo Split(VisualSelectionRange selectionRange) { selectionRange.SwapIfUnOrder(); EditableVisualPointInfo startPoint = selectionRange.StartPoint; EditableVisualPointInfo endPoint = selectionRange.EndPoint; if (startPoint.Run == endPoint.Run) { Run toBeCutTextRun = startPoint.Run; CopyRun leftPart = toBeCutTextRun.LeftCopy(startPoint.RunLocalSelectedIndex); CopyRun middlePart = toBeCutTextRun.Copy(startPoint.RunLocalSelectedIndex, endPoint.LineCharIndex - startPoint.LineCharIndex); CopyRun rightPart = toBeCutTextRun.Copy(endPoint.RunLocalSelectedIndex); EditableVisualPointInfo newStartRangePointInfo = null; EditableVisualPointInfo newEndRangePointInfo = null; TextLineBox line = this; if (startPoint.LineId != _currentLineNumber) { line = _textFlowLayer.GetTextLine(startPoint.LineId); } line.LocalSuspendLineReArrange(); if (leftPart != null) { Run leftRun = line.AddBefore(toBeCutTextRun, leftPart); newStartRangePointInfo = CreateTextPointInfo( startPoint.LineId, startPoint.LineCharIndex, startPoint.X, leftRun, startPoint.TextRunCharOffset, startPoint.TextRunPixelOffset); } else { //no left part, //so we connect to prev text run Run prevTxtRun = startPoint.Run.PrevRun; if (prevTxtRun != null) { newStartRangePointInfo = CreateTextPointInfo( startPoint.LineId, startPoint.LineCharIndex, startPoint.X, prevTxtRun, startPoint.TextRunCharOffset - leftPart.CharacterCount, startPoint.TextRunPixelOffset - prevTxtRun.Width); } else { //no prev run, we are at the begining of the line newStartRangePointInfo = CreateTextPointInfo( startPoint.LineId, startPoint.LineCharIndex, 0, null, 0, 0); } } if (rightPart != null) { Run rightRun = line.AddAfter(toBeCutTextRun, rightPart); newEndRangePointInfo = CreateTextPointInfo( endPoint.LineId, endPoint.LineCharIndex, endPoint.X, null, ///?? startPoint.TextRunCharOffset + middlePart.CharacterCount, startPoint.TextRunPixelOffset + MeasureCopyRunLength(middlePart).Width); } else { Run nextTxtRun = endPoint.Run.NextRun; if (nextTxtRun != null) { newEndRangePointInfo = CreateTextPointInfo( endPoint.LineId, endPoint.LineCharIndex, endPoint.X, null, ///?? endPoint.TextRunPixelOffset + endPoint.Run.CharacterCount, endPoint.TextRunPixelOffset + endPoint.Run.Width); } else { newEndRangePointInfo = CreateTextPointInfo( endPoint.LineId, endPoint.LineCharIndex, endPoint.X, null, endPoint.TextRunCharOffset, endPoint.TextRunPixelOffset); } } if (middlePart != null) { line.AddAfter(toBeCutTextRun, middlePart); } else { throw new NotSupportedException(); } line.Remove(toBeCutTextRun); line.LocalResumeLineReArrange(); return(new SelectionRangeInfo(newStartRangePointInfo, newEndRangePointInfo)); } else { TextLineBox workingLine = this; if (startPoint.LineId != _currentLineNumber) { workingLine = _textFlowLayer.GetTextLine(startPoint.LineId); } EditableVisualPointInfo newStartPoint = workingLine.Split(startPoint); workingLine = this; if (endPoint.LineId != _currentLineNumber) { workingLine = _textFlowLayer.GetTextLine(endPoint.LineId); } EditableVisualPointInfo newEndPoint = workingLine.Split(endPoint); return(new SelectionRangeInfo(newStartPoint, newEndPoint)); } }
internal void Remove(VisualSelectionRange selectionRange) { EditableVisualPointInfo startPoint = selectionRange.StartPoint; EditableVisualPointInfo endPoint = selectionRange.EndPoint; if (startPoint.Run != null) { if (startPoint.Run == endPoint.Run) { Run removedRun = startPoint.Run; Run.InnerRemove(removedRun, startPoint.RunLocalSelectedIndex, endPoint.LineCharIndex - startPoint.LineCharIndex, false); if (removedRun.CharacterCount == 0) { if (startPoint.LineId == _currentLineNumber) { this.Remove(removedRun); } else { TextLineBox line = _textFlowLayer.GetTextLine(startPoint.LineId); line.Remove(removedRun); } } } else { GetStartAndStopLine(startPoint, endPoint, out TextLineBox startLine, out TextLineBox stopLine); EditableVisualPointInfo newStartPoint = startLine.Split(startPoint); EditableVisualPointInfo newStopPoint = stopLine.Split(endPoint); if (startLine == stopLine) { if (newStartPoint.Run != null) { LinkedList <Run> tobeRemoveRuns = new LinkedList <Run>(); if (newStartPoint.LineCharIndex == 0) { foreach (Run t in _textFlowLayer.TextRunForward( newStartPoint.Run, newStopPoint.Run)) { tobeRemoveRuns.AddLast(t); } } else { foreach (Run t in _textFlowLayer.TextRunForward( newStartPoint.Run.NextRun, newStopPoint.Run)) { tobeRemoveRuns.AddLast(t); } } startLine.LocalSuspendLineReArrange(); foreach (Run t in tobeRemoveRuns) { startLine.Remove(t); } startLine.LocalResumeLineReArrange(); } else { //this may be the blank line startLine.Clear(); #if DEBUG //TODO: review here again //System.Diagnostics.Debug.WriteLine("EditableTextLine_adv1"); #endif } } else { int startLineId = newStartPoint.LineId; int stopLineId = newStopPoint.LineId; if (newStopPoint.LineCharIndex > 0) { stopLine.RemoveLeft(newStopPoint.Run); } for (int i = stopLineId - 1; i > startLineId; i--) { TextLineBox line = _textFlowLayer.GetTextLine(i); line.Clear(); line.JoinWithNextLine(); } if (newStartPoint.LineCharIndex == 0) { startLine.RemoveRight(newStartPoint.Run); } else { Run nextRun = (newStartPoint.Run).NextRun; if (nextRun != null) { startLine.RemoveRight(nextRun); } } startLine.JoinWithNextLine(); } } } else { GetStartAndStopLine(startPoint, endPoint, out TextLineBox startLine, out TextLineBox stopLine); EditableVisualPointInfo newStartPoint = startLine.Split(startPoint); EditableVisualPointInfo newStopPoint = stopLine.Split(endPoint); if (startLine == stopLine) { if (newStartPoint.Run != null) { LinkedList <Run> tobeRemoveRuns = new LinkedList <Run>(); if (newStartPoint.LineCharIndex == -1) { foreach (Run t in _textFlowLayer.TextRunForward( newStartPoint.Run, newStopPoint.Run)) { tobeRemoveRuns.AddLast(t); } } else { foreach (Run t in _textFlowLayer.TextRunForward( newStartPoint.Run.NextRun, newStopPoint.Run)) { tobeRemoveRuns.AddLast(t); } } foreach (Run t in tobeRemoveRuns) { startLine.Remove(t); } } else { throw new NotSupportedException(); } } else { int startLineId = newStartPoint.LineId; int stopLineId = newStopPoint.LineId; if (newStopPoint.LineCharIndex > -1) { stopLine.RemoveLeft(newStopPoint.Run); } for (int i = stopLineId - 1; i > startLineId; i--) { TextLineBox line = _textFlowLayer.GetTextLine(i); line.Clear(); line.JoinWithNextLine(); } if (newStartPoint.LineCharIndex == -1) { //TODO: review here again //at this point newStartPoint.TextRun should always null if (newStartPoint.Run != null) { startLine.RemoveRight(newStartPoint.Run); } } else { //at this point newStartPoint.TextRun should always null //TODO newStartPoint.TextRun == null??? if (newStartPoint.Run != null) { Run nextRun = newStartPoint.Run.NextRun; if (nextRun != null) { startLine.RemoveRight(nextRun); } } } startLine.JoinWithNextLine(); } } }
public static void InnerDoJoinWithNextLine(TextLineBox line) { line.JoinWithNextLine(); }
internal void DrawChildContentLcdEffectText(DrawBoard d, UpdateArea updateArea, VisualSelectionRange selRange) { List <TextLineBox> lines = _lines; int renderAreaTop = updateArea.Top; int renderAreaBottom = updateArea.Bottom; bool foundFirstLine = false; int j = lines.Count; int enter_canvasX = d.OriginX; int enter_canvasY = d.OriginY; Rectangle currentClip = d.CurrentClipRect; Color prev_colorHint = d.TextBackgroundColorHint; for (int i = 0; i < j; ++i) { //draw textline, along with visual selection range TextLineBox line = lines[i]; int linetop = line.Top; if (!foundFirstLine) { if (linetop + line.ActualLineHeight < renderAreaTop) { continue; } else { foundFirstLine = true; } } else { if (linetop > renderAreaBottom) { if (VisualLineOverlapped) { //more check if (i < j - 1) { //check next line TextLineBox lowerLine = lines[i + 1]; if (lowerLine.Top - lowerLine.OverlappedTop > linetop) { break; } } } else { break; } } } updateArea.OffsetY(-linetop); //offset switch (selRange.GetLineClip(i, out int clipLeft, out int clipWidth)) {
public void AcceptVisitor(RunVisitor visitor) { //similar to Draw... List <TextLineBox> lines = _lines; int renderAreaTop; int renderAreaBottom; if (visitor.UseUpdateArea) { renderAreaTop = visitor.UpdateArea.Top; renderAreaBottom = visitor.UpdateArea.Bottom; } else { renderAreaTop = 0; renderAreaBottom = this.Bottom; } bool foundFirstLine = false; int j = lines.Count; for (int i = 0; i < j; ++i) { TextLineBox line = lines[i]; int y = line.Top; if (visitor.StopOnNextLine) { break; //break from for loop=> go to end } visitor.VisitNewLine(y); //*** if (!visitor.SkipCurrentLineEditableRunIter) { LinkedListNode <Run> curNode = line.First; if (!foundFirstLine) { if (y + line.ActualLineHeight < renderAreaTop) { continue; } else { foundFirstLine = true; } } else { if (VisualLineOverlapped) { if (i < j - 1) { //check next line TextLineBox lowerLine = lines[i + 1]; if (lowerLine.Top > y) { break; } } else { break; } } else { if (y > renderAreaBottom) { break; } } } while (curNode != null) { Run child = curNode.Value; //iter entire line, not check horizontal line intersect visitor.VisitEditableRun(child); curNode = curNode.Next; } } } }
public void JoinWithNextLine() { TextLineBox.InnerDoJoinWithNextLine(this.CurrentLine); EnsureCurrentTextRun(); }