Example #1
0
File: Flow.cs Project: dzamkov/DUIP
        /// <summary>
        /// Gets the possible lines that may be formed from the given items.
        /// </summary>
        /// <param name="Start">The item to start the lines on.</param>
        /// <param name="Prefered">The prefered size of a line.</param>
        /// <param name="Max">The maximum size of a line.</param>
        private static IEnumerable<_PlannedLine> _GetPossibleLines(List<FlowItem> Items, int Start, double Prefered, double Max, FlowBlockStyle Style)
        {
            int cur = Start;
            int size = 0;
            double len = 0.0;
            bool hasline = false;
            while (cur < Items.Count)
            {
                // Insure line does not exceed size limit
                if (len - Layout.ErrorThreshold > Prefered && hasline)
                {
                    yield break;
                }
                if (len - Layout.ErrorThreshold > Max)
                {
                    yield break;
                }

                // Examine current item
                FlowItem item = Items[cur];

                // Break item
                if (item == BreakFlowItem.Instance)
                {
                    yield return new _PlannedLine
                    {
                        Length = len,
                        Next = cur + 1,
                        Size = size,
                        Cut = false
                    };
                    hasline = true;
                    cur++;
                    size++;
                    continue;
                }

                // Cut item
                if (item == CutFlowItem.Instance)
                {
                    yield return new _PlannedLine
                    {
                        Length = len,
                        Next = cur + 1,
                        Size = size,
                        Cut = true
                    };
                    yield break;
                }

                // Character item
                CharacterFlowItem cfi = item as CharacterFlowItem;
                if (cfi != null)
                {
                    len += cfi.Font.GetSize(cfi.Name)[Style.MinorAxis];
                    cur++;
                    size++;
                    continue;
                }

                // Space item
                SpaceFlowItem sfi = item as SpaceFlowItem;
                if (sfi != null)
                {
                    if (sfi.Breaking)
                    {
                        yield return new _PlannedLine
                        {
                            Length = len,
                            Next = cur + 1,
                            Size = size,
                            Cut = false
                        };
                        hasline = true;
                    }
                    len += sfi.Length;
                    cur++;
                    size++;
                    continue;
                }
            }

            // End of items can act as a valid break
            yield return new _PlannedLine
            {
                Length = len,
                Next = Items.Count,
                Size = size,
                Cut = false
            };
        }
Example #2
0
File: Flow.cs Project: dzamkov/DUIP
        /// <summary>
        /// Greedily creates a list of lines for a sequence of items, or returns null if not possible.
        /// </summary>
        /// <param name="Prefered">The prefered size of a line.</param>
        /// <param name="Max">The maximum size of a line.</param>
        private static List<_PlannedLine> _GetLinesGreedy(List<FlowItem> Items, double Prefered, double Max, FlowBlockStyle Style)
        {
            int cur = 0;
            List<_PlannedLine> lines = new List<_PlannedLine>();
            while (cur < Items.Count)
            {
                bool hasline = false;
                _PlannedLine last = new _PlannedLine();
                foreach(_PlannedLine line in _GetPossibleLines(Items, cur, Prefered, Max, Style))
                {
                    hasline = true;
                    last = line;
                }

                // Exit if no lines are found.
                if (!hasline)
                {
                    return null;
                }

                cur = last.Next;
                lines.Add(last);
            }
            return lines;
        }
Example #3
0
File: Flow.cs Project: dzamkov/DUIP
        /// <summary>
        /// Builds the layout lines for a list of planned lines.
        /// </summary>
        private static List<_Layout.Line> _BuildLayout(
            List<_PlannedLine> Lines, List<FlowItem> Items, FlowBlockStyle Style, 
            double MinorSize, double MinMajorSize, out double MajorSize)
        {
            List<_Layout.Line> lines = new List<_Layout.Line>(Lines.Count);
            int cur = 0;

            double majoroff = 0.0;
            MajorSize = 0.0;

            // Build lines
            foreach (_PlannedLine pl in Lines)
            {
                _Layout.Line line = _BuildLayoutLine(cur, pl.Size, pl.Length, pl.Cut, Items, Style, MinorSize);
                lines.Add(line);
                cur = pl.Next;

                line.MajorOffset = majoroff;
                MajorSize = majoroff + line.MajorSize;
                majoroff = MajorSize + Style.LineSpacing;
            }
            MajorSize = Math.Max(MajorSize, MinMajorSize);

            // Reverse line direction if needed
            if ((int)Style.Direction % 2 > 0)
            {
                majoroff = MajorSize;
                foreach (_Layout.Line line in lines)
                {
                    line.MajorOffset = majoroff - line.MajorSize;
                    majoroff = line.MajorOffset - Style.LineSpacing;
                }
            }

            return lines;
        }
Example #4
0
File: Flow.cs Project: dzamkov/DUIP
        /// <summary>
        /// Builds a layout line for a given subset of a list of items. The major offset of the line will not be set.
        /// </summary>
        /// <param name="Length">The known minimum length of the line.</param>
        private static _Layout.Line _BuildLayoutLine(int Start, int Size, double Length, bool Cut, List<FlowItem> Items, FlowBlockStyle Style, double MinorSize)
        {
            Axis minoraxis = Style.MinorAxis;
            double majorsize = Style.LineSize;
            _Layout.Item[] items = new _Layout.Item[Size];

            // Add visible items while determining their sizes
            double totalspace = 0.0;
            for (int t = 0; t < items.Length; t++)
            {
                FlowItem item = Items[Start++];

                // Character item
                CharacterFlowItem cfi = item as CharacterFlowItem;
                if (cfi != null)
                {
                    Point size = cfi.Font.GetSize(cfi.Name).Shift(Style.MinorAxis);
                    majorsize = Math.Max(majorsize, size.Y);
                    items[t] = new _Layout.Item
                    {
                        MinorSize = size.X,
                        Source = cfi
                    };
                }

                // Space item
                SpaceFlowItem sfi = item as SpaceFlowItem;
                if (sfi != null)
                {
                    totalspace += sfi.Length;
                    items[t] = new _Layout.Item
                    {
                        MinorSize = sfi.Length,
                        Source = sfi
                    };
                }
            }

            // If the flow is justified, adjust the sizes of spaces
            if (Style.Justification == FlowJustification.Justify && !Cut)
            {
                double spacemult = (MinorSize - Length + totalspace) / totalspace;
                for (int t = 0; t < items.Length; t++)
                {
                    if (items[t].Source is SpaceFlowItem)
                    {
                        items[t].MinorSize *= spacemult;
                    }
                }
            }

            // Set item offsets
            if ((int)Style.Direction % 4 < 2)
            {
                double off = Style.Justification == FlowJustification.Center ? MinorSize * 0.5 - Length * 0.5 : 0.0;
                for (int t = 0; t < items.Length; t++)
                {
                    items[t].MinorOffset = off;
                    off += items[t].MinorSize;
                }
            }
            else
            {
                double off = Style.Justification == FlowJustification.Center ? MinorSize * 0.5 + Length * 0.5 : MinorSize;
                for (int t = 0; t < items.Length; t++)
                {
                    off -= items[t].MinorSize;
                    items[t].MinorOffset = off;
                }
            }

            return new _Layout.Line
            {
                MajorSize = majorsize,
                Items = items
            };
        }
Example #5
0
File: Flow.cs Project: dzamkov/DUIP
 public FlowBlock(List<FlowItem> Items, FlowFit Fit, FlowBlockStyle Style)
 {
     this.Style = Style;
     this.Fit = Fit;
     this.Items = Items;
 }