public override void Paint(Cairo.Context gr, Rectangle rect, string subPart = "") { float widthRatio = 1f; float heightRatio = 1f; if (Scaled){ widthRatio = (float)rect.Width / Dimensions.Width; heightRatio = (float)rect.Height / Dimensions.Height; } if (KeepProportions) { if (widthRatio < heightRatio) heightRatio = widthRatio; else widthRatio = heightRatio; } gr.Save (); gr.Translate (rect.Left,rect.Top); gr.Scale (widthRatio, heightRatio); gr.Translate ((rect.Width/widthRatio - Dimensions.Width)/2, (rect.Height/heightRatio - Dimensions.Height)/2); using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32, Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) { gr.SetSourceSurface (imgSurf, 0,0); gr.Paint (); } gr.Restore (); }
public override void Paint(Cairo.Context gr, Rectangle rect, string subPart = "") { float widthRatio = 1f; float heightRatio = 1f; if (Scaled) { widthRatio = (float)rect.Width / Dimensions.Width; heightRatio = (float)rect.Height / Dimensions.Height; } if (KeepProportions) { if (widthRatio < heightRatio) heightRatio = widthRatio; else widthRatio = heightRatio; } gr.Save (); gr.Translate (rect.Left,rect.Top); gr.Scale (widthRatio, heightRatio); gr.Translate (((float)rect.Width/widthRatio - Dimensions.Width)/2f, ((float)rect.Height/heightRatio - Dimensions.Height)/2f); if (string.IsNullOrEmpty (subPart)) hSVG.RenderCairo (gr); else hSVG.RenderCairoSub (gr, "#" + subPart); gr.Restore (); }
/// <summary> /// Draw the robot taking into account the center x and y position of the map which /// will be different from the true center x and y positions on the drawing context. /// This method will result in a red wheeled robot with black tyres being drawn at /// the robots location on the map. /// /// The scale value is currently unused but it could be useful if the map was scaled /// in some way for example a mini-map may be 10 times smaller than the original /// results in 1:10 scale robot. /// </summary> /// <param name="cairoContext">Cairo context to draw to (assuming a map).</param> /// <param name="centerX">Center x position of map to draw onto.</param> /// <param name="centerY">Center y position of map to draw onto.</param> /// <param name="scale">Scale currently unused.</param> public void Draw(Cairo.Context cairoContext, int centerX, int centerY, double scale) { // Scale up to centimeters. int width = (int)(robot.Width * 100); int height = (int)(robot.Height * 100); int x = (int)(robot.X * 100); int y = (int)(robot.Y * 100); // Set a red colour. cairoContext.SetSourceRGB(255, 0, 0); cairoContext.LineWidth = 1.0; cairoContext.LineCap = LineCap.Butt; cairoContext.Translate (centerX + x, centerY - y); cairoContext.Rotate (relativeRotation); // Rotate the robot based on its orientation in radians. // Draw the robot as a triangle. cairoContext.MoveTo (0, -height / 2); cairoContext.LineTo (-width / 2, height / 2); cairoContext.LineTo (width / 2, height / 2); cairoContext.LineTo (0, -height / 2); cairoContext.Stroke (); // Reset the drawing context. cairoContext.Rotate (-relativeRotation); cairoContext.Translate (-(centerX + x), -(centerY - y)); }
protected override void ClippedRender (Cairo.Context cr) { Brush brush = Background; if (!brush.IsValid) { return; } double x = Double.IsNaN (brush.Width) ? 0 : (RenderSize.Width - brush.Width) * XAlign; double y = Double.IsNaN (brush.Height) ? 0 : (RenderSize.Height - brush.Height) * YAlign; cr.Rectangle (0, 0, RenderSize.Width, RenderSize.Height); cr.ClipPreserve (); if (x != 0 || y != 0) { cr.Translate (x, y); } cr.Antialias = Cairo.Antialias.None; brush.Apply (cr); cr.Fill (); }
protected override bool OnDrawn(Cairo.Context cr) { double step_width = Allocation.Width / (double)steps; double step_height = Allocation.Height / (double)steps; double h = 1.0; double s = 0.0; for (int xi = 0, i = 0; xi < steps; xi++) { for (int yi = 0; yi < steps; yi++, i++) { double bg_b = (double)(i / 255.0); double fg_b = 1.0 - bg_b; double x = xi * step_width; double y = yi * step_height; cr.Rectangle (x, y, step_width, step_height); cr.Color = CairoExtensions.ColorFromHsb (h, s, bg_b); cr.Fill (); int tw, th; Pango.Layout layout = new Pango.Layout (PangoContext); layout.SetText (((int)(bg_b * 255.0)).ToString ()); layout.GetPixelSize (out tw, out th); cr.Translate (0.5, 0.5); cr.MoveTo (x + (step_width - tw) / 2.0, y + (step_height - th) / 2.0); cr.Color = CairoExtensions.ColorFromHsb (h, s, fg_b); PangoCairoHelper.ShowLayout (cr, layout); cr.Translate (-0.5, -0.5); } } return true; }
static void oval_path (Cairo.Context gr, double xc, double yc, double xr, double yr) { gr.Translate (xc, yc); gr.Scale (1.0, yr / xr); gr.MoveTo (new PointD (xr, 0.0) ); gr.Arc (0, 0, xr, 0, 2 * M_PI); gr.ClosePath (); }
public virtual void Render(Cairo.Context cr, Layout layout, double x, double y, double w, double h) { cr.Save(); cr.Translate (x,y); // make the background white cr.Color = new Cairo.Color(1, 1, 1); cr.Rectangle(0,0,w,h); cr.Fill(); // calc some values int lw; string prefix = "INV-"+InventoryAbbreviation+"-"; string idString = Id.ToString("0000000000"); // basic text stuff layout.FontDescription = FontDescription.FromString(CalcFont(Layout,layout,h)); layout.Width = (int)(w*Scale.PangoScale); layout.Alignment = Alignment.Center; // draw the description int descH = 0; if(Layout.UseDescription){ Layout descLayout = layout.Copy(); descLayout.SetText (Description); descLayout.GetPixelSize(out lw, out descH); layout.Ellipsize = EllipsizeMode.Middle; layout.Justify = true; cr.Color = new Cairo.Color(0, 0, 0); Pango.CairoHelper.ShowLayout (cr, descLayout); } // draw the barcode text int codeH = 0; if(Layout.UseBarcodeText){ Layout codeLayout = layout.Copy(); codeLayout.SetText (prefix+idString); codeLayout.GetPixelSize(out lw, out codeH); cr.MoveTo(0,h-(double)codeH); cr.Color = new Cairo.Color(0, 0, 0); Pango.CairoHelper.ShowLayout (cr, codeLayout); } // draw the barcode if(Layout.UseBarcode){ double barcodeH = h-((double)codeH+(double)descH+Layout.SpacingSize*2); if(barcodeH>0){ IBarcode bc = new Code128(); bc.WriteString(prefix+idString); bc.WriteEnd(); RenderBarcode(bc,cr,0,descH+Layout.SpacingSize,w,barcodeH); } } cr.Restore(); }
static void draw (Cairo.Context gr, int width, int height) { int w, h; ImageSurface image; gr.Scale (width, height); gr.LineWidth = 0.04; image = new ImageSurface ("data/e.png"); w = image.Width; h = image.Height; gr.Translate (0.5, 0.5); gr.Rotate (45* M_PI/180); gr.Scale (1.0/w, 1.0/h); gr.Translate (-0.5*w, -0.5*h); image.Show (gr, 0, 0); image.Destroy (); }
void IIconBarMarker.DrawIcon (TextEditor ed, Cairo.Context cr, DocumentLine line, int lineNumber, double x, double y, double width, double height) { cr.Save (); cr.Translate ( x + 0.5 + (width - cache.errorPixbuf.Width) / 2, y + 0.5 + (height - cache.errorPixbuf.Height) / 2 ); Gdk.CairoHelper.SetSourcePixbuf ( cr, errors.Any (e => e.IsError) ? cache.errorPixbuf : cache.warningPixbuf, 0, 0); cr.Paint (); cr.Restore (); }
static void draw (Cairo.Context gr, int width, int height) { int w, h; ImageSurface image; Matrix matrix; SurfacePattern pattern; gr.Scale (width, height); gr.LineWidth = 0.04; image = new ImageSurface ("data/e.png"); w = image.Width; h = image.Height; pattern = new SurfacePattern (image); pattern.Extend = Cairo.Extend.Repeat; gr.Translate (0.5, 0.5); gr.Rotate (M_PI / 4); gr.Scale (1 / Math.Sqrt (2), 1 / Math.Sqrt (2)); gr.Translate (- 0.5, - 0.5); matrix = new Matrix (); matrix.InitScale (w * 5.0, h * 5.0); pattern.Matrix = matrix; gr.Pattern = pattern; gr.Rectangle ( new PointD (0, 0), 1.0, 1.0); gr.Fill (); pattern.Destroy (); image.Destroy(); }
public static void Gradient(Cairo.Context cr, Theme theme, Rect rect, double opacity) { cr.Save (); cr.Translate (rect.X, rect.Y); var x = rect.Width / 2.0; var y = rect.Height / 2.0; using (var grad = new Cairo.RadialGradient (x, y, 0, x, y, rect.Width / 2.0)) { grad.AddColorStop (0, new Cairo.Color (0, 0, 0, 0.1 * opacity)); grad.AddColorStop (1, new Cairo.Color (0, 0, 0, 0.35 * opacity)); cr.SetSource (grad); CairoExtensions.RoundedRectangle (cr, rect.X, rect.Y, rect.Width, rect.Height, theme.Context.Radius); cr.Fill (); } cr.Restore (); }
void DrawLinePart (Cairo.Context cr, DocumentLine line, int lineNumber, int logicalRulerColumn, int offset, int length, ref double pangoPosition, ref bool isSelectionDrawn, double y, double maxX, double _lineHeight) { ISyntaxMode mode = Document.SyntaxMode != null && textEditor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : new SyntaxMode (Document); int selectionStart; int selectionEnd; if (this.HideSelection) { selectionStart = selectionEnd = -1; } else { GetSelectionOffsets (line, out selectionStart, out selectionEnd); } // ---- new renderer LayoutWrapper layout = CreateLinePartLayout (mode, line, logicalRulerColumn, offset, length, selectionStart, selectionEnd); int lineOffset = line.Offset; double width = layout.PangoWidth / Pango.Scale.PangoScale; double xPos = pangoPosition / Pango.Scale.PangoScale; // The caret line marker must be drawn below the text markers otherwise the're invisible if ((HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNumber) DrawCaretLineMarker (cr, xPos, y, layout.PangoWidth / Pango.Scale.PangoScale, _lineHeight); // if (!(HighlightCaretLine || textEditor.Options.HighlightCaretLine) || Document.GetLine(Caret.Line) != line) { if (BackgroundRenderer == null) { foreach (var bg in layout.BackgroundColors) { int x1, x2; x1 = layout.Layout.IndexToPos (bg.FromIdx).X; x2 = layout.Layout.IndexToPos (bg.ToIdx).X; DrawRectangleWithRuler ( cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle ((x1 + pangoPosition) / Pango.Scale.PangoScale, y, (x2 - x1) / Pango.Scale.PangoScale + 1, _lineHeight), bg.Color, true); } } bool drawBg = true; bool drawText = true; LineMetrics metrics = new LineMetrics { LineSegment = line, Layout = layout, SelectionStart = selectionStart, SelectionEnd = selectionEnd, TextStartOffset = offset, TextEndOffset = offset + length, TextRenderStartPosition = xPos, TextRenderEndPosition = xPos + width, LineHeight = _lineHeight, WholeLineWidth = textEditor.Allocation.Width - xPos }; foreach (TextLineMarker marker in line.Markers) { if (!marker.IsVisible) continue; if (marker.DrawBackground (textEditor, cr, y, metrics)) { isSelectionDrawn |= (marker.Flags & TextLineMarkerFlags.DrawsSelection) == TextLineMarkerFlags.DrawsSelection; } var bgMarker = marker as IBackgroundMarker; if (bgMarker != null) { isSelectionDrawn |= (marker.Flags & TextLineMarkerFlags.DrawsSelection) == TextLineMarkerFlags.DrawsSelection; drawText &= bgMarker.DrawBackground (textEditor, cr, metrics.Layout, metrics.SelectionStart, metrics.SelectionEnd, metrics.TextStartOffset, metrics.TextEndOffset, y, metrics.TextRenderStartPosition, metrics.TextRenderEndPosition, ref drawBg); continue; } } if (DecorateLineBg != null) DecorateLineBg (cr, layout, offset, length, xPos, y, selectionStart, selectionEnd); if (!isSelectionDrawn && (layout.StartSet || selectionStart == offset + length) && BackgroundRenderer == null) { double startX; double endX; if (selectionStart != offset + length) { var start = layout.Layout.IndexToPos ((int)layout.SelectionStartIndex); startX = System.Math.Floor (start.X / Pango.Scale.PangoScale); var end = layout.Layout.IndexToPos ((int)layout.SelectionEndIndex); endX = System.Math.Ceiling (end.X / Pango.Scale.PangoScale); } else { startX = width; endX = startX; } if (textEditor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX) { endX = startX + 2; } DrawRectangleWithRuler (cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (xPos + startX, y, endX - startX, _lineHeight), this.SelectionColor.Background, true); } // highlight search results TextSegment firstSearch; int o = offset; uint curIndex = 0, byteIndex = 0; if (textEditor.HighlightSearchPattern) { while (!(firstSearch = GetFirstSearchResult (o, offset + length)).IsInvalid) { double x = pangoPosition; HandleSelection (lineOffset, logicalRulerColumn, selectionStart, selectionEnd, System.Math.Max (lineOffset, firstSearch.Offset), System.Math.Min (lineOffset + line.Length, firstSearch.EndOffset), delegate(int start, int end) { uint startIndex = (uint)(start - offset); uint endIndex = (uint)(end - offset); if (startIndex < endIndex && endIndex <= layout.LineChars.Length) { uint startTranslated = TranslateToUTF8Index (layout.LineChars, startIndex, ref curIndex, ref byteIndex); uint endTranslated = TranslateToUTF8Index (layout.LineChars, endIndex, ref curIndex, ref byteIndex); int l, x1, x2; layout.Layout.IndexToLineX ((int)startTranslated, false, out l, out x1); layout.Layout.IndexToLineX ((int)endTranslated, false, out l, out x2); int w = (int) System.Math.Ceiling ((x2 - x1) / Pango.Scale.PangoScale); int s = (int) System.Math.Floor ((x1 + x) / Pango.Scale.PangoScale); double corner = System.Math.Min (4, width) * textEditor.Options.Zoom; cr.Color = MainSearchResult.IsInvalid || MainSearchResult.Offset != firstSearch.Offset ? ColorStyle.SearchResult.Color : ColorStyle.SearchResultMain.Color; FoldingScreenbackgroundRenderer.DrawRoundRectangle (cr, true, true, s, y, corner, w + 1, LineHeight); cr.Fill (); } }, null); o = System.Math.Max (firstSearch.EndOffset, o + 1); } } cr.Save (); cr.Translate (xPos, y); cr.ShowLayout (layout.Layout); cr.Restore (); if (offset == line.Offset) { DrawIndent (cr, layout, line, xPos, y); } if (textEditor.Options.ShowWhitespaces != ShowWhitespaces.Never && !(BackgroundRenderer != null && textEditor.Options.ShowWhitespaces == ShowWhitespaces.Selection)) DecorateTabsAndSpaces (cr, layout, offset, length, xPos, y, selectionStart, selectionEnd); if (lineNumber == Caret.Line) { int caretOffset = Caret.Offset; if (offset <= caretOffset && caretOffset <= offset + length) { int index = caretOffset - offset; if (Caret.Column > line.Length + 1) { string virtualSpace = ""; var data = textEditor.GetTextEditorData (); if (data.HasIndentationTracker && line.Length == 0) { virtualSpace = this.textEditor.GetTextEditorData ().GetIndentationString (Caret.Location); } if (Caret.Column > line.Length + 1 + virtualSpace.Length) virtualSpace += new string (' ', Caret.Column - line.Length - 1 - virtualSpace.Length); // predit layout already contains virtual space. if (!string.IsNullOrEmpty (textEditor.preeditString)) virtualSpace = ""; LayoutWrapper wrapper = new LayoutWrapper (PangoUtil.CreateLayout (textEditor)); wrapper.LineChars = virtualSpace.ToCharArray (); wrapper.Layout.SetText (virtualSpace); wrapper.Layout.Tabs = tabArray; wrapper.Layout.FontDescription = textEditor.Options.Font; int vy, vx; wrapper.Layout.GetSize (out vx, out vy); var x = ((pangoPosition + vx + layout.PangoWidth) / Pango.Scale.PangoScale); SetVisibleCaretPosition (x, y, x, y); xPos = (pangoPosition + layout.PangoWidth) / Pango.Scale.PangoScale; if (!isSelectionDrawn && (selectionEnd == lineOffset + line.Length) && BackgroundRenderer == null) { double startX; double endX; startX = xPos; endX = (pangoPosition + vx + layout.PangoWidth) / Pango.Scale.PangoScale; DrawRectangleWithRuler (cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (startX, y, endX - startX, _lineHeight), this.SelectionColor.Background, true); } // When drawing virtual space before the selection start paint it as unselected. var virtualSpaceMod = selectionStart < caretOffset ? 0 : virtualSpace.Length; if ((!textEditor.IsSomethingSelected || (selectionStart >= offset && selectionStart != selectionEnd)) && (HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNumber) DrawCaretLineMarker (cr, pangoPosition / Pango.Scale.PangoScale, y, vx / Pango.Scale.PangoScale, _lineHeight); if (DecorateLineBg != null) DecorateLineBg (cr, wrapper, offset, length, xPos, y, selectionStart + virtualSpaceMod, selectionEnd + virtualSpace.Length); switch (textEditor.Options.ShowWhitespaces) { case ShowWhitespaces.Selection: if (textEditor.IsSomethingSelected && (selectionStart < offset || selectionStart == selectionEnd) && BackgroundRenderer == null) DecorateTabsAndSpaces (cr, wrapper, offset, length, xPos, y, selectionStart, selectionEnd + virtualSpace.Length); break; case ShowWhitespaces.Always: DecorateTabsAndSpaces (cr, wrapper, offset, length, xPos, y, selectionStart, selectionEnd + virtualSpace.Length); break; } wrapper.Dispose (); pangoPosition += vx; } else if (index == length && string.IsNullOrEmpty (textEditor.preeditString)) { var x = (pangoPosition + layout.PangoWidth) / Pango.Scale.PangoScale; SetVisibleCaretPosition (x, y, x, y); } else if (index >= 0 && index <= length) { Pango.Rectangle strong_pos, weak_pos; curIndex = byteIndex = 0; int utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, (uint)index, ref curIndex, ref byteIndex); layout.Layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); var cx = xPos + (strong_pos.X / Pango.Scale.PangoScale); var cy = y + (strong_pos.Y / Pango.Scale.PangoScale); if (textEditor.preeditCursorCharIndex == 0) { SetVisibleCaretPosition (cx, cy, cx, cy); } else { var preeditIndex = (uint)(index + textEditor.preeditCursorCharIndex); utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, preeditIndex, ref curIndex, ref byteIndex); layout.Layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); var pcx = xPos + (strong_pos.X / Pango.Scale.PangoScale); var pcy = y + (strong_pos.Y / Pango.Scale.PangoScale); SetVisibleCaretPosition (pcx, pcy, cx, cy); } } } } foreach (TextLineMarker marker in line.Markers.Where (m => m.IsVisible)) { if (layout.Layout != null) marker.Draw (textEditor, cr, y, metrics); } foreach (var marker in Document.GetTextSegmentMarkersAt (line).Where (m => m.IsVisible)) { if (layout.Layout != null) marker.Draw (textEditor, cr, layout.Layout, false, /*selected*/offset, offset + length, y, xPos, xPos + width); } pangoPosition += layout.PangoWidth; int scaledDown = (int)(pangoPosition / Pango.Scale.PangoScale); pangoPosition = scaledDown * Pango.Scale.PangoScale; if (layout.IsUncached) layout.Dispose (); }
void DrawEolMarker (Cairo.Context cr, DocumentLine line, bool selected, double x, double y) { if (!textEditor.Options.IncludeWhitespaces.HasFlag (IncludeWhitespaces.LineEndings)) return; Pango.Layout layout; Pango.Rectangle rect; var index = GetEolMarkerIndex (line.UnicodeNewline); layout = eolMarkerLayout [index]; rect = eolMarkerLayoutRect [index]; cr.Save (); cr.Translate (x, y + System.Math.Max (0, LineHeight - rect.Height - 1)); var col = ColorStyle.PlainText.Foreground; if (selected && !SelectionColor.TransparentForeground) { col = SelectionColor.Foreground; } else { if (line != null && line.NextLine != null && line.NextLine.StartSpan != null && line.NextLine.StartSpan.Count > 0) { var span = line.NextLine.StartSpan.Peek (); var chunkStyle = ColorStyle.GetChunkStyle (span.Color); if (chunkStyle != null) col = ColorStyle.GetForeground (chunkStyle); } } cr.SetSourceRGBA (col.R, col.G, col.B, whitespaceMarkerAlpha * 1.4); // needs to more opaque due to font rendering cr.ShowLayout (layout); cr.Restore (); }
void DrawLinePart (Cairo.Context cr, DocumentLine line, int lineNumber, int logicalRulerColumn, int offset, int length, ref double position, ref bool isSelectionDrawn, double y, double maxX, double _lineHeight) { ISyntaxMode mode = Document.SyntaxMode != null && textEditor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : new SyntaxMode (Document); int selectionStartOffset; int selectionEndOffset; if (this.HideSelection) { selectionStartOffset = selectionEndOffset = -1; } else { GetSelectionOffsets (line, out selectionStartOffset, out selectionEndOffset); } // ---- new renderer LayoutWrapper layout = CreateLinePartLayout (mode, line, logicalRulerColumn, offset, length, selectionStartOffset, selectionEndOffset); int lineOffset = line.Offset; double width = layout.Width; double xPos = position; // The caret line marker must be drawn below the text markers otherwise the're invisible if ((HighlightCaretLine || textEditor.GetTextEditorData ().HighlightCaretLine) && Caret.Line == lineNumber) DrawCaretLineMarker (cr, xPos, y, layout.Width, _lineHeight); // if (!(HighlightCaretLine || textEditor.Options.HighlightCaretLine) || Document.GetLine(Caret.Line) != line) { if (BackgroundRenderer == null) { foreach (var bg in layout.BackgroundColors) { int x1, x2; x1 = layout.Layout.IndexToPos (bg.FromIdx).X; x2 = layout.Layout.IndexToPos (bg.ToIdx).X; DrawRectangleWithRuler ( cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (x1 / Pango.Scale.PangoScale + position, y, (x2 - x1) / Pango.Scale.PangoScale + 1, _lineHeight), bg.Color, true); } } var metrics = new LineMetrics { LineSegment = line, Layout = layout, SelectionStart = selectionStartOffset, SelectionEnd = selectionEndOffset, TextStartOffset = offset, TextEndOffset = offset + length, TextRenderStartPosition = xPos, TextRenderEndPosition = xPos + width, LineHeight = _lineHeight, WholeLineWidth = textEditor.Allocation.Width - xPos, LineYRenderStartPosition = y }; foreach (TextLineMarker marker in line.Markers) { if (!marker.IsVisible) continue; if (marker.DrawBackground (textEditor, cr, metrics)) { isSelectionDrawn |= (marker.Flags & TextLineMarkerFlags.DrawsSelection) == TextLineMarkerFlags.DrawsSelection; } } var textSegmentMarkers = TextDocument.OrderTextSegmentMarkersByInsertion (Document.GetTextSegmentMarkersAt (line).Where (m => m.IsVisible)).ToArray (); foreach (var marker in textSegmentMarkers) { if (layout.Layout != null) marker.DrawBackground (textEditor, cr, metrics, offset, offset + length); } if (DecorateLineBg != null) DecorateLineBg (cr, layout, offset, length, xPos, y, selectionStartOffset, selectionEndOffset); if (!isSelectionDrawn && (layout.StartSet || selectionStartOffset == offset + length) && BackgroundRenderer == null) { double startX; int startY; double endX; int endY; if (selectionStartOffset != offset + length) { var start = layout.Layout.IndexToPos (layout.SelectionStartIndex); startX = System.Math.Floor (start.X / Pango.Scale.PangoScale); startY = (int)(y + System.Math.Floor (start.Y / Pango.Scale.PangoScale)); var end = layout.Layout.IndexToPos (layout.SelectionEndIndex); endX = System.Math.Ceiling (end.X / Pango.Scale.PangoScale); endY = (int)(y + System.Math.Ceiling (end.Y / Pango.Scale.PangoScale)); } else { startY = endY = (int)y; startX = width; endX = startX; } if (textEditor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX) { endX = startX + 2; } if (startY == endY) { DrawRectangleWithRuler ( cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (xPos + startX, startY, endX - startX, LineHeight), this.SelectionColor.Background, true ); } else { DrawRectangleWithRuler ( cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (xPos + startX, startY, textEditor.Allocation.Width - xPos - startX, LineHeight), this.SelectionColor.Background, true ); if (endY - startY > LineHeight) { DrawRectangleWithRuler ( cr, xPos, new Cairo.Rectangle (xPos, startY + LineHeight, textEditor.Allocation.Width - xPos, endY - startY - LineHeight), this.SelectionColor.Background, true ); } DrawRectangleWithRuler ( cr, xPos, new Cairo.Rectangle (xPos, endY, endX, LineHeight), this.SelectionColor.Background, true ); } } // highlight search results TextSegment firstSearch; int o = offset; uint curIndex = 0, byteIndex = 0; if (textEditor.HighlightSearchPattern) { while (!(firstSearch = GetFirstSearchResult (o, offset + length)).IsInvalid) { double x = position; HandleSelection (lineOffset, logicalRulerColumn, selectionStartOffset, selectionEndOffset, System.Math.Max (lineOffset, firstSearch.Offset), System.Math.Min (lineOffset + line.Length, firstSearch.EndOffset), delegate(int start, int end) { uint startIndex = (uint)(start - offset); uint endIndex = (uint)(end - offset); if (startIndex < endIndex && endIndex <= layout.LineChars.Length) { uint startTranslated = TranslateToUTF8Index (layout.LineChars, startIndex, ref curIndex, ref byteIndex); uint endTranslated = TranslateToUTF8Index (layout.LineChars, endIndex, ref curIndex, ref byteIndex); int l, x1, x2; layout.Layout.IndexToLineX ((int)startTranslated, false, out l, out x1); layout.Layout.IndexToLineX ((int)endTranslated, false, out l, out x2); int w = (int) System.Math.Ceiling ((x2 - x1) / Pango.Scale.PangoScale); int s = (int) System.Math.Floor (x1 / Pango.Scale.PangoScale + x); double corner = System.Math.Min (4, width) * textEditor.Options.Zoom; cr.SetSourceColor (MainSearchResult.IsInvalid || MainSearchResult.Offset != firstSearch.Offset ? ColorStyle.SearchResult.Color : ColorStyle.SearchResultMain.Color); FoldingScreenbackgroundRenderer.DrawRoundRectangle (cr, true, true, s, y, corner, w + 1, LineHeight); cr.Fill (); } }, null); o = System.Math.Max (firstSearch.EndOffset, o + 1); } } cr.Save (); cr.Translate (xPos, y); cr.ShowLayout (layout.Layout); cr.Restore (); if (offset == line.Offset) { DrawIndent (cr, layout, line, xPos, y); } if (textEditor.Options.ShowWhitespaces != ShowWhitespaces.Never && !(BackgroundRenderer != null && textEditor.Options.ShowWhitespaces == ShowWhitespaces.Selection)) DecorateTabsAndSpaces (cr, layout, offset, xPos, y, selectionStartOffset, selectionEndOffset); if (textEditor.IsSomethingSelected && !isSelectionDrawn && BackgroundRenderer == null) { if (lineNumber == textEditor.MainSelection.End.Line && textEditor.MainSelection.End.Column > line.Length + 1) { using (var wrapper = GetVirtualSpaceLayout (line, textEditor.MainSelection.End)) { double startX; double endX; startX = xPos; endX = position + wrapper.Width + layout.Width; DrawRectangleWithRuler (cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (startX, y, endX - startX, _lineHeight), this.SelectionColor.Background, true); if (lineNumber == Caret.Line && textEditor.Options.ShowWhitespaces == ShowWhitespaces.Selection && textEditor.IsSomethingSelected && (selectionStartOffset < offset || selectionStartOffset == selectionEndOffset) && BackgroundRenderer == null) { DecorateTabsAndSpaces (cr, wrapper, offset, xPos, y, selectionStartOffset, selectionEndOffset + wrapper.LineChars.Length); } } } } if (lineNumber == Caret.Line) { int caretOffset = Caret.Offset; if (offset <= caretOffset && caretOffset <= offset + length) { int index = caretOffset - offset; //This if means we have temporary indent if (Caret.Column > line.Length + 1) { using (var wrapper = GetVirtualSpaceLayout (line, Caret.Location)) { var x = (position + wrapper.Width) + layout.Width; SetVisibleCaretPosition (x, y, x, y); xPos = position + layout.Width; // When drawing virtual space before the selection start paint it as unselected. var virtualSpaceMod = selectionStartOffset < caretOffset ? 0 : wrapper.LineChars.Length; if ((!textEditor.IsSomethingSelected || (selectionStartOffset >= offset && selectionStartOffset != selectionEndOffset)) && (HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNumber) DrawCaretLineMarker (cr, position, y, wrapper.Width, _lineHeight); if (DecorateLineBg != null) DecorateLineBg (cr, wrapper, offset, length, xPos, y, selectionStartOffset + virtualSpaceMod, selectionEndOffset + wrapper.LineChars.Length); if (textEditor.Options.ShowWhitespaces == ShowWhitespaces.Always) { DecorateTabsAndSpaces (cr, wrapper, offset, xPos, y, selectionStartOffset, selectionEndOffset + wrapper.LineChars.Length); } } } else if (index == length && string.IsNullOrEmpty (textEditor.preeditString)) { var x = position + layout.Width; SetVisibleCaretPosition (x, y, x, y); } else if (index >= 0 && index <= length) { Pango.Rectangle strong_pos, weak_pos; curIndex = byteIndex = 0; int utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, (uint)index, ref curIndex, ref byteIndex); layout.Layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); var cx = xPos + (strong_pos.X / Pango.Scale.PangoScale); var cy = y + (strong_pos.Y / Pango.Scale.PangoScale); if (textEditor.preeditCursorCharIndex == 0) { SetVisibleCaretPosition (cx, cy, cx, cy); } else { var preeditIndex = (uint)(index + textEditor.preeditCursorCharIndex); utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, preeditIndex, ref curIndex, ref byteIndex); layout.Layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); var pcx = xPos + (strong_pos.X / Pango.Scale.PangoScale); var pcy = y + (strong_pos.Y / Pango.Scale.PangoScale); SetVisibleCaretPosition (pcx, pcy, cx, cy); } } } } foreach (TextLineMarker marker in line.Markers.Where (m => m.IsVisible)) { if (layout.Layout != null) marker.Draw (textEditor, cr, metrics); } foreach (var marker in textSegmentMarkers) { if (layout.Layout != null) marker.Draw (textEditor, cr, metrics, offset, offset + length); } position += System.Math.Floor (layout.LastLineWidth); if (layout.IsUncached) layout.Dispose (); }
protected void DrawScaledSurfaceAt(Cairo.Context gr, ImageSurface image, double x, double y, double height, double width) { //calculate proportional scaling var img_height = image.Height; var img_width = image.Width; var width_ratio = (width) / (img_width); var height_ratio = (height) / (img_height); var scale_xy = Math.Min(height_ratio, width_ratio); //scale image and add it gr.Save(); gr.Scale(scale_xy, scale_xy); gr.Translate(x, y); gr.SetSource(image,(int)x, (int)y); gr.Paint(); gr.Restore(); }
public void Draw (TextEditor editor, Cairo.Context g, int lineNr, Cairo.Rectangle lineArea) { EnsureLayoutCreated (editor); int lineNumber = editor.Document.OffsetToLineNumber (lineSegment.Offset); int errorNumber = lineNr - lineNumber; double x = editor.TextViewMargin.XOffset; double y = lineArea.Y; double right = editor.Allocation.Width; int errorCounterWidth = 0; int ew = 0, eh = 0; if (errors.Count > 1 && errorCountLayout != null) { errorCountLayout.GetPixelSize (out ew, out eh); errorCounterWidth = ew + 10; } double x2 = System.Math.Max (right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0) - errorCounterWidth, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); // bool isEolSelected = editor.IsSomethingSelected && editor.SelectionMode != SelectionMode.Block ? editor.SelectionRange.Contains (lineSegment.Offset + lineSegment.EditableLength) : false; int active = editor.Document.GetTextAt (lineSegment) == initialText ? 0 : 1; bool isCaretInLine = lineSegment.Offset <= editor.Caret.Offset && editor.Caret.Offset <= lineSegment.EndOffset; int highlighted = active == 0 && isCaretInLine ? 1 : 0; int selected = 0; LayoutDescriptor layout = layouts[errorNumber]; x2 = right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0); x2 -= errorCounterWidth; x2 = System.Math.Max (x2, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); g.MoveTo (new Cairo.PointD (x2 + 0.5, y)); g.LineTo (new Cairo.PointD (x2 + 0.5, y + editor.LineHeight)); g.LineTo (new Cairo.PointD (right, y + editor.LineHeight)); g.LineTo (new Cairo.PointD (right, y)); g.ClosePath (); g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, selected]; g.Fill (); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.MoveTo (new Cairo.PointD (x2 + 0.5, y)); g.LineTo (new Cairo.PointD (x2 + 0.5, y + editor.LineHeight)); if (errorNumber == errors.Count - 1) g.LineTo (new Cairo.PointD (lineArea.X + lineArea.Width, y + editor.LineHeight)); g.Stroke (); if (editor.Options.ShowRuler) { double divider = Math.Max (editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo (new Cairo.PointD (divider + 0.5, y)); g.LineTo (new Cairo.PointD (divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Stroke (); } } g.Save (); g.Translate (x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border, y + (editor.LineHeight - layout.Height) / 2 + layout.Height % 2); g.Color = selected == 0 ? gc : gcSelected; g.ShowLayout (layout.Layout); g.Restore (); // if (ShowIconsInBubble) // win.DrawPixbuf (editor.Style.BaseGC (Gtk.StateType.Normal), errors[errorNumber].IsError ? errorPixbuf : warningPixbuf, 0, 0, x2, y + (editor.LineHeight - errorPixbuf.Height) / 2, errorPixbuf.Width, errorPixbuf.Height, Gdk.RgbDither.None, 0, 0); }
public bool DrawBackground (TextEditor editor, Cairo.Context g, TextViewMargin.LayoutWrapper layout2, int selectionStart, int selectionEnd, int startOffset, int endOffset, double y, double startXPos, double endXPos, ref bool drawBg) { if (!IsVisible || DebuggingService.IsDebugging) return true; EnsureLayoutCreated (editor); double x = editor.TextViewMargin.XOffset; int right = editor.Allocation.Width; int errorCounterWidth = 0; bool isCaretInLine = startOffset <= editor.Caret.Offset && editor.Caret.Offset <= endOffset; int ew = 0, eh = 0; if (errors.Count > 1 && errorCountLayout != null) { errorCountLayout.GetPixelSize (out ew, out eh); errorCounterWidth = ew + 10; } double x2 = System.Math.Max (right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0) - errorCounterWidth, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); bool isEolSelected = editor.IsSomethingSelected && editor.SelectionMode != SelectionMode.Block ? editor.SelectionRange.Contains (lineSegment.Offset + lineSegment.EditableLength) : false; int active = editor.Document.GetTextAt (lineSegment) == initialText ? 0 : 1; int highlighted = active == 0 && isCaretInLine ? 1 : 0; int selected = 0; double topSize = editor.LineHeight / 2; double bottomSize = editor.LineHeight / 2 + editor.LineHeight % 2; if (!fitsInSameLine) { if (isEolSelected) { x -= (int)editor.HAdjustment.Value; editor.TextViewMargin.DrawRectangleWithRuler (g, x, new Cairo.Rectangle (x, y + editor.LineHeight, editor.TextViewMargin.TextStartPosition, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true); editor.TextViewMargin.DrawRectangleWithRuler (g, x + editor.TextViewMargin.TextStartPosition, new Cairo.Rectangle (x + editor.TextViewMargin.TextStartPosition, y + editor.LineHeight, editor.Allocation.Width + (int)editor.HAdjustment.Value, editor.LineHeight), editor.ColorStyle.Selection.CairoBackgroundColor, true); x += (int)editor.HAdjustment.Value; } else { editor.TextViewMargin.DrawRectangleWithRuler (g, x, new Cairo.Rectangle (x, y + editor.LineHeight, x2, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true); } } DrawRectangle (g, x, y, right, topSize); g.Color = colorMatrix[active, TOP, LIGHT, highlighted, selected]; g.Fill (); DrawRectangle (g, x, y + topSize, right, bottomSize); g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, selected]; g.Fill (); g.MoveTo (new Cairo.PointD (x, y + 0.5)); g.LineTo (new Cairo.PointD (x + right, y + 0.5)); g.Color = colorMatrix[active, TOP, LINE, highlighted, selected]; g.Stroke (); g.MoveTo (new Cairo.PointD (x, y + editor.LineHeight - 0.5)); g.LineTo (new Cairo.PointD ((fitsInSameLine ? x + right : x2 + 1), y + editor.LineHeight - 0.5)); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.Stroke (); if (editor.Options.ShowRuler) { double divider = Math.Max (editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); g.MoveTo (new Cairo.PointD (divider + 0.5, y)); g.LineTo (new Cairo.PointD (divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.Stroke (); } // draw background if (layout2.StartSet || selectionStart == endOffset) { double startX; double endX; if (selectionStart != endOffset) { var start = layout2.Layout.IndexToPos ((int)layout2.SelectionStartIndex); startX = (int)(start.X / Pango.Scale.PangoScale); var end = layout2.Layout.IndexToPos ((int)layout2.SelectionEndIndex); endX = (int)(end.X / Pango.Scale.PangoScale); } else { startX = x2; endX = startX; } if (editor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX) endX = startX + 2; startX += startXPos; endX += startXPos; startX = Math.Max (editor.TextViewMargin.XOffset, startX); // clip region to textviewmargin start if (isEolSelected) endX = editor.Allocation.Width + (int)editor.HAdjustment.Value; if (startX < endX) { DrawRectangle (g, startX, y, endX - startX, topSize); g.Color = colorMatrix[active, TOP, LIGHT, highlighted, 1]; g.Fill (); DrawRectangle (g, startX, y + topSize, endX - startX, bottomSize); g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, 1]; g.Fill (); g.MoveTo (new Cairo.PointD (startX, y + 0.5)); g.LineTo (new Cairo.PointD (endX, y + 0.5)); g.Color = colorMatrix[active, TOP, LINE, highlighted, 1]; g.Stroke (); if (startX < x2) { g.MoveTo (new Cairo.PointD (startX, y + editor.LineHeight - 0.5)); g.LineTo (new Cairo.PointD (System.Math.Min (endX, x2 + 1), y + editor.LineHeight - 0.5)); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, 1]; g.Stroke (); if (x2 + 1 < endX) { g.MoveTo (new Cairo.PointD (x2 + 1, y + editor.LineHeight - 0.5)); g.LineTo (new Cairo.PointD (endX, y + editor.LineHeight - 0.5)); g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, 1]; g.Stroke (); } } if (editor.Options.ShowRuler) { double divider = Math.Max (editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); g.MoveTo (new Cairo.PointD (divider + 0.5, y)); g.LineTo (new Cairo.PointD (divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, 1]; g.Stroke (); } } } if (!fitsInSameLine) y += editor.LineHeight; double y2 = y + 0.5; double y2Bottom = y2 + editor.LineHeight - 1; selected = isEolSelected && (CollapseExtendedErrors || errors.Count == 1) ? 1 : 0; // draw message text background if (CollapseExtendedErrors || errors.Count == 1) { if (!fitsInSameLine) { // draw box below line g.MoveTo (new Cairo.PointD (x2 + 0.5, y2 - 1)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2 - 1)); g.ClosePath (); g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, selected]; g.Fill (); g.MoveTo (new Cairo.PointD (x2 + 0.5, y2 - 1)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2Bottom)); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.Stroke (); } else { // draw 'arrow marker' in the same line g.MoveTo (new Cairo.PointD (x2 + 0.5, y2)); double mid = y2 + topSize; g.LineTo (new Cairo.PointD (x2 - editor.LineHeight / 2 + 0.5, mid)); g.LineTo (new Cairo.PointD (right, mid)); g.LineTo (new Cairo.PointD (right, y2)); g.ClosePath (); g.Color = colorMatrix[active, TOP, DARK, highlighted, selected]; g.Fill (); g.MoveTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.LineTo (new Cairo.PointD (x2 - editor.LineHeight / 2 + 0.5, mid)); g.LineTo (new Cairo.PointD (right, mid)); g.LineTo (new Cairo.PointD (right, y2Bottom)); g.ClosePath (); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Fill (); // draw border g.MoveTo (new Cairo.PointD (x2 + 0.5, y2)); g.LineTo (new Cairo.PointD (x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2)); g.ClosePath (); g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.Stroke (); } } else { if (!fitsInSameLine) { // draw box below line g.MoveTo (new Cairo.PointD (x2 + 0.5, y2 - 1)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2 - 1)); g.ClosePath (); } else { // draw filled arrow box g.MoveTo (new Cairo.PointD (x2 + 0.5, y2)); g.LineTo (new Cairo.PointD (x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2Bottom)); g.LineTo (new Cairo.PointD (right, y2)); g.ClosePath (); } g.Color = colorMatrix[active, BOTTOM, LIGHT, highlighted, selected]; g.Fill (); // draw light bottom line g.MoveTo (new Cairo.PointD (right, y2Bottom)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); g.Stroke (); // stroke left line if (fitsInSameLine) { g.MoveTo (new Cairo.PointD (x2 + 0.5, y2)); g.LineTo (new Cairo.PointD (x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom)); } else { g.MoveTo (new Cairo.PointD (x2 + 0.5, y2 - 1)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2Bottom + 1)); } g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.Stroke (); // stroke top line if (fitsInSameLine) { g.Color = colorMatrix[active, BOTTOM, LINE, highlighted, selected]; g.MoveTo (new Cairo.PointD (right, y2)); g.LineTo (new Cairo.PointD (x2 + 0.5, y2)); g.Stroke (); } } if (editor.Options.ShowRuler) { double divider = Math.Max (editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo (new Cairo.PointD (divider + 0.5, y2)); g.LineTo (new Cairo.PointD (divider + 0.5, y2Bottom)); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Stroke (); } } if (errors.Count > 1 && errorCountLayout != null) { double rX = x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth; double rY = y + editor.LineHeight / 6; double rW = errorCounterWidth - 2; double rH = editor.LineHeight * 3 / 4; BookmarkMarker.DrawRoundRectangle (g, rX, rY, 8, rW, rH); g.Color = oldIsOver ? new Cairo.Color (0.3, 0.3, 0.3) : new Cairo.Color (0.5, 0.5, 0.5); g.Fill (); if (CollapseExtendedErrors) { g.Color = gcLight; g.Save (); g.Translate (x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth + 4, y + (editor.LineHeight - eh) / 2 + eh % 2); g.ShowLayout (errorCountLayout); g.Restore (); } else { g.MoveTo (rX + rW / 2 - rW / 4, rY + rH - rH / 4); g.LineTo (rX + rW / 2 + rW / 4, rY + rH - rH / 4); g.LineTo (rX + rW / 2, rY + rH / 4); g.ClosePath (); g.Color = new Cairo.Color (1, 1, 1); g.Fill (); } } for (int i = 0; i < layouts.Count; i++) { LayoutDescriptor layout = layouts[i]; x2 = right - layout.Width - border - errorPixbuf.Width; if (i == 0) x2 -= errorCounterWidth; x2 = System.Math.Max (x2, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset); if (i > 0) { editor.TextViewMargin.DrawRectangleWithRuler (g, x, new Cairo.Rectangle (x, y, right, editor.LineHeight), isEolSelected ? editor.ColorStyle.Selection.CairoBackgroundColor : editor.ColorStyle.Default.CairoBackgroundColor, true); g.MoveTo (new Cairo.PointD (x2 + 0.5, y)); g.LineTo (new Cairo.PointD (x2 + 0.5, y + editor.LineHeight)); g.LineTo (new Cairo.PointD (right, y + editor.LineHeight)); g.LineTo (new Cairo.PointD (right, y)); g.ClosePath (); if (CollapseExtendedErrors) { Cairo.Gradient pat = new Cairo.LinearGradient (x2, y, x2, y + editor.LineHeight); pat.AddColorStop (0, colorMatrix[active, TOP, LIGHT, highlighted, selected]); pat.AddColorStop (1, colorMatrix[active, BOTTOM, LIGHT, highlighted, selected]); g.Pattern = pat; } else { g.Color = colorMatrix[active, TOP, LIGHT, highlighted, selected]; } g.Fill (); if (editor.Options.ShowRuler) { double divider = Math.Max (editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX); if (divider >= x2) { g.MoveTo (new Cairo.PointD (divider + 0.5, y)); g.LineTo (new Cairo.PointD (divider + 0.5, y + editor.LineHeight)); g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected]; g.Stroke (); } } } int lw, lh; layout.Layout.GetPixelSize (out lw, out lh); g.Color = (HslColor)(selected == 0 ? gc : gcSelected); g.Save (); g.Translate (x2 + errorPixbuf.Width + border, y + (editor.LineHeight - layout.Height) / 2 + layout.Height % 2); g.ShowLayout (layout.Layout); g.Restore (); y += editor.LineHeight; if (!UseVirtualLines) break; } return true; }
public override void DrawAfterEol (TextEditor textEditor, Cairo.Context g, double y, EndOfLineMetrics metrics) { EnsureLayoutCreated (editor); int errorCounterWidth = 0, eh = 0; if (errorCountLayout != null) errorCountLayout.GetPixelSize (out errorCounterWidth, out eh); var sx = metrics.TextRenderEndPosition; var width = LayoutWidth + errorCounterWidth + editor.LineHeight; var drawLayout = layouts[0].Layout; int ex = 0 , ey = 0; bool customLayout = sx + width > editor.Allocation.Width; bool hideText = false; bubbleIsReduced = customLayout; if (customLayout) { width = editor.Allocation.Width - sx; string text = layouts[0].Layout.Text; drawLayout = new Pango.Layout (editor.PangoContext); drawLayout.FontDescription = cache.fontDescription; for (int j = text.Length - 4; j > 0; j--) { drawLayout.SetText (text.Substring (0, j) + "..."); drawLayout.GetPixelSize (out ex, out ey); if (ex + (errorCountLayout != null ? errorCounterWidth : 0) + editor.LineHeight < width) break; } if (ex + (errorCountLayout != null ? errorCounterWidth : 0) + editor.LineHeight > width) { hideText = true; drawLayout.SetMarkup ("<span weight='heavy'>···</span>"); width = Math.Max (17, errorCounterWidth) + editor.LineHeight; sx = Math.Min (sx, editor.Allocation.Width - width); } } bubbleDrawX = sx - editor.TextViewMargin.XOffset; bubbleDrawY = y; bubbleWidth = width; g.RoundedRectangle (sx, y + 1, width, editor.LineHeight - 2, editor.LineHeight / 2 - 1); g.Color = TagColor.Color; g.Fill (); if (errorCounterWidth > 0 && errorCountLayout != null) { g.RoundedRectangle (sx + width - errorCounterWidth - editor.LineHeight / 2, y + 2, errorCounterWidth, editor.LineHeight - 4, editor.LineHeight / 2 - 3); g.Color = CounterColor.Color; g.Fill (); g.Save (); g.Translate (sx + width - errorCounterWidth - editor.LineHeight / 2 + (errorCounterWidth - errorCounterWidth) / 2, y + 1); g.Color = CounterColor.SecondColor; g.ShowLayout (errorCountLayout); g.Restore (); } if (errorCounterWidth <= 0 || errorCountLayout == null || !hideText) { g.Save (); g.Translate (sx + editor.LineHeight / 2, y + (editor.LineHeight - layouts [0].Height) / 2 + layouts [0].Height % 2); g.Color = TagColor.SecondColor; g.ShowLayout (drawLayout); g.Restore (); } if (customLayout) drawLayout.Dispose (); }
void DrawBuildEffect (Cairo.Context context, Gdk.Rectangle area, double progress, double opacity) { context.Save (); LayoutRoundedRectangle (context, area); context.Clip (); Gdk.Point center = new Gdk.Point (area.Left + 19, (area.Top + area.Bottom) / 2); context.Translate (center.X, center.Y); var circles = new [] { new { Radius = 200, Thickness = 12, Speed = 1, ArcLength = Math.PI * 1.50 }, new { Radius = 195, Thickness = 15, Speed = 2, ArcLength = Math.PI * 0.50 }, new { Radius = 160, Thickness = 17, Speed = 3, ArcLength = Math.PI * 0.75 }, new { Radius = 200, Thickness = 15, Speed = 2, ArcLength = Math.PI * 0.25 }, new { Radius = 240, Thickness = 12, Speed = 3, ArcLength = Math.PI * 1.50 }, new { Radius = 160, Thickness = 17, Speed = 3, ArcLength = Math.PI * 0.75 }, new { Radius = 200, Thickness = 15, Speed = 2, ArcLength = Math.PI * 0.25 }, new { Radius = 215, Thickness = 20, Speed = 2, ArcLength = Math.PI * 1.25 } }; double zmod = 1.0d; double zporg = progress; foreach (var arc in circles) { double zoom = 1.0d; zoom = (double) Math.Sin (zporg * Math.PI * 2 + zmod); zoom = ((zoom + 1) / 6.0d) + .05d; context.Rotate (Math.PI * 2 * progress * arc.Speed); context.MoveTo (arc.Radius * zoom, 0); context.Arc (0, 0, arc.Radius * zoom, 0, arc.ArcLength); context.LineWidth = arc.Thickness * zoom; context.Color = CairoExtensions.ParseColor ("B1DDED", 0.35 * opacity); context.Stroke (); context.Rotate (Math.PI * 2 * -progress * arc.Speed); progress = -progress; context.Rotate (Math.PI * 2 * progress * arc.Speed); context.MoveTo (arc.Radius * zoom, 0); context.Arc (0, 0, arc.Radius * zoom, 0, arc.ArcLength); context.LineWidth = arc.Thickness * zoom; context.Stroke (); context.Rotate (Math.PI * 2 * -progress * arc.Speed); progress = -progress; zmod += (float)Math.PI / circles.Length; } context.LineWidth = 1; context.ResetClip (); context.Restore (); }
public override void DrawForeground (TextEditor editor, Cairo.Context cr, MarginDrawMetrics metrics) { cr.Save (); cr.Translate ( metrics.X + 0.5 + (metrics.Width - 2 - cache.errorPixbuf.Width) / 2, metrics.Y + 0.5 + (metrics.Height - cache.errorPixbuf.Height) / 2 ); Gdk.CairoHelper.SetSourcePixbuf ( cr, errors.Any (e => e.IsError) ? cache.errorPixbuf : cache.warningPixbuf, 0, 0); cr.Paint (); cr.Restore (); }
protected override void OnDrawContent (Gdk.EventExpose evnt, Cairo.Context g) { g.Rectangle (0, 0, Allocation.Width, Allocation.Height); g.SetSourceColor (marker.TooltipColor.Color); g.Fill (); using (var drawingLayout = new Pango.Layout (this.PangoContext)) { drawingLayout.FontDescription = cache.tooltipFontDescription; double y = verticalTextBorder; var showBulletedList = marker.Errors.Count > 1; foreach (var msg in marker.Errors) { var icon = msg.IsError ? errorPixbuf : warningPixbuf; int w, h; if (!showBulletedList) drawingLayout.Width = maxTextWidth; drawingLayout.SetText (GetFirstLine (msg)); drawingLayout.GetPixelSize (out w, out h); if (showBulletedList) { g.Save (); g.Translate (textBorder, y + verticalTextSpace / 2 + Math.Max (0, (h - icon.Height) / 2)); g.DrawImage (this, icon, 0, 0); g.Restore (); } g.Save (); g.Translate (showBulletedList ? textBorder + iconTextSpacing + icon.Width: textBorder, y + verticalTextSpace / 2); g.SetSourceColor (marker.TagColor.SecondColor); g.ShowLayout (drawingLayout); g.Restore (); y += h + verticalTextSpace; } } }
void DrawEolMarker (Cairo.Context cr, DocumentLine line, bool selected, double x, double y) { if (!textEditor.Options.IncludeWhitespaces.HasFlag (IncludeWhitespaces.LineEndings)) return; Pango.Layout layout; Pango.Rectangle rect; switch (line.DelimiterLength) { case 0: // an emty line end should only happen at eof layout = eofEolLayout; rect = eofEolLayoutRect; break; case 1: var eolIndex = GetEolMarkerIndex (Document.GetCharAt (line.Offset + line.Length)); layout = eolMarkerLayout[eolIndex]; rect = eolMarkerLayoutRect[eolIndex]; break; case 2: layout = eolMarkerLayout[2]; rect = eolMarkerLayoutRect[2]; break; default: throw new InvalidOperationException (); // other line endings are not known. } cr.Save (); cr.Translate (x, y + System.Math.Max (0, LineHeight - rect.Height - 1)); var col = ColorStyle.PlainText.Foreground; if (selected && !SelectionColor.TransparentForeground) { col = SelectionColor.Foreground; } else { if (line != null && line.NextLine != null && line.NextLine.StartSpan != null && line.NextLine.StartSpan.Count > 0) { var span = line.NextLine.StartSpan.Peek (); var chunkStyle = ColorStyle.GetChunkStyle (span.Color); if (chunkStyle != null) col = ColorStyle.GetForeground (chunkStyle); } } cr.Color = new Cairo.Color (col.R, col.G, col.B, whitespaceMarkerAlpha); cr.ShowLayout (layout); cr.Restore (); }
private static unsafe void Renderer() { int tmp_mouse_X, tmp_mouse_Y; int old_mouse_X = -1, old_mouse_Y = -1; bool update; while (true) { tmp_mouse_X = Mouse_X; tmp_mouse_Y = Mouse_Y; update = false; Cairo.Save(MainContext); Cairo.Save(VideoContext); if (tmp_mouse_X != old_mouse_X || tmp_mouse_Y != old_mouse_Y) { update = true; Cairo.Rectangle(32, 32, old_mouse_Y, old_mouse_X, MainContext); Cairo.Rectangle(32, 32, old_mouse_Y, old_mouse_X, VideoContext); Cairo.Rectangle(32, 32, tmp_mouse_Y, tmp_mouse_X, VideoContext); } old_mouse_X = tmp_mouse_X; old_mouse_Y = tmp_mouse_Y; var queue = RedrawRects; Monitor.AcquireLock(ref RedrawRectsLock); while (queue.Count > 0) { var rect = (Rect *)queue.Dequeue(); Cairo.Rectangle(rect->Height, rect->Width, rect->Y, rect->X, MainContext); Cairo.Rectangle(rect->Height, rect->Width, rect->Y, rect->X, VideoContext); Libc.free((uint)rect); update = true; } Monitor.ReleaseLock(ref RedrawRectsLock); if (update) { Cairo.Clip(MainContext); var list = Stacking; Monitor.AcquireLock(ref StackingLock); int count = list.Count; for (int index = 0; index < count; index++) { var win = list[index]; Cairo.Save(MainContext); Cairo.Translate(win.Y, win.X, MainContext); Cairo.SetSourceSurface(0, 0, win.Surface, MainContext); Cairo.Paint(MainContext); Cairo.Restore(MainContext); } Monitor.ReleaseLock(ref StackingLock); } if (update) { Cairo.Clip(VideoContext); Cairo.Translate(0, 0, VideoContext); Cairo.SetOperator(Operator.Source, VideoContext); Cairo.SetSourceSurface(0, 0, MainSurface, VideoContext); Cairo.Paint(VideoContext); Cairo.Translate(old_mouse_Y, old_mouse_X, VideoContext); Cairo.SetOperator(Operator.Over, VideoContext); Cairo.SetSourceSurface(0, 0, MouseSurface, VideoContext); Cairo.Paint(VideoContext); } Cairo.Restore(MainContext); Cairo.Restore(VideoContext); Task.Switch(); } }
protected internal override void Draw (Cairo.Context cr, Cairo.Rectangle area, DocumentLine line, int lineNr, double x, double y, double _lineHeight) { // double xStart = System.Math.Max (area.X, XOffset); // xStart = System.Math.Max (0, xStart); var correctedXOffset = System.Math.Floor (XOffset) - 1; var lineArea = new Cairo.Rectangle (correctedXOffset, y, textEditor.Allocation.Width - correctedXOffset, _lineHeight); int width, height; double pangoPosition = (x - textEditor.HAdjustment.Value + TextStartPosition) * Pango.Scale.PangoScale; defaultBgColor = Document.ReadOnly ? ColorStyle.BackgroundReadOnly.Color : ColorStyle.PlainText.Background; // Draw the default back color for the whole line. Colors other than the default // background will be drawn when rendering the text chunks. if (BackgroundRenderer == null) DrawRectangleWithRuler (cr, x, lineArea, defaultBgColor, true); bool isSelectionDrawn = false; // Check if line is beyond the document length if (line == null) { var marker = Document.GetExtendingTextMarker (lineNr); if (marker != null) marker.Draw (textEditor, cr, lineNr, lineArea); return; } IEnumerable<FoldSegment> foldings = Document.GetStartFoldings (line); int offset = line.Offset; int caretOffset = Caret.Offset; bool isEolFolded = false; restart: int logicalRulerColumn = line.GetLogicalColumn (textEditor.GetTextEditorData (), textEditor.Options.RulerColumn); if ((HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNr) DrawCaretLineMarker (cr, x, y, TextStartPosition, _lineHeight); foreach (FoldSegment folding in foldings) { int foldOffset = folding.StartLine.Offset + folding.Column - 1; if (foldOffset < offset) continue; if (folding.IsFolded) { DrawLinePart (cr, line, lineNr, logicalRulerColumn, offset, foldOffset - offset, ref pangoPosition, ref isSelectionDrawn, y, area.X + area.Width, _lineHeight); offset = folding.EndLine.Offset + folding.EndColumn - 1; markerLayout.SetText (folding.Description); markerLayout.GetSize (out width, out height); bool isFoldingSelected = !this.HideSelection && textEditor.IsSomethingSelected && textEditor.SelectionRange.Contains (folding.Segment); double pixelX = 0.5 + System.Math.Floor (pangoPosition / Pango.Scale.PangoScale); double foldXMargin = foldMarkerXMargin * textEditor.Options.Zoom; double pixelWidth = System.Math.Floor ((pangoPosition + width) / Pango.Scale.PangoScale - pixelX + foldXMargin * 2); var foldingRectangle = new Cairo.Rectangle ( pixelX, y, pixelWidth, this.LineHeight); if (BackgroundRenderer == null && isFoldingSelected) { cr.Color = SelectionColor.Background; cr.Rectangle (foldingRectangle); cr.Fill (); } if (isFoldingSelected && SelectionColor.TransparentForeground) { cr.Color = ColorStyle.CollapsedText.Foreground; } else { cr.Color = isFoldingSelected ? SelectionColor.Foreground : ColorStyle.CollapsedText.Foreground; } var boundingRectangleHeight = foldingRectangle.Height - 1; var boundingRectangleY = System.Math.Floor (foldingRectangle.Y + (foldingRectangle.Height - boundingRectangleHeight) / 2); RoundedRectangle (cr, System.Math.Floor (foldingRectangle.X) + 0.5, boundingRectangleY + 0.5, System.Math.Floor (foldingRectangle.Width - cr.LineWidth), System.Math.Floor (boundingRectangleHeight - cr.LineWidth), LineHeight / 8, CairoCorners.All, false); cr.Stroke (); cr.Save (); cr.Translate ( pangoPosition / Pango.Scale.PangoScale + foldXMargin, System.Math.Floor (boundingRectangleY + (boundingRectangleHeight - System.Math.Floor (height / Pango.Scale.PangoScale)) / 2)); cr.ShowLayout (markerLayout); cr.Restore (); if (caretOffset == foldOffset && !string.IsNullOrEmpty (folding.Description)) { var cx = (int)(pangoPosition / Pango.Scale.PangoScale); SetVisibleCaretPosition (cx, y, cx, y); } pangoPosition += foldingRectangle.Width * Pango.Scale.PangoScale; if (caretOffset == foldOffset + folding.Length && !string.IsNullOrEmpty (folding.Description)) { var cx = (int)(pangoPosition / Pango.Scale.PangoScale); SetVisibleCaretPosition (cx, y, cx, y); } if (folding.EndLine != line) { line = folding.EndLine; lineNr = line.LineNumber; foldings = Document.GetStartFoldings (line); isEolFolded = line.Length <= folding.EndColumn; goto restart; } isEolFolded = line.Length <= folding.EndColumn; } } // Draw remaining line - must be called for empty line parts as well because the caret may be at this positon // and the caret position is calculated in DrawLinePart. if (line.EndOffsetIncludingDelimiter - offset >= 0) { DrawLinePart (cr, line, lineNr, logicalRulerColumn, offset, line.Offset + line.Length - offset, ref pangoPosition, ref isSelectionDrawn, y, area.X + area.Width, _lineHeight); } bool isEolSelected = !this.HideSelection && textEditor.IsSomethingSelected && textEditor.SelectionMode == SelectionMode.Normal && textEditor.SelectionRange.Contains (line.Offset + line.Length); var lx = (int)(pangoPosition / Pango.Scale.PangoScale); lineArea = new Cairo.Rectangle (lx, lineArea.Y, textEditor.Allocation.Width - lx, lineArea.Height); if (textEditor.SelectionMode == SelectionMode.Block && textEditor.IsSomethingSelected && textEditor.SelectionRange.Contains (line.Offset + line.Length)) { DocumentLocation start = textEditor.MainSelection.Anchor; DocumentLocation end = textEditor.MainSelection.Lead; DocumentLocation visStart = textEditor.LogicalToVisualLocation (start); DocumentLocation visEnd = textEditor.LogicalToVisualLocation (end); double x1 = this.ColumnToX (line, visStart.Column); double x2 = this.ColumnToX (line, visEnd.Column); if (x1 > x2) { var tmp = x1; x1 = x2; x2 = tmp; } x1 += correctedXOffset - textEditor.HAdjustment.Value; x2 += correctedXOffset - textEditor.HAdjustment.Value; if (x2 > lineArea.X && BackgroundRenderer == null) { if (x1 - lineArea.X > 0) { DrawRectangleWithRuler (cr, x, new Cairo.Rectangle (lineArea.X, lineArea.Y, x1 - lineArea.X, lineArea.Height), defaultBgColor, false); lineArea = new Cairo.Rectangle (x1, lineArea.Y, lineArea.Width, lineArea.Height); } DrawRectangleWithRuler (cr, x, new Cairo.Rectangle (lineArea.X, lineArea.Y, x2 - lineArea.X, lineArea.Height), this.SelectionColor.Background, false); lineArea = new Cairo.Rectangle (x2, lineArea.Y, textEditor.Allocation.Width - lineArea.X, lineArea.Height); } } if (!isSelectionDrawn && BackgroundRenderer == null) { if (isEolSelected) { // prevent "gaps" in the selection drawing ('fuzzy' lines problem) var eolStartX = System.Math.Floor (pangoPosition / Pango.Scale.PangoScale); lineArea = new Cairo.Rectangle ( eolStartX, lineArea.Y, textEditor.Allocation.Width - eolStartX, lineArea.Height); DrawRectangleWithRuler (cr, x, lineArea, this.SelectionColor.Background, false); if (line.Length == 0) DrawIndent (cr, GetLayout (line), line, lx, y); } else if (!(HighlightCaretLine || textEditor.Options.HighlightCaretLine) || Caret.Line != lineNr) { LayoutWrapper wrapper = GetLayout (line); if (wrapper.EolSpanStack != null) { foreach (var span in wrapper.EolSpanStack) { var spanStyle = textEditor.ColorStyle.GetChunkStyle (span.Color); if (spanStyle == null) continue; if (!spanStyle.TransparentBackground && GetPixel (ColorStyle.PlainText.Background) != GetPixel (spanStyle.Background)) { DrawRectangleWithRuler (cr, x, lineArea, spanStyle.Background, false); break; } } } } else { double xPos = pangoPosition / Pango.Scale.PangoScale; DrawCaretLineMarker (cr, xPos, y, lineArea.X + lineArea.Width - xPos, _lineHeight); } } if (textEditor.Options.ShowWhitespaces != ShowWhitespaces.Never) { if (!isEolFolded && isEolSelected || textEditor.Options.ShowWhitespaces == ShowWhitespaces.Always) if (!(BackgroundRenderer != null && textEditor.Options.ShowWhitespaces == ShowWhitespaces.Selection)) DrawEolMarker (cr, line, isEolSelected, pangoPosition / Pango.Scale.PangoScale, y); } var extendingMarker = Document.GetExtendingTextMarker (lineNr); if (extendingMarker != null) extendingMarker.Draw (textEditor, cr, lineNr, lineArea); if (BackgroundRenderer == null) { var metrics = new EndOfLineMetrics { LineSegment = line, TextRenderEndPosition = TextStartPosition + pangoPosition / Pango.Scale.PangoScale, LineHeight = _lineHeight }; foreach (var marker in line.Markers) { marker.DrawAfterEol (textEditor, cr, y, metrics); } } lastLineRenderWidth = pangoPosition / Pango.Scale.PangoScale; if (textEditor.HAdjustment.Value > 0) { cr.LineWidth = textEditor.Options.Zoom; for (int i = 0; i < verticalShadowAlphaTable.Length; i++) { cr.Color = new Cairo.Color (0, 0, 0, 1 - verticalShadowAlphaTable[i]); cr.MoveTo (x + i * cr.LineWidth + 0.5, y); cr.LineTo (x + i * cr.LineWidth + 0.5, y + 1 + _lineHeight); cr.Stroke (); } } }
void DrawLinePart (Cairo.Context cr, LineSegment line, int lineNumber, int logicalRulerColumn, int offset, int length, ref double pangoPosition, ref bool isSelectionDrawn, double y, double maxX) { ISyntaxMode mode = Document.SyntaxMode != null && textEditor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : new SyntaxMode (Document); int selectionStart; int selectionEnd; if (this.HideSelection) { selectionStart = selectionEnd = -1; } else { GetSelectionOffsets (line, out selectionStart, out selectionEnd); } // ---- new renderer LayoutWrapper layout = CreateLinePartLayout (mode, line, logicalRulerColumn, offset, length, selectionStart, selectionEnd); int lineOffset = line.Offset; double width = layout.PangoWidth / Pango.Scale.PangoScale; double xPos = pangoPosition / Pango.Scale.PangoScale; // if (!(HighlightCaretLine || textEditor.Options.HighlightCaretLine) || Document.GetLine(Caret.Line) != line) { foreach (var bg in layout.BackgroundColors) { int x1, x2; x1 = layout.Layout.IndexToPos (bg.FromIdx).X; x2 = layout.Layout.IndexToPos (bg.ToIdx).X; DrawRectangleWithRuler (cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle ((x1 + pangoPosition) / Pango.Scale.PangoScale, y, (x2 - x1) / Pango.Scale.PangoScale + 1, LineHeight), bg.Color, true); } // } bool drawBg = true; bool drawText = true; foreach (TextMarker marker in line.Markers) { IBackgroundMarker bgMarker = marker as IBackgroundMarker; if (bgMarker == null || !marker.IsVisible) continue; isSelectionDrawn |= (marker.Flags & TextMarkerFlags.DrawsSelection) == TextMarkerFlags.DrawsSelection; drawText &= bgMarker.DrawBackground (textEditor, cr, layout, selectionStart, selectionEnd, offset, offset + length, y, xPos, xPos + width, ref drawBg); } if (DecorateLineBg != null) DecorateLineBg (cr, layout, offset, length, xPos, y, selectionStart, selectionEnd); if ((HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNumber) DrawCaretLineMarker (cr, xPos, y, layout.PangoWidth / Pango.Scale.PangoScale); if (!isSelectionDrawn && (layout.StartSet || selectionStart == offset + length)) { double startX; double endX; if (selectionStart != offset + length) { var start = layout.Layout.IndexToPos ((int)layout.SelectionStartIndex); startX = start.X / Pango.Scale.PangoScale; var end = layout.Layout.IndexToPos ((int)layout.SelectionEndIndex); endX = end.X / Pango.Scale.PangoScale; } else { startX = width; endX = startX; } if (textEditor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX) { endX = startX + 2; } DrawRectangleWithRuler (cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (xPos + startX, y, endX - startX, LineHeight), this.SelectionColor.CairoBackgroundColor, true); } // highlight search results TextSegment firstSearch; int o = offset; uint curIndex = 0, byteIndex = 0; if (textEditor.HighlightSearchPattern) { while (!(firstSearch = GetFirstSearchResult (o, offset + length)).IsInvalid) { double x = pangoPosition; HandleSelection (lineOffset, logicalRulerColumn, selectionStart, selectionEnd, System.Math.Max (lineOffset, firstSearch.Offset), System.Math.Min (lineOffset + line.Length, firstSearch.EndOffset), delegate(int start, int end) { uint startIndex = (uint)(start - offset); uint endIndex = (uint)(end - offset); if (startIndex < endIndex && endIndex <= layout.LineChars.Length) { uint startTranslated = TranslateToUTF8Index (layout.LineChars, startIndex, ref curIndex, ref byteIndex); uint endTranslated = TranslateToUTF8Index (layout.LineChars, endIndex, ref curIndex, ref byteIndex); int l, x1, x2; layout.Layout.IndexToLineX ((int)startTranslated, false, out l, out x1); layout.Layout.IndexToLineX ((int)endTranslated, false, out l, out x2); x1 += (int)x; x2 += (int)x; x1 /= (int)Pango.Scale.PangoScale; x2 /= (int)Pango.Scale.PangoScale; cr.Color = MainSearchResult.IsInvalid || MainSearchResult.Offset != firstSearch.Offset ? ColorStyle.SearchTextBg : ColorStyle.SearchTextMainBg; FoldingScreenbackgroundRenderer.DrawRoundRectangle (cr, true, true, x1, y, System.Math.Min (10, width) * textEditor.Options.Zoom, x2 - x1, LineHeight); cr.Fill (); } }, null); o = System.Math.Max (firstSearch.EndOffset, o + 1); } } cr.Save (); cr.Translate (xPos, y); cr.ShowLayout (layout.Layout); cr.Restore (); if (DecorateLineFg != null) DecorateLineFg (cr, layout, offset, length, xPos, y, selectionStart, selectionEnd); if (lineNumber == Caret.Line) { int caretOffset = Caret.Offset; if (offset <= caretOffset && caretOffset <= offset + length) { int index = caretOffset - offset; if (Caret.Column > line.Length + 1) { string virtualSpace = ""; var data = textEditor.GetTextEditorData (); if (data.HasIndentationTracker && line.Length == 0) { virtualSpace = this.textEditor.GetTextEditorData ().GetIndentationString (Caret.Location); } if (Caret.Column > line.Length + 1 + virtualSpace.Length) virtualSpace += new string (' ', Caret.Column - line.Length - 1 - virtualSpace.Length); LayoutWrapper wrapper = new LayoutWrapper (PangoUtil.CreateLayout (textEditor)); wrapper.LineChars = virtualSpace.ToCharArray (); wrapper.Layout.SetText (virtualSpace); wrapper.Layout.Tabs = tabArray; wrapper.Layout.FontDescription = textEditor.Options.Font; int vy, vx; wrapper.Layout.GetSize (out vx, out vy); SetVisibleCaretPosition (((pangoPosition + vx + layout.PangoWidth) / Pango.Scale.PangoScale), y); xPos = (pangoPosition + layout.PangoWidth) / Pango.Scale.PangoScale; if (!isSelectionDrawn && (selectionEnd == lineOffset + line.Length)) { double startX; double endX; startX = xPos; endX = (pangoPosition + vx + layout.PangoWidth) / Pango.Scale.PangoScale; DrawRectangleWithRuler (cr, xPos + textEditor.HAdjustment.Value - TextStartPosition, new Cairo.Rectangle (startX, y, endX - startX, LineHeight), this.SelectionColor.CairoBackgroundColor, true); } if ((HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNumber) DrawCaretLineMarker (cr, pangoPosition / Pango.Scale.PangoScale, y, vx / Pango.Scale.PangoScale); // When drawing virtual space before the selection start paint it as unselected. var virtualSpaceMod = selectionStart < caretOffset ? 0 : virtualSpace.Length; if (DecorateLineBg != null) DecorateLineBg (cr, wrapper, offset, length, xPos, y, selectionStart + virtualSpaceMod, selectionEnd + virtualSpace.Length); if (DecorateLineFg != null) DecorateLineFg (cr, wrapper, offset, length, xPos, y, selectionStart + virtualSpaceMod, selectionEnd + virtualSpace.Length); wrapper.Dispose (); pangoPosition += vx; } else if (index == length && textEditor.preeditString == null) { SetVisibleCaretPosition ((pangoPosition + layout.PangoWidth) / Pango.Scale.PangoScale, y); } else if (index >= 0 && index <= length) { Pango.Rectangle strong_pos, weak_pos; curIndex = byteIndex = 0; int utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, (uint)index, ref curIndex, ref byteIndex); if (textEditor.preeditString != null && textEditor.preeditCursorCharIndex > 0) { curIndex = byteIndex = 0; int preeditUtf8ByteIndex = (int)TranslateToUTF8Index (textEditor.preeditString.ToCharArray (), (uint)textEditor.preeditCursorCharIndex, ref curIndex, ref byteIndex); utf8ByteIndex += preeditUtf8ByteIndex; } layout.Layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); SetVisibleCaretPosition (xPos + (strong_pos.X / Pango.Scale.PangoScale), y); } } } foreach (TextMarker marker in line.Markers.Where (m => m.IsVisible)) { if (layout.Layout != null) marker.Draw (textEditor, cr, layout.Layout, false, /*selected*/offset, offset + length, y, xPos, xPos + width); } pangoPosition += layout.PangoWidth; if (layout.IsUncached) layout.Dispose (); }
public override void DrawAfterEol (TextEditor textEditor, Cairo.Context g, double y, EndOfLineMetrics metrics) { if (!IsVisible) return; EnsureLayoutCreated (editor); int errorCounterWidth = 0, eh = 0; if (errorCountLayout != null) { errorCountLayout.GetPixelSize (out errorCounterWidth, out eh); errorCounterWidth = Math.Max (15, Math.Max (errorCounterWidth + 3, (int)(editor.LineHeight * 3 / 4))); } var sx = metrics.TextRenderEndPosition; var width = LayoutWidth + errorCounterWidth + editor.LineHeight; var drawLayout = layouts[0].Layout; int ex = 0 , ey = 0; bool customLayout = true; //sx + width > editor.Allocation.Width; bool hideText = false; bubbleIsReduced = customLayout; var showErrorCount = errorCounterWidth > 0 && errorCountLayout != null; if (customLayout) { width = editor.Allocation.Width - sx; string text = layouts[0].Layout.Text; drawLayout = new Pango.Layout (editor.PangoContext); drawLayout.FontDescription = cache.fontDescription; var paintWidth = (width - errorCounterWidth - editor.LineHeight + 4); var minWidth = Math.Max (17, errorCounterWidth) + editor.LineHeight; if (paintWidth < minWidth) { hideText = true; drawLayout.SetMarkup ("<span weight='heavy'>···</span>"); width = minWidth; showErrorCount = false; sx = Math.Min (sx, editor.Allocation.Width - width); } else { drawLayout.Ellipsize = Pango.EllipsizeMode.End; drawLayout.Width = (int)(paintWidth * Pango.Scale.PangoScale); drawLayout.SetText (text); int w2, h2; drawLayout.GetPixelSize (out w2, out h2); width = w2 + errorCounterWidth + editor.LineHeight; } } bubbleDrawX = sx - editor.TextViewMargin.XOffset; bubbleDrawY = y; bubbleWidth = width; var bubbleHeight = editor.LineHeight - 1; g.RoundedRectangle (sx, y + 1, width, bubbleHeight, editor.LineHeight / 2 - 1); g.SetSourceColor (TagColor.Color); g.Fill (); // Draw error count icon if (showErrorCount) { var errorCounterHeight = bubbleHeight - 2; var errorCounterX = sx + width - errorCounterWidth - 3; var errorCounterY = y + 1 + (bubbleHeight - errorCounterHeight) / 2; g.RoundedRectangle ( errorCounterX - 1, errorCounterY - 1, errorCounterWidth + 2, errorCounterHeight + 2, editor.LineHeight / 2 - 3 ); g.SetSourceColor (new Cairo.Color (0, 0, 0, 0.081)); g.Fill (); g.RoundedRectangle ( errorCounterX, errorCounterY, errorCounterWidth, errorCounterHeight, editor.LineHeight / 2 - 3 ); using (var lg = new Cairo.LinearGradient (errorCounterX, errorCounterY, errorCounterX, errorCounterY + errorCounterHeight)) { lg.AddColorStop (0, CounterColor.Color); lg.AddColorStop (1, CounterColor.Color.AddLight (-0.1)); g.Pattern = lg; g.Fill (); } g.Save (); int ew; errorCountLayout.GetPixelSize (out ew, out eh); g.Translate ( errorCounterX + (errorCounterWidth - ew) / 2, errorCounterY + (errorCounterHeight - eh) / 2 ); g.SetSourceColor (CounterColor.SecondColor); g.ShowLayout (errorCountLayout); g.Restore (); } // Draw label text if (!showErrorCount || !hideText) { g.Save (); g.Translate (sx + editor.LineHeight / 2, y + (editor.LineHeight - layouts [0].Height) / 2 + 1); // draw shadow g.SetSourceColor (MessageBubbleCache.ShadowColor); g.ShowLayout (drawLayout); g.Translate (0, -1); g.SetSourceColor (TagColor.SecondColor); g.ShowLayout (drawLayout); g.Restore (); } if (customLayout) drawLayout.Dispose (); }
void DrawEolMarker (Cairo.Context cr, LineSegment line, bool selected, double x, double y) { Pango.Layout layout; switch (line.DelimiterLength) { case 0: // an emty line end should only happen at eof layout = eofEolLayout; break; case 1: if (Document.GetCharAt (line.Offset + line.Length) == '\n') { layout = unixEolLayout; } else { layout = macEolLayout; } break; case 2: layout = windowEolLayout; break; default: throw new InvalidOperationException (); // other line endings are not known. } cr.Save (); cr.Translate (x, y); cr.Color = selected ? SelectionColor.CairoColor : ColorStyle.EolWhitespaceMarker; cr.ShowLayout (layout); cr.Restore (); }
protected override void OnDrawContent (Gdk.EventExpose evnt, Cairo.Context g) { g.Rectangle (0, 0, Allocation.Width, Allocation.Height); g.Color = marker.LineColor.SecondColor; g.Fill (); double y = 8; double x = 4; foreach (var layout in marker.Layouts) { g.Save (); g.Translate (x, y); g.Color = marker.TagColor.SecondColor; g.ShowLayout (layout.Layout); g.Restore (); y += layout.Height; } }
void DrawInvalidLineMarker (Cairo.Context cr, double x, double y) { cr.Save (); cr.Translate (x, y); cr.Color = ColorStyle.InvalidLineMarker; cr.ShowLayout (invalidLineLayout); cr.Restore (); }
protected virtual void DrawBackground (Cairo.Context context, Gdk.Rectangle region) { LayoutRoundedRectangle (context, region); context.ClipPreserve (); using (LinearGradient lg = new LinearGradient (region.X, region.Y, region.X, region.Y + region.Height)) { lg.AddColorStop (0, Styles.StatusBarFill1Color); lg.AddColorStop (1, Styles.StatusBarFill4Color); context.Pattern = lg; context.FillPreserve (); } context.Save (); double midX = region.X + region.Width / 2.0; double midY = region.Y + region.Height; context.Translate (midX, midY); using (RadialGradient rg = new RadialGradient (0, 0, 0, 0, 0, region.Height * 1.2)) { rg.AddColorStop (0, Styles.StatusBarFill1Color); rg.AddColorStop (1, Styles.WithAlpha (Styles.StatusBarFill1Color, 0)); context.Scale (region.Width / (double)region.Height, 1.0); context.Pattern = rg; context.Fill (); } context.Restore (); using (LinearGradient lg = new LinearGradient (0, region.Y, 0, region.Y + region.Height)) { lg.AddColorStop (0, Styles.StatusBarShadowColor1); lg.AddColorStop (1, Styles.WithAlpha (Styles.StatusBarShadowColor1, Styles.StatusBarShadowColor1.A * 0.2)); LayoutRoundedRectangle (context, region, 0, -1); context.LineWidth = 1; context.Pattern = lg; context.Stroke (); } using (LinearGradient lg = new LinearGradient (0, region.Y, 0, region.Y + region.Height)) { lg.AddColorStop (0, Styles.StatusBarShadowColor2); lg.AddColorStop (1, Styles.WithAlpha (Styles.StatusBarShadowColor2, Styles.StatusBarShadowColor2.A * 0.2)); LayoutRoundedRectangle (context, region, 0, -2); context.LineWidth = 1; context.Pattern = lg; context.Stroke (); } context.ResetClip (); }
protected internal override void Draw (Cairo.Context cr, Cairo.Rectangle area, LineSegment line, int lineNr, double x, double y, double _lineHeight) { // double xStart = System.Math.Max (area.X, XOffset); // xStart = System.Math.Max (0, xStart); var lineArea = new Cairo.Rectangle (XOffset - 1, y, textEditor.Allocation.Width - XOffset + 1, _lineHeight); int width, height; double pangoPosition = (x - textEditor.HAdjustment.Value + TextStartPosition) * Pango.Scale.PangoScale; defaultBgColor = Document.ReadOnly ? ColorStyle.ReadOnlyTextBg : ColorStyle.Default.CairoBackgroundColor; // Draw the default back color for the whole line. Colors other than the default // background will be drawn when rendering the text chunks. DrawRectangleWithRuler (cr, x, lineArea, defaultBgColor, true); bool isSelectionDrawn = false; if (BackgroundRenderer != null) BackgroundRenderer.Draw (cr, area, line, x, y, _lineHeight); // Check if line is beyond the document length if (line == null) { if (textEditor.Options.ShowInvalidLines) DrawInvalidLineMarker (cr, pangoPosition / Pango.Scale.PangoScale, y); var marker = Document.GetExtendingTextMarker (lineNr); if (marker != null) marker.Draw (textEditor, cr, lineNr, lineArea); return; } IEnumerable<FoldSegment> foldings = Document.GetStartFoldings (line); int offset = line.Offset; int caretOffset = Caret.Offset; bool isEolFolded = false; restart: int logicalRulerColumn = line.GetLogicalColumn (textEditor.GetTextEditorData (), textEditor.Options.RulerColumn); foreach (FoldSegment folding in foldings) { int foldOffset = folding.StartLine.Offset + folding.Column - 1; if (foldOffset < offset) continue; if (folding.IsFolded) { DrawLinePart (cr, line, lineNr, logicalRulerColumn, offset, foldOffset - offset, ref pangoPosition, ref isSelectionDrawn, y, area.X + area.Width); offset = folding.EndLine.Offset + folding.EndColumn; markerLayout.SetText (folding.Description); markerLayout.GetSize (out width, out height); bool isFoldingSelected = !this.HideSelection && textEditor.IsSomethingSelected && textEditor.SelectionRange.Contains (folding.Segment); double pixelX = pangoPosition / Pango.Scale.PangoScale; double pixelWidth = (pangoPosition + width) / Pango.Scale.PangoScale - pixelX; var foldingRectangle = new Cairo.Rectangle (pixelX + 0.5, y + 0.5, pixelWidth - cr.LineWidth, this.LineHeight - cr.LineWidth); if (BackgroundRenderer == null) { cr.Color = isFoldingSelected ? SelectionColor.CairoBackgroundColor : defaultBgColor; cr.Rectangle (foldingRectangle); cr.Fill (); } cr.Color = isFoldingSelected ? SelectionColor.CairoColor : ColorStyle.FoldLine.CairoColor; cr.Rectangle (foldingRectangle); cr.Stroke (); cr.Save (); cr.Translate (pangoPosition / Pango.Scale.PangoScale, y); cr.Color = isFoldingSelected ? SelectionColor.CairoColor : ColorStyle.FoldLine.CairoColor; cr.ShowLayout (markerLayout); cr.Restore (); if (caretOffset == foldOffset && !string.IsNullOrEmpty (folding.Description)) SetVisibleCaretPosition ((int)(pangoPosition / Pango.Scale.PangoScale), y); pangoPosition += width; if (caretOffset == foldOffset + folding.Length && !string.IsNullOrEmpty (folding.Description)) SetVisibleCaretPosition ((int)(pangoPosition / Pango.Scale.PangoScale), y); if (folding.EndLine != line) { line = folding.EndLine; lineNr = Document.OffsetToLineNumber (line.Offset); foldings = Document.GetStartFoldings (line); isEolFolded = line.Length <= folding.EndColumn; goto restart; } isEolFolded = line.Length <= folding.EndColumn; } } // Draw remaining line - must be called for empty line parts as well because the caret may be at this positon // and the caret position is calculated in DrawLinePart. if (line.EndOffsetIncludingDelimiter - offset >= 0) DrawLinePart (cr, line, lineNr, logicalRulerColumn, offset, line.Offset + line.Length - offset, ref pangoPosition, ref isSelectionDrawn, y, area.X + area.Width); bool isEolSelected = !this.HideSelection && textEditor.IsSomethingSelected && textEditor.SelectionMode == SelectionMode.Normal && textEditor.SelectionRange.Contains (line.Offset + line.Length); lineArea = new Cairo.Rectangle (pangoPosition / Pango.Scale.PangoScale, lineArea.Y, textEditor.Allocation.Width - pangoPosition / Pango.Scale.PangoScale, lineArea.Height); if (textEditor.SelectionMode == SelectionMode.Block && textEditor.IsSomethingSelected && textEditor.SelectionRange.Contains (line.Offset + line.Length)) { DocumentLocation start = textEditor.MainSelection.Anchor; DocumentLocation end = textEditor.MainSelection.Lead; DocumentLocation visStart = textEditor.LogicalToVisualLocation (start); DocumentLocation visEnd = textEditor.LogicalToVisualLocation (end); double x1 = this.ColumnToX (line, visStart.Column); double x2 = this.ColumnToX (line, visEnd.Column); if (x1 > x2) { var tmp = x1; x1 = x2; x2 = tmp; } x1 += XOffset - textEditor.HAdjustment.Value; x2 += XOffset - textEditor.HAdjustment.Value; if (x2 > lineArea.X) { if (x1 - lineArea.X > 0) { DrawRectangleWithRuler (cr, x, new Cairo.Rectangle (lineArea.X, lineArea.Y, x1 - lineArea.X, lineArea.Height), defaultBgColor, false); lineArea = new Cairo.Rectangle (x1, lineArea.Y, lineArea.Width, lineArea.Height); } DrawRectangleWithRuler (cr, x, new Cairo.Rectangle (lineArea.X, lineArea.Y, x2 - lineArea.X, lineArea.Height), this.SelectionColor.CairoBackgroundColor, false); lineArea = new Cairo.Rectangle (x2, lineArea.Y, textEditor.Allocation.Width - lineArea.X, lineArea.Height); } } if (!isSelectionDrawn) { if (isEolSelected) { if (!Platform.IsMac) { // prevent "gaps" in the selection drawing ('fuzzy' lines problem) lineArea = new Cairo.Rectangle (pangoPosition / Pango.Scale.PangoScale, lineArea.Y, textEditor.Allocation.Width - pangoPosition / Pango.Scale.PangoScale + 1, lineArea.Height); } else { // prevent "gaps" in the selection drawing ('fuzzy' lines problem) lineArea = new Cairo.Rectangle (pangoPosition / Pango.Scale.PangoScale - 1, lineArea.Y, textEditor.Allocation.Width - pangoPosition / Pango.Scale.PangoScale + 1, lineArea.Height); } DrawRectangleWithRuler (cr, x, lineArea, this.SelectionColor.CairoBackgroundColor, false); } else if (!(HighlightCaretLine || textEditor.Options.HighlightCaretLine) || Caret.Line != lineNr) { LayoutWrapper wrapper = GetLayout (line); if (wrapper.EolSpanStack != null) { foreach (var span in wrapper.EolSpanStack) { var spanStyle = textEditor.ColorStyle.GetChunkStyle (span.Color); if (!spanStyle.TransparentBackround && GetPixel (ColorStyle.Default.BackgroundColor) != GetPixel (spanStyle.BackgroundColor)) { DrawRectangleWithRuler (cr, x, lineArea, spanStyle.CairoBackgroundColor, false); break; } } } } else { double xPos = pangoPosition / Pango.Scale.PangoScale; DrawCaretLineMarker (cr, xPos, y, lineArea.X + lineArea.Width - xPos); } } if (!isEolFolded && textEditor.Options.ShowEolMarkers) DrawEolMarker (cr, line, isEolSelected, pangoPosition / Pango.Scale.PangoScale, y); var extendingMarker = Document.GetExtendingTextMarker (lineNr); if (extendingMarker != null) extendingMarker.Draw (textEditor, cr, lineNr, lineArea); lastLineRenderWidth = pangoPosition / Pango.Scale.PangoScale; }