protected override Gdk.Pixbuf RenderInitialPixbuf(Gdk.Window parentwindow, Gdk.Rectangle bounds)
 {
     //FIXME add a drop shadow on the pixmap, and expand the bounds to include this
     using (Gdk.Pixmap pixmap = new Gdk.Pixmap(parentwindow, bounds.Width, bounds.Height)) {
         using (var bgGc = new Gdk.GC(pixmap)) {
             marker.EnsureLayoutCreated(base.Editor);
             bgGc.RgbFgColor = CairoExtensions.CairoColorToGdkColor(marker.colorMatrix[0, 0, 0, 0, 0]);
             pixmap.DrawRectangle(bgGc, true, 0, 0, bounds.Width, bounds.Height);
             bgGc.RgbFgColor = (Mono.TextEditor.HslColor)marker.gc;
             pixmap.DrawLayout(bgGc, 4, (bounds.Height - marker.Layouts[0].Height) / 2, marker.Layouts[0].Layout);
         }
         return(Gdk.Pixbuf.FromDrawable(pixmap, Colormap, 0, 0, 0, 0, bounds.Width, bounds.Height));
     }
 }
        protected override bool OnExposeEvent(Gdk.EventExpose evnt)
        {
            using (var cr = Gdk.CairoHelper.Create(evnt.Window)) {
                cr.SetSourceRGBA(1, 1, 1, 0);
                cr.Operator = Cairo.Operator.Source;
                cr.Paint();
            }

            using (var cr = Gdk.CairoHelper.Create(evnt.Window)) {
                cr.Translate(width / 2, height / 2);
                cr.Scale(1 + scale / 8, 1 + scale / 8);
                int x = -(marker.ErrorTextBounds.Width) / 2;
                int y = -marker.ErrorTextBounds.Height / 2;

                if (marker.FitsInSameLine)
                {
                    cr.MoveTo(x + Editor.LineHeight / 2, y);
                    cr.LineTo(x, 0);
                    cr.LineTo(x + Editor.LineHeight / 2, marker.ErrorTextBounds.Height / 2);
                }
                else
                {
                    cr.MoveTo(x, -marker.ErrorTextBounds.Height / 2);
                    cr.LineTo(x, marker.ErrorTextBounds.Height / 2);
                }
                cr.LineTo(x + marker.ErrorTextBounds.Width, marker.ErrorTextBounds.Height / 2);
                cr.LineTo(x + marker.ErrorTextBounds.Width, y);
                cr.ClosePath();

                Mono.TextEditor.HslColor hsl = marker.colorMatrix [0, 0, 0, 0, 0];
                double delta = 1 + 2 - scale;
                hsl.S += delta;
                var color = (Cairo.Color)hsl;
                color.A  = opacity;
                cr.Color = color;
                cr.FillPreserve();
                color    = marker.colorMatrix [0, 0, 2, 0, 0];
                color.A  = opacity;
                cr.Color = color;
                cr.Stroke();
                int errorCounterWidth = 0;

                if (marker.Errors.Count > 1)
                {
                    double rY = y + Editor.LineHeight / 6;
                    int    ew, eh;
                    marker.errorCountLayout.GetPixelSize(out ew, out eh);
                    errorCounterWidth = ew + 10;
                    int rX = x + marker.ErrorTextBounds.Width - errorCounterWidth;

                    int    rW = errorCounterWidth - 2;
                    double rH = Editor.LineHeight * 3 / 4;

                    BookmarkMarker.DrawRoundRectangle(cr, rX, rY, 8, rW, rH);
                    cr.Color = new Cairo.Color(0.5, 0.5, 0.5);
                    cr.Fill();

                    cr.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4);
                    cr.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4);
                    cr.LineTo(rX + rW / 2, rY + rH / 4);
                    cr.ClosePath();

                    cr.Color = new Cairo.Color(1, 1, 1);
                    cr.Fill();
                }

                cr.Color = new Cairo.Color(0, 0, 0);
                marker.EnsureLayoutCreated(base.Editor);

                int layoutWidth, layoutHeight;
                marker.Layouts [0].Layout.GetPixelSize(out layoutWidth, out layoutHeight);
                double ly;
                if (marker.CollapseExtendedErrors || marker.Errors.Count == 1)
                {
                    ly = 1 + y + (marker.ErrorTextBounds.Height - layoutHeight) / 2;
                    double x2 = x + MessageBubbleTextMarker.border;
                    if (marker.FitsInSameLine)
                    {
                        x2 += 1 + Editor.LineHeight / 2;
                    }
                    cr.Translate(x2, ly);
                    cr.ShowLayout(marker.Layouts [0].Layout);
                }
                else
                {
                    ly = 1 + y + (Editor.LineHeight - layoutHeight) / 2;
                    for (int i = 0; i < marker.Errors.Count; i++)
                    {
                        marker.Layouts [i].Layout.GetPixelSize(out layoutWidth, out layoutHeight);
                        cr.Save();
                        double x2;
                        if (i == 0)
                        {
                            x2 = x + marker.ErrorTextBounds.Width - layoutWidth - errorCounterWidth;
                        }
                        else
                        {
                            x2 = x + MessageBubbleTextMarker.border;
                        }
                        if (marker.FitsInSameLine)
                        {
                            x2 += Editor.LineHeight / 2;
                        }
                        cr.Translate(x2, ly);
                        cr.ShowLayout(marker.Layouts [i].Layout);
                        cr.Restore();
                        ly += Editor.LineHeight;
                    }
                }
            }
            return(false);
        }