public virtual IEnumerable<StyleRun> GetStyles()
{
this.CheckInvalid();
// We need to translate the array Scintilla gives us representing the style of each text
// byte into a list of style runs. Our run lengths, however, are measured in characters,
// not bytes, so we need to also read the annotation text and adjust as necessary when we find
// characters that span more than one byte.
int length = this._scintilla.DirectMessage(NativeMethods.SCI_ANNOTATIONGETTEXT, new IntPtr(this._lineIndex), IntPtr.Zero).ToInt32();
var textBuffer = new byte[length];
var stylesBuffer = new byte[length];
unsafe
{
fixed (byte* bp = textBuffer)
this._scintilla.DirectMessage(NativeMethods.SCI_ANNOTATIONGETTEXT, new IntPtr(this._lineIndex), new IntPtr(bp)).ToInt32();
fixed (byte* bp = stylesBuffer)
this._scintilla.DirectMessage(NativeMethods.SCI_ANNOTATIONGETSTYLES, new IntPtr(this._lineIndex), new IntPtr(bp)).ToInt32();
}
var styles = new List<StyleRun>();
Decoder decoder = this._scintilla.Encoding.GetDecoder();
var sr = new StyleRun { Style = -1 };
int index = 0;
int count = 1;
while (index < stylesBuffer.Length)
{
if (sr.Style != stylesBuffer[index])
{
// A new style has been encountered. Save the last one
// to the list we're building and start tracking a new one
if (sr.Length > 0)
styles.Add(sr);
sr = new StyleRun
{
Style = stylesBuffer[index]
};
}
// At the end of this loop, the 'count' variable will tell us
// how many bytes there are for one character.
while (decoder.GetCharCount(textBuffer, index, count) != 1)
count++;
sr.Length++;
index += count;
count = 1;
}
// Add the last style run
styles.Add(sr);
return styles.ToArray();
}