示例#1
0
        public unsafe override void Render(Surface dst, System.Drawing.Point offset)
        {
            if (OwnerList.ScaleFactor < new ScaleFactor(2, 1))
            {
                return;
            }

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

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

            // draw horizontal lines
            int sTop    = d2SLookupY[offset.Y];
            int sBottom = d2SLookupY[offset.Y + dst.Height];

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

                if (dst.IsRowVisible(dstRow))
                {
                    ColorBgra *dstRowPtr    = dst.GetRowAddress(dstRow);
                    ColorBgra *dstRowEndPtr = dstRowPtr + dst.Width;

                    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 + dst.Width];

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

                if (dst.IsColumnVisible(dstX - offset.X))
                {
                    byte *dstColPtr    = (byte *)dst.GetPointAddress(dstCol, 0);
                    byte *dstColEndPtr = dstColPtr + dst.Stride * dst.Height;

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

                    while (dstColPtr < dstColEndPtr)
                    {
                        *((ColorBgra *)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dst.Stride;
                    }
                }
            }
        }
        public static void RenderZoomOutRotatedGridMultisampling(Surface dst, Surface source, Point offset, Size destinationSize)
        {
            unsafe
            {
                const int fpShift = 12;
                const int fpFactor = (1 << fpShift);

                Size sourceSize = source.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;

                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

            #if DEBUG
                    Debug.Assert(source.IsRowVisible(srcY1));
                    Debug.Assert(source.IsRowVisible(srcY2));
                    Debug.Assert(source.IsRowVisible(srcY3));
                    Debug.Assert(source.IsRowVisible(srcY4));
                    Debug.Assert(dst.IsRowVisible(dstRow));
            #endif

                    ColorBgra* src1 = source.GetRowAddressUnchecked(srcY1);
                    ColorBgra* src2 = source.GetRowAddressUnchecked(srcY2);
                    ColorBgra* src3 = source.GetRowAddressUnchecked(srcY3);
                    ColorBgra* src4 = source.GetRowAddressUnchecked(srcY4);
                    ColorBgra* dstPtr = dst.GetRowAddressUnchecked(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

            #if DEBUG
                        Debug.Assert(source.IsColumnVisible(srcX1));
                        Debug.Assert(source.IsColumnVisible(srcX2));
                        Debug.Assert(source.IsColumnVisible(srcX3));
                        Debug.Assert(source.IsColumnVisible(srcX4));
            #endif

                        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
                        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;
                        ++dstPtr;
                    }
                }
            }
        }
        public static void RenderZoomOutRotatedGridMultisampling(Surface dst, Surface source, Point offset, Size destinationSize)
        {
            unsafe
            {
                const int fpShift  = 12;
                const int fpFactor = (1 << fpShift);

                Size sourceSize     = source.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;

                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

#if DEBUG
                    Debug.Assert(source.IsRowVisible(srcY1));
                    Debug.Assert(source.IsRowVisible(srcY2));
                    Debug.Assert(source.IsRowVisible(srcY3));
                    Debug.Assert(source.IsRowVisible(srcY4));
                    Debug.Assert(dst.IsRowVisible(dstRow));
#endif

                    ColorBgra *src1        = source.GetRowAddressUnchecked(srcY1);
                    ColorBgra *src2        = source.GetRowAddressUnchecked(srcY2);
                    ColorBgra *src3        = source.GetRowAddressUnchecked(srcY3);
                    ColorBgra *src4        = source.GetRowAddressUnchecked(srcY4);
                    ColorBgra *dstPtr      = dst.GetRowAddressUnchecked(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

#if DEBUG
                        Debug.Assert(source.IsColumnVisible(srcX1));
                        Debug.Assert(source.IsColumnVisible(srcX2));
                        Debug.Assert(source.IsColumnVisible(srcX3));
                        Debug.Assert(source.IsColumnVisible(srcX4));
#endif

                        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
                        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;
                        ++dstPtr;
                    }
                }
            }
        }
        public unsafe override void Render(Surface dst, System.Drawing.Point offset)
        {
            if (OwnerList.ScaleFactor < new ScaleFactor(2, 1))
            {
                return;
            }

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

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

            // draw horizontal lines
            int sTop = d2SLookupY[offset.Y];
            int sBottom = d2SLookupY[offset.Y + dst.Height];

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

                if (dst.IsRowVisible(dstRow))
                {
                    ColorBgra *dstRowPtr = dst.GetRowAddress(dstRow);
                    ColorBgra *dstRowEndPtr = dstRowPtr + dst.Width;

                    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 + dst.Width];

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

                if (dst.IsColumnVisible(dstX - offset.X))
                {
                    byte *dstColPtr = (byte *)dst.GetPointAddress(dstCol, 0);
                    byte *dstColEndPtr = dstColPtr + dst.Stride * dst.Height;

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

                    while (dstColPtr < dstColEndPtr)
                    {
                        *((ColorBgra *)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dst.Stride;
                    }
                }
            }
        }
示例#5
0
        private unsafe void DrawText(Surface dst, Font textFont, string text, Point pt, Size measuredSize, bool antiAliasing, Surface brush8x8)
        {
            Point pt2 = pt;
            Size measuredSize2 = measuredSize;
            int offset = (int)textFont.Height;
            pt.X -= offset;
            measuredSize.Width += 2 * offset;
            Rectangle dstRect = new Rectangle(pt, measuredSize);
            Rectangle dstRectClipped = Rectangle.Intersect(dstRect, ScratchSurface.Bounds);

            if (dstRectClipped.Width == 0 || dstRectClipped.Height == 0)
            {
                return;
            }

            // We only use the first 8,8 of brush
            using (RenderArgs renderArgs = new RenderArgs(this.ScratchSurface))
            {
                renderArgs.Graphics.FillRectangle(Brushes.White, pt.X, pt.Y, measuredSize.Width, measuredSize.Height);

                if (measuredSize.Width > 0 && measuredSize.Height > 0)
                {
                    using (Surface s2 = renderArgs.Surface.CreateWindow(dstRectClipped))
                    {
                        using (RenderArgs renderArgs2 = new RenderArgs(s2))
                        {
                            SystemLayer.Fonts.DrawText(
                                renderArgs2.Graphics, 
                                this.font, 
                                text, 
                                new Point(dstRect.X - dstRectClipped.X + offset, dstRect.Y - dstRectClipped.Y),
                                AppEnvironment.AntiAliasing,
                                AppEnvironment.FontSmoothing);
                        }
                    }
                }

                // Mask out anything that isn't within the user's clip region (selected region)
                using (PdnRegion clip = Selection.CreateRegion())
                {
                    clip.Xor(renderArgs.Surface.Bounds); // invert
                    clip.Intersect(new Rectangle(pt, measuredSize));
                    renderArgs.Graphics.FillRegion(Brushes.White, clip.GetRegionReadOnly());
                }

                int skipX;

                if (pt.X < 0)
                {
                    skipX = -pt.X;
                }
                else
                {
                    skipX = 0;
                }

                int xEnd = Math.Min(dst.Width, pt.X + measuredSize.Width);

                bool blending = AppEnvironment.AlphaBlending;

                if (dst.IsColumnVisible(pt.X + skipX))
                {
                    for (int y = pt.Y; y < pt.Y + measuredSize.Height; ++y)
                    {
                        if (!dst.IsRowVisible(y))
                        {
                            continue;
                        }

                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(pt.X + skipX, y);
                        ColorBgra *srcPtr = ScratchSurface.GetPointAddress(pt.X + skipX, y);
                        ColorBgra *brushPtr = brush8x8.GetRowAddressUnchecked(y & 7);

                        for (int x = pt.X + skipX; x < xEnd; ++x)
                        {
                            ColorBgra srcPixel = *srcPtr;
                            ColorBgra dstPixel = *dstPtr;
                            ColorBgra brushPixel = brushPtr[x & 7];

                            int alpha = ((255 - srcPixel.R) * brushPixel.A) / 255; // we could use srcPixel.R, .G, or .B -- the choice here is arbitrary
                            brushPixel.A = (byte)alpha;

                            if (srcPtr->R == 255) // could use R, G, or B -- arbitrary choice
                            {
                                // do nothing -- leave dst alone
                            }
                            else if (alpha == 255 || !blending)
                            {
                                // copy it straight over
                                *dstPtr = brushPixel;
                            }
                            else
                            {
                                // do expensive blending
                                *dstPtr = UserBlendOps.NormalBlendOp.ApplyStatic(dstPixel, brushPixel);
                            }

                            ++dstPtr;
                            ++srcPtr;
                        }
                    }
                }
            }
        }