示例#1
0
		protected override Gdk.Rectangle OnMouseMove (Context g, Color strokeColor, ImageSurface surface,
		                                              int x, int y, int lastX, int lastY)
		{
			// Cairo does not support a single-pixel-long single-pixel-wide line
			if (x == lastX && y == lastY && g.LineWidth == 1 &&
			    PintaCore.Workspace.ActiveWorkspace.PointInCanvas (new PointD(x,y))) {
				surface.Flush ();

				ColorBgra source = surface.GetColorBgraUnchecked (x, y);
				source = UserBlendOps.NormalBlendOp.ApplyStatic (source, strokeColor.ToColorBgra ());
				surface.SetColorBgra (source, x, y);
				surface.MarkDirty ();

				return new Gdk.Rectangle (x - 1, y - 1, 3, 3);
			}

			g.MoveTo (lastX + 0.5, lastY + 0.5);
			g.LineTo (x + 0.5, y + 0.5);
			g.StrokePreserve ();

			Gdk.Rectangle dirty = g.FixedStrokeExtents ().ToGdkRectangle ();

			// For some reason (?!) we need to inflate the dirty
			// rectangle for small brush widths in zoomed images
			dirty.Inflate (1, 1);

			return dirty;
		}
示例#2
0
		private ColorBgra ComputeCellColor (int x, int y, ImageSurface src, int cellSize, Gdk.Rectangle srcBounds) {
			Gdk.Rectangle cell = GetCellBox (x, y, cellSize);
			cell.Intersect (srcBounds);
			
			int left = cell.Left;
			int right = cell.GetRight ();
			int bottom = cell.GetBottom ();
			int top = cell.Top;
			
			ColorBgra colorTopLeft = src.GetColorBgraUnchecked (left, top);
			ColorBgra colorTopRight = src.GetColorBgraUnchecked (right, top);
			ColorBgra colorBottomLeft = src.GetColorBgraUnchecked (left, bottom);
			ColorBgra colorBottomRight = src.GetColorBgraUnchecked (right, bottom);
			
			ColorBgra c = ColorBgra.BlendColors4W16IP (colorTopLeft, 16384, colorTopRight, 16384, colorBottomLeft, 16384, colorBottomRight, 16384);
			
			return c;
		}
示例#3
0
文件: Document.cs 项目: msiyer/Pinta
		/// <summary>
		/// Gets the final pixel color for the given point, taking layers, opacity, and blend modes into account.
		/// </summary>
		public ColorBgra GetComputedPixel (int x, int y)
		{
            using (var dst = new ImageSurface (Format.Argb32, 1, 1)) {
                using (var g = new Context (dst)) {
			        foreach (var layer in GetLayersToPaint ()) {
                        var color = layer.Surface.GetColorBgraUnchecked (x, y).ToStraightAlpha ().ToCairoColor ();

                        g.SetBlendMode (layer.BlendMode);
                        g.SetSourceColor (color);

                        g.Rectangle (dst.GetBounds ().ToCairoRectangle ());
                        g.PaintWithAlpha (layer.Opacity);
                    }
                }

                return dst.GetColorBgraUnchecked (0, 0);
            }
		}
示例#4
0
文件: FloodTool.cs 项目: msiyer/Pinta
		public unsafe static void FillStencilFromPoint (ImageSurface surface, IBitVector2D stencil, Point start, int tolerance, 
		                                                out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
		{
			ColorBgra cmp = surface.GetColorBgraUnchecked (start.X, start.Y);
			int top = int.MaxValue;
			int bottom = int.MinValue;
			int left = int.MaxValue;
			int right = int.MinValue;
			Gdk.Rectangle[] scans;

			stencil.Clear (false);

			if (limitToSelection) {
				using (Gdk.Region excluded = Gdk.Region.Rectangle (new Gdk.Rectangle (0, 0, stencil.Width, stencil.Height))) {
					excluded.Xor (limitRegion);
					scans = excluded.GetRectangles ();
				}
			} else {
				scans = new Gdk.Rectangle[0];
			}

			foreach (Gdk.Rectangle rect in scans) {
				stencil.Set (rect, true);
			}

			Queue<Point> queue = new Queue<Point> (16);
			queue.Enqueue (start);

			while (queue.Count > 0) {
				Point pt = queue.Dequeue ();

				ColorBgra* rowPtr = surface.GetRowAddressUnchecked (pt.Y);
				int localLeft = pt.X - 1;
				int localRight = pt.X;

				while (localLeft >= 0 &&
				       !stencil.GetUnchecked (localLeft, pt.Y) &&
				       CheckColor (cmp, rowPtr[localLeft], tolerance)) {
					stencil.SetUnchecked (localLeft, pt.Y, true);
					--localLeft;
				}

                int surfaceWidth = surface.Width;
				while (localRight < surfaceWidth &&
				       !stencil.GetUnchecked (localRight, pt.Y) &&
				       CheckColor (cmp, rowPtr[localRight], tolerance)) {
					stencil.SetUnchecked (localRight, pt.Y, true);
					++localRight;
				}

				++localLeft;
				--localRight;

                Action<int> checkRow = (row) =>
                {
					int sleft = localLeft;
					int sright = localLeft;
					ColorBgra* otherRowPtr = surface.GetRowAddressUnchecked (row);

					for (int sx = localLeft; sx <= localRight; ++sx) {
						if (!stencil.GetUnchecked (sx, row) &&
						    CheckColor (cmp, otherRowPtr[sx], tolerance)) {
							++sright;
						} else {
							if (sright - sleft > 0) {
								queue.Enqueue (new Point (sleft, row));
							}

							++sright;
							sleft = sright;
						}
					}

					if (sright - sleft > 0) {
						queue.Enqueue (new Point (sleft, row));
					}
                };

				if (pt.Y > 0) {
                    checkRow (pt.Y - 1);
				}

				if (pt.Y < surface.Height - 1) {
                    checkRow (pt.Y + 1);
				}

				if (localLeft < left) {
					left = localLeft;
				}

				if (localRight > right) {
					right = localRight;
				}

				if (pt.Y < top) {
					top = pt.Y;
				}

				if (pt.Y > bottom) {
					bottom = pt.Y;
				}
			}

			foreach (Gdk.Rectangle rect in scans)
				stencil.Set (rect, false);
			
			boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1);
		}
示例#5
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            var selection = PintaCore.LivePreview.RenderBounds;
            this.defaultRadius = Math.Min (selection.Width, selection.Height) * 0.5;
            this.defaultRadius2 = this.defaultRadius * this.defaultRadius;

            var x_center_offset = selection.Left + (selection.Width * (1.0 + Data.CenterOffset.X) * 0.5);
            var y_center_offset = selection.Top + (selection.Height * (1.0 + Data.CenterOffset.Y) * 0.5);

            ColorBgra colPrimary = PintaCore.Palette.PrimaryColor.ToColorBgra ();
            ColorBgra colSecondary = PintaCore.Palette.SecondaryColor.ToColorBgra ();
            ColorBgra colTransparent = ColorBgra.Transparent;

            int aaSampleCount = Data.Quality * Data.Quality;
            Cairo.PointD* aaPoints = stackalloc Cairo.PointD[aaSampleCount];
            Utility.GetRgssOffsets (aaPoints, aaSampleCount, Data.Quality);
            ColorBgra* samples = stackalloc ColorBgra[aaSampleCount];

            TransformData td;

            foreach (Gdk.Rectangle rect in rois) {

                for (int y = rect.Top; y <= rect.GetBottom (); y++) {
                    ColorBgra* dstPtr = dst.GetPointAddressUnchecked (rect.Left, y);

                    double relativeY = y - y_center_offset;

                    for (int x = rect.Left; x <= rect.GetRight (); x++) {
                        double relativeX = x - x_center_offset;

                        int sampleCount = 0;

                        for (int p = 0; p < aaSampleCount; ++p) {
                            td.X = relativeX + aaPoints[p].X;
                            td.Y = relativeY - aaPoints[p].Y;

                            InverseTransform (ref td);

                            float sampleX = (float)(td.X + x_center_offset);
                            float sampleY = (float)(td.Y + y_center_offset);

                            ColorBgra sample = colPrimary;

                            if (IsOnSurface (src, sampleX, sampleY)) {
                                sample = src.GetBilinearSample (sampleX, sampleY);
                            } else {
                                switch (Data.EdgeBehavior) {
                                case WarpEdgeBehavior.Clamp:
                                    sample = src.GetBilinearSampleClamped (sampleX, sampleY);
                                    break;

                                case WarpEdgeBehavior.Wrap:
                                    sample = src.GetBilinearSampleWrapped (sampleX, sampleY);
                                    break;

                                case WarpEdgeBehavior.Reflect:
                                    sample = src.GetBilinearSampleClamped (ReflectCoord (sampleX, src.Width), ReflectCoord (sampleY, src.Height));

                                    break;

                                case WarpEdgeBehavior.Primary:
                                    sample = colPrimary;
                                    break;

                                case WarpEdgeBehavior.Secondary:
                                    sample = colSecondary;
                                    break;

                                case WarpEdgeBehavior.Transparent:
                                    sample = colTransparent;
                                    break;

                                case WarpEdgeBehavior.Original:
                                    sample = src.GetColorBgraUnchecked (x, y);
                                    break;
                                default:

                                    break;
                                }
                            }

                            samples[sampleCount] = sample;
                            ++sampleCount;
                        }

                        *dstPtr = ColorBgra.Blend (samples, sampleCount);
                        ++dstPtr;
                    }
                }
            }
        }