+2007-11-14 Jonathan Pobst <monkey@jpobst.com>
+
+ * LineTag.cs: Don't attempt to draw '\r', treat it like it doesn't exist.
+ When measureing CR or LF, use /u000D instead of /u0013. (Hex, not decimal.)
+ * TextControl.cs: Fix a case in GetLineEnding where a \n before a \r would
+ be ignored. Create a new GetLineEnding that can specify which types of
+ line endings to look for. On Insert, only create new lines for \n and \r\n.
+ [Fixes bug #324274]
+
2007-11-14 Jonathan Pobst <monkey@jpobst.com>
* TextBoxBase.cs: As we loop through each line changing the font, tell
\r
public virtual void Draw (Graphics dc, Color color, float x, float y, int start, int end)\r
{\r
- TextBoxTextRenderer.DrawText (dc, line.text.ToString (start, end), font, color, x, y, false);\r
+ TextBoxTextRenderer.DrawText (dc, line.text.ToString (start, end).Replace ("\r", string.Empty), font, color, x, y, false);\r
}\r
\r
public virtual void Draw (Graphics dc, Color color, float xoff, float y, int start, int end, string text)\r
if (tab_index == -1)\r
tab_index = end;\r
\r
- TextBoxTextRenderer.DrawText (dc, text.Substring (start, tab_index - start), font, color, xoff + line.widths[start], y, false);\r
+ TextBoxTextRenderer.DrawText (dc, text.Substring (start, tab_index - start).Replace ("\r", string.Empty), font, color, xoff + line.widths[start], y, false);\r
\r
// non multilines get the unknown char \r
if (!line.document.multiline && tab_index != end)\r
return res;\r
case 10:\r
case 13:\r
- return TextBoxTextRenderer.MeasureText (dc, "\u0013", font);\r
+ return TextBoxTextRenderer.MeasureText (dc, "\u000D", font);\r
}\r
\r
return TextBoxTextRenderer.MeasureText (dc, text, font);\r
}
internal enum LineEnding {
- Wrap, // line wraps to the next line
- Limp, // \r
- Hard, // \r\n
- Soft, // \r\r\n
- Rich, // \n
+ Wrap = 1, // line wraps to the next line
+ Limp = 2, // \r
+ Hard = 4, // \r\n
+ Soft = 8, // \r\r\n
+ Rich = 16, // \n
- None
+ None = 0
}
internal class Document : ICloneable, IEnumerable {
}
}
- internal int GetLineEnding (string line, int start, out LineEnding ending)
+ private int GetLineEnding (string line, int start, out LineEnding ending)
{
int res;
+ int rich_index;
+ if (start >= line.Length) {
+ ending = LineEnding.Wrap;
+ return -1;
+ }
+
res = line.IndexOf ('\r', start);
+ rich_index = line.IndexOf ('\n', start);
+
+ // Handle the case where we find both of them, and the \n is before the \r
+ if (res != -1 && rich_index != -1)
+ if (rich_index < res) {
+ ending = LineEnding.Rich;
+ return rich_index;
+ }
+
if (res != -1) {
if (res + 2 < line.Length && line [res + 1] == '\r' && line [res + 2] == '\n') {
ending = LineEnding.Soft;
return res;
}
- res = line.IndexOf ('\n', start);
- if (res != -1) {
+ if (rich_index != -1) {
ending = LineEnding.Rich;
- return res;
+ return rich_index;
}
ending = LineEnding.Wrap;
return line.Length;
}
+ // Get the line ending, but only of the types specified
+ private int GetLineEnding (string line, int start, out LineEnding ending, LineEnding type)
+ {
+ int index = start;
+ int last_length = 0;
+
+ do {
+ index = GetLineEnding (line, index + last_length, out ending);
+ last_length = LineEndingLength (ending);
+ } while
+ ((ending & type) != ending && index != -1);
+
+ return index == -1 ? line.Length : index;
+ }
+
internal int LineEndingLength (LineEnding ending)
{
switch (ending) {
base_line = line.line_no;
old_line_count = lines;
- break_index = GetLineEnding (s, 0, out ending);
+ break_index = GetLineEnding (s, 0, out ending, LineEnding.Hard | LineEnding.Rich);
// There are no line feeds in our text to be pasted
if (break_index == s.Length) {
// Insert brand new lines for any more line feeds in the inserted string
while (true) {
- int next_break = GetLineEnding (s, break_index, out ending);
+ int next_break = GetLineEnding (s, break_index, out ending, LineEnding.Hard | LineEnding.Rich);
if (next_break == s.Length)
break;