protected override bool OnExposeEvent(Gdk.EventExpose ev)
        {
            base.OnExposeEvent(ev);

            if (thumbnail == null)
            {
                UpdateThumbnail();
            }

            Rectangle rect = GdkWindow.GetBounds();

            Cairo.PointD pos   = PositionToClientPt(Position);
            Cairo.Color  black = new Cairo.Color(0, 0, 0);

            using (Cairo.Context g = CairoHelper.Create(GdkWindow)) {
                //background
                g.SetSource(thumbnail, 0.0, 0.0);
                g.Paint();

                g.DrawRectangle(new Cairo.Rectangle(rect.X + 1, rect.Y + 1, rect.Width - 1, rect.Height - 1), new Cairo.Color(.75, .75, .75), 1);
                g.DrawRectangle(new Cairo.Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 3, rect.Height - 3), black, 1);

                //cursor
                g.DrawLine(new Cairo.PointD(pos.X + 1, rect.Top + 2), new Cairo.PointD(pos.X + 1, rect.Bottom - 2), black, 1);
                g.DrawLine(new Cairo.PointD(rect.Left + 2, pos.Y + 1), new Cairo.PointD(rect.Right - 2, pos.Y + 1), black, 1);

                //point
                g.DrawEllipse(new Cairo.Rectangle(pos.X - 1, pos.Y - 1, 3, 3), black, 2);
            }
            return(true);
        }
Exemple #2
0
 public static Pixbuf CreateColorSwatch(int size, Color color)
 {
     using (var surf = CairoExtensions.CreateImageSurface(Cairo.Format.Argb32, size, size))
         using (var g = new Cairo.Context(surf)) {
             g.FillRectangle(new Cairo.Rectangle(0, 0, size, size), color.ToCairoColor());
             g.DrawRectangle(new Cairo.Rectangle(0, 0, size, size), new Cairo.Color(0, 0, 0), 1);
             return(surf.ToPixbuf());
         }
 }
Exemple #3
0
        public static Pixbuf CreateTransparentColorSwatch(bool drawBorder)
        {
            var size = 16;

            using (var surface = CairoExtensions.CreateTransparentBackgroundSurface(size))
                using (var g = new Cairo.Context(surface)) {
                    if (drawBorder)
                    {
                        g.DrawRectangle(new Cairo.Rectangle(0, 0, size, size), new Cairo.Color(0, 0, 0), 1);
                    }

                    return(surface.ToPixbuf());
                }
        }
Exemple #4
0
        /// <summary>
        /// Create a cursor icon with a shape that visually represents the tool's thickness.
        /// </summary>
        /// <param name="imgName">A string containing the name of the tool's icon image to use.</param>
        /// <param name="shape">The shape to draw.</param>
        /// <param name="shapeWidth">The width of the shape.</param>
        /// <param name="imgToShapeX">The horizontal distance between the image's top-left corner and the shape center.</param>
        /// <param name="imgToShapeY">The verical distance between the image's top-left corner and the shape center.</param>
        /// <param name="shapeX">The X position in the returned Pixbuf that will be the center of the shape.</param>
        /// <param name="shapeY">The Y position in the returned Pixbuf that will be the center of the shape.</param>
        /// <returns>The new cursor icon with an shape that represents the tool's thickness.</returns>
        public static Gdk.Pixbuf CreateIconWithShape(string imgName, CursorShape shape, int shapeWidth,
                                                     int imgToShapeX, int imgToShapeY,
                                                     out int shapeX, out int shapeY)
        {
            Gdk.Pixbuf img = PintaCore.Resources.GetIcon(imgName);

            double zoom = 1d;

            if (PintaCore.Workspace.HasOpenDocuments)
            {
                zoom = Math.Min(30d, PintaCore.Workspace.ActiveDocument.Workspace.Scale);
            }

            shapeWidth = (int)Math.Min(800d, ((double)shapeWidth) * zoom);
            int halfOfShapeWidth = shapeWidth / 2;

            // Calculate bounding boxes around the both image and shape
            // relative to the image top-left corner.
            Gdk.Rectangle imgBBox   = new Gdk.Rectangle(0, 0, img.Width, img.Height);
            Gdk.Rectangle shapeBBox = new Gdk.Rectangle(
                imgToShapeX - halfOfShapeWidth,
                imgToShapeY - halfOfShapeWidth,
                shapeWidth,
                shapeWidth);

            // Inflate shape bounding box to allow for anti-aliasing
            shapeBBox.Inflate(2, 2);

            // To determine required size of icon,
            // find union of the image and shape bounding boxes
            // (still relative to image top-left corner)
            Gdk.Rectangle iconBBox = imgBBox.Union(shapeBBox);

            // Image top-left corner in icon co-ordinates
            int imgX = imgBBox.Left - iconBBox.Left;
            int imgY = imgBBox.Top - iconBBox.Top;

            // Shape center point in icon co-ordinates
            shapeX = imgToShapeX - iconBBox.Left;
            shapeY = imgToShapeY - iconBBox.Top;

            using (var i = CairoExtensions.CreateImageSurface(Cairo.Format.ARGB32, iconBBox.Width, iconBBox.Height)) {
                using (var g = new Cairo.Context(i)) {
                    // Don't show shape if shapeWidth less than 3,
                    if (shapeWidth > 3)
                    {
                        int             diam      = Math.Max(1, shapeWidth - 2);
                        Cairo.Rectangle shapeRect = new Cairo.Rectangle(shapeX - halfOfShapeWidth,
                                                                        shapeY - halfOfShapeWidth,
                                                                        diam,
                                                                        diam);

                        Cairo.Color outerColor = new Cairo.Color(255, 255, 255, 0.75);
                        Cairo.Color innerColor = new Cairo.Color(0, 0, 0);

                        switch (shape)
                        {
                        case CursorShape.Ellipse:
                            g.DrawEllipse(shapeRect, outerColor, 2);
                            shapeRect = shapeRect.Inflate(-1, -1);
                            g.DrawEllipse(shapeRect, innerColor, 1);
                            break;

                        case CursorShape.Rectangle:
                            g.DrawRectangle(shapeRect, outerColor, 1);
                            shapeRect = shapeRect.Inflate(-1, -1);
                            g.DrawRectangle(shapeRect, innerColor, 1);
                            break;
                        }
                    }

                    // Draw the image
                    g.DrawPixbuf(img, new Cairo.Point(imgX, imgY));
                }

                return(CairoExtensions.ToPixbuf(i));
            }
        }
Exemple #5
0
        protected override bool OnExposeEvent(EventExpose e)
        {
            base.OnExposeEvent(e);

            if (!PintaCore.Workspace.HasOpenDocuments)
            {
                return(true);
            }

            double scale = PintaCore.Workspace.Scale;

            int x = (int)PintaCore.Workspace.Offset.X;
            int y = (int)PintaCore.Workspace.Offset.Y;

            // Translate our expose area for the whole drawingarea to just our canvas
            Rectangle canvas_bounds = new Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height);

            canvas_bounds.Intersect(e.Area);

            if (canvas_bounds.IsEmpty)
            {
                return(true);
            }

            canvas_bounds.X -= x;
            canvas_bounds.Y -= y;

            // Resize our offscreen surface to a surface the size of our drawing area
            if (canvas == null || canvas.Width != canvas_bounds.Width || canvas.Height != canvas_bounds.Height)
            {
                if (canvas != null)
                {
                    (canvas as IDisposable).Dispose();
                }

                canvas = new Cairo.ImageSurface(Cairo.Format.Argb32, canvas_bounds.Width, canvas_bounds.Height);
            }

            cr.Initialize(PintaCore.Workspace.ImageSize, PintaCore.Workspace.CanvasSize);

            using (Cairo.Context g = CairoHelper.Create(GdkWindow)) {
                // Draw our 1 px black border
                g.DrawRectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width + 1, PintaCore.Workspace.CanvasSize.Height + 1), new Cairo.Color(0, 0, 0), 1);

                // Set up our clip rectangle
                g.Rectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height));
                g.Clip();

                g.Translate(x, y);

                bool checker = true;

                // Resize each layer and paint it to the screen
                foreach (Layer layer in PintaCore.Layers.GetLayersToPaint())
                {
                    cr.Render(layer.Surface, canvas, canvas_bounds.Location, checker);
                    g.SetSourceSurface(canvas, canvas_bounds.X + (int)(layer.Offset.X * scale), canvas_bounds.Y + (int)(layer.Offset.Y * scale));
                    g.PaintWithAlpha(layer.Opacity);

                    if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled)
                    {
                        cr.Render(PintaCore.LivePreview.LivePreviewSurface, canvas, canvas_bounds.Location, checker);

                        g.Save();
                        g.Scale(scale, scale);
                        g.AppendPath(PintaCore.Layers.SelectionPath);
                        g.Clip();

                        g.Scale(1 / scale, 1 / scale);
                        g.SetSourceSurface(canvas, canvas_bounds.X, canvas_bounds.Y);
                        g.PaintWithAlpha(layer.Opacity);

                        g.Restore();
                    }

                    checker = false;
                }

                // If we are at least 200% and grid is requested, draw it
                if (PintaCore.Actions.View.PixelGrid.Active && cr.ScaleFactor.Ratio <= 0.5d)
                {
                    gr.Render(canvas, canvas_bounds.Location);
                    g.SetSourceSurface(canvas, canvas_bounds.X, canvas_bounds.Y);
                    g.Paint();
                }

                // Selection outline
                if (PintaCore.Layers.ShowSelection)
                {
                    g.Save();
                    g.Translate(0.5, 0.5);
                    g.Scale(scale, scale);

                    g.AppendPath(PintaCore.Layers.SelectionPath);

                    if (PintaCore.Tools.CurrentTool.Name.Contains("Select") && !PintaCore.Tools.CurrentTool.Name.Contains("Selected"))
                    {
                        g.Color    = new Cairo.Color(0.7, 0.8, 0.9, 0.2);
                        g.FillRule = Cairo.FillRule.EvenOdd;
                        g.FillPreserve();
                    }

                    g.LineWidth = 1 / scale;

                    // Draw a white line first so it shows up on dark backgrounds
                    g.Color = new Cairo.Color(1, 1, 1);
                    g.StrokePreserve();

                    // Draw a black dashed line over the white line
                    g.SetDash(new double[] { 2 / scale, 4 / scale }, 0);
                    g.Color = new Cairo.Color(0, 0, 0);

                    g.Stroke();
                    g.Restore();
                }
            }

            return(true);
        }
Exemple #6
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 #7
0
        protected override bool OnExposeEvent(EventExpose e)
        {
            base.OnExposeEvent(e);

            if (!PintaCore.Workspace.HasOpenDocuments)
            {
                return(true);
            }

            double scale = PintaCore.Workspace.Scale;

            int x = (int)PintaCore.Workspace.Offset.X;
            int y = (int)PintaCore.Workspace.Offset.Y;

            // Translate our expose area for the whole drawingarea to just our canvas
            Rectangle canvas_bounds = new Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height);

            canvas_bounds.Intersect(e.Area);

            if (canvas_bounds.IsEmpty)
            {
                return(true);
            }

            canvas_bounds.X -= x;
            canvas_bounds.Y -= y;

            // Resize our offscreen surface to a surface the size of our drawing area
            if (canvas == null || canvas.Width != canvas_bounds.Width || canvas.Height != canvas_bounds.Height)
            {
                if (canvas != null)
                {
                    (canvas as IDisposable).Dispose();
                }

                canvas = new Cairo.ImageSurface(Cairo.Format.Argb32, canvas_bounds.Width, canvas_bounds.Height);
            }

            cr.Initialize(PintaCore.Workspace.ImageSize, PintaCore.Workspace.CanvasSize);

            using (Cairo.Context g = CairoHelper.Create(GdkWindow)) {
                // Draw our canvas drop shadow
                g.DrawRectangle(new Cairo.Rectangle(x - 1, y - 1, PintaCore.Workspace.CanvasSize.Width + 2, PintaCore.Workspace.CanvasSize.Height + 2), new Cairo.Color(.5, .5, .5), 1);
                g.DrawRectangle(new Cairo.Rectangle(x - 2, y - 2, PintaCore.Workspace.CanvasSize.Width + 4, PintaCore.Workspace.CanvasSize.Height + 4), new Cairo.Color(.8, .8, .8), 1);
                g.DrawRectangle(new Cairo.Rectangle(x - 3, y - 3, PintaCore.Workspace.CanvasSize.Width + 6, PintaCore.Workspace.CanvasSize.Height + 6), new Cairo.Color(.9, .9, .9), 1);

                // Set up our clip rectangle
                g.Rectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height));
                g.Clip();

                g.Translate(x, y);

                // Render all the layers to a surface
                var layers = PintaCore.Layers.GetLayersToPaint();
                if (layers.Count == 0)
                {
                    canvas.Clear();
                }
                cr.Render(layers, canvas, canvas_bounds.Location);

                // Paint the surface to our canvas
                g.SetSourceSurface(canvas, canvas_bounds.X + (int)(0 * scale), canvas_bounds.Y + (int)(0 * scale));
                g.Paint();

                // Selection outline
                if (PintaCore.Layers.ShowSelection)
                {
                    bool fillSelection = PintaCore.Tools.CurrentTool.Name.Contains("Select") &&
                                         !PintaCore.Tools.CurrentTool.Name.Contains("Selected");
                    PintaCore.Workspace.ActiveDocument.Selection.Draw(g, scale, fillSelection);
                }
            }

            return(true);
        }
Exemple #8
0
        protected override bool OnExposeEvent(EventExpose e)
        {
            base.OnExposeEvent(e);

            if (!PintaCore.Workspace.HasOpenDocuments)
            {
                return(true);
            }

            double scale = PintaCore.Workspace.Scale;

            int x = (int)PintaCore.Workspace.Offset.X;
            int y = (int)PintaCore.Workspace.Offset.Y;

            // Translate our expose area for the whole drawingarea to just our canvas
            Rectangle canvas_bounds = new Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height);

            canvas_bounds.Intersect(e.Area);

            if (canvas_bounds.IsEmpty)
            {
                return(true);
            }

            canvas_bounds.X -= x;
            canvas_bounds.Y -= y;

            // Resize our offscreen surface to a surface the size of our drawing area
            if (canvas == null || canvas.Width != canvas_bounds.Width || canvas.Height != canvas_bounds.Height)
            {
                if (canvas != null)
                {
                    (canvas as IDisposable).Dispose();
                }

                canvas = new Cairo.ImageSurface(Cairo.Format.Argb32, canvas_bounds.Width, canvas_bounds.Height);
            }

            cr.Initialize(PintaCore.Workspace.ImageSize, PintaCore.Workspace.CanvasSize);

            using (Cairo.Context g = CairoHelper.Create(GdkWindow)) {
                // Draw our canvas drop shadow
                g.DrawRectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width + 1, PintaCore.Workspace.CanvasSize.Height + 1), new Cairo.Color(.5, .5, .5), 1);
                g.DrawRectangle(new Cairo.Rectangle(x - 1, y - 1, PintaCore.Workspace.CanvasSize.Width + 3, PintaCore.Workspace.CanvasSize.Height + 3), new Cairo.Color(.8, .8, .8), 1);
                g.DrawRectangle(new Cairo.Rectangle(x - 2, y - 2, PintaCore.Workspace.CanvasSize.Width + 5, PintaCore.Workspace.CanvasSize.Height + 5), new Cairo.Color(.9, .9, .9), 1);

                // Set up our clip rectangle
                g.Rectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height));
                g.Clip();

                g.Translate(x, y);

                // Render all the layers to a surface
                var layers = PintaCore.Layers.GetLayersToPaint();
                if (layers.Count == 0)
                {
                    canvas.Clear();
                }
                cr.Render(layers, canvas, canvas_bounds.Location);

                // Paint the surface to our canvas
                g.SetSourceSurface(canvas, canvas_bounds.X + (int)(0 * scale), canvas_bounds.Y + (int)(0 * scale));
                g.Paint();

                // Selection outline
                if (PintaCore.Layers.ShowSelection)
                {
                    g.Save();
                    g.Translate(0.5, 0.5);
                    g.Scale(scale, scale);

                    g.AppendPath(PintaCore.Workspace.ActiveDocument.Selection.SelectionPath);

                    if (PintaCore.Tools.CurrentTool.Name.Contains("Select") && !PintaCore.Tools.CurrentTool.Name.Contains("Selected"))
                    {
                        g.Color    = new Cairo.Color(0.7, 0.8, 0.9, 0.2);
                        g.FillRule = Cairo.FillRule.EvenOdd;
                        g.FillPreserve();
                    }

                    g.LineWidth = 1 / scale;

                    // Draw a white line first so it shows up on dark backgrounds
                    g.Color = new Cairo.Color(1, 1, 1);
                    g.StrokePreserve();

                    // Draw a black dashed line over the white line
                    g.SetDash(new double[] { 2 / scale, 4 / scale }, 0);
                    g.Color = new Cairo.Color(0, 0, 0);

                    g.Stroke();
                    g.Restore();
                }
            }

            return(true);
        }