예제 #1
0
        private void ConstrainTextFlowPath(List <TextFlowPath> flowPath, double posY, Rectangled rect, EnumFloat elementFloat)
        {
            double x1 = elementFloat == EnumFloat.Left ? rect.Width : 0;
            double x2 = elementFloat == EnumFloat.Right ? Bounds.InnerWidth - rect.Width : Bounds.InnerWidth;

            double remainingHeight = rect.Height;

            for (int i = 0; i < flowPath.Count; i++)
            {
                TextFlowPath tfp = flowPath[i];

                if (tfp.Y2 <= posY)
                {
                    continue;                 // we already passed this one
                }
                double hereX1 = Math.Max(x1, tfp.X1);
                double hereX2 = Math.Min(x2, tfp.X2);


                // Current bounds are taller, let's make a split and insert ours
                if (tfp.Y2 > posY + rect.Height)
                {
                    // Already more contrained, don't touch
                    if (x1 <= tfp.X1 && x2 >= tfp.X2)
                    {
                        continue;
                    }

                    if (i == 0)
                    {
                        // We're at the begining, so don't need a "before" element
                        flowPath[i] = new TextFlowPath(hereX1, posY, hereX2, posY + rect.Height);
                        flowPath.Insert(i + 1, new TextFlowPath(tfp.X1, posY + rect.Height, tfp.X2, tfp.Y2));
                    }
                    else
                    {
                        flowPath[i] = new TextFlowPath(tfp.X1, tfp.Y1, tfp.X2, posY);
                        flowPath.Insert(i + 1, new TextFlowPath(tfp.X1, posY + rect.Height, tfp.X2, tfp.Y2));
                        flowPath.Insert(i, new TextFlowPath(hereX1, posY, hereX2, posY + rect.Height));
                    }

                    remainingHeight = 0;
                    break;
                }
                else

                // Current bounds are shorter, let's update it
                {
                    flowPath[i].X1   = hereX1;
                    flowPath[i].X2   = hereX2;
                    remainingHeight -= tfp.Y2 - posY;
                }
            }

            if (remainingHeight > 0)
            {
                flowPath.Add(new TextFlowPath(x1, posY, x2, posY + remainingHeight));
            }
        }
예제 #2
0
        public override bool CalcBounds(TextFlowPath[] flowPath, double currentLineHeight, double lineX, double lineY)
        {
            TextFlowPath curfp            = GetCurrentFlowPathSection(flowPath, lineY);
            bool         requireLinebreak = lineX + BoundsPerLine[0].Width > curfp.X2;

            this.BoundsPerLine[0].X = requireLinebreak ? 0 : lineX;
            this.BoundsPerLine[0].Y = lineY + (requireLinebreak ? currentLineHeight : 0);

            return(requireLinebreak);
        }
예제 #3
0
        private double getLeftIndentAt(List <TextFlowPath> flowPath, double posY)
        {
            for (int i = 0; i < flowPath.Count; i++)
            {
                TextFlowPath tfp = flowPath[i];
                if (tfp.Y1 <= posY && tfp.Y2 >= posY)
                {
                    return(tfp.X1);
                }
            }

            return(0);
        }
예제 #4
0
        public override bool CalcBounds(TextFlowPath[] flowPath, double currentLineHeight, double lineX, double lineY)
        {
            double y2 = lineY;

            for (int i = 0; i < flowPath.Length; i++)
            {
                TextFlowPath curFp = flowPath[i];
                if (curFp.Y1 <= lineY && curFp.Y2 >= lineY)
                {
                    if (curFp.X1 > 0)
                    {
                        y2 = curFp.Y2;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            this.BoundsPerLine = new LineRectangled[] { new LineRectangled(0, lineY, 10, y2 - lineY + 1) };

            return(this.Float == EnumFloat.None);
        }
예제 #5
0
        /// <summary>
        /// Turns the supplied text into line of text constrained by supplied flow path and starting at supplied start coordinates
        /// </summary>
        /// <param name="ctx">Contexts of the GUI.</param>
        /// <param name="text">The text to be split</param>
        /// <param name="flowPath">Sets the general flow of text.</param>
        /// <param name="startOffsetX">The offset start position for X</param>
        /// <param name="startY">The offset start position for Y</param>
        /// <returns>The text broken up into lines.</returns>
        public TextLine[] Lineize(Context ctx, string text, TextFlowPath[] flowPath, double startOffsetX = 0, double startY = 0, double lineHeightMultiplier = 1f)
        {
            if (text == null || text.Length == 0)
            {
                return(new TextLine[0]);
            }

            string        word;
            StringBuilder lineTextBldr = new StringBuilder();

            List <TextLine> lines = new List <TextLine>();

            caretPos = 0;

            double lineheight = ctx.FontExtents.Height * lineHeightMultiplier;

            double       curX = startOffsetX;
            double       curY = startY;
            double       usableWidth;
            TextFlowPath currentSection;
            int          i = startOffsetX > 0 ? 1 : 0;

            var linebreak = Lang.CurrentLocale == "ja" ? EnumLinebreakBehavior.AfterCharacter : EnumLinebreakBehavior.AfterWord;

            while ((word = getNextWord(text, linebreak)) != null)
            {
                string spc = (gotLinebreak || caretPos >= text.Length || !gotSpace ? "" : " ");

                double nextWidth = ctx.TextExtents(lineTextBldr + word + spc).Width;

                currentSection = GetCurrentFlowPathSection(flowPath, curY);

                if (currentSection == null)
                {
                    Console.WriteLine("Flow path underflow. Something in the text flow system is incorrectly programmed.");
                    currentSection = new TextFlowPath(500);
                }


                usableWidth = currentSection.X2 - currentSection.X1 - curX;

                if (nextWidth >= usableWidth && i > 0)
                {
                    string linetext     = lineTextBldr.ToString();
                    double withoutWidth = ctx.TextExtents(linetext).Width;

                    lines.Add(new TextLine()
                    {
                        Text   = linetext,
                        Bounds = new LineRectangled(currentSection.X1 + curX, curY, withoutWidth, lineheight)
                        {
                            Ascent = ctx.FontExtents.Ascent
                        },
                        LeftSpace  = 0,
                        RightSpace = usableWidth - withoutWidth
                    });

                    lineTextBldr.Clear();
                    curY += lineheight;
                    curX  = 0;

                    if (gotLinebreak)
                    {
                        currentSection = GetCurrentFlowPathSection(flowPath, curY);
                    }
                }

                i++;

                lineTextBldr.Append(word);
                if (gotSpace /* && word.Length > 0*/)
                {
                    lineTextBldr.Append(" ");
                }

                if (gotLinebreak)
                {
                    string linetext     = lineTextBldr.ToString();
                    double withoutWidth = ctx.TextExtents(linetext).Width;

                    lines.Add(new TextLine()
                    {
                        Text   = linetext,
                        Bounds = new LineRectangled(currentSection.X1 + curX, curY, withoutWidth, lineheight)
                        {
                            Ascent = ctx.FontExtents.Ascent
                        },
                        LeftSpace  = 0,
                        RightSpace = usableWidth - withoutWidth
                    });

                    lineTextBldr.Clear();
                    curY += lineheight;
                    curX  = 0;
                }
            }

            currentSection = GetCurrentFlowPathSection(flowPath, curY);
            usableWidth    = currentSection.X2 - currentSection.X1 - curX;
            string lineTextStr = lineTextBldr.ToString();
            double endWidth    = ctx.TextExtents(lineTextStr).Width;


            lines.Add(new TextLine()
            {
                Text   = lineTextStr,
                Bounds = new LineRectangled(currentSection.X1 + curX, curY, endWidth, lineheight)
                {
                    Ascent = ctx.FontExtents.Ascent
                },
                LeftSpace  = 0,
                RightSpace = usableWidth - endWidth
            });

            return(lines.ToArray());
        }
예제 #6
0
        /// <summary>
        /// Turns the supplied text into line of text constrained by supplied flow path and starting at supplied start coordinates
        /// </summary>
        /// <param name="ctx">Contexts of the GUI.</param>
        /// <param name="text">The text to be split</param>
        /// <param name="flowPath">Sets the general flow of text.</param>
        /// <param name="startOffsetX">The offset start position for X</param>
        /// <param name="startY">The offset start position for Y</param>
        /// <returns>The text broken up into lines.</returns>
        public TextLine[] Lineize(Context ctx, string text, TextFlowPath[] flowPath, double startOffsetX = 0, double startY = 0, double lineHeightMultiplier = 1f)
        {
            if (text == null || text.Length == 0)
            {
                return(new TextLine[0]);
            }

            string        word;
            StringBuilder lineTextBldr = new StringBuilder();

            List <TextLine> lines = new List <TextLine>();

            caretPos = 0;
            int previousCaretPos = 0;

            double lineheight = ctx.FontExtents.Height * lineHeightMultiplier;

            double       curX = startOffsetX;
            double       curY = startY;
            double       usableWidth;
            TextFlowPath currentSection = null;

            while ((word = getNextWord(text)) != null)
            {
                double width = ctx.TextExtents(lineTextBldr + (gotLinebreak || caretPos >= text.Length ? "" : " ") + word).Width;

                currentSection = GetCurrentFlowPathSection(flowPath, curY);

                if (currentSection == null)
                {
                    Console.WriteLine("Flow path underflow. Something in the text flow system is incorrectly programmed.");
                    currentSection = new TextFlowPath(500);
                }


                usableWidth = currentSection.X2 - currentSection.X1 - curX;

                if (width >= usableWidth)
                {
                    double withoutWidth = ctx.TextExtents(lineTextBldr.ToString()).Width;

                    lines.Add(new TextLine()
                    {
                        Text   = lineTextBldr.ToString(),
                        Bounds = new LineRectangled(currentSection.X1 + curX, curY, withoutWidth, lineheight)
                        {
                            Ascent = ctx.FontExtents.Ascent
                        },
                        LeftSpace  = 0,
                        RightSpace = usableWidth - withoutWidth
                    });

                    lineTextBldr.Clear();
                    curY += lineheight;
                    curX  = 0;

                    if (gotLinebreak)
                    {
                        currentSection = GetCurrentFlowPathSection(flowPath, curY);
                    }
                }

                if (lineTextBldr.Length > 0)
                {
                    lineTextBldr.Append(" ");
                }

                lineTextBldr.Append(word);

                if (gotLinebreak)
                {
                    double withoutWidth = ctx.TextExtents(lineTextBldr.ToString()).Width;

                    lines.Add(new TextLine()
                    {
                        Text   = lineTextBldr.ToString(),
                        Bounds = new LineRectangled(currentSection.X1 + curX, curY, withoutWidth, lineheight)
                        {
                            Ascent = ctx.FontExtents.Ascent
                        },
                        LeftSpace  = 0,
                        RightSpace = usableWidth - withoutWidth
                    });

                    lineTextBldr.Clear();
                    curY += lineheight;
                    curX  = 0;
                }

                previousCaretPos = caretPos;
            }

            currentSection = GetCurrentFlowPathSection(flowPath, curY);
            usableWidth    = currentSection.X2 - currentSection.X1 - curX;
            string lineTextStr = lineTextBldr.ToString();
            double endWidth    = ctx.TextExtents(lineTextStr).Width;


            lines.Add(new TextLine()
            {
                Text   = lineTextStr,
                Bounds = new LineRectangled(currentSection.X1 + curX, curY, endWidth, lineheight)
                {
                    Ascent = ctx.FontExtents.Ascent
                },
                LeftSpace  = 0,
                RightSpace = usableWidth - endWidth
            });

            return(lines.ToArray());
        }