aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <unknown>2009-04-22 02:29:58 +0000
committernyamatongwe <unknown>2009-04-22 02:29:58 +0000
commit3c79d3dd6c981c8216023724ee41bbb844f115f1 (patch)
treeb32d830e801dd0eb432b8ddcaa188cfb9ea20102 /src
parent387dc83a671978805467102a5de417deace52b23 (diff)
downloadscintilla-mirror-3c79d3dd6c981c8216023724ee41bbb844f115f1.tar.gz
Fixed bug where not styling last document line on screen when followed by
annotation lines. StyledText class encapsulates related data when drawing annotations and margins.
Diffstat (limited to 'src')
-rw-r--r--src/Document.cxx10
-rw-r--r--src/Document.h13
-rw-r--r--src/Editor.cxx277
3 files changed, 154 insertions, 146 deletions
diff --git a/src/Document.cxx b/src/Document.cxx
index 2c9ac34a9..b0070233f 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -1285,6 +1285,11 @@ const char *Document::MarginStyles(int line) {
return static_cast<LineAnnotation*>(perLineData[ldMargin])->Styles(line);
}
+StyledText Document::MarginStyledText(int line) {
+ return StyledText(MarginLength(line), MarginText(line),
+ MarginMultipleStyles(line), MarginStyle(line), MarginStyles(line));
+}
+
void Document::MarginSetText(int line, const char *text) {
static_cast<LineAnnotation*>(perLineData[ldMargin])->SetText(line, text);
DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line);
@@ -1331,6 +1336,11 @@ const char *Document::AnnotationStyles(int line) {
return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Styles(line);
}
+StyledText Document::AnnotationStyledText(int line) {
+ return StyledText(AnnotationLength(line), AnnotationText(line),
+ AnnotationMultipleStyles(line), AnnotationStyle(line), AnnotationStyles(line));
+}
+
void Document::AnnotationSetText(int line, const char *text) {
const int linesBefore = AnnotationLines(line);
static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetText(line, text);
diff --git a/src/Document.h b/src/Document.h
index c0d221d35..2804a9a4f 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -93,6 +93,17 @@ public:
/// Factory function for RegexSearchBase
extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
+struct StyledText {
+ size_t length;
+ const char *text;
+ bool multipleStyles;
+ int style;
+ const char *styles;
+ StyledText( size_t length_, const char *text_, bool multipleStyles_, int style_, const char *styles_) :
+ length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
+ }
+};
+
/**
*/
class Document : PerLine {
@@ -258,6 +269,7 @@ public:
const char *MarginText(int line);
int MarginStyle(int line);
const char *MarginStyles(int line);
+ StyledText MarginStyledText(int line);
void MarginSetStyle(int line, int style);
void MarginSetStyles(int line, const char *styles);
void MarginSetText(int line, const char *text);
@@ -269,6 +281,7 @@ public:
const char *AnnotationText(int line);
const char *AnnotationStyles(int line);
int AnnotationStyle(int line);
+ StyledText AnnotationStyledText(int line);
void AnnotationSetText(int line, const char *text);
void AnnotationSetStyle(int line, int style);
void AnnotationSetStyles(int line, const char *styles);
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 0c15a8c98..580e2baa3 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -1459,27 +1459,109 @@ static int istrlen(const char *s) {
return static_cast<int>(strlen(s));
}
+bool ValidStyledText(ViewStyle &vs, int styleOffset, const StyledText &st) {
+ if (st.multipleStyles) {
+ for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+ if (!vs.ValidStyle(static_cast<size_t>(styleOffset + st.styles[iStyle])))
+ return false;
+ }
+ } else {
+ if (!vs.ValidStyle(static_cast<size_t>(styleOffset + st.style)))
+ return false;
+ }
+ return true;
+}
+
+struct LineSegment {
+ const char *s;
+ int len;
+};
+
+class LineEnumerator {
+public:
+ const char *s;
+ int len;
+ LineEnumerator(const char *s_, size_t len_) : s(s_), len(len_) {
+ }
+ LineSegment Next() {
+ LineSegment ret;
+ ret.s = s;
+ int cur = 0;
+ while ((cur < len) && (s[cur] != '\n'))
+ cur++;
+ ret.len = cur;
+ s += cur + 1;
+ len -= cur + 1;
+ return ret;
+ }
+ bool Finished() const {
+ return len <= 0;
+ }
+};
+
+static int WidthStyledText(Surface *surface, ViewStyle &vs, int styleOffset,
+ const char *text, const char *styles, size_t len) {
+ int width = 0;
+ size_t start = 0;
+ while (start < len) {
+ int style = styles[start];
+ size_t endSegment = start;
+ while ((endSegment < len-1) && (styles[endSegment+1] == style))
+ endSegment++;
+ width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, endSegment - start + 1);
+ start = endSegment + 1;
+ }
+ return width;
+}
+
+static int WidestLineWidth(Surface *surface, ViewStyle &vs, int styleOffset, const StyledText &st) {
+ const char *styles = st.styles;
+ LineEnumerator le(st.text, st.length);
+ int widthMax = 0;
+ while (!le.Finished()) {
+ LineSegment ls = le.Next();
+ int widthSubLine;
+ if (st.multipleStyles) {
+ widthSubLine = WidthStyledText(surface, vs, styleOffset, ls.s, styles, ls.len);
+ styles += ls.len + 1;
+ } else {
+ widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font, ls.s, ls.len);
+ }
+ if (widthSubLine > widthMax)
+ widthMax = widthSubLine;
+ }
+ return widthMax;
+}
+
void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent,
- const char *text, const char *styles, int length) {
-
- int x = rcText.left;
- int i = 0;
- while (i < length) {
- int end = i;
- int style = styles[i];
- while (end < length-1 && styles[end+1] == style)
- end++;
- style += styleOffset;
- int width = surface->WidthText(vs.styles[style].font, text + i, end - i + 1);
- PRectangle rcSegment = rcText;
- rcSegment.left = x;
- rcSegment.right = x + width + 1;
- surface->DrawTextNoClip(rcSegment, vs.styles[style].font,
- ascent, text + i, end - i + 1,
+ const StyledText &st, size_t start, size_t length) {
+
+ if (st.multipleStyles) {
+ int x = rcText.left;
+ size_t i = 0;
+ while (i < length) {
+ size_t end = i;
+ int style = st.styles[i + start];
+ while (end < length-1 && st.styles[start+end+1] == style)
+ end++;
+ style += styleOffset;
+ int width = surface->WidthText(vs.styles[style].font, st.text + start + i, end - i + 1);
+ PRectangle rcSegment = rcText;
+ rcSegment.left = x;
+ rcSegment.right = x + width + 1;
+ surface->DrawTextNoClip(rcSegment, vs.styles[style].font,
+ ascent, st.text + start + i, end - i + 1,
+ vs.styles[style].fore.allocated,
+ vs.styles[style].back.allocated);
+ x += width;
+ i = end + 1;
+ }
+ } else {
+ int style = st.style + styleOffset;
+ surface->DrawTextNoClip(rcText, vs.styles[style].font,
+ rcText.top + vs.maxAscent, st.text, st.length,
vs.styles[style].fore.allocated,
vs.styles[style].back.allocated);
- x += width;
- i = end + 1;
}
}
@@ -1666,34 +1748,20 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
vs.styles[STYLE_LINENUMBER].back.allocated);
} else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) {
if (firstSubLine) {
- const char *marginText = pdoc->MarginText(lineDoc);
- int lengthMargin = pdoc->MarginLength(lineDoc);
- if (marginText) {
- if (pdoc->MarginMultipleStyles(lineDoc)) {
- const char *marginStyles = pdoc->MarginStyles(lineDoc);
- for (size_t iStyle=0;iStyle<static_cast<size_t>(lengthMargin); iStyle++) {
- if (!vs.ValidStyle(static_cast<size_t>(
- vs.marginStyleOffset + marginStyles[iStyle])))
- return;
- }
+ StyledText marginStyledText = pdoc->MarginStyledText(lineDoc);
+ if (marginStyledText.text && ValidStyledText(vs, vs.marginStyleOffset, marginStyledText)) {
+ if (marginStyledText.multipleStyles) {
surface->FillRectangle(rcMarker,
- vs.styles[marginStyles[0]+vs.marginStyleOffset].back.allocated);
- DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent,
- marginText, marginStyles, lengthMargin);
+ vs.styles[marginStyledText.styles[0]+vs.marginStyleOffset].back.allocated);
} else {
- int style = pdoc->MarginStyle(lineDoc) + vs.marginStyleOffset;
- if (!vs.ValidStyle(static_cast<size_t>(style)))
- return;
- surface->FillRectangle(rcMarker, vs.styles[style].back.allocated);
- if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
- int width = surface->WidthText(vs.styles[style].font, marginText, istrlen(marginText));
- rcMarker.left = rcMarker.right - width - 3;
- }
- surface->DrawTextNoClip(rcMarker, vs.styles[style].font,
- rcMarker.top + vs.maxAscent, marginText, lengthMargin,
- vs.styles[style].fore.allocated,
- vs.styles[style].back.allocated);
+ surface->FillRectangle(rcMarker, vs.styles[marginStyledText.style].back.allocated);
}
+ if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
+ int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, marginStyledText);
+ rcMarker.left = rcMarker.right - width - 3;
+ }
+ DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent,
+ marginStyledText, 0, marginStyledText.length);
}
}
}
@@ -2279,107 +2347,30 @@ void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
textBack, textFore);
}
-struct LineSegment {
- const char *s;
- int len;
-};
-
-class LineEnumerator {
-public:
- const char *s;
- int len;
- LineEnumerator(const char *s_, size_t len_) : s(s_), len(len_) {
- }
- LineSegment Next() {
- LineSegment ret;
- ret.s = s;
- int cur = 0;
- while ((cur < len) && (s[cur] != '\n'))
- cur++;
- ret.len = cur;
- s += cur + 1;
- len -= cur + 1;
- return ret;
- }
- bool Finished() const {
- return len <= 0;
- }
-};
-
-static int WidthStyledText(Surface *surface, ViewStyle &vs, int styleOffset,
- const char *text, const char *styles, size_t len) {
- int width = 0;
- size_t start = 0;
- while (start < len) {
- int style = styles[start];
- size_t endSegment = start;
- while ((endSegment < len-1) && (styles[endSegment+1] == style))
- endSegment++;
- width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, endSegment - start + 1);
- start = endSegment + 1;
- }
- return width;
-}
-
-static int WidestLineWidth(Surface *surface, ViewStyle &vs, int styleOffset,
- const char *text, const char *styles, size_t len) {
- LineEnumerator le(text, len);
- int widthComment = 0;
- while (!le.Finished()) {
- LineSegment ls = le.Next();
- int widthSubLine = WidthStyledText(surface, vs, styleOffset, ls.s, styles, ls.len);
- if (widthSubLine > widthComment)
- widthComment = widthSubLine;
- styles += ls.len;
- }
- return widthComment;
-}
-
-static int WidestLineWidth(Surface *surface, const char *text, size_t len, Font &font) {
- LineEnumerator le(text, len);
- int widthComment = 0;
- while (!le.Finished()) {
- LineSegment ls = le.Next();
- int widthSubLine = surface->WidthText(font, ls.s, ls.len);
- if (widthSubLine > widthComment)
- widthComment = widthSubLine;
- }
- return widthComment;
-}
-
void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine) {
int indent = pdoc->GetLineIndentation(line) * vsDraw.spaceWidth;
PRectangle rcSegment = rcLine;
int annotationLine = subLine - ll->lines;
- int annotationStyle = pdoc->AnnotationStyle(line) + vsDraw.annotationStyleOffset;
- const char *annotationText = pdoc->AnnotationText(line);
- const char *annotationStyles = pdoc->AnnotationStyles(line);
- int lengthAnnotation = pdoc->AnnotationLength(line);
- const bool multipleStyles = pdoc->AnnotationMultipleStyles(line);
- if (multipleStyles) {
- for (size_t iStyle=0;iStyle<static_cast<size_t>(lengthAnnotation); iStyle++) {
+ StyledText annotationStyledText = pdoc->AnnotationStyledText(line);
+ int annotationStyle = annotationStyledText.style + vsDraw.annotationStyleOffset;
+ if (annotationStyledText.multipleStyles) {
+ for (size_t iStyle=0;iStyle<annotationStyledText.length; iStyle++) {
if (!vsDraw.ValidStyle(static_cast<size_t>(
- vsDraw.annotationStyleOffset + annotationStyles[iStyle])))
+ vsDraw.annotationStyleOffset + annotationStyledText.styles[iStyle])))
return;
}
} else {
if (!vsDraw.ValidStyle(static_cast<size_t>(annotationStyle)))
return;
}
- if (annotationText) {
+ if (annotationStyledText.text) {
surface->FillRectangle(rcSegment, vsDraw.styles[0].back.allocated);
if (vs.annotationVisible == ANNOTATION_BOXED) {
// Only care about calculating width if need to draw box
- int widthAnnotation;
- if (multipleStyles) {
- widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset,
- annotationText, annotationStyles, lengthAnnotation);
- } else {
- widthAnnotation = WidestLineWidth(surface, annotationText, lengthAnnotation, vsDraw.styles[annotationStyle].font);
- }
- widthAnnotation += 16; // Margin
+ int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, annotationStyledText);
+ widthAnnotation += vsDraw.spaceWidth * 2; // Margins
rcSegment.left = xStart + indent;
rcSegment.right = rcSegment.left + widthAnnotation;
surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore.allocated);
@@ -2387,36 +2378,28 @@ void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int x
rcSegment.left = xStart;
}
const int annotationLines = pdoc->AnnotationLines(line);
- LineEnumerator le(annotationText, lengthAnnotation);
+ LineEnumerator le(annotationStyledText.text, annotationStyledText.length);
LineSegment ls = le.Next();
- annotationText = ls.s;
- lengthAnnotation = ls.len;
+ size_t start = 0;
+ size_t lengthAnnotation = ls.len;
int lineInAnnotation = 0;
while ((lineInAnnotation < annotationLine) && !le.Finished()) {
- annotationStyles += ls.len;
+ start += ls.len + 1;
ls = le.Next();
- annotationText = ls.s;
lengthAnnotation = ls.len;
lineInAnnotation++;
}
PRectangle rcText = rcSegment;
if (vs.annotationVisible == ANNOTATION_BOXED) {
- if (multipleStyles) {
- surface->FillRectangle(rcText, vsDraw.styles[annotationStyles[0] + vsDraw.annotationStyleOffset].back.allocated);
+ if (annotationStyledText.multipleStyles) {
+ surface->FillRectangle(rcText, vsDraw.styles[annotationStyledText.styles[start] + vsDraw.annotationStyleOffset].back.allocated);
} else {
surface->FillRectangle(rcText, vsDraw.styles[annotationStyle].back.allocated);
}
- rcText.left += 8;
- }
- if (multipleStyles) {
- DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent,
- annotationText, annotationStyles, lengthAnnotation);
- } else {
- surface->DrawTextNoClip(rcText, vsDraw.styles[annotationStyle].font,
- rcLine.top + vsDraw.maxAscent, annotationText, lengthAnnotation,
- vsDraw.styles[annotationStyle].fore.allocated,
- vsDraw.styles[annotationStyle].back.allocated);
+ rcText.left += vsDraw.spaceWidth;
}
+ DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent,
+ annotationStyledText, start, lengthAnnotation);
if (vs.annotationVisible == ANNOTATION_BOXED) {
surface->MoveTo(rcSegment.left, rcSegment.top);
surface->LineTo(rcSegment.left, rcSegment.bottom);
@@ -3017,7 +3000,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
//Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast);
int endPosPaint = pdoc->Length();
if (lineStyleLast < cs.LinesDisplayed())
- endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast + 1));
+ endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast) + 1);
int xStart = vs.fixedColumnWidth - xOffset;
int ypos = 0;
@@ -3707,6 +3690,8 @@ void Editor::ClearAll() {
}
if (!pdoc->IsReadOnly()) {
cs.Clear();
+ pdoc->AnnotationClearAll();
+ pdoc->MarginClearAll();
}
pdoc->EndUndoAction();
anchor = 0;