public override void DrawRect(CGRect dirtyRect) { base.DrawRect(dirtyRect); var attributes = new NSStringAttributes { ForegroundColor = NSColor.Blue, Font = NSFont.FromFontName("Andale Mono", 14) }; ProcessTextFormat(attributes); NSColor.Black.SetFill(); NSBezierPath.FillRect(dirtyRect); lock (Terminal) { int row = ViewTop; float verticalOffset = -row * (float)CharacterHeight; var lines = Terminal.ViewPort.GetLines(ViewTop, Rows); foreach (var line in lines) { if (line == null) { row++; continue; } int column = 0; var xform = new NSAffineTransform(); xform.Scale((nfloat)(line.DoubleWidth ? 2.0 : 1.0), (nfloat)((line.DoubleHeightTop || line.DoubleHeightBottom) ? 2.0 : 1.0)); xform.Concat(); var spanStart = 0; while (column < line.Count) { bool selected = TextSelection == null ? false : TextSelection.Within(column, row); var backgroundColor = GetBackgroundColor(line[column].Attributes, selected); if (column < (line.Count - 1) && GetBackgroundColor(line[column + 1].Attributes, TextSelection == null ? false : TextSelection.Within(column + 1, row)) == backgroundColor) { column++; continue; } var rect = new CGRect( spanStart * CharacterWidth, ((row - (line.DoubleHeightBottom ? 1 : 0)) * CharacterHeight + verticalOffset) * (line.DoubleHeightBottom | line.DoubleHeightTop ? 0.5 : 1.0), ((column - spanStart + 1) * CharacterWidth) + 0.9, CharacterHeight + 0.9 ); backgroundColor.SetFill(); NSBezierPath.FillRect(rect); column++; spanStart = column; } xform.Invert(); xform.Concat(); row++; } row = ViewTop; foreach (var line in lines) { if (line == null) { row++; continue; } int column = 0; var xform = new NSAffineTransform(); xform.Scale((nfloat)(line.DoubleWidth ? 2.0 : 1.0), (nfloat)((line.DoubleHeightTop || line.DoubleHeightBottom) ? 2.0 : 1.0)); xform.Concat(); var spanStart = 0; string toDisplay = string.Empty; while (column < line.Count) { bool selected = TextSelection == null ? false : TextSelection.Within(column, row); var foregroundColor = GetForegroundColor(line[column].Attributes, selected); toDisplay += line[column].Char.ToString() + line[column].CombiningCharacters; if ( column < (line.Count - 1) && GetForegroundColor(line[column + 1].Attributes, TextSelection == null ? false : TextSelection.Within(column + 1, row)) == foregroundColor && line[column + 1].Attributes.Underscore == line[column].Attributes.Underscore && line[column + 1].Attributes.Reverse == line[column].Attributes.Reverse && line[column + 1].Attributes.Bright == line[column].Attributes.Bright ) { column++; continue; } var textPosition = new CGPoint( spanStart * CharacterWidth, ((row - (line.DoubleHeightBottom ? 1 : 0)) * CharacterHeight + verticalOffset + attributes.Font.Descender) * (line.DoubleHeightBottom | line.DoubleHeightTop ? 0.5 : 1.0) ); attributes.ForegroundColor = foregroundColor; attributes.UnderlineStyle = line[column].Attributes.Underscore ? 1 : 0; var nsStr = new NSString(toDisplay); nsStr.DrawAtPoint(textPosition, attributes.Dictionary); column++; spanStart = column; toDisplay = ""; } xform.Invert(); xform.Concat(); row++; } if (Terminal.CursorState.ShowCursor) { var cursorY = Terminal.ViewPort.TopRow - ViewTop + Terminal.CursorState.CurrentRow; var cursorRect = new CGRect( Terminal.CursorState.CurrentColumn * CharacterWidth, cursorY * CharacterHeight, CharacterWidth + 0.9, CharacterHeight + 0.9 ); var path = NSBezierPath.FromRect(cursorRect); GetForegroundColor(Terminal.CursorState.Attributes, false).Set(); path.Stroke(); } } }