Exemplo n.º 1
0
        /// <summary>
        /// Converts all <see cref="DelaunayEdges"/> to a planar <see cref="Subdivision"/>, using
        /// the specified clipping bounds.</summary>
        /// <param name="bounds">
        /// A <see cref="RectD"/> that indicates the clipping bounds for all <see
        /// cref="DelaunayEdges"/>.</param>
        /// <param name="addRegions">
        /// <c>true</c> to add all <see cref="VoronoiRegions"/> with the corresponding <see
        /// cref="GeneratorSites"/> to the <see cref="Subdivision.VertexRegions"/> collection of the
        /// new <see cref="Subdivision"/>; otherwise, <c>false</c>.</param>
        /// <returns>
        /// A new <see cref="Subdivision"/> whose <see cref="Subdivision.Edges"/> correspond to the
        /// <see cref="DelaunayEdges"/> of the <see cref="VoronoiResults"/>.</returns>
        /// <remarks><para>
        /// The specified <paramref name="bounds"/> determine the subset of <see
        /// cref="GeneratorSites"/> and <see cref="DelaunayEdges"/> that is stored in the new <see
        /// cref="Subdivision"/>, as described in <see cref="ClipDelaunayEdges"/>.
        /// </para><para>
        /// If <paramref name="addRegions"/> is <c>true</c>, the polygons added to the <see
        /// cref="Subdivision.VertexRegions"/> collection are also clipped the specified <paramref
        /// name="bounds"/>.</para></remarks>

        public Subdivision ToDelaunySubdivision(RectD bounds, bool addRegions = false)
        {
            LineD[]     edges    = ClipDelaunayEdges(bounds);
            Subdivision division = Subdivision.FromLines(edges);

            if (addRegions)
            {
                for (int i = 0; i < GeneratorSites.Length; i++)
                {
                    PointD site = GeneratorSites[i];
                    if (!bounds.Contains(site))
                    {
                        continue;
                    }

                    PointD[] region;
                    if (bounds.Intersect(VoronoiRegions[i], out region))
                    {
                        division.VertexRegions.Add(site, region);
                    }
                }
            }

            return(division);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Renders a bitmap using any affine transformation and transparency into this bitmap
        /// Unlike Silverlight's Render() method, this one uses 2-3 times less memory, and is the same or better quality
        /// The algorithm is simple dx/dy (bresenham-like) step by step painting, optimized with fixed point and fast bilinear filtering
        /// It's used in Fantasia Painter for drawing stickers and 3D objects on screen
        /// </summary>
        /// <param name="bmp">Destination bitmap.</param>
        /// <param name="source">The source WriteableBitmap.</param>
        /// <param name="shouldClear">If true, the the destination bitmap will be set to all clear (0) before rendering.</param>
        /// <param name="opacity">opacity of the source bitmap to render, between 0 and 1 inclusive</param>
        /// <param name="transform">Transformation to apply</param>
        public static void BlitRender(this BitmapBuffer bmp, BitmapBuffer source, bool shouldClear = true, float opacity = 1f, GeneralTransform transform = null)
        {
            const int PRECISION_SHIFT = 10;
            const int PRECISION_VALUE = (1 << PRECISION_SHIFT);
            const int PRECISION_MASK  = PRECISION_VALUE - 1;

            using (BitmapContext destContext = bmp.GetBitmapContext())
            {
                if (transform == null)
                {
                    transform = new MatrixTransform(Affine.IdentityMatrix);
                }

                int[]           destPixels = destContext.Pixels;
                int             destWidth  = destContext.Width;
                int             destHeight = destContext.Height;
                MatrixTransform inverse    = transform.Inverse;
                if (shouldClear)
                {
                    destContext.Clear();
                }

                using (BitmapContext sourceContext = source.GetBitmapContext(ReadWriteMode.ReadOnly))
                {
                    var sourcePixels = sourceContext.Pixels;
                    int sourceWidth  = sourceContext.Width;
                    int sourceHeight = sourceContext.Height;

                    RectD sourceRect = new RectD(0, 0, sourceWidth, sourceHeight);
                    RectD destRect   = new RectD(0, 0, destWidth, destHeight);
                    RectD bounds     = transform.TransformBounds(sourceRect);
                    bounds.Intersect(destRect);

                    int startX = (int)bounds.Left;
                    int startY = (int)bounds.Top;
                    int endX   = (int)bounds.Right;
                    int endY   = (int)bounds.Bottom;

#if NETFX_CORE
                    Point zeroZero = inverse.TransformPoint(new Point(startX, startY));
                    Point oneZero  = inverse.TransformPoint(new Point(startX + 1, startY));
                    Point zeroOne  = inverse.TransformPoint(new Point(startX, startY + 1));
#else
                    PointD zeroZero = inverse.Transform(new PointD(startX, startY));
                    PointD oneZero  = inverse.Transform(new PointD(startX + 1, startY));
                    PointD zeroOne  = inverse.Transform(new PointD(startX, startY + 1));
#endif
                    float sourceXf = ((float)zeroZero.X);
                    float sourceYf = ((float)zeroZero.Y);
                    int   dxDx     = (int)((((float)oneZero.X) - sourceXf) * PRECISION_VALUE); // for 1 unit in X coord, how much does X change in source texture?
                    int   dxDy     = (int)((((float)oneZero.Y) - sourceYf) * PRECISION_VALUE); // for 1 unit in X coord, how much does Y change in source texture?
                    int   dyDx     = (int)((((float)zeroOne.X) - sourceXf) * PRECISION_VALUE); // for 1 unit in Y coord, how much does X change in source texture?
                    int   dyDy     = (int)((((float)zeroOne.Y) - sourceYf) * PRECISION_VALUE); // for 1 unit in Y coord, how much does Y change in source texture?

                    int sourceX           = (int)(((float)zeroZero.X) * PRECISION_VALUE);
                    int sourceY           = (int)(((float)zeroZero.Y) * PRECISION_VALUE);
                    int sourceWidthFixed  = sourceWidth << PRECISION_SHIFT;
                    int sourceHeightFixed = sourceHeight << PRECISION_SHIFT;

                    int opacityInt = (int)(opacity * 255);

                    int index = 0;
                    for (int destY = startY; destY < endY; destY++)
                    {
                        index = destY * destWidth + startX;
                        int savedSourceX = sourceX;
                        int savedSourceY = sourceY;

                        for (int destX = startX; destX < endX; destX++)
                        {
                            if ((sourceX >= 0) && (sourceX < sourceWidthFixed) && (sourceY >= 0) && (sourceY < sourceHeightFixed))
                            {
                                // bilinear filtering
                                int xFloor = sourceX >> PRECISION_SHIFT;
                                int yFloor = sourceY >> PRECISION_SHIFT;

                                if (xFloor < 0)
                                {
                                    xFloor = 0;
                                }
                                if (yFloor < 0)
                                {
                                    yFloor = 0;
                                }

                                int xCeil = xFloor + 1;
                                int yCeil = yFloor + 1;

                                if (xCeil >= sourceWidth)
                                {
                                    xFloor = sourceWidth - 1;
                                    xCeil  = 0;
                                }
                                else
                                {
                                    xCeil = 1;
                                }

                                if (yCeil >= sourceHeight)
                                {
                                    yFloor = sourceHeight - 1;
                                    yCeil  = 0;
                                }
                                else
                                {
                                    yCeil = sourceWidth;
                                }

                                int i1 = yFloor * sourceWidth + xFloor;
                                int p1 = sourcePixels[i1];
                                int p2 = sourcePixels[i1 + xCeil];
                                int p3 = sourcePixels[i1 + yCeil];
                                int p4 = sourcePixels[i1 + yCeil + xCeil];

                                int xFrac = sourceX & PRECISION_MASK;
                                int yFrac = sourceY & PRECISION_MASK;

                                // alpha
                                byte a1 = (byte)(p1 >> 24);
                                byte a2 = (byte)(p2 >> 24);
                                byte a3 = (byte)(p3 >> 24);
                                byte a4 = (byte)(p4 >> 24);

                                int  comp1, comp2;
                                byte a;

                                if ((a1 == a2) && (a1 == a3) && (a1 == a4))
                                {
                                    if (a1 == 0)
                                    {
                                        destPixels[index] = 0;

                                        sourceX += dxDx;
                                        sourceY += dxDy;
                                        index++;
                                        continue;
                                    }

                                    a = a1;
                                }
                                else
                                {
                                    comp1 = a1 + ((xFrac * (a2 - a1)) >> PRECISION_SHIFT);
                                    comp2 = a3 + ((xFrac * (a4 - a3)) >> PRECISION_SHIFT);
                                    a     = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT));
                                }

                                // red
                                comp1 = ((byte)(p1 >> 16)) + ((xFrac * (((byte)(p2 >> 16)) - ((byte)(p1 >> 16)))) >> PRECISION_SHIFT);
                                comp2 = ((byte)(p3 >> 16)) + ((xFrac * (((byte)(p4 >> 16)) - ((byte)(p3 >> 16)))) >> PRECISION_SHIFT);
                                byte r = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT));

                                // green
                                comp1 = ((byte)(p1 >> 8)) + ((xFrac * (((byte)(p2 >> 8)) - ((byte)(p1 >> 8)))) >> PRECISION_SHIFT);
                                comp2 = ((byte)(p3 >> 8)) + ((xFrac * (((byte)(p4 >> 8)) - ((byte)(p3 >> 8)))) >> PRECISION_SHIFT);
                                byte g = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT));

                                // blue
                                comp1 = ((byte)p1) + ((xFrac * (((byte)p2) - ((byte)p1))) >> PRECISION_SHIFT);
                                comp2 = ((byte)p3) + ((xFrac * (((byte)p4) - ((byte)p3))) >> PRECISION_SHIFT);
                                byte b = (byte)(comp1 + ((yFrac * (comp2 - comp1)) >> PRECISION_SHIFT));

                                // save updated pixel
                                if (opacityInt != 255)
                                {
                                    a = (byte)((a * opacityInt) >> 8);
                                    r = (byte)((r * opacityInt) >> 8);
                                    g = (byte)((g * opacityInt) >> 8);
                                    b = (byte)((b * opacityInt) >> 8);
                                }
                                destPixels[index] = (a << 24) | (r << 16) | (g << 8) | b;
                            }

                            sourceX += dxDx;
                            sourceY += dxDy;
                            index++;
                        }

                        sourceX = savedSourceX + dyDx;
                        sourceY = savedSourceY + dyDy;
                    }
                }
            }
        }
Exemplo n.º 3
0
        public static void Blit(BitmapContext destContext, int dpw, int dph, RectD destRect, BitmapContext srcContext, RectD sourceRect, int sourceWidth)
        {
            int dw = (int)destRect.Width;
            int dh = (int)destRect.Height;

            RectD intersect = new RectD(0, 0, dpw, dph);

            intersect.Intersect(destRect);
            if (intersect.IsEmpty)
            {
                return;
            }
#if WPF
            bool isPrgba = srcContext.Format == PixelFormats.Pbgra32 || srcContext.Format == PixelFormats.Prgba64 || srcContext.Format == PixelFormats.Prgba128Float;
#endif

            int[]  sourcePixels = srcContext.Pixels;
            int[]  destPixels   = destContext.Pixels;
            int    sourceLength = srcContext.Length;
            int    sourceIdx    = -1;
            int    px           = (int)destRect.X;
            int    py           = (int)destRect.Y;
            int    x;
            int    y;
            int    idx;
            double ii;
            double jj;
            int    sr = 0;
            int    sg = 0;
            int    sb = 0;
            int    dr, dg, db;
            int    sourcePixel;
            int    sa = 0;
            int    da;

            int    sw = (int)sourceRect.Width;
            double sdx = sourceRect.Width / destRect.Width;
            double sdy = sourceRect.Height / destRect.Height;
            int    sourceStartX = (int)sourceRect.X;
            int    sourceStartY = (int)sourceRect.Y;
            int    lastii, lastjj;
            lastii = -1;
            lastjj = -1;
            jj     = sourceStartY;
            y      = py;
            for (int j = 0; j < dh; j++)
            {
                if (y >= 0 && y < dph)
                {
                    ii          = sourceStartX;
                    idx         = px + y * dpw;
                    x           = px;
                    sourcePixel = sourcePixels[0];

                    // Pixel by pixel copying
                    for (int i = 0; i < dw; i++)
                    {
                        if (x >= 0 && x < dpw)
                        {
                            if ((int)ii != lastii || (int)jj != lastjj)
                            {
                                sourceIdx = (int)ii + (int)jj * sourceWidth;
                                if (sourceIdx >= 0 && sourceIdx < sourceLength)
                                {
                                    sourcePixel = sourcePixels[sourceIdx];
                                    sa          = ((sourcePixel >> 24) & 0xff);
                                    sr          = ((sourcePixel >> 16) & 0xff);
                                    sg          = ((sourcePixel >> 8) & 0xff);
                                    sb          = ((sourcePixel) & 0xff);
                                }
                                else
                                {
                                    sa = 0;
                                }
                            }

                            if (sa > 0)
                            {
                                int destPixel = destPixels[idx];
                                da = ((destPixel >> 24) & 0xff);
                                if ((sa == 255 || da == 0))
                                {
                                    destPixels[idx] = sourcePixel;
                                }
                                else
                                {
                                    dr = ((destPixel >> 16) & 0xff);
                                    dg = ((destPixel >> 8) & 0xff);
                                    db = ((destPixel) & 0xff);
                                    int isa = 255 - sa;

#if NETFX_CORE
                                    // Special case for WinRT since it does not use pARGB (pre-multiplied alpha)
                                    destPixel = ((da & 0xff) << 24) |
                                                ((((sr * sa + isa * dr) >> 8) & 0xff) << 16) |
                                                ((((sg * sa + isa * dg) >> 8) & 0xff) << 8) |
                                                (((sb * sa + isa * db) >> 8) & 0xff);
#elif WPF
                                    if (isPrgba)
                                    {
                                        destPixel = ((da & 0xff) << 24) |
                                                    (((((sr << 8) + isa * dr) >> 8) & 0xff) << 16) |
                                                    (((((sg << 8) + isa * dg) >> 8) & 0xff) << 8) |
                                                    ((((sb << 8) + isa * db) >> 8) & 0xff);
                                    }
                                    else
                                    {
                                        destPixel = ((da & 0xff) << 24) |
                                                    (((((sr * sa) + isa * dr) >> 8) & 0xff) << 16) |
                                                    (((((sg * sa) + isa * dg) >> 8) & 0xff) << 8) |
                                                    ((((sb * sa) + isa * db) >> 8) & 0xff);
                                    }
#else
                                    destPixel = ((da & 0xff) << 24) |
                                                (((((sr << 8) + isa * dr) >> 8) & 0xff) << 16) |
                                                (((((sg << 8) + isa * dg) >> 8) & 0xff) << 8) |
                                                ((((sb << 8) + isa * db) >> 8) & 0xff);
#endif
                                    destPixels[idx] = destPixel;
                                }
                            }
                        }
                        x++;
                        idx++;
                        ii += sdx;
                    }
                }
                jj += sdy;
                y++;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Copies (blits) the pixels from the WriteableBitmap source to the destination WriteableBitmap (this).
        /// </summary>
        /// <param name="bmp">The destination WriteableBitmap.</param>
        /// <param name="destRect">The rectangle that defines the destination region.</param>
        /// <param name="source">The source WriteableBitmap.</param>
        /// <param name="sourceRect">The rectangle that will be copied from the source to the destination.</param>
        /// <param name="color">If not Colors.White, will tint the source image. A partially transparent color and the image will be drawn partially transparent. If the BlendMode is ColorKeying, this color will be used as color key to mask all pixels with this value out.</param>
        /// <param name="blendMode">The blending mode <see cref="BlendMode"/>.</param>
        internal static void Blit(this BitmapBuffer bmp, RectD destRect, BitmapBuffer source, RectD sourceRect, ColorInt color, BlendMode blendMode)
        {
            if (color.A == 0)
            {
                return;
            }
#if WPF
            bool isPrgba = source.Format == PixelFormats.Pbgra32 || source.Format == PixelFormats.Prgba64 || source.Format == PixelFormats.Prgba128Float;
#endif
            int dw = (int)destRect.Width;
            int dh = (int)destRect.Height;

            using (var srcContext = source.GetBitmapContext(ReadWriteMode.ReadOnly))
                using (var destContext = bmp.GetBitmapContext())
                {
                    int sourceWidth = srcContext.Width;
                    int dpw         = destContext.Width;
                    int dph         = destContext.Height;

                    RectD intersect = new RectD(0, 0, dpw, dph);
                    intersect.Intersect(destRect);
                    if (intersect.IsEmpty)
                    {
                        return;
                    }

                    int[] sourcePixels = srcContext.Pixels;
                    int[] destPixels   = destContext.Pixels;
                    int   sourceLength = srcContext.Length;

                    int sourceIdx = -1;
                    int px        = (int)destRect.X;
                    int py        = (int)destRect.Y;

                    int    x;
                    int    y;
                    int    idx;
                    double ii;
                    double jj;
                    //
                    int sr = 0;
                    int sg = 0;
                    int sb = 0;
                    //
                    int    dr, dg, db;
                    int    sourcePixel;
                    int    sa = 0;
                    int    da;
                    int    ca = color.A;
                    int    cr = color.R;
                    int    cg = color.G;
                    int    cb = color.B;
                    bool   tinted = color != Colors.White;
                    int    sw = (int)sourceRect.Width;
                    double sdx = sourceRect.Width / destRect.Width;
                    double sdy = sourceRect.Height / destRect.Height;
                    int    sourceStartX = (int)sourceRect.X;
                    int    sourceStartY = (int)sourceRect.Y;
                    int    lastii, lastjj;
                    lastii = -1;
                    lastjj = -1;
                    jj     = sourceStartY;
                    y      = py;
                    for (int j = 0; j < dh; j++)
                    {
                        if (y >= 0 && y < dph)
                        {
                            ii          = sourceStartX;
                            idx         = px + y * dpw;
                            x           = px;
                            sourcePixel = sourcePixels[0];

                            // Scanline BlockCopy is much faster (3.5x) if no tinting and blending is needed,
                            // even for smaller sprites like the 32x32 particles.
                            if (blendMode == BlendMode.None && !tinted)
                            {
                                sourceIdx = (int)ii + (int)jj * sourceWidth;
                                int offset = x < 0 ? -x : 0;
                                int xx     = x + offset;
                                int wx     = sourceWidth - offset;
                                int len    = xx + wx < dpw ? wx : dpw - xx;
                                if (len > sw)
                                {
                                    len = sw;
                                }
                                if (len > dw)
                                {
                                    len = dw;
                                }
                                BitmapContext.BlockCopy(srcContext, (sourceIdx + offset) * 4, destContext, (idx + offset) * 4, len * 4);
                            }

                            // Pixel by pixel copying
                            else
                            {
                                for (int i = 0; i < dw; i++)
                                {
                                    if (x >= 0 && x < dpw)
                                    {
                                        if ((int)ii != lastii || (int)jj != lastjj)
                                        {
                                            sourceIdx = (int)ii + (int)jj * sourceWidth;
                                            if (sourceIdx >= 0 && sourceIdx < sourceLength)
                                            {
                                                sourcePixel = sourcePixels[sourceIdx];
                                                sa          = ((sourcePixel >> 24) & 0xff);
                                                sr          = ((sourcePixel >> 16) & 0xff);
                                                sg          = ((sourcePixel >> 8) & 0xff);
                                                sb          = ((sourcePixel) & 0xff);
                                                if (tinted && sa != 0)
                                                {
                                                    sa          = (((sa * ca) * 0x8081) >> 23);
                                                    sr          = ((((((sr * cr) * 0x8081) >> 23) * ca) * 0x8081) >> 23);
                                                    sg          = ((((((sg * cg) * 0x8081) >> 23) * ca) * 0x8081) >> 23);
                                                    sb          = ((((((sb * cb) * 0x8081) >> 23) * ca) * 0x8081) >> 23);
                                                    sourcePixel = (sa << 24) | (sr << 16) | (sg << 8) | sb;
                                                }
                                            }
                                            else
                                            {
                                                sa = 0;
                                            }
                                        }
                                        if (blendMode == BlendMode.None)
                                        {
                                            destPixels[idx] = sourcePixel;
                                        }
                                        else if (blendMode == BlendMode.ColorKeying)
                                        {
                                            sr = ((sourcePixel >> 16) & 0xff);
                                            sg = ((sourcePixel >> 8) & 0xff);
                                            sb = ((sourcePixel) & 0xff);

                                            if (!color.EqualsOnRGB(sr, sg, sb))
                                            {
                                                destPixels[idx] = sourcePixel;
                                            }
                                            //if (sr != color.R || sg != color.G || sb != color.B)
                                            //{
                                            //    destPixels[idx] = sourcePixel;
                                            //}
                                        }
                                        else if (blendMode == BlendMode.Mask)
                                        {
                                            int destPixel = destPixels[idx];
                                            da        = ((destPixel >> 24) & 0xff);
                                            dr        = ((destPixel >> 16) & 0xff);
                                            dg        = ((destPixel >> 8) & 0xff);
                                            db        = ((destPixel) & 0xff);
                                            destPixel = ((((da * sa) * 0x8081) >> 23) << 24) |
                                                        ((((dr * sa) * 0x8081) >> 23) << 16) |
                                                        ((((dg * sa) * 0x8081) >> 23) << 8) |
                                                        ((((db * sa) * 0x8081) >> 23));
                                            destPixels[idx] = destPixel;
                                        }
                                        else if (sa > 0)
                                        {
                                            int destPixel = destPixels[idx];
                                            da = ((destPixel >> 24) & 0xff);
                                            if ((sa == 255 || da == 0) &&
                                                blendMode != BlendMode.Additive &&
                                                blendMode != BlendMode.Subtractive &&
                                                blendMode != BlendMode.Multiply
                                                )
                                            {
                                                destPixels[idx] = sourcePixel;
                                            }
                                            else
                                            {
                                                dr = ((destPixel >> 16) & 0xff);
                                                dg = ((destPixel >> 8) & 0xff);
                                                db = ((destPixel) & 0xff);
                                                if (blendMode == BlendMode.Alpha)
                                                {
                                                    int isa = 255 - sa;
#if NETFX_CORE
                                                    // Special case for WinRT since it does not use pARGB (pre-multiplied alpha)
                                                    destPixel = ((da & 0xff) << 24) |
                                                                ((((sr * sa + isa * dr) >> 8) & 0xff) << 16) |
                                                                ((((sg * sa + isa * dg) >> 8) & 0xff) << 8) |
                                                                (((sb * sa + isa * db) >> 8) & 0xff);
#elif WPF
                                                    if (isPrgba)
                                                    {
                                                        destPixel = ((da & 0xff) << 24) |
                                                                    (((((sr << 8) + isa * dr) >> 8) & 0xff) << 16) |
                                                                    (((((sg << 8) + isa * dg) >> 8) & 0xff) << 8) |
                                                                    ((((sb << 8) + isa * db) >> 8) & 0xff);
                                                    }
                                                    else
                                                    {
                                                        destPixel = ((da & 0xff) << 24) |
                                                                    (((((sr * sa) + isa * dr) >> 8) & 0xff) << 16) |
                                                                    (((((sg * sa) + isa * dg) >> 8) & 0xff) << 8) |
                                                                    ((((sb * sa) + isa * db) >> 8) & 0xff);
                                                    }
#else
                                                    destPixel = ((da & 0xff) << 24) |
                                                                (((((sr << 8) + isa * dr) >> 8) & 0xff) << 16) |
                                                                (((((sg << 8) + isa * dg) >> 8) & 0xff) << 8) |
                                                                ((((sb << 8) + isa * db) >> 8) & 0xff);
#endif
                                                }
                                                else if (blendMode == BlendMode.Additive)
                                                {
                                                    int a = (255 <= sa + da) ? 255 : (sa + da);
                                                    destPixel = (a << 24) |
                                                                (((a <= sr + dr) ? a : (sr + dr)) << 16) |
                                                                (((a <= sg + dg) ? a : (sg + dg)) << 8) |
                                                                (((a <= sb + db) ? a : (sb + db)));
                                                }
                                                else if (blendMode == BlendMode.Subtractive)
                                                {
                                                    int a = da;
                                                    destPixel = (a << 24) |
                                                                (((sr >= dr) ? 0 : (sr - dr)) << 16) |
                                                                (((sg >= dg) ? 0 : (sg - dg)) << 8) |
                                                                (((sb >= db) ? 0 : (sb - db)));
                                                }
                                                else if (blendMode == BlendMode.Multiply)
                                                {
                                                    // Faster than a division like (s * d) / 255 are 2 shifts and 2 adds
                                                    int ta = (sa * da) + 128;
                                                    int tr = (sr * dr) + 128;
                                                    int tg = (sg * dg) + 128;
                                                    int tb = (sb * db) + 128;

                                                    int ba = ((ta >> 8) + ta) >> 8;
                                                    int br = ((tr >> 8) + tr) >> 8;
                                                    int bg = ((tg >> 8) + tg) >> 8;
                                                    int bb = ((tb >> 8) + tb) >> 8;

                                                    destPixel = (ba << 24) |
                                                                ((ba <= br ? ba : br) << 16) |
                                                                ((ba <= bg ? ba : bg) << 8) |
                                                                ((ba <= bb ? ba : bb));
                                                }

                                                destPixels[idx] = destPixel;
                                            }
                                        }
                                    }
                                    x++;
                                    idx++;
                                    ii += sdx;
                                }
                            }
                        }
                        jj += sdy;
                        y++;
                    }
                }
        }
Exemplo n.º 5
0
        public void IntersectLine()
        {
            LineD resultD;

            Assert.IsTrue(rectD.Intersect(new LineD(1, 2, 5, 7), out resultD));
            Assert.AreEqual(new LineD(1, 2, 5, 7), resultD);
            Assert.IsTrue(rectD.Intersect(new LineD(2, 6, 4, 3), out resultD));
            Assert.AreEqual(new LineD(2, 6, 4, 3), resultD);
            Assert.IsTrue(rectD.Intersect(new LineD(3, 1, 3, 8), out resultD));
            Assert.AreEqual(new LineD(3, 2, 3, 7), resultD);
            Assert.IsTrue(rectD.Intersect(new LineD(0, 4, 6, 4), out resultD));
            Assert.AreEqual(new LineD(1, 4, 5, 4), resultD);

            Assert.IsFalse(rectD.Intersect(new LineD(0, 1, 0, 8), out resultD));
            Assert.IsFalse(rectD.Intersect(new LineD(0, 1, 6, 1), out resultD));
            Assert.IsFalse(rectD.Intersect(new LineD(6, 1, 6, 8), out resultD));
            Assert.IsFalse(rectD.Intersect(new LineD(0, 8, 6, 8), out resultD));
            Assert.IsFalse(rectD.Intersect(new LineD(-2, 3, 2, -3), out resultD));

            LineF resultF;

            Assert.IsTrue(rectF.Intersect(new LineF(1, 2, 5, 7), out resultF));
            Assert.AreEqual(new LineF(1, 2, 5, 7), resultF);
            Assert.IsTrue(rectF.Intersect(new LineF(2, 6, 4, 3), out resultF));
            Assert.AreEqual(new LineF(2, 6, 4, 3), resultF);
            Assert.IsTrue(rectF.Intersect(new LineF(3, 1, 3, 8), out resultF));
            Assert.AreEqual(new LineF(3, 2, 3, 7), resultF);
            Assert.IsTrue(rectF.Intersect(new LineF(0, 4, 6, 4), out resultF));
            Assert.AreEqual(new LineF(1, 4, 5, 4), resultF);

            Assert.IsFalse(rectF.Intersect(new LineF(0, 1, 0, 8), out resultF));
            Assert.IsFalse(rectF.Intersect(new LineF(0, 1, 6, 1), out resultF));
            Assert.IsFalse(rectF.Intersect(new LineF(6, 1, 6, 8), out resultF));
            Assert.IsFalse(rectF.Intersect(new LineF(0, 8, 6, 8), out resultF));
            Assert.IsFalse(rectF.Intersect(new LineF(-2, 3, 2, -3), out resultF));
        }