public override void Draw(Graphics gr, Point position, Range range) { //draw background if (BackgroundBrush != null) { gr.FillRectangle(BackgroundBrush, position.X, position.Y, (range.End.iChar - range.Start.iChar) * range.tb.CharWidth, range.tb.CharHeight); } //draw chars using (var f = new Font(range.tb.Font, FontStyle)) { Line line = range.tb[range.Start.iLine]; float dx = range.tb.CharWidth; float dxu = range.tb.CharUnicodeWidth; float y = position.Y + range.tb.LineInterval / 2; float x = position.X - range.tb.CharWidth / 3; if (ForeBrush == null) { ForeBrush = new SolidBrush(range.tb.ForeColor); } if (range.tb.ImeAllowed) { //IME mode for (int i = range.Start.iChar; i < range.End.iChar; i++) { SizeF size = FastColoredTextBox.GetCharSize(f, line[i].c); var gs = gr.Save(); float k = size.Width > range.tb.CharWidth + 1 ? range.tb.CharWidth / size.Width : 1; gr.TranslateTransform(x, y + (1 - k) * range.tb.CharHeight / 2); gr.ScaleTransform(k, (float)Math.Sqrt(k)); gr.DrawString(line[i].c.ToString(), f, ForeBrush, 0, 0, stringFormat); gr.Restore(gs); x += line[i].c > 0xFF ? dxu : dx; } } else { //classic mode for (int i = range.Start.iChar; i < range.End.iChar; i++) { //draw char gr.DrawString(line[i].c.ToString(), f, ForeBrush, x, y, stringFormat); x += line[i].c > 0xFF ? dxu : dx; } } } }
internal void CalcCutOffsW(int maxWidth, bool allowIME, bool charWrap, Line line, Font font) { int segmentLength = 0; int cutOff = 0; CutOffPositions.Clear(); for (int i = 0; i < line.Count; i++) { char c = line[i].c; if (charWrap) { //char wrapping cutOff = Math.Min(i + 1, line.Count - 1); } else { //word wrapping if (allowIME && isCJKLetter(c))//in CJK languages cutoff can be in any letter { cutOff = i; } else if (!char.IsLetterOrDigit(c) && c != '_') { cutOff = Math.Min(i + 1, line.Count - 1); } } int width = (int)FastColoredTextBox.GetCharSize(font, line[i].c).Width; if (segmentLength + width >= maxWidth) { if (cutOff == 0 || (cutOffPositions.Count > 0 && cutOff == cutOffPositions[cutOffPositions.Count - 1])) { cutOff = i + 1; } CutOffPositions.Add(cutOff); // segmentLength = 1 + i - cutOff; segmentLength = 0; } else { segmentLength += width; } } }
internal static void InsertChar(char c, ref char deletedChar, TextSource ts) { var tb = ts.CurrentTB; switch (c) { case '\n': if (ts.Count == 0) { InsertLine(ts); } InsertLine(ts); break; case '\r': break; case '\b': //backspace if (tb.Selection.Start.iChar == 0 && tb.Selection.Start.iLine == 0) { return; } if (tb.Selection.Start.iChar == 0) { if (tb.lineInfos[tb.Selection.Start.iLine - 1].VisibleState != VisibleState.Visible) { tb.ExpandBlock(tb.Selection.Start.iLine - 1); } deletedChar = '\n'; MergeLines(tb.Selection.Start.iLine - 1, ts); } else { deletedChar = ts[tb.Selection.Start.iLine][tb.Selection.Start.iChar - 1].c; ts[tb.Selection.Start.iLine].RemoveAt(tb.Selection.Start.iChar - 1); tb.Selection.Start = new Place(tb.Selection.Start.iChar - 1, tb.Selection.Start.iLine); } break; case '\t': for (int i = 0; i < tb.TabLength; i++) { ts[tb.Selection.Start.iLine].Insert(tb.Selection.Start.iChar, new Char(' ', FastColoredTextBox.GetCharSize(tb.Font, ' '))); } tb.Selection.Start = new Place(tb.Selection.Start.iChar + tb.TabLength, tb.Selection.Start.iLine); break; default: ts[tb.Selection.Start.iLine].Insert(tb.Selection.Start.iChar, new Char(c, FastColoredTextBox.GetCharSize(tb.Font, ' '))); tb.Selection.Start = new Place(tb.Selection.Start.iChar + 1, tb.Selection.Start.iLine); break; } }