/// <summary> /// analyzes a node /// </summary> /// <param name="activeNode"> the active node </param> /// <param name="index"> indicates the index of the item </param> /// <param name="tolerance"> indicates the tolerance for badness </param> /// <param name="lineProvider"> the line provider </param> /// <returns> the next node </returns> private LinkedListNode<Breakpoint> AnalyzeNode( LinkedListNode<Breakpoint> activeNode, int index, double tolerance, ILineProvider lineProvider) { Contract.Requires(activeNode != null); Contract.Requires(index >= 0); Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); LinkedListNode<Breakpoint> nextNode = activeNode.Next; int currentLine = activeNode.Value.Line; LineItem indexItem = _Items[index]; double ratio = ComputeRatio( ref indexItem, activeNode, currentLine, lineProvider); if(ratio < -1.0 || indexItem.IsForcedBreak) { _Active.Remove(activeNode); _LastDeactivated = activeNode.Value; } if(ratio >= -1.0 && ratio <= tolerance) { Demerits demerits = indexItem.ComputeDemerits(ratio / tolerance); demerits = indexItem.CombineFlaggedDemerits( _Items[activeNode.Value.Position], demerits); LineFitness fitness = LineFitness.FromLineRatio(ratio / tolerance); if(fitness.MeasureFitnessGap(activeNode.Value.Fitness) > 1) { demerits += Demerits.FitnessPenalty; } demerits += activeNode.Value.Demerits; if(demerits < _Candidates[fitness].Demerits) { double totalWidth; double totalShrink; double totalStretch; ComputeSum(index, out totalWidth, out totalShrink, out totalStretch); _Candidates[fitness] = new Breakpoint( index, currentLine + 1, fitness, totalWidth, totalStretch, totalShrink, demerits, ratio, activeNode.Value); _MinimumCandidate = Math.Min(_MinimumCandidate.Value, demerits.Value); } } return nextNode; }
/// <summary> /// analyzes a breaking point /// </summary> /// <param name="index"> indicates the index of the breaking point </param> /// <param name="tolerance"> indicates the tolerance for badness </param> /// <param name="lineProvider"> the line provider </param> private void AnalyzeBreakpoint( int index, double tolerance, ILineProvider lineProvider) { Contract.Requires(index >= 0); Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); LinkedListNode<Breakpoint> activeNode = _Active.First; while(activeNode != null) { _MinimumCandidate = Demerits.Infinity; _Candidates[0] = Breakpoint.MaxDemerits; _Candidates[1] = Breakpoint.MaxDemerits; _Candidates[2] = Breakpoint.MaxDemerits; _Candidates[3] = Breakpoint.MaxDemerits; while(activeNode != null) { activeNode = AnalyzeNode(activeNode, index, tolerance, lineProvider); } if(_MinimumCandidate < Demerits.Infinity) { Demerits limit = _MinimumCandidate + Demerits.FitnessPenalty; foreach(Breakpoint candidate in _Candidates) { if(candidate.Demerits <= limit) { _Active.AddLast(candidate); } } } } }