KeepTogetherBatch(Pointer originalPosition, List<Line> originalLines) { this.originalPosition = originalPosition; this.originalLines = originalLines; CurrentNumberOfLinesBeingBacktracked = 0; AllowKeepTogether = this.originalLines.Count > 1; Results = new List<Line>(); WorkingQueue = new Queue<Line>(this.originalLines); }
public static KeepTogetherBatch Batch(Pointer topOfBatch, IEnumerable<Line> linesToKeepTogether) { return new KeepTogetherBatch(topOfBatch, linesToKeepTogether.Where(x => x.OuterHeight > 0.cm()).ToList()); }
StopOr<Change<Line>> TryToStayPut(Pointer position, bool mayTryKeepTogether) { if (!allowStayPut) return new Stop<Change<Line>>(); if (position.PreviousLine != null && position.PreviousLine.KeepWithNextLine && mayTryKeepTogether) { if (position.NextPage - position.PageHeight > position.PreviousLine.Top && Top >= position.PreviousLine.Bottom /*TODO er dette check nødvendigt, hvornår kan previousline ende efter toppen på currentline*/) return new Stop<Change<Line>>(); } if (LineIsNotCrossingTheSplitPoint(position.NextPage)) return new KeepCurrent<Line>(); return new Stop<Change<Line>>(); }
StopOr<Change<Line>> TrySplit(Pointer position, bool fallBackToCrop) { var upperElements = new List<LayoutedElement>(); var lowerElements = new List<LayoutedElement>(); var spaceLeftBeforeSplit = position.NextPage - position.Current; foreach (var element in elements) { var signal = element.Split(position.PageHeight, spaceLeftBeforeSplit); if (signal.OperationWasNotAllowed) { if (!fallBackToCrop) return new Stop<Change<Line>>(); if (!allowStayPut) return new KeepTogether<Line>(); upperElements.Add(element.Crop(spaceLeftBeforeSplit)); } else if (signal.Result is Changed<LayoutedElement>) { upperElements.Add(signal.Result[0]); lowerElements.Add(signal.Result[1]); } else { upperElements.Add(element); } } if (lowerElements.Count > 0) { return new Changed<Line>(new Line(Top, false, upperElements), new Line(spaceLeftBeforeSplit, KeepWithNextLine, lowerElements)); } return new Changed<Line>(new Line(Top, false, upperElements)); }
StopOr<Change<Line>> TryMove(Pointer position) { if (position.PreviousLine != null && position.PreviousLine.KeepWithNextLine) return new Stop<Change<Line>>(); if (IsAtTopOfAnyPage(position)) return new Stop<Change<Line>>(); return new Move<Line>(MoveTo(position.NextPage)); }
StopOr<Change<Line>> TryKeepTogether(Pointer position) { if (position.PreviousLine != null && position.PreviousLine.KeepWithNextLine) return new KeepTogether<Line>(); return new Stop<Change<Line>>(); }
bool IsAtTopOfAnyPage(Pointer position) { var spaceToEndOfPage = position.NextPage%position.PageHeight; if ((Top + (position.PageHeight - spaceToEndOfPage))%position.PageHeight == 0.cm()) { return true; } return false; }
public StopOr<Change<Line>> FitTo(Pointer position, bool mayTryKeepTogether, bool forceIfNothingElseWorks) { if (position.Current != Top) return new Move<Line>(MoveTo(position.Current)); var result = TryToStayPut(position, mayTryKeepTogether); if (result.OperationWasNotAllowed) result = TrySplit(position, fallBackToCrop: false); if (result.OperationWasNotAllowed) result = TryMove(position); if (result.OperationWasNotAllowed && mayTryKeepTogether) result = TryKeepTogether(position); if (result.OperationWasNotAllowed && forceIfNothingElseWorks) result = TrySplit(position, fallBackToCrop: true); return result; }