コード例 #1
0
ファイル: CanvasRenderer.cs プロジェクト: p07r0457/Pinta
        private unsafe void RenderZoomIn(Cairo.ImageSurface src, Cairo.ImageSurface dst, Gdk.Point offset, bool checker)
        {
            ColorBgra *src_ptr = (ColorBgra *)src.DataPtr;
            ColorBgra *dst_ptr = (ColorBgra *)dst.DataPtr;

            int src_width  = src.Width;
            int dst_width  = dst.Width;
            int dst_height = dst.Height;

            if (!generated)
            {
                d2sLookupX = CreateLookupX(src_width, destination_size.Width, scale_factor);
                d2sLookupY = CreateLookupY(src.Height, destination_size.Height, scale_factor);
                s2dLookupX = CreateS2DLookupX(src_width, destination_size.Width, scale_factor);
                s2dLookupY = CreateS2DLookupY(src.Height, destination_size.Height, scale_factor);

                generated = true;
            }

            for (int dstRow = 0; dstRow < dst_height; ++dstRow)
            {
                int nnY  = dstRow + offset.Y;
                int srcY = d2sLookupY[nnY];

                ColorBgra *dstPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);
                ColorBgra *srcRow = src.GetRowAddressUnchecked(src_ptr, src_width, srcY);

                for (int dstCol = 0; dstCol < dst_width; ++dstCol)
                {
                    int nnX  = dstCol + offset.X;
                    int srcX = d2sLookupX[nnX];

                    if (checker)
                    {
                        ColorBgra src2 = *(srcRow + srcX);
                        int       b    = src2.B;
                        int       g    = src2.G;
                        int       r    = src2.R;
                        int       a    = src2.A;

                        // Blend it over the checkerboard background
                        int v = (((dstCol + offset.X) ^ (dstRow + offset.Y)) & 8) * 8 + 191;
                        a = a + (a >> 7);
                        int vmia = v * (256 - a);

                        r = ((r * a) + vmia) >> 8;
                        g = ((g * a) + vmia) >> 8;
                        b = ((b * a) + vmia) >> 8;

                        dstPtr->Bgra = (uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)255 << 24);
                    }
                    else
                    {
                        *dstPtr = *(srcRow + srcX);
                    }

                    ++dstPtr;
                }
            }
        }
コード例 #2
0
        private unsafe void RenderPixelGrid(Cairo.ImageSurface dst, Gdk.Point offset)
        {
            EnsureLookupTablesCreated();

            // Draw horizontal lines
            var dst_ptr   = (ColorBgra *)dst.DataPtr;
            int dstHeight = dst.Height;
            int dstWidth  = dst.Width;
            int dstStride = dst.Stride;
            int sTop      = d2sLookupY[offset.Y];
            int sBottom   = d2sLookupY[offset.Y + dstHeight];

            for (int srcY = sTop; srcY <= sBottom; ++srcY)
            {
                int dstY   = s2dLookupY[srcY];
                int dstRow = dstY - offset.Y;

                if (dstRow >= 0 && dstRow < dstHeight)
                {
                    ColorBgra *dstRowPtr    = dst.GetRowAddressUnchecked(dst_ptr, dstWidth, dstRow);
                    ColorBgra *dstRowEndPtr = dstRowPtr + dstWidth;

                    dstRowPtr += offset.X & 1;

                    while (dstRowPtr < dstRowEndPtr)
                    {
                        *dstRowPtr = ColorBgra.Black;
                        dstRowPtr += 2;
                    }
                }
            }

            // Draw vertical lines
            int sLeft  = d2sLookupX[offset.X];
            int sRight = d2sLookupX[offset.X + dstWidth];

            for (int srcX = sLeft; srcX <= sRight; ++srcX)
            {
                int dstX   = s2dLookupX[srcX];
                int dstCol = dstX - offset.X;

                if (dstCol >= 0 && dstCol < dstWidth)
                {
                    byte *dstColPtr    = (byte *)dst.GetPointAddress(dstCol, 0);
                    byte *dstColEndPtr = dstColPtr + dstStride * dstHeight;

                    dstColPtr += (offset.Y & 1) * dstStride;

                    while (dstColPtr < dstColEndPtr)
                    {
                        *((ColorBgra *)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dstStride;
                    }
                }
            }
        }
コード例 #3
0
ファイル: CanvasRenderer.cs プロジェクト: mfcallahan/Pinta
        private unsafe void RenderPixelGrid(Cairo.ImageSurface dst, Point offset)
        {
            // Draw horizontal lines
            var dst_ptr   = (ColorBgra *)dst.DataPtr;
            var dstHeight = dst.Height;
            var dstWidth  = dst.Width;
            var dstStride = dst.Stride;
            var sTop      = D2SLookupY[offset.Y];
            var sBottom   = D2SLookupY[offset.Y + dstHeight];

            for (var srcY = sTop; srcY <= sBottom; ++srcY)
            {
                var dstY   = S2DLookupY[srcY];
                var dstRow = dstY - offset.Y;

                if (dstRow >= 0 && dstRow < dstHeight)
                {
                    var dstRowPtr    = dst.GetRowAddressUnchecked(dst_ptr, dstWidth, dstRow);
                    var dstRowEndPtr = dstRowPtr + dstWidth;

                    dstRowPtr += offset.X & 1;

                    while (dstRowPtr < dstRowEndPtr)
                    {
                        *dstRowPtr = ColorBgra.Black;
                        dstRowPtr += 2;
                    }
                }
            }

            // Draw vertical lines
            var sLeft  = D2SLookupX[offset.X];
            var sRight = D2SLookupX[offset.X + dstWidth];

            for (var srcX = sLeft; srcX <= sRight; ++srcX)
            {
                var dstX   = S2DLookupX[srcX];
                var dstCol = dstX - offset.X;

                if (dstCol >= 0 && dstCol < dstWidth)
                {
                    var dstColPtr    = (byte *)dst.GetPointAddress(dstCol, 0);
                    var dstColEndPtr = dstColPtr + dstStride * dstHeight;

                    dstColPtr += (offset.Y & 1) * dstStride;

                    while (dstColPtr < dstColEndPtr)
                    {
                        *((ColorBgra *)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dstStride;
                    }
                }
            }
        }
コード例 #4
0
ファイル: CanvasRenderer.cs プロジェクト: p07r0457/Pinta
        private unsafe void RenderOneToOne(Cairo.ImageSurface src, Cairo.ImageSurface dst, Gdk.Point offset, bool checker)
        {
            Gdk.Rectangle srcRect = new Gdk.Rectangle(offset, dst.GetBounds().Size);
            srcRect.Intersect(src.GetBounds());

            ColorBgra *src_ptr = (ColorBgra *)src.DataPtr;
            ColorBgra *dst_ptr = (ColorBgra *)dst.DataPtr;

            int src_width  = src.Width;
            int dst_width  = dst.Width;
            int dst_height = dst.Height;

            for (int dstRow = 0; dstRow < srcRect.Height; ++dstRow)
            {
                ColorBgra *dstRowPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);
                ColorBgra *srcRowPtr = src.GetPointAddressUnchecked(src_ptr, src_width, offset.X, dstRow + offset.Y);

                int dstCol    = offset.X;
                int dstColEnd = offset.X + srcRect.Width;
                int checkerY  = dstRow + offset.Y;

                while (dstCol < dstColEnd)
                {
                    // Blend it over the checkerboard background
                    if (checker)
                    {
                        int b = srcRowPtr->B;
                        int g = srcRowPtr->G;
                        int r = srcRowPtr->R;
                        int a = srcRowPtr->A;

                        int v = (((dstCol ^ checkerY) & 8) << 3) + 191;
                        a = a + (a >> 7);
                        int vmia = v * (256 - a);

                        r = ((r * a) + vmia) >> 8;
                        g = ((g * a) + vmia) >> 8;
                        b = ((b * a) + vmia) >> 8;

                        dstRowPtr->Bgra = (uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)255 << 24);
                    }
                    else
                    {
                        *dstRowPtr = *srcRowPtr;
                    }

                    ++dstRowPtr;
                    ++srcRowPtr;
                    ++dstCol;
                }
            }
        }
コード例 #5
0
ファイル: BinaryPixelOp.cs プロジェクト: p07r0457/Pinta
        public void Apply(Cairo.ImageSurface dst, Cairo.ImageSurface src)
        {
            if (dst.GetSize() != src.GetSize())
            {
                throw new ArgumentException("dst.Size != src.Size");
            }

            unsafe {
                for (int y = 0; y < dst.Height; ++y)
                {
                    ColorBgra *dstPtr = dst.GetRowAddressUnchecked(y);
                    ColorBgra *srcPtr = src.GetRowAddressUnchecked(y);
                    Apply(dstPtr, srcPtr, dst.Width);
                }
            }
        }
コード例 #6
0
        private unsafe void CopyScaledZoomIn(Cairo.ImageSurface src, Cairo.ImageSurface dst, Rectangle roi)
        {
            // Tell Cairo we need the latest raw data
            dst.Flush();

            EnsureLookupTablesCreated();

            // Cache pointers to surface raw data
            var src_ptr = (ColorBgra *)src.DataPtr;
            var dst_ptr = (ColorBgra *)dst.DataPtr;

            // Cache surface sizes
            var src_width  = src.Width;
            var dst_width  = dst.Width;
            var dst_height = dst.Height;

            for (var dst_row = 0; dst_row < dst_height; ++dst_row)
            {
                // For each dest row, look up the src row to copy from
                var nnY  = dst_row + roi.Y;
                var srcY = d2sLookupY[nnY];

                // Get pointers to src and dest rows
                var dst_row_ptr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dst_row);
                var src_row_ptr = src.GetRowAddressUnchecked(src_ptr, src_width, srcY);

                for (var dstCol = 0; dstCol < dst_width; ++dstCol)
                {
                    // Look up the src column to copy from
                    var nnX  = dstCol + roi.X;
                    var srcX = d2sLookupX[nnX];

                    // Copy source to destination
                    *dst_row_ptr++ = *(src_row_ptr + srcX);
                }
            }

            // Tell Cairo we changed the raw data
            dst.MarkDirty();
        }
コード例 #7
0
ファイル: BinaryPixelOp.cs プロジェクト: p07r0457/Pinta
        public void Apply(Cairo.ImageSurface dst, Cairo.ImageSurface lhs, Cairo.ImageSurface rhs)
        {
            if (dst.GetSize() != lhs.GetSize())
            {
                throw new ArgumentException("dst.Size != lhs.Size");
            }

            if (lhs.GetSize() != rhs.GetSize())
            {
                throw new ArgumentException("lhs.Size != rhs.Size");
            }

            unsafe {
                for (int y = 0; y < dst.Height; ++y)
                {
                    ColorBgra *dstPtr = dst.GetRowAddressUnchecked(y);
                    ColorBgra *lhsPtr = lhs.GetRowAddressUnchecked(y);
                    ColorBgra *rhsPtr = rhs.GetRowAddressUnchecked(y);

                    Apply(dstPtr, lhsPtr, rhsPtr, dst.Width);
                }
            }
        }
コード例 #8
0
ファイル: CanvasRenderer.cs プロジェクト: mfcallahan/Pinta
        private unsafe void CopyScaledZoomOut(Cairo.ImageSurface src, Cairo.ImageSurface dst, Rectangle roi)
        {
            // Tell Cairo we need the latest raw data
            dst.Flush();

            const int fpShift  = 12;
            const int fpFactor = (1 << fpShift);

            var source_size = src.GetBounds().Size;

            // Find destination bounds
            var dst_left   = (int)(((long)roi.X * fpFactor * (long)source_size.Width) / (long)destination_size.Width);
            var dst_top    = (int)(((long)roi.Y * fpFactor * (long)source_size.Height) / (long)destination_size.Height);
            var dst_right  = (int)(((long)(roi.X + dst.Width) * fpFactor * (long)source_size.Width) / (long)destination_size.Width);
            var dst_bottom = (int)(((long)(roi.Y + dst.Height) * fpFactor * (long)source_size.Height) / (long)destination_size.Height);
            var dx         = (dst_right - dst_left) / dst.Width;
            var dy         = (dst_bottom - dst_top) / dst.Height;

            // Cache pointers to surface raw data and sizes
            var src_ptr    = (ColorBgra *)src.DataPtr;
            var dst_ptr    = (ColorBgra *)dst.DataPtr;
            var src_width  = src.Width;
            var dst_width  = dst.Width;
            var dst_height = dst.Height;

            for (int dstRow = 0, fDstY = dst_top; dstRow < dst_height && fDstY < dst_bottom; ++dstRow, fDstY += dy)
            {
                var srcY1 = fDstY >> fpShift;                                            // y
                var srcY2 = (fDstY + (dy >> 2)) >> fpShift;                              // y + 0.25
                var srcY3 = (fDstY + (dy >> 1)) >> fpShift;                              // y + 0.50
                var srcY4 = (fDstY + (dy >> 1) + (dy >> 2)) >> fpShift;                  // y + 0.75

                var src1   = src.GetRowAddressUnchecked(src_ptr, src_width, srcY1);
                var src2   = src.GetRowAddressUnchecked(src_ptr, src_width, srcY2);
                var src3   = src.GetRowAddressUnchecked(src_ptr, src_width, srcY3);
                var src4   = src.GetRowAddressUnchecked(src_ptr, src_width, srcY4);
                var dstPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);

                var checkerY    = dstRow + roi.Y;
                var checkerX    = roi.X;
                var maxCheckerX = checkerX + dst.Width;

                for (var fDstX = dst_left; checkerX < maxCheckerX && fDstX < dst_right; ++checkerX, fDstX += dx)
                {
                    var srcX1 = (fDstX + (dx >> 2)) >> fpShift;                                 // x + 0.25
                    var srcX2 = (fDstX + (dx >> 1) + (dx >> 2)) >> fpShift;                     // x + 0.75
                    var srcX3 = fDstX >> fpShift;                                               // x
                    var srcX4 = (fDstX + (dx >> 1)) >> fpShift;                                 // x + 0.50

                    var p1 = src1 + srcX1;
                    var p2 = src2 + srcX2;
                    var p3 = src3 + srcX3;
                    var p4 = src4 + srcX4;

                    var r = (2 + p1->R + p2->R + p3->R + p4->R) >> 2;
                    var g = (2 + p1->G + p2->G + p3->G + p4->G) >> 2;
                    var b = (2 + p1->B + p2->B + p3->B + p4->B) >> 2;
                    var a = (2 + p1->A + p2->A + p3->A + p4->A) >> 2;

                    // Copy color to destination
                    *dstPtr++ = ColorBgra.FromUInt32((uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)a << 24));
                }
            }

            // Tell Cairo we changed the raw data
            dst.MarkDirty();
        }
コード例 #9
0
        public unsafe void Render(Cairo.ImageSurface dst, Gdk.Point offset)
        {
            if (cr.ScaleFactor > new ScaleFactor(1, 2))
            {
                return;
            }

            int[] d2SLookupX = cr.Dst2SrcLookupX;
            int[] d2SLookupY = cr.Dst2SrcLookupY;
            int[] s2DLookupX = cr.Src2DstLookupX;
            int[] s2DLookupY = cr.Src2DstLookupY;

            ColorBgra[] blackAndWhite = new ColorBgra[2] {
                ColorBgra.White, ColorBgra.Black
            };

            // draw horizontal lines
            int dstHeight = dst.Height;
            int dstWidth  = dst.Width;
            int dstStride = dst.Stride;
            int sTop      = d2SLookupY[offset.Y];
            int sBottom   = d2SLookupY[offset.Y + dstHeight];

            dst.Flush();

            for (int srcY = sTop; srcY <= sBottom; ++srcY)
            {
                int dstY   = s2DLookupY[srcY];
                int dstRow = dstY - offset.Y;

                if (dstRow >= 0 && dstRow < dstHeight)
                {
                    ColorBgra *dstRowPtr    = dst.GetRowAddressUnchecked(dstRow);
                    ColorBgra *dstRowEndPtr = dstRowPtr + dstWidth;

                    dstRowPtr += offset.X & 1;

                    while (dstRowPtr < dstRowEndPtr)
                    {
                        *dstRowPtr = ColorBgra.Black;
                        dstRowPtr += 2;
                    }
                }
            }

            // draw vertical lines
            int sLeft  = d2SLookupX[offset.X];
            int sRight = d2SLookupX[offset.X + dstWidth];

            for (int srcX = sLeft; srcX <= sRight; ++srcX)
            {
                int dstX   = s2DLookupX[srcX];
                int dstCol = dstX - offset.X;

                if (dstCol >= 0 && dstCol < dstWidth)
                {
                    byte *dstColPtr    = (byte *)dst.GetPointAddress(dstCol, 0);
                    byte *dstColEndPtr = dstColPtr + dstStride * dstHeight;

                    dstColPtr += (offset.Y & 1) * dstStride;

                    while (dstColPtr < dstColEndPtr)
                    {
                        *((ColorBgra *)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dstStride;
                    }
                }
            }

            dst.MarkDirty();
        }
コード例 #10
0
        public unsafe void Export(Document document, string fileName, Window parent)
        {
            int    w = 64, h = 64;                       //Default value to configure, pixels per block
            string chars = DefaultCharacters.AsciiChars; //Get the selection from config

            ASCIIOptionsDialog dialog = new ASCIIOptionsDialog(w, h);

            try {
                dialog.WindowPosition = Gtk.WindowPosition.CenterOnParent;

                int response = dialog.Run();

                if (response == (int)Gtk.ResponseType.Ok)
                {
                    w     = dialog.ExportImageWidth;
                    h     = dialog.ExportImageHeight;
                    chars = dialog.ExportImageChars;
                }
                else
                {
                    return;
                }
            } finally {
                dialog.Destroy();
            }


            Cairo.ImageSurface surface = document.GetFlattenedImage();
            int W = surface.Width, H = surface.Height;


            // Special case where 1 cell corresponds directly to 1 pixel
            // Written separately for performance
            if (h == 1 && w == 1)
            {
                StreamWriter writer = new StreamWriter(fileName);
                for (int y = 0; y < H; y++)
                {
                    ColorBgra *current = surface.GetRowAddressUnchecked(y);
                    for (int x = 0; x < W; x++)
                    {
                        int  pos = (int)((1 - current->GetIntensity()) * chars.Length);
                        char c   = chars[pos == chars.Length ? pos - 1 : pos];
                        writer.Write(c);
                        current++;
                    }
                    if (y != H - 1)
                    {
                        writer.WriteLine();
                    }
                }
                writer.Flush();
            }
            else
            {
                double[,] totals = new double[W / w, H / h];
                for (int y = 0; y < H / h * h; y++)
                {
                    ColorBgra *current = surface.GetRowAddressUnchecked(y);
                    for (int x = 0; x < W / w * w; x++)
                    {
                        totals[x / w, y / h] += 1 - current->GetIntensity();
                        current++;
                    }
                }

                int          ppc    = w * h;
                StreamWriter writer = new StreamWriter(fileName);
                for (int y = 0; y < H / h; y++)
                {
                    for (int x = 0; x < W / w; x++)
                    {
                        int  pos = (int)(totals[x, y] / ppc * chars.Length);
                        char c   = chars[pos == chars.Length ? pos - 1 : pos];
                        writer.Write(c);
                    }
                    if (y != H / h - 1)
                    {
                        writer.WriteLine();
                    }
                }
                writer.Flush();
            }
        }
コード例 #11
0
ファイル: CanvasRenderer.cs プロジェクト: casey0102/Pinta
        private unsafe void RenderZoomOut(List <Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset, Gdk.Size destinationSize)
        {
            // The first layer should be blended with the transparent checkerboard
            var checker = true;
            CheckerBoardOperation checker_op = null;

            for (int i = 0; i < layers.Count; i++)
            {
                var layer = layers[i];

                // If we're in LivePreview, substitute current layer with the preview layer
                if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled)
                {
                    layer = CreateLivePreviewLayer(layer);
                }

                // If the layer is offset, handle it here
                if (!layer.Offset.IsEmpty())
                {
                    layer = CreateOffsetLayer(layer);
                }

                var src = layer.Surface;

                // Get the blend mode for this layer and opacity
                var blend_op = UserBlendOps.GetBlendOp(layer.BlendMode, layer.Opacity);

                if (checker)
                {
                    checker_op = new CheckerBoardOperation(layer.Opacity);
                }

                const int fpShift  = 12;
                const int fpFactor = (1 << fpShift);

                Gdk.Size sourceSize     = src.GetBounds().Size;
                long     fDstLeftLong   = ((long)offset.X * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width;
                long     fDstTopLong    = ((long)offset.Y * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height;
                long     fDstRightLong  = ((long)(offset.X + dst.Width) * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width;
                long     fDstBottomLong = ((long)(offset.Y + dst.Height) * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height;
                int      fDstLeft       = (int)fDstLeftLong;
                int      fDstTop        = (int)fDstTopLong;
                int      fDstRight      = (int)fDstRightLong;
                int      fDstBottom     = (int)fDstBottomLong;
                int      dx             = (fDstRight - fDstLeft) / dst.Width;
                int      dy             = (fDstBottom - fDstTop) / dst.Height;

                ColorBgra *src_ptr   = (ColorBgra *)src.DataPtr;
                ColorBgra *dst_ptr   = (ColorBgra *)dst.DataPtr;
                int        src_width = src.Width;
                int        dst_width = dst.Width;

                for (int dstRow = 0, fDstY = fDstTop; dstRow < dst.Height && fDstY < fDstBottom; ++dstRow, fDstY += dy)
                {
                    int srcY1 = fDstY >> fpShift;                                                // y
                    int srcY2 = (fDstY + (dy >> 2)) >> fpShift;                                  // y + 0.25
                    int srcY3 = (fDstY + (dy >> 1)) >> fpShift;                                  // y + 0.50
                    int srcY4 = (fDstY + (dy >> 1) + (dy >> 2)) >> fpShift;                      // y + 0.75

                    ColorBgra *src1        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY1);
                    ColorBgra *src2        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY2);
                    ColorBgra *src3        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY3);
                    ColorBgra *src4        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY4);
                    ColorBgra *dstPtr      = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);
                    int        checkerY    = dstRow + offset.Y;
                    int        checkerX    = offset.X;
                    int        maxCheckerX = checkerX + dst.Width;

                    for (int fDstX = fDstLeft; checkerX < maxCheckerX && fDstX < fDstRight; ++checkerX, fDstX += dx)
                    {
                        int        srcX1 = (fDstX + (dx >> 2)) >> fpShift;                              // x + 0.25
                        int        srcX2 = (fDstX + (dx >> 1) + (dx >> 2)) >> fpShift;                  // x + 0.75
                        int        srcX3 = fDstX >> fpShift;                                            // x
                        int        srcX4 = (fDstX + (dx >> 1)) >> fpShift;                              // x + 0.50
                        ColorBgra *p1    = src1 + srcX1;
                        ColorBgra *p2    = src2 + srcX2;
                        ColorBgra *p3    = src3 + srcX3;
                        ColorBgra *p4    = src4 + srcX4;

                        int r = (2 + p1->R + p2->R + p3->R + p4->R) >> 2;
                        int g = (2 + p1->G + p2->G + p3->G + p4->G) >> 2;
                        int b = (2 + p1->B + p2->B + p3->B + p4->B) >> 2;
                        int a = (2 + p1->A + p2->A + p3->A + p4->A) >> 2;

                        // Blend it over the checkerboard background
                        if (checker)
                        {
                            *dstPtr = checker_op.Apply(ColorBgra.FromUInt32((uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)a << 24)), checkerX, checkerY);
                        }
                        else
                        {
                            *dstPtr = blend_op.Apply(*dstPtr, ColorBgra.FromUInt32((uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)a << 24)));
                        }

                        ++dstPtr;
                    }
                }

                // Only checker the first layer
                checker = false;
            }
        }
コード例 #12
0
ファイル: CanvasRenderer.cs プロジェクト: casey0102/Pinta
        private unsafe void RenderZoomIn(List <Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset)
        {
            // The first layer should be blended with the transparent checkerboard
            var checker = true;
            CheckerBoardOperation checker_op = null;

            for (int i = 0; i < layers.Count; i++)
            {
                var layer = layers[i];

                // If we're in LivePreview, substitute current layer with the preview layer
                if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled)
                {
                    layer = CreateLivePreviewLayer(layer);
                }

                // If the layer is offset, handle it here
                if (!layer.Offset.IsEmpty())
                {
                    layer = CreateOffsetLayer(layer);
                }

                var src = layer.Surface;

                // Get the blend mode for this layer and opacity
                var blend_op = UserBlendOps.GetBlendOp(layer.BlendMode, layer.Opacity);

                if (checker)
                {
                    checker_op = new CheckerBoardOperation(layer.Opacity);
                }

                ColorBgra *src_ptr = (ColorBgra *)src.DataPtr;
                ColorBgra *dst_ptr = (ColorBgra *)dst.DataPtr;

                int src_width  = src.Width;
                int dst_width  = dst.Width;
                int dst_height = dst.Height;

                if (!generated)
                {
                    d2sLookupX = CreateLookupX(src_width, destination_size.Width, scale_factor);
                    d2sLookupY = CreateLookupY(src.Height, destination_size.Height, scale_factor);
                    s2dLookupX = CreateS2DLookupX(src_width, destination_size.Width, scale_factor);
                    s2dLookupY = CreateS2DLookupY(src.Height, destination_size.Height, scale_factor);

                    generated = true;
                }

                for (int dstRow = 0; dstRow < dst_height; ++dstRow)
                {
                    int nnY  = dstRow + offset.Y;
                    int srcY = d2sLookupY[nnY];

                    ColorBgra *dstPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);
                    ColorBgra *srcRow = src.GetRowAddressUnchecked(src_ptr, src_width, srcY);

                    for (int dstCol = 0; dstCol < dst_width; ++dstCol)
                    {
                        int nnX  = dstCol + offset.X;
                        int srcX = d2sLookupX[nnX];

                        // Blend it over the checkerboard background
                        if (checker)
                        {
                            *dstPtr = checker_op.Apply(*(srcRow + srcX), dstCol + offset.X, dstRow + offset.Y);
                        }
                        else
                        {
                            *dstPtr = blend_op.Apply(*dstPtr, *(srcRow + srcX));
                        }

                        ++dstPtr;
                    }
                }

                // Only checker the first layer
                checker = false;
            }

            // If we are at least 200% and grid is requested, draw it
            if (PintaCore.Actions.View.PixelGrid.Active && scale_factor.Ratio <= 0.5d)
            {
                RenderPixelGrid(dst, offset);
            }
        }
コード例 #13
0
ファイル: CanvasRenderer.cs プロジェクト: casey0102/Pinta
        private unsafe void RenderOneToOne(List <Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset)
        {
            // The first layer should be blended with the transparent checkerboard
            var checker = true;
            CheckerBoardOperation checker_op = null;

            for (int i = 0; i < layers.Count; i++)
            {
                var layer = layers[i];

                // If we're in LivePreview, substitute current layer with the preview layer
                if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled)
                {
                    layer = CreateLivePreviewLayer(layer);
                }

                // If the layer is offset, handle it here
                if (!layer.Offset.IsEmpty())
                {
                    layer = CreateOffsetLayer(layer);
                }

                var src = layer.Surface;

                // Get the blend mode for this layer and opacity
                var blend_op = UserBlendOps.GetBlendOp(layer.BlendMode, layer.Opacity);

                if (checker)
                {
                    checker_op = new CheckerBoardOperation(layer.Opacity);
                }

                // Figure out where our source and destination intersect
                var srcRect = new Gdk.Rectangle(offset, dst.GetBounds().Size);
                srcRect.Intersect(src.GetBounds());

                // Get pointers to our surfaces
                var src_ptr = (ColorBgra *)src.DataPtr;
                var dst_ptr = (ColorBgra *)dst.DataPtr;

                // Cache widths
                int src_width = src.Width;
                int dst_width = dst.Width;

                for (int dstRow = 0; dstRow < srcRect.Height; ++dstRow)
                {
                    ColorBgra *dstRowPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);
                    ColorBgra *srcRowPtr = src.GetPointAddressUnchecked(src_ptr, src_width, offset.X, dstRow + offset.Y);

                    int dstCol    = offset.X;
                    int dstColEnd = offset.X + srcRect.Width;
                    int checkerY  = dstRow + offset.Y;

                    while (dstCol < dstColEnd)
                    {
                        // Blend it over the checkerboard background
                        if (checker)
                        {
                            *dstRowPtr = checker_op.Apply(*srcRowPtr, dstCol, checkerY);
                        }
                        else
                        {
                            *dstRowPtr = blend_op.Apply(*dstRowPtr, *srcRowPtr);
                        }

                        ++dstRowPtr;
                        ++srcRowPtr;
                        ++dstCol;
                    }
                }

                // Only checker the first layer
                checker = false;
            }
        }
コード例 #14
0
ファイル: CanvasRenderer.cs プロジェクト: p07r0457/Pinta
        private unsafe void RenderZoomOut(Cairo.ImageSurface src, Cairo.ImageSurface dst, Gdk.Point offset, Gdk.Size destinationSize, bool checker)
        {
            const int fpShift  = 12;
            const int fpFactor = (1 << fpShift);

            Gdk.Size sourceSize     = src.GetBounds().Size;
            long     fDstLeftLong   = ((long)offset.X * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width;
            long     fDstTopLong    = ((long)offset.Y * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height;
            long     fDstRightLong  = ((long)(offset.X + dst.Width) * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width;
            long     fDstBottomLong = ((long)(offset.Y + dst.Height) * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height;
            int      fDstLeft       = (int)fDstLeftLong;
            int      fDstTop        = (int)fDstTopLong;
            int      fDstRight      = (int)fDstRightLong;
            int      fDstBottom     = (int)fDstBottomLong;
            int      dx             = (fDstRight - fDstLeft) / dst.Width;
            int      dy             = (fDstBottom - fDstTop) / dst.Height;

            ColorBgra *src_ptr   = (ColorBgra *)src.DataPtr;
            ColorBgra *dst_ptr   = (ColorBgra *)dst.DataPtr;
            int        src_width = src.Width;
            int        dst_width = dst.Width;

            for (int dstRow = 0, fDstY = fDstTop; dstRow < dst.Height && fDstY < fDstBottom; ++dstRow, fDstY += dy)
            {
                int srcY1 = fDstY >> fpShift;                                            // y
                int srcY2 = (fDstY + (dy >> 2)) >> fpShift;                              // y + 0.25
                int srcY3 = (fDstY + (dy >> 1)) >> fpShift;                              // y + 0.50
                int srcY4 = (fDstY + (dy >> 1) + (dy >> 2)) >> fpShift;                  // y + 0.75

                ColorBgra *src1        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY1);
                ColorBgra *src2        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY2);
                ColorBgra *src3        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY3);
                ColorBgra *src4        = src.GetRowAddressUnchecked(src_ptr, src_width, srcY4);
                ColorBgra *dstPtr      = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow);
                int        checkerY    = dstRow + offset.Y;
                int        checkerX    = offset.X;
                int        maxCheckerX = checkerX + dst.Width;

                for (int fDstX = fDstLeft; checkerX < maxCheckerX && fDstX < fDstRight; ++checkerX, fDstX += dx)
                {
                    int        srcX1 = (fDstX + (dx >> 2)) >> fpShift;                          // x + 0.25
                    int        srcX2 = (fDstX + (dx >> 1) + (dx >> 2)) >> fpShift;              // x + 0.75
                    int        srcX3 = fDstX >> fpShift;                                        // x
                    int        srcX4 = (fDstX + (dx >> 1)) >> fpShift;                          // x + 0.50
                    ColorBgra *p1    = src1 + srcX1;
                    ColorBgra *p2    = src2 + srcX2;
                    ColorBgra *p3    = src3 + srcX3;
                    ColorBgra *p4    = src4 + srcX4;

                    int r = (2 + p1->R + p2->R + p3->R + p4->R) >> 2;
                    int g = (2 + p1->G + p2->G + p3->G + p4->G) >> 2;
                    int b = (2 + p1->B + p2->B + p3->B + p4->B) >> 2;
                    int a = (2 + p1->A + p2->A + p3->A + p4->A) >> 2;

                    if (checker)
                    {
                        // Blend it over the checkerboard background
                        int v = ((checkerX ^ checkerY) & 8) * 8 + 191;
                        a = a + (a >> 7);
                        int vmia = v * (256 - a);

                        r = ((r * a) + vmia) >> 8;
                        g = ((g * a) + vmia) >> 8;
                        b = ((b * a) + vmia) >> 8;

                        dstPtr->Bgra = (uint)b + ((uint)g << 8) + ((uint)r << 16) + 0xff000000;
                    }
                    else
                    {
                        dstPtr->Bgra = (uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)a << 24);
                    }

                    ++dstPtr;
                }
            }
        }