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)); } }
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); }
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); }
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); }
/// <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()); }
/// <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()); }