Exemple #1
0
        public override void Draw(TextEditor editor, Cairo.Context cr, Pango.Layout layout, bool selected, int startOffset, int endOffset, double y, double startXPos, double endXPos)
        {
            if (Debugger.DebuggingService.IsDebugging)
            {
                return;
            }
            int markerStart = Segment.Offset;
            int markerEnd   = Segment.EndOffset;

            if (markerEnd < startOffset || markerStart > endOffset)
            {
                return;
            }

            bool drawOverlay = result.InspectionMark == IssueMarker.GrayOut;

            if (drawOverlay && editor.IsSomethingSelected)
            {
                var selectionRange = editor.SelectionRange;
                if (selectionRange.Contains(markerStart) && selectionRange.Contains(markerEnd))
                {
                    return;
                }
                if (selectionRange.Contains(markerEnd))
                {
                    markerEnd = selectionRange.Offset;
                }
                if (selectionRange.Contains(markerStart))
                {
                    markerStart = selectionRange.EndOffset;
                }
                if (markerEnd <= markerStart)
                {
                    return;
                }
            }

            double drawFrom;
            double drawTo;

            if (markerStart < startOffset && endOffset < markerEnd)
            {
                drawTo = endXPos;
                var line   = editor.GetLineByOffset(startOffset);
                int offset = line.GetIndentation(editor.Document).Length;
                drawFrom = startXPos + (layout.IndexToPos(offset).X / Pango.Scale.PangoScale);
            }
            else
            {
                int start;
                if (startOffset < markerStart)
                {
                    start = markerStart;
                }
                else
                {
                    var line   = editor.GetLineByOffset(startOffset);
                    int offset = line.GetIndentation(editor.Document).Length;
                    start = startOffset + offset;
                }
                int end = endOffset < markerEnd ? endOffset : markerEnd;
                int x_pos;

                x_pos    = layout.IndexToPos(start - startOffset).X;
                drawFrom = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
                x_pos    = layout.IndexToPos(end - startOffset).X;

                drawTo = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
            }

            drawFrom = System.Math.Max(drawFrom, editor.TextViewMargin.XOffset);
            drawTo   = System.Math.Max(drawTo, editor.TextViewMargin.XOffset);
            if (drawFrom >= drawTo)
            {
                return;
            }

            double height = editor.LineHeight / 5;

            cr.SetSourceColor(GetColor(editor, Result));
            if (drawOverlay)
            {
                cr.Rectangle(drawFrom, y, drawTo - drawFrom, editor.LineHeight);
                var color = editor.ColorStyle.PlainText.Background;
                color.A = 0.6;
                cr.SetSourceColor(color);
                cr.Fill();
            }
            else if (result.InspectionMark == IssueMarker.WavedLine)
            {
                Pango.CairoHelper.ShowErrorUnderline(cr, drawFrom, y + editor.LineHeight - height, drawTo - drawFrom, height);
            }
            else if (result.InspectionMark == IssueMarker.DottedLine)
            {
                cr.Save();
                cr.LineWidth = 1;
                cr.MoveTo(drawFrom + 1, y + editor.LineHeight - 1 + 0.5);
                cr.RelLineTo(System.Math.Min(drawTo - drawFrom, 4 * 3), 0);
                cr.SetDash(new double[] { 2, 2 }, 0);
                cr.Stroke();
                cr.Restore();
            }
            else
            {
                cr.MoveTo(drawFrom, y + editor.LineHeight - 1);
                cr.LineTo(drawTo, y + editor.LineHeight - 1);
                cr.Stroke();
            }
        }
Exemple #2
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="showCursor">Whether or not to show the mouse cursor in the drawing.</param>
        /// <param name="useTextLayer">Whether or not to use the TextLayer (as opposed to the Userlayer).</param>
        private void RedrawText(bool showCursor, bool useTextLayer)
        {
            Rectangle r = CurrentTextEngine.GetLayoutBounds();

            r.Inflate(10 + OutlineWidth, 10 + OutlineWidth);
            InflateAndInvalidate(r);
            CurrentTextBounds = r;

            Rectangle cursorBounds = Rectangle.Zero;

            Cairo.ImageSurface surf;

            if (!useTextLayer)
            {
                //Draw text on the current UserLayer's surface as finalized text.
                surf = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.Surface;
            }
            else
            {
                //Draw text on the current UserLayer's TextLayer's surface as re-editable text.
                surf = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.TextLayer.Layer.Surface;

                ClearTextLayer();
            }

            using (var g = new Cairo.Context(surf)) {
                g.Save();

                // Show selection if on text layer
                if (useTextLayer)
                {
                    // Selected Text
                    Cairo.Color c = new Cairo.Color(0.7, 0.8, 0.9, 0.5);
                    foreach (Rectangle rect in CurrentTextEngine.SelectionRectangles)
                    {
                        g.FillRectangle(rect.ToCairoRectangle(), c);
                    }
                }

                if (selection != null)
                {
                    g.AppendPath(selection.SelectionPath);
                    g.FillRule = Cairo.FillRule.EvenOdd;
                    g.Clip();
                }

                g.MoveTo(new Cairo.PointD(CurrentTextEngine.Origin.X, CurrentTextEngine.Origin.Y));

                g.SetSourceColor(PintaCore.Palette.PrimaryColor);

                //Fill in background
                if (BackgroundFill)
                {
                    using (var g2 = new Cairo.Context(surf)) {
                        g2.FillRectangle(CurrentTextEngine.GetLayoutBounds().ToCairoRectangle(), PintaCore.Palette.SecondaryColor);
                    }
                }

                // Draw the text
                if (FillText)
                {
                    Pango.CairoHelper.ShowLayout(g, CurrentTextEngine.Layout);
                }

                if (FillText && StrokeText)
                {
                    g.SetSourceColor(PintaCore.Palette.SecondaryColor);
                    g.LineWidth = OutlineWidth;

                    Pango.CairoHelper.LayoutPath(g, CurrentTextEngine.Layout);
                    g.Stroke();
                }
                else if (StrokeText)
                {
                    g.SetSourceColor(PintaCore.Palette.PrimaryColor);
                    g.LineWidth = OutlineWidth;

                    Pango.CairoHelper.LayoutPath(g, CurrentTextEngine.Layout);
                    g.Stroke();
                }

                if (showCursor)
                {
                    var loc = CurrentTextEngine.GetCursorLocation();

                    g.Antialias = Cairo.Antialias.None;
                    g.DrawLine(new Cairo.PointD(loc.X, loc.Y), new Cairo.PointD(loc.X, loc.Y + loc.Height), new Cairo.Color(0, 0, 0, 1), 1);
                    g.DrawRectangle(new Cairo.Rectangle(loc.X - 1, loc.Y - 1, 3, loc.Height + 2), new Cairo.Color(255, 255, 255), 1);

                    cursorBounds = Rectangle.Inflate(loc, 2, 10);
                }

                g.Restore();


                if (useTextLayer && (is_editing || ctrlKey) && !CurrentTextEngine.IsEmpty())
                {
                    //Draw the text edit rectangle.

                    g.Save();

                    g.Translate(.5, .5);

                    using (Cairo.Path p = g.CreateRectanglePath(CurrentTextBounds.ToCairoRectangle()))
                    {
                        g.AppendPath(p);
                    }

                    g.LineWidth = 1;

                    g.SetSourceColor(new Cairo.Color(1, 1, 1));
                    g.StrokePreserve();

                    g.SetDash(new double[] { 2, 4 }, 0);
                    g.SetSourceColor(new Cairo.Color(1, .1, .2));

                    g.Stroke();

                    g.Restore();
                }
            }

            InflateAndInvalidate(PintaCore.Workspace.ActiveDocument.CurrentUserLayer.previousTextBounds);
            PintaCore.Workspace.Invalidate(old_cursor_bounds);
            InflateAndInvalidate(r);
            PintaCore.Workspace.Invalidate(cursorBounds);

            old_cursor_bounds = cursorBounds;
        }
Exemple #3
0
        public void Draw(Cairo.Context cr, Cairo.Rectangle area)
        {
            TextViewMargin textViewMargin = editor.TextViewMargin;
            ISyntaxMode    mode           = Document.SyntaxMode != null && editor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : new SyntaxMode(Document);

            TextViewMargin.LayoutWrapper lineLayout = null;
            double brightness = HslColor.Brightness(editor.ColorStyle.PlainText.Background);

            int colorCount = foldSegments.Count + 2;

            cr.SetSourceColor(GetColor(-1, brightness, colorCount));
            cr.Rectangle(area);
            cr.Fill();
            var       rectangles         = new Cairo.Rectangle[foldSegments.Count];
            const int xPadding           = 4;
            const int yPadding           = 2;
            const int rightMarginPadding = 16;

            for (int i = foldSegments.Count - 1; i >= 0; i--)
            {
                var segment = foldSegments [i];
                if (segment.IsInvalid)
                {
                    continue;
                }
                var segmentStartLine = segment.StartLine;
                var segmentEndLine   = segment.EndLine;

                int curWidth = 0;
                var endLine  = segmentEndLine.NextLine;
                var y        = editor.LineToY(segmentStartLine.LineNumber);
                if (y < editor.VAdjustment.Value)
                {
                    segmentStartLine = editor.GetLine(editor.YToLine(editor.VAdjustment.Value));
                    y = editor.LineToY(segmentStartLine.LineNumber);
                }

                for (var curLine = segmentStartLine; curLine != endLine && y < editor.VAdjustment.Value + editor.Allocation.Height; curLine = curLine.NextLine)
                {
                    var curLayout = textViewMargin.CreateLinePartLayout(mode, curLine, curLine.Offset, curLine.Length, -1, -1);
                    var width     = (int)(curLayout.Width);
                    if (curLayout.IsUncached)
                    {
                        curLayout.Dispose();
                    }
                    curWidth = System.Math.Max(curWidth, width);
                    y       += editor.GetLineHeight(curLine);
                }

                double xPos = textViewMargin.XOffset;
                double rectangleWidth = 0, rectangleHeight = 0;

                lineLayout = textViewMargin.CreateLinePartLayout(mode, segmentStartLine, segmentStartLine.Offset, segmentStartLine.Length, -1, -1);
                var rectangleStart = lineLayout.Layout.IndexToPos(GetFirstNonWsIdx(lineLayout.Layout.Text));
                if (lineLayout.IsUncached)
                {
                    lineLayout.Dispose();
                }

                xPos = System.Math.Max(textViewMargin.XOffset, (textViewMargin.XOffset + textViewMargin.TextStartPosition + rectangleStart.X / Pango.Scale.PangoScale) - xPadding);

                lineLayout = textViewMargin.CreateLinePartLayout(mode, segmentEndLine, segmentEndLine.Offset, segmentEndLine.Length, -1, -1);
                var rectangleEnd = lineLayout.Layout.IndexToPos(GetFirstNonWsIdx(lineLayout.Layout.Text));
                if (lineLayout.IsUncached)
                {
                    lineLayout.Dispose();
                }

                xPos = System.Math.Min(xPos, System.Math.Max(textViewMargin.XOffset, (textViewMargin.XOffset + textViewMargin.TextStartPosition + rectangleEnd.X / Pango.Scale.PangoScale) - xPadding));

                rectangleWidth = textViewMargin.XOffset + textViewMargin.TextStartPosition + curWidth - xPos + xPadding * 2;

                if (i < foldSegments.Count - 1)
                {
                    rectangleWidth = System.Math.Max((rectangles [i + 1].X + rectangles[i + 1].Width + rightMarginPadding) - xPos, rectangleWidth);
                }

                y = editor.LineToY(segment.StartLine.LineNumber);
                var yEnd = editor.LineToY(segment.EndLine.LineNumber + 1) + (segment.EndLine.LineNumber == editor.LineCount ? editor.LineHeight : 0);
                if (yEnd == 0)
                {
                    yEnd = editor.VAdjustment.Upper;
                }
                rectangleHeight = yEnd - y;

                rectangles[i] = new Cairo.Rectangle(xPos, y - yPadding, rectangleWidth, rectangleHeight + yPadding * 2);
            }

            for (int i = 0; i < foldSegments.Count; i++)
            {
                Cairo.Rectangle clampedRect;
                var             rect = rectangles[i];

                if (i == foldSegments.Count - 1)
                {
/*					var radius = (int)(editor.Options.Zoom * 2);
 *                                      int w = 2 * radius;
 *                                      using (var shadow = new Blur (
 *                                              System.Math.Min ((int)rect.Width + w * 2, editor.Allocation.Width),
 *                                              System.Math.Min ((int)rect.Height + w * 2, editor.Allocation.Height),
 *                                              radius)) {
 *                                              using (var gctx = shadow.GetContext ()) {
 *                                                      gctx.Color = new Cairo.Color (0, 0, 0, 0);
 *                                                      gctx.Fill ();
 *
 *                                                      var a = 0;
 *                                                      var b = 0;
 *                                                      DrawRoundRectangle (gctx, true, true, w - a, w - b, editor.LineHeight / 4, rect.Width + a * 2, rect.Height + a * 2);
 *                                                      var bg = editor.ColorStyle.Default.CairoColor;
 *                                                      gctx.Color = new Cairo.Color (bg.R, bg.G, bg.B, 0.6);
 *                                                      gctx.Fill ();
 *                                              }
 *
 *                                              cr.Save ();
 *                                              cr.Translate (rect.X - w - editor.HAdjustment.Value, rect.Y - editor.VAdjustment.Value - w);
 *                                              shadow.Draw (cr);
 *                                              cr.Restore ();
 *                                      }*/

                    var curPadSize = 1;

                    var age   = (DateTime.Now - startTime).TotalMilliseconds;
                    var alpha = 0.1;
                    if (age < animationLength)
                    {
                        var animationState = age / (double)animationLength;
                        curPadSize = (int)(3 + System.Math.Sin(System.Math.PI * animationState) * 3);
                        alpha      = 0.1 + (1.0 - animationState) / 5;
                    }

                    var bg = editor.ColorStyle.PlainText.Foreground;
                    cr.SetSourceRGBA(bg.R, bg.G, bg.B, alpha);
                    clampedRect = ClampRect(rect.X - editor.HAdjustment.Value - curPadSize, rect.Y - editor.VAdjustment.Value - curPadSize, editor.LineHeight / 2, rect.Width + curPadSize * 2, rect.Height + curPadSize * 2, area);
                    DrawRoundRectangle(cr, true, true, clampedRect.X, clampedRect.Y, editor.LineHeight / 2, clampedRect.Width, clampedRect.Height);
                    cr.Fill();

                    if (age < animationLength)
                    {
                        var animationState = age / (double)animationLength;
                        curPadSize  = (int)(2 + System.Math.Sin(System.Math.PI * animationState) * 2);
                        clampedRect = ClampRect(rect.X - editor.HAdjustment.Value - curPadSize, rect.Y - editor.VAdjustment.Value - curPadSize, editor.LineHeight / 2, rect.Width + curPadSize * 2, rect.Height + curPadSize * 2, area);
                        DrawRoundRectangle(cr, true, true, clampedRect.X, clampedRect.Y, editor.LineHeight / 2, clampedRect.Width, clampedRect.Height);
                        cr.SetSourceColor(GetColor(i, brightness, colorCount));
                        cr.Fill();

                        continue;
                    }
                }

                clampedRect = ClampRect(rect.X - editor.HAdjustment.Value, rect.Y - editor.VAdjustment.Value, editor.LineHeight / 2, rect.Width, rect.Height, area);
                DrawRoundRectangle(cr, true, true, clampedRect.X, clampedRect.Y, editor.LineHeight / 2, clampedRect.Width, clampedRect.Height);

                cr.SetSourceColor(GetColor(i, brightness, colorCount));
                cr.Fill();
            }
        }
Exemple #4
0
        internal protected override void Draw(Cairo.Context ctx, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
        {
            bool backgroundIsDrawn = false;

            if (lineSegment != null)
            {
                foreach (var marker in lineSegment.Markers)
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawBackground(this))
                    {
                        backgroundIsDrawn = marginMarker.DrawBackground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                    }

#pragma warning disable 618
                    var iconMarker = marker as IIconBarMarker;
                    if (iconMarker == null || !iconMarker.CanDrawBackground)
                    {
                        continue;
                    }
                    iconMarker.DrawBackground(editor, ctx, lineSegment, line, x, y, (int)Width, editor.LineHeight);
                    backgroundIsDrawn = true;
                    break;
#pragma warning restore 618
                }
            }

            if (!backgroundIsDrawn)
            {
                ctx.Rectangle(x, y, Width, lineHeight);
                ctx.SetSourceColor(backgroundColor);
                ctx.Fill();

                ctx.MoveTo(x + Width - 0.5, y);
                ctx.LineTo(x + Width - 0.5, y + lineHeight);
                ctx.SetSourceColor(separatorColor);
                ctx.Stroke();
            }

            if (lineSegment != null && line <= editor.Document.LineCount)
            {
                foreach (var marker in lineSegment.Markers)
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawForeground(this))
                    {
                        marginMarker.DrawForeground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                    }

#pragma warning disable 618
                    if (marker is IIconBarMarker)
                    {
                        ((IIconBarMarker)marker).DrawIcon(editor, ctx, lineSegment, line, x, y, (int)Width, editor.LineHeight);
                    }
#pragma warning restore 618
                }
                if (DrawEvent != null)
                {
                    DrawEvent(this, new BookmarkMarginDrawEventArgs(editor, ctx, lineSegment, line, x, y));
                }
            }
        }
        protected override void OnRender(Cairo.Context cr, Widget widget, Gdk.Rectangle background_area,
                                         Gdk.Rectangle cell_area, CellRendererState flags)
        {
            if (source == null || source is SourceManager.GroupSource)
            {
                return;
            }

            view = widget as SourceView;
            bool       selected = view != null && view.Selection.IterIsSelected(iter);
            StateFlags state    = RendererStateToWidgetState(widget, flags);

            RenderBackground(cr, background_area, selected, state);

            int title_layout_width = 0, title_layout_height = 0;
            int count_layout_width = 0, count_layout_height = 0;
            int max_title_layout_width;

            int  img_padding           = 6;
            int  expander_icon_spacing = 3;
            int  x      = cell_area.X;
            bool np_etc = (source.Order + Depth * 100) < 40;

            if (!np_etc)
            {
                x += Depth * img_padding + (int)Xpad;
            }
            else
            {
                // Don't indent NowPlaying and Play Queue as much
                x += Math.Max(0, (int)Xpad - 2);
            }

            // Draw the expander if the source has children
            double exp_h = (cell_area.Height - 2.0 * Ypad) / 2.0;
            double exp_w = exp_h * 1.6;
            int    y     = Middle(cell_area, (int)exp_h);

            if (view != null && source.Children != null && source.Children.Count > 0)
            {
                var r = new Gdk.Rectangle(x, y, (int)exp_w, (int)exp_h);
                view.Theme.DrawArrow(cr, r, source.Expanded ? Math.PI / 2.0 : 0.0);
            }

            if (!np_etc)
            {
                x += (int)exp_w;
                x += 2; // a little spacing after the expander
                expander_right_x = x;
            }

            // Draw icon
            Pixbuf icon = SourceIconResolver.ResolveIcon(source, RowHeight);

            bool dispose_icon = false;

            if (state == StateFlags.Insensitive)
            {
                // Code ported from gtk_cell_renderer_pixbuf_render()
                var icon_source = new IconSource()
                {
                    Pixbuf         = icon,
                    Size           = IconSize.SmallToolbar,
                    SizeWildcarded = false
                };

                icon = widget.StyleContext.RenderIconPixbuf(icon_source, (IconSize)(-1));

                dispose_icon = true;
                icon_source.Dispose();
            }

            if (icon != null)
            {
                x += expander_icon_spacing;

                cr.Save();
                Gdk.CairoHelper.SetSourcePixbuf(cr, icon, x, Middle(cell_area, icon.Height));
                cr.Paint();
                cr.Restore();

                x += icon.Width;

                if (dispose_icon)
                {
                    icon.Dispose();
                }
            }

            // Setup font info for the title/count, and see if we should show the count
            bool            hide_count = source.EnabledCount <= 0 || source.Properties.Get <bool> ("SourceView.HideCount");
            FontDescription fd         = widget.PangoContext.FontDescription.Copy();

            fd.Weight = (ISource)ServiceManager.PlaybackController.NextSource == (ISource)source
                ? Pango.Weight.Bold
                : Pango.Weight.Normal;

            if (view != null && source == view.NewPlaylistSource)
            {
                fd.Style   = Pango.Style.Italic;
                hide_count = true;
            }

            Pango.Layout title_layout = new Pango.Layout(widget.PangoContext);
            Pango.Layout count_layout = null;

            // If we have a count to draw, setup its fonts and see how wide it is to see if we have room
            if (!hide_count)
            {
                count_layout = new Pango.Layout(widget.PangoContext);
                count_layout.FontDescription = fd;
                count_layout.SetMarkup(String.Format("<span size=\"small\">{0}</span>", source.EnabledCount));
                count_layout.GetPixelSize(out count_layout_width, out count_layout_height);
            }

            // Hide the count if the title has no space
            max_title_layout_width = cell_area.Width - x - count_layout_width;//(icon == null ? 0 : icon.Width) - count_layout_width - 10;
            if (!hide_count && max_title_layout_width <= 0)
            {
                hide_count = true;
            }

            // Draw the source Name
            title_layout.FontDescription = fd;
            title_layout.Width           = (int)(max_title_layout_width * Pango.Scale.PangoScale);
            title_layout.Ellipsize       = EllipsizeMode.End;
            title_layout.SetText(source.Name);
            title_layout.GetPixelSize(out title_layout_width, out title_layout_height);

            x += img_padding;
            widget.StyleContext.RenderLayout(cr, x, Middle(cell_area, title_layout_height), title_layout);

            title_layout.Dispose();

            // Draw the count
            if (!hide_count)
            {
                if (view != null)
                {
                    cr.SetSourceColor(state == StateFlags.Normal || (view != null && state == StateFlags.Prelight)
                        ? view.Theme.TextMidColor
                        : CairoExtensions.GdkRGBAToCairoColor(view.Theme.Widget.StyleContext.GetColor(state)));

                    cr.MoveTo(
                        cell_area.X + cell_area.Width - count_layout_width - 2,
                        cell_area.Y + 0.5 + (double)(cell_area.Height - count_layout_height) / 2.0);
                    Pango.CairoHelper.ShowLayout(cr, count_layout);
                }

                count_layout.Dispose();
            }

            fd.Dispose();
        }
Exemple #6
0
 public override void Apply(object control, Cairo.Context context)
 {
     context.SetSourceColor((Cairo.Color)control);
 }
				public BgBufferUpdate (Minimpap mode)
				{
					this.mode = mode;
					
					cr = Gdk.CairoHelper.Create (mode.backgroundBuffer);
					
					cr.LineWidth = 1;
					int w = mode.backgroundBuffer.ClipRegion.Clipbox.Width;
					int h = mode.backgroundBuffer.ClipRegion.Clipbox.Height;
					cr.Rectangle (0, 0, w, h);
					if (mode.TextEditor.ColorStyle != null)
						cr.SetSourceColor (mode.TextEditor.ColorStyle.PlainText.Background);
					cr.Fill ();
					
					maxLine = mode.TextEditor.GetTextEditorData ().VisibleLineCount;
					sx = w / (double)mode.TextEditor.Allocation.Width;
					sy = Math.Min (1, lineHeight * maxLine / (double)mode.TextEditor.GetTextEditorData ().TotalHeight );
					cr.Scale (sx, sy);
					
					handler = GLib.Idle.Add (BgBufferUpdater);
				}
Exemple #8
0
        protected override bool OnExposeEvent(Gdk.EventExpose args)
        {
            Gdk.Window win = GdkWindow;
            int        rwidth, rheight;

            Cairo.Context ctx = CairoHelper.Create(win);

            win.GetSize(out rwidth, out rheight);

            if (autoStartY || autoEndY)
            {
                double nstartY = double.MaxValue;
                double nendY   = double.MinValue;
                GetValueRange(AxisDimension.Y, out nstartY, out nendY);

                if (!autoStartY)
                {
                    nstartY = startY;
                }
                if (!autoEndY)
                {
                    nendY = endY;
                }
                if (nendY < nstartY)
                {
                    nendY = nstartY;
                }

                if (nstartY != startY || nendY != endY)
                {
                    yrangeChanged = true;
                    startY        = nstartY;
                    endY          = nendY;
                }
            }

            if (autoStartX || autoEndX)
            {
                double nstartX = double.MaxValue;
                double nendX   = double.MinValue;
                GetValueRange(AxisDimension.X, out nstartX, out nendX);

                if (!autoStartX)
                {
                    nstartX = startX;
                }
                if (!autoEndX)
                {
                    nendX = endX;
                }
                if (nendX < nstartX)
                {
                    nendX = nstartX;
                }

                if (nstartX != startX || nendX != endX)
                {
                    xrangeChanged = true;
                    startX        = nstartX;
                    endX          = nendX;
                }
            }

            if (yrangeChanged)
            {
                FixOrigins();
                int right = rwidth - 2 - AreaBorderWidth;
                left          = AreaBorderWidth;
                left         += MeasureAxisSize(AxisPosition.Left) + 1;
                right        -= MeasureAxisSize(AxisPosition.Right) + 1;
                yrangeChanged = false;
                width         = right - left + 1;
                if (width <= 0)
                {
                    width = 1;
                }
            }

            if (xrangeChanged)
            {
                FixOrigins();
                int bottom = rheight - 2 - AreaBorderWidth;
                top     = AreaBorderWidth;
                bottom -= MeasureAxisSize(AxisPosition.Bottom);
                top    += MeasureAxisSize(AxisPosition.Top);

                // Make room for cursor handles
                foreach (ChartCursor cursor in cursors)
                {
                    if (cursor.Dimension == AxisDimension.X && top - AreaBorderWidth < cursor.HandleSize)
                    {
                        top = cursor.HandleSize + AreaBorderWidth;
                    }
                }

                xrangeChanged = false;
                height        = bottom - top + 1;
                if (height <= 0)
                {
                    height = 1;
                }
            }

            if (AutoScaleMargin != 0 && height > 0)
            {
                double margin = (double)AutoScaleMargin * (endY - startY) / (double)height;
                if (autoStartY)
                {
                    startY -= margin;
                }
                if (autoEndY)
                {
                    endY += margin;
                }
            }

//			Console.WriteLine ("L:" + left + " T:" + top + " W:" + width + " H:" + height);

            // Draw the background

            if (backgroundDisplay == BackgroundDisplay.Gradient)
            {
                ctx.Rectangle(left - 1, top - 1, width + 2, height + 2);
                using (var pat = new Cairo.LinearGradient(left - 1, top - 1, left - 1, height + 2)) {
                    pat.AddColorStop(0, backroundColor);
                    Cairo.Color endc = new Cairo.Color(1, 1, 1);
                    pat.AddColorStop(1, endc);
                    ctx.SetSource(pat);
                    ctx.Fill();
                }
            }
            else
            {
                ctx.Rectangle(left - 1, top - 1, width + 2, height + 2);
                ctx.SetSourceColor(backroundColor);
                ctx.Fill();
            }
//			win.DrawRectangle (Style.WhiteGC, true, left - 1, top - 1, width + 2, height + 2);
            win.DrawRectangle(Style.BlackGC, false, left - AreaBorderWidth, top - AreaBorderWidth, width + AreaBorderWidth * 2, height + AreaBorderWidth * 2);

            // Draw selected area

            if (enableSelection)
            {
                int sx, sy, ex, ey;
                GetPoint(selectionStart.Value, selectionStart.Value, out sx, out sy);
                GetPoint(selectionEnd.Value, selectionEnd.Value, out ex, out ey);
                if (sx > ex)
                {
                    int tmp = sx; sx = ex; ex = tmp;
                }
                Gdk.GC sgc = new Gdk.GC(GdkWindow);
                sgc.RgbFgColor = new Color(225, 225, 225);
                win.DrawRectangle(sgc, true, sx, top, ex - sx, height + 1);
            }

            // Draw axes

            Gdk.GC gc = Style.BlackGC;

            foreach (Axis ax in axis)
            {
                DrawAxis(win, gc, ax);
            }

            // Draw values
            foreach (Serie serie in series)
            {
                if (serie.Visible)
                {
                    DrawSerie(ctx, serie);
                }
            }

            // Draw cursors
            foreach (ChartCursor cursor in cursors)
            {
                DrawCursor(cursor);
            }

            // Draw cursor labels
            foreach (ChartCursor cursor in cursors)
            {
                if (cursor.ShowValueLabel)
                {
                    DrawCursorLabel(cursor);
                }
            }

            ((IDisposable)ctx).Dispose();
            return(true);
        }
Exemple #9
0
        /*
         * protected override bool OnExposeEvent(Gdk.EventExpose ev)
         * {
         *  Graphics g = Gtk.DotNet.Graphics.FromDrawable(ev.Window);
         *
         *  if (ViewObjects)
         *      g.DrawImage(Image, XOffset, YOffset, Image.Width*Scale, Image.Height*Scale);
         *  else
         *      base.OnExposeEvent(ev);
         *
         *  if (ViewObjects && objectEditor != null) {
         *      // Draw objects
         *
         *      int cursorX=-1,cursorY=-1;
         *      int selectedX=-1,selectedY=-1;
         *      hoveringObjectIndices = new List<int>();
         *
         *      ObjectGroup group = objectEditor.ObjectGroup;
         *      DrawObjectGroup(g, 0, ref cursorX, ref cursorY, ref selectedX, ref selectedY, group, objectEditor, ref hoveringObjectIndices);
         *
         *      // Object hovering over
         *      if (cursorX != -1)
         *          g.DrawRectangle(new Pen(Color.Red), cursorX, cursorY, 15, 15);
         *      // Object selected
         *      if (selectedX != -1)
         *          g.DrawRectangle(new Pen(Color.White), selectedX, selectedY, 15, 15);
         *  }
         *
         *
         *  g.Dispose();
         *
         *  return true;
         * }
         */

        int DrawObjectGroup(Cairo.Context cr, int index, ref int cursorX, ref int cursorY, ref int selectedX, ref int selectedY, ObjectGroup group, ObjectGroupEditor editor, ref List <int> objectIndices)
        {
            if (group == null)
            {
                return(index);
            }

            List <int> localObjectIndices = new List <int>(objectIndices);

            bool foundHoveringMatch = false;

            for (int i = 0; i < group.GetNumObjects(); i++)
            {
                ObjectData data = group.GetObjectData(i);
                if (data.GetObjectType() >= ObjectType.Pointer &&
                    data.GetObjectType() <= ObjectType.AntiBossPointer)
                {
                    ObjectGroup nextGroup = data.GetPointedObjectGroup();
                    if (nextGroup != null)
                    {
                        List <int> pointerObjectIndices = new List <int>(objectIndices);
                        pointerObjectIndices.Add(i);
                        if (editor != null && i == editor.SelectedIndex)
                        {
                            index = DrawObjectGroup(cr, index, ref cursorX, ref cursorY,
                                                    ref selectedX, ref selectedY, nextGroup, editor.SubEditor, ref pointerObjectIndices);
                        }
                        else
                        {
                            index = DrawObjectGroup(cr, index, ref cursorX, ref cursorY,
                                                    ref selectedX, ref selectedY, nextGroup, null, ref pointerObjectIndices);
                        }
                        if (pointerObjectIndices.Count > objectIndices.Count + 1)
                        {
                            localObjectIndices = pointerObjectIndices;
                        }
                    }
                }
                else
                {
                    Color color = data.GetColor();
                    int   x, y;
                    int   width;
                    if (data.HasXY())
                    {
                        x     = data.GetX();
                        y     = data.GetY();
                        width = 16;
                        // Objects with specific positions get
                        // transparency
                        color = Color.FromArgb(0xd0, color.R, color.G, color.B);
                    }
                    else
                    {
                        // No X/Y values exist
                        x = index;
                        y = 0;
                        while (x >= 0xf)
                        {
                            x -= 0xf;
                            y++;
                        }
                        x    *= 16;
                        y    *= 16;
                        x    += 8;
                        y    += 8;
                        width = 8;
                        index++;
                    }

                    if (editor != null && i == editor.SelectedIndex)
                    {
                        selectedX = x - 8 + XOffset;
                        selectedY = y - 8 + YOffset;
                    }
                    if (mouseX - XOffset >= x - 8 && mouseX - XOffset < x + 8 &&
                        mouseY - YOffset >= y - 8 && mouseY - YOffset < y + 8)
                    {
                        if (localObjectIndices.Count == objectIndices.Count)
                        {
                            if (foundHoveringMatch)
                            {
                                localObjectIndices[localObjectIndices.Count - 1] = i;
                            }
                            else
                            {
                                localObjectIndices.Add(i);
                            }
                            cursorX            = x - 8 + XOffset;
                            cursorY            = y - 8 + YOffset;
                            foundHoveringMatch = true;
                        }
                    }

                    // x and y are the center coordinates for the object

                    if (ViewObjectBoxes)
                    {
                        cr.SetSourceColor(CairoHelper.ConvertColor(color));
                        cr.Rectangle(x - width / 2 + XOffset, y - width / 2 + YOffset, width, width);
                        cr.Fill();
                    }

                    if (data.GetGameObject() != null)
                    {
                        try {
                            ObjectAnimationFrame o = data.GetGameObject().DefaultAnimation.GetFrame(0);
                            o.Draw(cr, x + XOffset, y + YOffset);
                        }
                        catch (NoAnimationException) {
                            // No animation defined
                        }
                        catch (InvalidAnimationException) {
                            // Error parsing an animation; draw a blue X to indicate the error
                            // TODO: cairo
                            int xPos = x - width / 2 + XOffset;
                            int yPos = y - width / 2 + YOffset;

                            /*
                             * g.DrawLine(new Pen(Color.Blue), xPos, yPos, xPos+width-1, yPos+width-1);
                             * g.DrawLine(new Pen(Color.Blue), xPos+width-1, yPos, xPos, yPos+width-1);
                             */
                        }
                    }
                }
            }

            objectIndices = localObjectIndices;
            return(index);
        }
Exemple #10
0
        protected override bool OnExposeEvent(Gdk.EventExpose evnt)
        {
            if (State == StateType.Prelight)
            {
                int    w = Allocation.Width, h = Allocation.Height;
                double x = Allocation.Left, y = Allocation.Top, r = 3;
                x += 0.5; y += 0.5; h -= 1; w -= 1;

                using (Cairo.Context ctx = Gdk.CairoHelper.Create(GdkWindow)) {
                    HslColor c  = new HslColor(Style.Background(Gtk.StateType.Normal));
                    HslColor c1 = c;
                    HslColor c2 = c;
                    if (State != StateType.Prelight)
                    {
                        c1.L *= 0.8;
                        c2.L *= 0.95;
                    }
                    else
                    {
                        c1.L *= 1.1;
                        c2.L *= 1;
                    }
                    Cairo.Gradient pat;
                    switch (bar.Position)
                    {
                    case PositionType.Top: pat = new Cairo.LinearGradient(x, y, x, y + h); break;

                    case PositionType.Bottom: pat = new Cairo.LinearGradient(x, y, x, y + h); break;

                    case PositionType.Left: pat = new Cairo.LinearGradient(x + w, y, x, y); break;

                    default: pat = new Cairo.LinearGradient(x, y, x + w, y); break;
                    }
                    pat.AddColorStop(0, c1);
                    pat.AddColorStop(1, c2);
                    ctx.NewPath();
                    ctx.Arc(x + r, y + r, r, 180 * (Math.PI / 180), 270 * (Math.PI / 180));
                    ctx.LineTo(x + w - r, y);
                    ctx.Arc(x + w - r, y + r, r, 270 * (Math.PI / 180), 360 * (Math.PI / 180));
                    ctx.LineTo(x + w, y + h);
                    ctx.LineTo(x, y + h);
                    ctx.ClosePath();
                    ctx.SetSource(pat);
                    ctx.FillPreserve();
                    c1            = c;
                    c1.L         *= 0.7;
                    ctx.LineWidth = 1;
                    ctx.SetSourceColor(c1);
                    ctx.Stroke();

                    // Inner line
                    ctx.NewPath();
                    ctx.Arc(x + r + 1, y + r + 1, r, 180 * (Math.PI / 180), 270 * (Math.PI / 180));
                    ctx.LineTo(x + w - r - 1, y + 1);
                    ctx.Arc(x + w - r - 1, y + r + 1, r, 270 * (Math.PI / 180), 360 * (Math.PI / 180));
                    ctx.LineTo(x + w - 1, y + h - 1);
                    ctx.LineTo(x + 1, y + h - 1);
                    ctx.ClosePath();
                    c1 = c;
                    //c1.L *= 0.9;
                    ctx.LineWidth = 1;
                    ctx.SetSourceColor(c1);
                    ctx.Stroke();
                }
            }

            bool res = base.OnExposeEvent(evnt);

            return(res);
        }
Exemple #11
0
        protected override void onDraw(Cairo.Context gr)
        {
            base.onDraw(gr);

            Rectangle cb = new Rectangle(0, 0, designWidth, designHeight);

            gr.Save();

            double z = zoom / 100.0;

            gr.Scale(z, z);

            if (drawGrid)
            {
                double gridLineWidth = 0.2 / z;
                double glhw          = gridLineWidth / 2.0;
                int    nbLines       = cb.Width / gridSpacing;
                double d             = cb.Left + gridSpacing;
                for (int i = 0; i < nbLines; i++)
                {
                    gr.MoveTo(d - glhw, cb.Y);
                    gr.LineTo(d - glhw, cb.Bottom);
                    d += gridSpacing;
                }
                nbLines = cb.Height / gridSpacing;
                d       = cb.Top + gridSpacing;
                for (int i = 0; i < nbLines; i++)
                {
                    gr.MoveTo(cb.X, d - glhw);
                    gr.LineTo(cb.Right, d - glhw);
                    d += gridSpacing;
                }
                gr.LineWidth = gridLineWidth;
                Foreground.SetAsSource(gr, cb);
                gr.Stroke();
            }

            lock (imlVE.RenderMutex) {
                gr.SetSourceSurface(imlVE.surf, cb.Left, cb.Top);
                gr.Paint();
                imlVE.IsDirty = false;
            }

            /*if (Error == null) {
             *      gr.SetSourceColor (Color.Black);
             *      gr.Rectangle (cb, 1.0 / z);
             * } else {
             *      gr.SetSourceColor (Color.LavenderBlush);
             *      gr.Rectangle (cb, 2.0 / z);
             *      string[] lerrs = Error.ToString ().Split ('\n');
             *      Point p = cb.Center;
             *      p.Y -= lerrs.Length * 20;
             *      foreach (string le in lerrs) {
             *              drawCenteredTextLine(gr, p, le);
             *              p.Y += 20;
             *
             *      }
             * }
             * gr.Stroke ();*/

            Rectangle hr;

            if (SelectedItem?.Parent != null)
            {
                gr.SelectFontFace(Font.Name, Font.Slant, Font.Wheight);
                gr.SetFontSize(Font.Size);
                gr.FontOptions = Interface.FontRenderingOptions;
                gr.Antialias   = Interface.Antialias;

                Widget g = SelectedItem;
                hr = g.ScreenCoordinates(g.getSlot());

//				Rectangle rIcons = new Rectangle (iconSize);
//				rIcons.Width *= 4;
//				rIcons.Top = hr.Bottom;
//				rIcons.Left = hr.Right - rIcons.Width + iconSize.Width;
                Rectangle rIcoMove = new Rectangle(hr.BottomRight, iconSize);
//				Rectangle rIcoStyle = rIcoMove;
//				rIcoStyle.Left += iconSize.Width + 4;

                using (Surface mask = new ImageSurface(Format.Argb32, cb.Width, cb.Height)) {
                    using (Context ctx = new Context(mask)) {
                        ctx.Save();
                        ctx.SetSourceRGBA(1.0, 1.0, 1.0, 0.4);
                        ctx.Paint();
                        ctx.Rectangle(hr);
                        ctx.Operator = Operator.Clear;
                        ctx.Fill();
                    }

                    gr.SetSourceSurface(mask, 0, 0);
                    gr.Paint();

                    using (Surface ol = new ImageSurface(Format.Argb32, cb.Width, cb.Height)) {
                        using (Context ctx = new Context(ol)) {
                            ctx.SetSourceColor(Colors.Black);
                            drawDesignOverlay(ctx, g, cb, hr, 0.4 / z, 6.5);
                        }

                        gr.SetSourceSurface(ol, 0, 0);
                        gr.Paint();
                    }

                    drawIcon(gr, icoMove, rIcoMove);
                    //drawIcon (gr, icoStyle, rIcoStyle);
                }
            }
            if (HoverWidget != null)
            {
                hr = HoverWidget.ScreenCoordinates(HoverWidget.getSlot());
                gr.SetSourceColor(Colors.SkyBlue);
                //gr.SetDash (new double[]{ 5.0, 3.0 }, 0.0);
                gr.Rectangle(hr, 0.4 / z);
            }
            gr.Restore();
        }
Exemple #12
0
            public void Read(string fontFileName, char character, string expectedImageFilePath)
            {
                Typeface typeFace;

                using (var fs = Utility.ReadFile(Utility.FontDir + fontFileName))
                {
                    var reader = new OpenFontReader();
                    typeFace = reader.Read(fs);
                }

                Typography.OpenFont.Glyph glyph = typeFace.Lookup(character);

                // read polygons and bezier segments
                GlyphLoader.Read(glyph, out var polygons, out var bezierSegments);

                Rect aabb = new Rect(polygons[0][0], polygons[0][1]);

                //print to test output
                //calcualte the aabb
                for (int i = 0; i < polygons.Count; i++)
                {
                    o.WriteLine("Polygon " + i);
                    var polygon = polygons[i];
                    foreach (var p in polygon)
                    {
                        aabb.Union(p);
                        o.WriteLine("{0}, {1}", (int)p.X, (int)p.Y);
                    }
                    o.WriteLine("");
                }

                foreach (var segment in bezierSegments)
                {
                    aabb.Union(segment.Item1);
                    aabb.Union(segment.Item2);
                    aabb.Union(segment.Item3);
                    o.WriteLine("<{0}, {1}> <{2}, {3}> <{4}, {5}>",
                                (int)segment.Item1.X, (int)segment.Item1.Y,
                                (int)segment.Item2.X, (int)segment.Item2.Y,
                                (int)segment.Item3.X, (int)segment.Item3.Y);
                }

                o.WriteLine("");

                // draw to an image
                using (Cairo.ImageSurface surface = new Cairo.ImageSurface(Cairo.Format.Argb32, MathEx.RoundToInt(aabb.Width), MathEx.RoundToInt(aabb.Height)))
                    using (Cairo.Context g = new Cairo.Context(surface))
                    {
                        g.Translate(-aabb.Min.X, -aabb.Min.Y);
                        //essential: set surface back ground to white (1,1,1,1)
                        g.SetSourceColor(CairoEx.ColorWhite);
                        g.Paint();

                        for (var i = 0; i < polygons.Count; i++)
                        {
                            var polygon = polygons[i];
                            g.MoveTo(polygon[0].X, polygon[0].Y);
                            foreach (var point in polygon)
                            {
                                g.LineTo(point.X, point.Y);
                            }
                            g.ClosePath();
                        }
                        g.SetSourceColor(new Cairo.Color(0, 0, 0));
                        g.LineWidth = 4;
                        g.StrokePreserve();
                        g.SetSourceColor(new Cairo.Color(0.8, 0, 0, 0.6));
                        g.Fill();

                        foreach (var segment in bezierSegments)
                        {
                            var p0 = segment.Item1;
                            var c  = segment.Item2;
                            var p1 = segment.Item3;
                            g.MoveTo(p0.X, p0.Y);
                            g.QuadraticTo(c.X, c.Y, p1.X, p1.Y);
                        }

                        g.LineWidth = 4;
                        g.SetSourceColor(CairoEx.ColorRgb(0, 122, 204));
                        g.Stroke();

                        //used to generate expected image
                        //surface.WriteToPng($"{Util.OutputPath}\\GlyphReaderFacts.TheReadMethod.Read_{fontFileName}_{character}.png");

                        var image         = Image.LoadPixelData <Bgra32>(Configuration.Default, surface.Data, surface.Width, surface.Height);
                        var expectedImage = Image.Load(expectedImageFilePath);
                        Assert.True(Util.CompareImage(expectedImage, image));
                    }
            }
Exemple #13
0
        protected override bool OnExposeEvent(Gdk.EventExpose e)
        {
            using (Cairo.Context cr = Gdk.CairoHelper.Create(e.Window)) {
                double xPos = padding, yPos = padding;
                var    layout = PangoUtil.CreateLayout(this);
                int    w, h;
                layout.SetText(new string ('X', maxLength));
                layout.GetPixelSize(out w, out h);

                foreach (Category cat in categories)
                {
                    yPos = padding;
                    cr.MoveTo(xPos, yPos);
                    layout.SetMarkup("<b>" + cat.Title + "</b>");
                    cr.SetSourceColor(Style.Text(StateType.Normal).ToCairoColor());
                    cr.ShowLayout(layout);

                    if (cat.Items.Count == 0)
                    {
                        continue;
                    }

                    layout.SetMarkup("");
                    int w2, h2;
                    layout.GetPixelSize(out w2, out h2);
                    yPos += h2;
                    yPos += headerDistance;
                    var startY     = yPos;
                    int curItem    = 0;
                    int row        = 0;
                    var iconHeight = Math.Max(h, cat.Items [0].Icon.Height + 2) + itemPadding * 2;
                    if (cat.FirstVisibleItem > 0)
                    {
                        Gtk.Style.PaintArrow(Style, e.Window, State, ShadowType.None,
                                             new Rectangle((int)xPos, (int)yPos, w, h),
                                             this,
                                             "",
                                             ArrowType.Up,
                                             true,
                                             (int)xPos,
                                             (int)yPos,
                                             w,
                                             h);
                        yPos += iconHeight;
                        curItem++;
                    }

                    for (int i = cat.FirstVisibleItem; i < cat.Items.Count; i++)
                    {
                        var item = cat.Items [i];

                        if (curItem + 1 >= maxItems && row + 1 >= maxRows && i + 1 < cat.Items.Count)
                        {
                            Gtk.Style.PaintArrow(Style, e.Window, State, ShadowType.None,
                                                 new Rectangle((int)xPos, (int)yPos, w, h),
                                                 this,
                                                 "",
                                                 ArrowType.Down,
                                                 true,
                                                 (int)xPos,
                                                 (int)yPos,
                                                 w,
                                                 h);
                            break;
                        }

                        if (item == ActiveItem)
                        {
                            int itemWidth = w + (int)item.Icon.Width + 2 + itemPadding * 2;
                            cr.Rectangle(xPos, yPos, itemWidth, iconHeight);
                            cr.LineWidth = 1;
                            cr.SetSourceColor(Style.Base(StateType.Selected).ToCairoColor());
                            cr.Fill();
                        }
                        else if (item == hoverItem)
                        {
                            int itemWidth = w + (int)item.Icon.Width + 2 + itemPadding * 2;
                            cr.Rectangle(xPos + 0.5, yPos + 0.5, itemWidth - 1, iconHeight);
                            cr.LineWidth = 1;
                            cr.SetSourceColor(Style.Base(StateType.Selected).ToCairoColor());
                            cr.Stroke();
                        }
                        cr.SetSourceColor(Style.Text(item == ActiveItem? StateType.Selected : StateType.Normal).ToCairoColor());
                        cr.MoveTo(xPos + item.Icon.Width + 2 + itemPadding, yPos + (iconHeight - h) / 2);
                        layout.SetText(Ellipsize(item.ListTitle ?? item.Title, maxLength));
                        cr.ShowLayout(layout);
                        cr.DrawImage(this, item.Icon, (int)xPos + itemPadding,
                                     (int)(yPos + (iconHeight - item.Icon.Height) / 2));
                        yPos += iconHeight;
                        if (++curItem >= maxItems)
                        {
                            curItem = 0;
                            yPos    = startY;
                            xPos   += w + cat.Items [0].Icon.Width + 2 + padding + itemPadding * 2;
                            row++;
                        }
                    }


                    xPos += w + cat.Items [0].Icon.Width + 2 + padding + itemPadding * 2;
                }
                layout.Dispose();
            }
            return(true);
        }
Exemple #14
0
        internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double lineHeight)
        {
            bool backgroundIsDrawn    = false;
            bool lineMarkerIsSelected = false;

            if (line != null)
            {
                foreach (var marker in editor.Document.GetMarkersOrderedByInsertion(line))
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null)
                    {
                        if (marginMarker.CanDrawBackground(this))
                        {
                            backgroundIsDrawn = marginMarker.DrawBackground(editor, cr, new MarginDrawMetrics(this, area, line, lineNumber, x, y, lineHeight));
                        }

                        if (focusMarkers != null)
                        {
                            SanitizeFocusedIndex();

                            lineMarkerIsSelected = (HasFocus && (marginMarker == focusMarkers[focusedIndex]));
                        }
                    }
                }
            }

            if (!backgroundIsDrawn)
            {
                cr.Rectangle(x, y, Width, lineHeight);
                if (HasFocus && lineMarkerIsSelected)
                {
                    cr.SetSourceColor(focusedMarkerColor);
                }
                else
                {
                    cr.SetSourceColor(HasFocus ? focusedBackgroundColor : backgroundColor);
                }
                cr.Fill();

                cr.MoveTo(x + Width - 0.5, y);
                cr.LineTo(x + Width - 0.5, y + lineHeight);
                cr.SetSourceColor(separatorColor);
                cr.Stroke();
            }

            if (line != null && lineNumber <= editor.Document.LineCount)
            {
                foreach (var marker in editor.Document.GetMarkersOrderedByInsertion(line))
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawForeground(this))
                    {
                        var metrics = new MarginDrawMetrics(this, area, line, lineNumber, x, y, lineHeight);
                        marginMarker.DrawForeground(editor, cr, metrics);

                        if (markerToAccessible != null)
                        {
                            var accessible = markerToAccessible [marker];
                            if (accessible != null)
                            {
                                accessible.Metrics = metrics;
                                accessible.UpdateAccessibilityDetails();
                            }
                        }
                    }
                }
                if (DrawEvent != null)
                {
                    DrawEvent(this, new BookmarkMarginDrawEventArgs(editor, cr, line, lineNumber, x, y));
                }
            }
        }
Exemple #15
0
        public void ShowGlyphAsDirectedContours_Cairo()
        {
            //load the glyph
            Typeface typeFace;

            using (var fs = Utility.ReadFile(Utility.FontDir + fontFileName))
            {
                var reader = new OpenFontReader();
                typeFace = reader.Read(fs);
            }
            Glyph  glyph       = typeFace.Lookup(character);
            Bounds boundingBox = typeFace.Bounds;
            short  ascender    = typeFace.Ascender;

            //read polygons and quadratic bezier segments
            GlyphLoader.Read(glyph, out var polygons, out var quadraticBezierSegments);

            //The actual position of points should apply ascender offset
            var offset = new Vector(0, ascender);

            // draw to an image
            using (Cairo.ImageSurface surface = new Cairo.ImageSurface(Cairo.Format.Argb32,
                                                                       boundingBox.XMax - boundingBox.XMin,
                                                                       boundingBox.YMax - boundingBox.YMin))
                using (Cairo.Context g = new Cairo.Context(surface))
                {
                    //set surface back ground to white (1,1,1,1)
                    g.SetSourceColor(CairoEx.ColorWhite);
                    g.Paint();

                    //polygons
                    for (var i = 0; i < polygons.Count; i++)
                    {
                        var polygon    = polygons[i];
                        var startPoint = polygon[0] + offset;
                        g.MoveTo(startPoint.X, startPoint.Y);
                        var previousPoint = startPoint;
                        foreach (var point in polygon)
                        {
                            var p = point + offset;
                            g.LineTo(p.X, p.Y);
                            g.DrawArrow(previousPoint, p);
                            previousPoint = p;
                        }
                        g.LineTo(startPoint.X, startPoint.Y);
                        g.DrawArrow(previousPoint, startPoint);
                    }
                    g.LineWidth = polygonLineWidth;
                    g.SetSourceColor(polygonColor.ToCairoColor());
                    g.Stroke();

                    //quadratic bezier segments
                    foreach (var segment in quadraticBezierSegments)
                    {
                        var p0 = segment.Item1 + offset;
                        var c  = segment.Item2 + offset;
                        var p1 = segment.Item3 + offset;
                        g.MoveTo(p0.X, p0.Y);
                        g.QuadraticTo(c.X, c.Y, p1.X, p1.Y);
                    }
                    g.LineWidth = quadraticLineWidth;
                    g.SetSourceColor(quadraticSegmentColor.ToCairoColor());
                    g.Stroke();

                    //start points
                    g.SetSourceColor(startPointColor.ToCairoColor());
                    for (var i = 0; i < polygons.Count; i++)
                    {
                        var polygon    = polygons[i];
                        var startPoint = polygon[0] + offset;
                        g.Arc(startPoint.x, startPoint.y, 10, 0, System.Math.PI * 2);
                        g.Fill();
                    }

                    //show the image of contours
                    var path = $"{OutputDir}{Path.DirectorySeparatorChar}{fontFileName}_{character}.png";
                    surface.WriteToPng(path);
                    Util.OpenImage(path);
                }
        }
Exemple #16
0
        protected override void OnDrawContent(Gdk.EventExpose evnt, Cairo.Context context)
        {
            context.LineWidth = 1;
            var alloc = ChildAllocation;
            var adjustedMarginSize = alloc.X - Allocation.X + headerMarginSize;

            var r = results.Where(res => res.Item2.Count > 0).ToArray();

            if (r.Any())
            {
                context.SetSourceColor(lightSearchBackground);
                context.Rectangle(Allocation.X, Allocation.Y, adjustedMarginSize, Allocation.Height);
                context.Fill();

                context.SetSourceColor(darkSearchBackground);
                context.Rectangle(Allocation.X + adjustedMarginSize, Allocation.Y, Allocation.Width - adjustedMarginSize, Allocation.Height);
                context.Fill();
                context.MoveTo(0.5 + Allocation.X + adjustedMarginSize, 0);
                context.LineTo(0.5 + Allocation.X + adjustedMarginSize, Allocation.Height);
                context.SetSourceColor(separatorLine);
                context.Stroke();
            }
            else
            {
                context.SetSourceRGB(1, 1, 1);
                context.Rectangle(Allocation.X, Allocation.Y, Allocation.Width, Allocation.Height);
                context.Fill();
            }

            double y = alloc.Y + yMargin;
            int    w, h;

            if (topItem != null)
            {
                headerLayout.SetText(GettextCatalog.GetString("Top Result"));
                headerLayout.GetPixelSize(out w, out h);
                context.MoveTo(alloc.Left + headerMarginSize - w - xMargin, y);
                context.SetSourceColor(headerColor);
                Pango.CairoHelper.ShowLayout(context, headerLayout);

                var category = topItem.Category;
                var dataSrc  = topItem.DataSource;
                var i        = topItem.Item;

                double x = alloc.X + xMargin + headerMarginSize;
                context.SetSourceRGB(0, 0, 0);
                layout.SetMarkup(GetRowMarkup(dataSrc[i]));
                layout.GetPixelSize(out w, out h);
                if (selectedItem != null && selectedItem.Category == category && selectedItem.Item == i)
                {
                    context.SetSourceColor(selectionBackgroundColor);
                    context.Rectangle(alloc.X + headerMarginSize, y, Allocation.Width - adjustedMarginSize, h);
                    context.Fill();
                    context.SetSourceRGB(1, 1, 1);
                }

                var px = dataSrc[i].Icon;
                if (px != null)
                {
                    context.DrawImage(this, px, (int)x + marginIconSpacing, (int)y + (h - px.Height) / 2);
                    x += px.Width + iconTextSpacing + marginIconSpacing;
                }

                context.MoveTo(x, y);
                context.SetSourceRGB(0, 0, 0);
                Pango.CairoHelper.ShowLayout(context, layout);

                y += h + itemSeparatorHeight;
            }

            foreach (var result in r)
            {
                var category = result.Item1;
                var dataSrc  = result.Item2;
                if (dataSrc.Count == 0)
                {
                    continue;
                }
                if (dataSrc.Count == 1 && topItem != null && topItem.DataSource == dataSrc)
                {
                    continue;
                }
                headerLayout.SetText(category.Name);
                headerLayout.GetPixelSize(out w, out h);

                if (y + h > Allocation.Height)
                {
                    break;
                }

                context.MoveTo(alloc.X + headerMarginSize - w - xMargin, y);
                context.SetSourceColor(headerColor);
                Pango.CairoHelper.ShowLayout(context, headerLayout);

                layout.Width = Pango.Units.FromPixels(Allocation.Width - adjustedMarginSize - 35);

                for (int i = 0; i < maxItems && i < dataSrc.Count; i++)
                {
                    if (topItem != null && topItem.Category == category && topItem.Item == i)
                    {
                        continue;
                    }
                    double x = alloc.X + xMargin + headerMarginSize;
                    context.SetSourceRGB(0, 0, 0);
                    layout.SetMarkup(GetRowMarkup(dataSrc[i]));
                    layout.GetPixelSize(out w, out h);
                    if (y + h + itemSeparatorHeight > Allocation.Height)
                    {
                        break;
                    }
                    if (selectedItem != null && selectedItem.Category == category && selectedItem.Item == i)
                    {
                        context.SetSourceColor(selectionBackgroundColor);
                        context.Rectangle(alloc.X + headerMarginSize, y, Allocation.Width - adjustedMarginSize, h);
                        context.Fill();
                        context.SetSourceRGB(1, 1, 1);
                    }

                    var px = dataSrc[i].Icon;
                    if (px != null)
                    {
                        context.DrawImage(this, px, (int)x + marginIconSpacing, (int)y + (h - px.Height) / 2);
                        x += px.Width + iconTextSpacing + marginIconSpacing;
                    }

                    context.MoveTo(x, y);
                    context.SetSourceRGB(0, 0, 0);
                    Pango.CairoHelper.ShowLayout(context, layout);

                    y += h + itemSeparatorHeight;
                }
                if (result != r.Last())
                {
                    y += categorySeparatorHeight;
                }
            }
            if (y == alloc.Y + yMargin)
            {
                context.SetSourceRGB(0, 0, 0);
                layout.SetMarkup(isInSearch ? GettextCatalog.GetString("Searching...") : GettextCatalog.GetString("No matches"));
                context.MoveTo(alloc.X + xMargin, y);
                Pango.CairoHelper.ShowLayout(context, layout);
            }
        }
Exemple #17
0
 /// <summary>
 /// Renders the background. Rendering will automatically be clipped to border constraints in later steps.
 /// </summary>
 public virtual void RenderBackground(Cairo.Context context, Gdk.Rectangle region)
 {
     context.Rectangle(region.X, region.Y, region.Width, region.Height);
     context.SetSourceColor(BackgroundColor);
     context.Fill();
 }
Exemple #18
0
        public void Draw(Cairo.Context cr)
        {
            //WireArray(cr, WiresList);
            //cr.SetSourceRGB(0.2, 0.9, 0.2);
            //cr.SetSourceColor(GetValueColor(Value.Error));
            //cr.Fill();

            foreach (var bundle in Bundles)
            {
                WireArray(cr, bundle.Wires);

                foreach (var connection in FindConnectionPoints(bundle.Wires))
                {
                    double x = connection.X * CircuitEditor.DotSpacing;
                    double y = connection.Y * CircuitEditor.DotSpacing;
                    cr.Arc(x, y, ConnectionRadius, 0, Math.PI * 2);
                    cr.ClosePath();
                }

                cr.SetSourceRGB(0.2, 0.9, 0.2);
                cr.SetSourceColor(GetValueColor(bundle.Subnet?.Value ?? Value.Floating));
                cr.Fill();
            }

            //WireArray(cr, Powered);
            //cr.SetSourceRGB(0.2, 0.9, 0.2);
            //cr.Fill();

            //WireArray(cr, UnPowered);
            //cr.SetSourceRGB(0.1, 0.4, 0.1);
            //cr.Fill();

            /*
             * foreach (var connection in FindConnectionPoints(WiresList))
             * {
             *  double x = connection.X * CircuitEditor.DotSpacing;
             *  double y = connection.Y * CircuitEditor.DotSpacing;
             *  cr.Arc(x, y, ConnectionRadius, 0, Math.PI * 2);
             *  cr.ClosePath();
             * }
             * cr.SetSourceRGB(0.2, 0.9, 0.2);
             * cr.Fill();*/

            /*
             * foreach (var connection in PoweredConnections)
             * {
             *  double x = connection.X * CircuitEditor.DotSpacing;
             *  double y = connection.Y * CircuitEditor.DotSpacing;
             *  cr.Arc(x, y, ConnectionRadius, 0, Math.PI * 2);
             *  cr.ClosePath();
             * }
             * cr.SetSourceRGB(0.2, 0.9, 0.2);
             * cr.Fill();
             *
             * foreach (var connection in UnPoweredConnections)
             * {
             *  double x = connection.X * CircuitEditor.DotSpacing;
             *  double y = connection.Y * CircuitEditor.DotSpacing;
             *  cr.Arc(x, y, ConnectionRadius, 0, Math.PI * 2);
             *  cr.ClosePath();
             * }
             * cr.SetSourceRGB(0.1, 0.4, 0.1);
             * cr.Fill();
             */
        }
        public override void DrawAfterEol(MonoTextEditor textEditor, Cairo.Context g, 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;
            var  y            = metrics.LineYRenderStartPosition;
            bool customLayout = true;             //sx + width > editor.Allocation.Width;
            bool hideText     = false;

            bubbleIsReduced = customLayout;
            var    showErrorCount = errorCounterWidth > 0 && errorCountLayout != null;
            double roundingRadius = editor.LineHeight / 2 - 1;

            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(25, errorCounterWidth) * editor.Options.Zoom;
                if (paintWidth < minWidth)
                {
                    hideText       = true;
                    showErrorCount = false;
//					drawLayout.SetMarkup ("<span weight='heavy'>···</span>");
                    width = minWidth;
                    //roundingRadius = 10 * editor.Options.Zoom;
                    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 - 2;
                }
            }

            bubbleDrawX = sx - editor.TextViewMargin.XOffset;
            bubbleDrawY = y + 2;
            bubbleWidth = width;
            var bubbleHeight = editor.LineHeight;

            g.RoundedRectangle(sx, y, width, bubbleHeight, roundingRadius);
            g.SetSourceColor(TagColor.Color);
            g.Fill();

            // Draw error count icon
            if (showErrorCount)
            {
                var errorCounterHeight = bubbleHeight - 2;
                var errorCounterX      = sx + width - errorCounterWidth - 1;
                var errorCounterY      = Math.Round(y + (bubbleHeight - errorCounterHeight) / 2);

                g.RoundedRectangle(
                    errorCounterX,
                    errorCounterY,
                    errorCounterWidth,
                    errorCounterHeight,
                    editor.LineHeight / 2 - 2
                    );

                // FIXME: VV: Remove gradient features
                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.SetSource(lg);
                    g.Fill();
                }

                g.Save();

                int ew;
                errorCountLayout.GetPixelSize(out ew, out eh);

                var tx = Math.Round(errorCounterX + (2 + errorCounterWidth - ew) / 2);
                var ty = Math.Round(errorCounterY + (-1 + errorCounterHeight - eh) / 2);

                g.Translate(tx, ty);
                g.SetSourceColor(CounterColor.SecondColor);
                g.ShowLayout(errorCountLayout);
                g.Restore();
            }

            if (hideText)
            {
                // Draw dots
                double radius  = 2 * editor.Options.Zoom;
                double spacing = 1 * editor.Options.Zoom;

                sx += 1 * editor.Options.Zoom + Math.Ceiling((bubbleWidth - 3 * (radius * 2) - 2 * spacing) / 2);

                for (int i = 0; i < 3; i++)
                {
                    g.Arc(sx, y + bubbleHeight / 2, radius, 0, Math.PI * 2);
                    g.SetSourceColor(TagColor.SecondColor);
                    g.Fill();
                    sx += radius * 2 + spacing;
                }
            }
            else
            {
                // Draw label text
                var tx = Math.Round(sx + editor.LineHeight / 2);
                var ty = Math.Round(y + (editor.LineHeight - layouts [0].Height) / 2) - 1;

                g.Save();
                g.Translate(tx, ty);

                g.SetSourceColor(TagColor.SecondColor);
                g.ShowLayout(drawLayout);
                g.Restore();
            }

            if (customLayout)
            {
                drawLayout.Dispose();
            }
        }
Exemple #20
0
        protected override void onDraw(Cairo.Context gr)
        {
            base.onDraw(gr);
            if (!drawGrid)
            {
                return;
            }


            Rectangle    cb            = ClientRectangle;
            const double gridLineWidth = 0.1;
            double       glhw          = gridLineWidth / 2.0;
            int          nbLines       = cb.Width / gridSpacing;
            double       d             = cb.Left + gridSpacing;

            for (int i = 0; i < nbLines; i++)
            {
                gr.MoveTo(d - glhw, cb.Y);
                gr.LineTo(d - glhw, cb.Bottom);
                d += gridSpacing;
            }
            nbLines = cb.Height / gridSpacing;
            d       = cb.Top + gridSpacing;
            for (int i = 0; i < nbLines; i++)
            {
                gr.MoveTo(cb.X, d - glhw);
                gr.LineTo(cb.Right, d - glhw);
                d += gridSpacing;
            }
            gr.LineWidth = gridLineWidth;
            Foreground.SetAsSource(gr, cb);
            gr.Stroke();

            lock (imlVE.RenderMutex) {
                using (Cairo.Surface surf = new Cairo.ImageSurface(imlVE.bmp, Cairo.Format.Argb32,
                                                                   imlVE.ClientRectangle.Width, imlVE.ClientRectangle.Height, imlVE.ClientRectangle.Width * 4)) {
                    gr.SetSourceSurface(surf, cb.Left, cb.Top);
                    gr.Paint();
                }
                imlVE.IsDirty = false;
            }

            Rectangle hr;

            if (imlVE.HoverWidget != null)
            {
                hr = imlVE.HoverWidget.ScreenCoordinates(imlVE.HoverWidget.getSlot());
//			gr.SetSourceColor (Color.LightGray);
//			gr.DrawCote (new Cairo.PointD (hr.X, hr.Center.Y), new Cairo.PointD (hr.Right, hr.Center.Y));
//			gr.DrawCote (new Cairo.PointD (hr.Center.X, hr.Y), new Cairo.PointD (hr.Center.X, hr.Bottom));
                //hr.Inflate (2);
                gr.SetSourceColor(Color.LightGray);
                gr.SetDash(new double[] { 3.0, 3.0 }, 0.0);
                gr.Rectangle(hr, 1.0);
            }

            if (SelectedItem == null)
            {
                return;
            }
            hr = SelectedItem.ScreenCoordinates(SelectedItem.getSlot());
            hr.Inflate(1);
            gr.SetSourceColor(Color.Yellow);
            gr.SetDash(new double[] { 5.0, 3.0 }, 0.0);
            gr.Rectangle(hr, 1.0);
        }
Exemple #21
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="showCursor">Whether or not to show the mouse cursor in the drawing.</param>
        /// <param name="useTextLayer">Whether or not to use the TextLayer (as opposed to the Userlayer).</param>
        private void RedrawText(bool showCursor, bool useTextLayer)
        {
            Rectangle r = CurrentTextLayout.GetLayoutBounds();
            r.Inflate(10 + OutlineWidth, 10 + OutlineWidth);
            InflateAndInvalidate(r);
            CurrentTextBounds = r;

            Rectangle cursorBounds = Rectangle.Zero;

            Cairo.ImageSurface surf;

            if (!useTextLayer)
            {
                //Draw text on the current UserLayer's surface as finalized text.
                surf = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.Surface;
            }
            else
            {
                //Draw text on the current UserLayer's TextLayer's surface as re-editable text.
                surf = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.TextLayer.Layer.Surface;

                ClearTextLayer();
            }

            using (var g = new Cairo.Context (surf)) {
                g.Save ();

                // Show selection if on text layer
                if (useTextLayer) {
                    // Selected Text
                    Cairo.Color c = new Cairo.Color (0.7, 0.8, 0.9, 0.5);
                    foreach (Rectangle rect in CurrentTextLayout.SelectionRectangles)
                        g.FillRectangle (rect.ToCairoRectangle (), c);
                }

                if (selection != null) {
                    g.AppendPath (selection.SelectionPath);
                    g.FillRule = Cairo.FillRule.EvenOdd;
                    g.Clip ();
                }

                g.MoveTo (new Cairo.PointD (CurrentTextEngine.Origin.X, CurrentTextEngine.Origin.Y));

                g.SetSourceColor (PintaCore.Palette.PrimaryColor);

                //Fill in background
                if (BackgroundFill) {
                    using (var g2 = new Cairo.Context (surf)) {
                        g2.FillRectangle(CurrentTextLayout.GetLayoutBounds().ToCairoRectangle(), PintaCore.Palette.SecondaryColor);
                    }
                }

                // Draw the text
                if (FillText)
                    Pango.CairoHelper.ShowLayout (g, CurrentTextLayout.Layout);

                if (FillText && StrokeText) {
                    g.SetSourceColor (PintaCore.Palette.SecondaryColor);
                    g.LineWidth = OutlineWidth;

                    Pango.CairoHelper.LayoutPath (g, CurrentTextLayout.Layout);
                    g.Stroke ();
                } else if (StrokeText) {
                    g.SetSourceColor (PintaCore.Palette.PrimaryColor);
                    g.LineWidth = OutlineWidth;

                    Pango.CairoHelper.LayoutPath (g, CurrentTextLayout.Layout);
                    g.Stroke ();
                }

                if (showCursor) {
                    var loc = CurrentTextLayout.GetCursorLocation ();
                    var color = PintaCore.Palette.PrimaryColor;

                    g.Antialias = Cairo.Antialias.None;
                    g.DrawLine (new Cairo.PointD (loc.X, loc.Y),
                            new Cairo.PointD (loc.X, loc.Y + loc.Height),
                            color, 1);

                    cursorBounds = Rectangle.Inflate (loc, 2, 10);
                }

                g.Restore ();

                if (useTextLayer && (is_editing || ctrlKey) && !CurrentTextEngine.IsEmpty())
                {
                    //Draw the text edit rectangle.

                    g.Save();

                    g.Translate(.5, .5);

                    using (Cairo.Path p = g.CreateRectanglePath(CurrentTextBounds.ToCairoRectangle ()))
                    {
                        g.AppendPath(p);
                    }

                    g.LineWidth = 1;

                    g.SetSourceColor (new Cairo.Color (1, 1, 1));
                    g.StrokePreserve();

                    g.SetDash(new double[] { 2, 4 }, 0);
                    g.SetSourceColor (new Cairo.Color(1, .1, .2));

                    g.Stroke();

                    g.Restore();
                }
            }

            InflateAndInvalidate(PintaCore.Workspace.ActiveDocument.CurrentUserLayer.previousTextBounds);
            PintaCore.Workspace.Invalidate(old_cursor_bounds);
            InflateAndInvalidate (r);
            PintaCore.Workspace.Invalidate(cursorBounds);

            old_cursor_bounds = cursorBounds;
        }
        protected override void Render(Drawable window, Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, CellRendererState flags)
        {
            if (isDisposed || layout == null)
            {
                return;
            }
            if (diffMode)
            {
                if (path.Equals(selctedPath))
                {
                    selectedLine = -1;
                    selctedPath  = null;
                }

                int w, maxy;
                window.GetSize(out w, out maxy);
                if (DrawLeft)
                {
                    cell_area.Width += cell_area.X - leftSpace;
                    cell_area.X      = leftSpace;
                }
                var treeview = widget as FileTreeView;
                var p        = treeview != null? treeview.CursorLocation : null;
                cell_area.Width -= RightPadding;

                window.DrawRectangle(widget.Style.BaseGC(Gtk.StateType.Normal), true, cell_area.X, cell_area.Y, cell_area.Width - 1, cell_area.Height);

                Gdk.GC normalGC  = widget.Style.TextGC(StateType.Normal);
                Gdk.GC removedGC = new Gdk.GC(window);
                removedGC.Copy(normalGC);
                removedGC.RgbFgColor = Styles.LogView.DiffRemoveBackgroundColor.AddLight(-0.3).ToGdkColor();
                Gdk.GC addedGC = new Gdk.GC(window);
                addedGC.Copy(normalGC);
                addedGC.RgbFgColor = Styles.LogView.DiffAddBackgroundColor.AddLight(-0.3).ToGdkColor();
                Gdk.GC infoGC = new Gdk.GC(window);
                infoGC.Copy(normalGC);
                infoGC.RgbFgColor = widget.Style.Text(StateType.Normal).AddLight(0.2);

                Cairo.Context ctx = CairoHelper.Create(window);

                // Rendering is done in two steps:
                // 1) Get a list of blocks to render
                // 2) render the blocks

                var blocks = CalculateBlocks(maxy, cell_area.Y + 2);

                // Now render the blocks

                // The y position of the highlighted line
                int selectedLineRowTop = -1;

                BlockInfo lastCodeSegmentStart = null;
                BlockInfo lastCodeSegmentEnd   = null;

                foreach (BlockInfo block in blocks)
                {
                    if (block.Type == BlockType.Info)
                    {
                        // Finished drawing the content of a code segment. Now draw the segment border and label.
                        if (lastCodeSegmentStart != null)
                        {
                            DrawCodeSegmentBorder(infoGC, ctx, cell_area.X, cell_area.Width, lastCodeSegmentStart, lastCodeSegmentEnd, lines, widget, window);
                        }
                        lastCodeSegmentStart = block;
                    }

                    lastCodeSegmentEnd = block;

                    if (block.YEnd < 0)
                    {
                        continue;
                    }

                    // Draw the block background
                    DrawBlockBg(ctx, cell_area.X + 1, cell_area.Width - 2, block);

                    // Get all text for the current block
                    StringBuilder sb = new StringBuilder();
                    for (int n = block.FirstLine; n <= block.LastLine; n++)
                    {
                        string s = ProcessLine(lines [n]);
                        if (n > block.FirstLine)
                        {
                            sb.Append('\n');
                        }
                        if ((block.Type == BlockType.Added || block.Type == BlockType.Removed) && s.Length > 0)
                        {
                            sb.Append(' ');
                            sb.Append(s, 1, s.Length - 1);
                        }
                        else
                        {
                            sb.Append(s);
                        }
                    }

                    // Draw a special background for the selected line

                    if (block.Type != BlockType.Info && p.HasValue && p.Value.X >= cell_area.X && p.Value.X <= cell_area.Right && p.Value.Y >= block.YStart && p.Value.Y <= block.YEnd)
                    {
                        int    row  = (p.Value.Y - block.YStart) / lineHeight;
                        double yrow = block.YStart + lineHeight * row;
                        double xrow = cell_area.X + LeftPaddingBlock;
                        int    wrow = cell_area.Width - 1 - LeftPaddingBlock;
                        if (block.Type == BlockType.Added)
                        {
                            ctx.SetSourceColor(Styles.LogView.DiffAddBackgroundColor.AddLight(0.1).ToCairoColor());
                        }
                        else if (block.Type == BlockType.Removed)
                        {
                            ctx.SetSourceColor(Styles.LogView.DiffRemoveBackgroundColor.AddLight(0.1).ToCairoColor());
                        }
                        else
                        {
                            ctx.SetSourceColor(Styles.LogView.DiffHighlightColor.ToCairoColor());
                            xrow -= LeftPaddingBlock;
                            wrow += LeftPaddingBlock;
                        }
                        ctx.Rectangle(xrow, yrow, wrow, lineHeight);
                        ctx.Fill();
                        selectedLine       = block.SourceLineStart + row;
                        selctedPath        = path;
                        selectedLineRowTop = (int)yrow;
                    }

                    // Draw the line text. Ignore header blocks, since they are drawn as labels in DrawCodeSegmentBorder

                    if (block.Type != BlockType.Info)
                    {
                        layout.SetMarkup("");
                        layout.SetText(sb.ToString());
                        Gdk.GC gc;
                        switch (block.Type)
                        {
                        case BlockType.Removed: gc = removedGC; break;

                        case BlockType.Added: gc = addedGC; break;

                        case BlockType.Info: gc = infoGC; break;

                        default: gc = normalGC; break;
                        }
                        window.DrawLayout(gc, cell_area.X + 2 + LeftPaddingBlock, block.YStart, layout);
                    }

                    // Finally draw the change symbol at the left margin

                    DrawChangeSymbol(ctx, widget, cell_area.X + 1, cell_area.Width - 2, block);
                }

                // Finish the drawing of the code segment
                if (lastCodeSegmentStart != null)
                {
                    DrawCodeSegmentBorder(infoGC, ctx, cell_area.X, cell_area.Width, lastCodeSegmentStart, lastCodeSegmentEnd, lines, widget, window);
                }

                // Draw the source line number at the current selected line. It must be done at the end because it must
                // be drawn over the source code text and segment borders.
                if (selectedLineRowTop != -1)
                {
                    DrawLineBox(normalGC, ctx, ((Gtk.TreeView)widget).VisibleRect.Right - 4, selectedLineRowTop, selectedLine, widget, window);
                }

                ((IDisposable)ctx).Dispose();
                removedGC.Dispose();
                addedGC.Dispose();
                infoGC.Dispose();
            }
            else
            {
                // Rendering a normal text row
                int y = cell_area.Y + (cell_area.Height - height) / 2;
                window.DrawLayout(widget.Style.TextGC(GetState(widget, flags)), cell_area.X, y, layout);
            }
        }