コード例 #1
0
        private ActiveNode TryBreakHere(
            IParagraphModel <TLine, TState> paragraph, IFrameModel frame,
            IBreakPoint breakPoint, ActiveNode prevNode,
            out bool doDeactivate)
        {
            var nextLineNumber = prevNode.LineNumber + 1;
            var suitableLength = frame.LengthOf(nextLineNumber);
            var constraint     = new LineConstraint {
                SuitableLength = suitableLength
            };
            var    newStyle = new TState();
            var    line     = paragraph.CreateLine(constraint, prevNode.Point, breakPoint, prevNode.Style, out newStyle);
            double ratio    = _evaluator.ComputeAdjustmentRatio(line, suitableLength);

            doDeactivate = (ratio < -1 || _evaluator.IsForcedBreakPoint(breakPoint));

            if (-1 <= ratio && ratio <= _tolerance)
            {
                var fitnessClass     = _evaluator.ComputeFitnessClass(ratio);
                var prevIsFlagged    = prevNode.Point.IsFlagged;
                var prevFitnessClass = prevNode.FitnessClass;
                var demerits         = _evaluator.ComputeDemerits(breakPoint, ratio, fitnessClass, prevIsFlagged, prevFitnessClass);
                return(ActiveNode.CreateBreakNode(breakPoint, line, fitnessClass, newStyle, ratio, demerits, prevNode));
            }
            else
            {
                return(null);
            }
        }
コード例 #2
0
        private static IUnjustifiedLine <TLine> ForceLayoutInOneLine(IParagraphModel <TLine, TState> paragraph, IFrameModel frame)
        {
            var length     = frame.LengthOf(1);
            var constraint = new LineConstraint {
                SuitableLength = length
            };
            var style           = new TState();
            var ignore          = new TState();
            var unjustifiedLine = paragraph.CreateLine(constraint, paragraph.StartPoint, paragraph.EndPoint, style, out ignore);

            return(unjustifiedLine);
        }
コード例 #3
0
        public IEnumerable <TLine> Layout(IParagraphModel <TLine, TState> paragraph, IFrameModel frame)
        {
            var track = ComputeBreakPoints(paragraph, frame);

            if (track.Count == 0)
            {
                return(new TLine[] { ForceLayoutInOneLine(paragraph, frame).Justify(1) });
            }
            else
            {
                return(from x in track select x.CreateLine());
            }
        }
コード例 #4
0
        private List <ActiveNode> ComputeBreakPoints(IParagraphModel <TLine, TState> paragraph, IFrameModel frame)
        {
            var startNode            = ActiveNode.CreateStartNode(paragraph.StartPoint);
            var storedActiveNodeList = new LinkedList <ActiveNode>();

            storedActiveNodeList.AddLast(startNode);
            foreach (var breakPoint in paragraph.FeasibleBreakPoints)
            {
                var breakPointNodes = new HashSet <ActiveNode>();
                var activeNodeNode  = storedActiveNodeList.First;
                while (activeNodeNode != null)
                {
                    ActiveNode activeNode = activeNodeNode.Value;
                    bool       doDeactivate;
                    ActiveNode nextNode = TryBreakHere(paragraph, frame, breakPoint, activeNode, out doDeactivate);
                    if (nextNode != null)
                    {
                        bool betterThanTheOthers = AddBetterActiveNode(breakPointNodes, nextNode);
#if TRACE_TRY_BREAK
                        Console.WriteLine("#ACTIVATE    | {0}", nextNode);
                        if (betterThanTheOthers)
                        {
                            Console.WriteLine("#...BETTER   |");
                        }
#endif
                    }
                    var next = activeNodeNode.Next;
                    if (doDeactivate)
                    {
                        storedActiveNodeList.Remove(activeNodeNode);
#if TRACE_TRY_BREAK
                        if (nextNode != null)
                        {
                            Console.WriteLine("#ACCEPT  From| {0:12} | To:{1:12}", activeNode, nextNode);
                        }
                        else
                        {
                            Console.WriteLine("#DECLINE From| {0:12}", activeNode);
                        }
#endif
                    }
                    activeNodeNode = next;
                }
                MergeActiveNodes(storedActiveNodeList, breakPointNodes);
            }

            var endedNodes = (from x in storedActiveNodeList where x.Point == paragraph.EndPoint select x);
            if (IsNotEmpty(endedNodes))
            {
                var bestNode = FindTheWorstDemerits(endedNodes);
                storedActiveNodeList.Clear();
                return(bestNode.TrackFromStartToHere());
            }
            else
            {
                //失敗した場合は一行におさめる
                var line = ForceLayoutInOneLine(paragraph, frame);
                return(new List <ActiveNode>
                {
                    ActiveNode.CreateBreakNode(paragraph.EndPoint, line, FitnessClass.Tight /*dummy*/, null, 0.0, 0.0, startNode)
                });
            }
        }