예제 #1
0
 public void ExpandToInclude(RectangleInt rectToInclude)
 {
     if (Right < rectToInclude.Right) Right = rectToInclude.Right;
     if (Top < rectToInclude.Top) Top = rectToInclude.Top;
     if (Left > rectToInclude.Left) Left = rectToInclude.Left;
     if (Bottom > rectToInclude.Bottom) Bottom = rectToInclude.Bottom;
 }
예제 #2
0
 public RectangleDouble(RectangleInt intRect)
 {
     Left = intRect.Left;
     Bottom = intRect.Bottom;
     Right = intRect.Right;
     Top = intRect.Top;
 }
예제 #3
0
		//--------------------------------------------------------------------
		public VectorClipper()
		{
			clipBox = new RectangleInt(0, 0, 0, 0);
			m_x1 = (0);
			m_y1 = (0);
			m_f1 = (0);
			m_clipping = (false);
		}
예제 #4
0
 public bool clip(RectangleInt r)
 {
     if (Right > r.Right) Right = r.Right;
     if (Top > r.Top) Top = r.Top;
     if (Left < r.Left) Left = r.Left;
     if (Bottom < r.Bottom) Bottom = r.Bottom;
     return Left <= Right && Bottom <= Top;
 }
예제 #5
0
		public void DoTrace()
		{
			CreateScene();
			RectangleInt rect = new RectangleInt(0, 0, size.x, size.y);
			if (destImage == null || destImage.Width != rect.Width || destImage.Height != rect.Height)
			{
				destImage = new ImageBuffer(rect.Width, rect.Height, 32, new BlenderBGRA());
			}

			raytracer.RayTraceScene(rect, scene);
			raytracer.CopyColorBufferToImage(destImage, rect);
		}
예제 #6
0
        public bool IntersectRectangles(RectangleInt rectToCopy, RectangleInt rectToIntersectWith)
        {
            Left = rectToCopy.Left;
            Bottom = rectToCopy.Bottom;
            Right = rectToCopy.Right;
            Top = rectToCopy.Top;

            if (Left < rectToIntersectWith.Left) Left = rectToIntersectWith.Left;
            if (Bottom < rectToIntersectWith.Bottom) Bottom = rectToIntersectWith.Bottom;
            if (Right > rectToIntersectWith.Right) Right = rectToIntersectWith.Right;
            if (Top > rectToIntersectWith.Top) Top = rectToIntersectWith.Top;

            if (Left < Right && Bottom < Top)
            {
                return true;
            }

            return false;
        }
예제 #7
0
		//---------------------------------------------------------------------
		//typedef renderer_outline_image<BaseRenderer, ImagePattern> self_type;

		//---------------------------------------------------------------------
		public ImageLineRenderer(IImageByte ren, line_image_pattern patt)
		{
			m_ren = ren;
			m_pattern = patt;
			m_start = (0);
			m_scale_x = (1.0);
			m_clip_box = new RectangleInt(0, 0, 0, 0);
			m_clipping = (false);
		}
예제 #8
0
		public void Rectangle(RectangleInt rect, RGBA_Bytes color)
		{
			Rectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, color);
		}
예제 #9
0
		//***************************************************************************************************************************************************
		public static bool ClipRect(RectangleInt pBoundingRect, ref RectangleInt pDestRect)
		{
			// clip off the top so we don't write into random memory
			if (pDestRect.Top < pBoundingRect.Top)
			{
				pDestRect.Top = pBoundingRect.Top;
				if (pDestRect.Top >= pDestRect.Bottom)
				{
					return false;
				}
			}
			// clip off the bottom
			if (pDestRect.Bottom > pBoundingRect.Bottom)
			{
				pDestRect.Bottom = pBoundingRect.Bottom;
				if (pDestRect.Bottom <= pDestRect.Top)
				{
					return false;
				}
			}

			// clip off the left
			if (pDestRect.Left < pBoundingRect.Left)
			{
				pDestRect.Left = pBoundingRect.Left;
				if (pDestRect.Left >= pDestRect.Right)
				{
					return false;
				}
			}

			// clip off the right
			if (pDestRect.Right > pBoundingRect.Right)
			{
				pDestRect.Right = pBoundingRect.Right;
				if (pDestRect.Right <= pDestRect.Left)
				{
					return false;
				}
			}

			return true;
		}
예제 #10
0
		//---------------------------------------------------------unite_rectangles
		public void unite_rectangles(RectangleInt r1, RectangleInt r2)
		{
			Left = r1.Left;
			Bottom = r1.Bottom;
			Right = r1.Right;
			Right = r1.Top;
			if (Right < r2.Right) Right = r2.Right;
			if (Top < r2.Top) Top = r2.Top;
			if (Left > r2.Left) Left = r2.Left;
			if (Bottom > r2.Bottom) Bottom = r2.Bottom;
		}
예제 #11
0
        public static bool ClipRects(RectangleInt pBoundingRect, ref RectangleInt pSourceRect, ref RectangleInt pDestRect)
        {
            // clip off the top so we don't write into random memory
            if (pDestRect.Top < pBoundingRect.Top)
            {
                // This type of clipping only works when we aren't scaling an image...
                // If we are scaling an image, the source and dest sizes won't match
                if (pSourceRect.Height != pDestRect.Height)
                {
                    throw new Exception("source and dest rects must have the same height");
                }

                pSourceRect.Top += pBoundingRect.Top - pDestRect.Top;
                pDestRect.Top    = pBoundingRect.Top;
                if (pDestRect.Top >= pDestRect.Bottom)
                {
                    return(false);
                }
            }
            // clip off the bottom
            if (pDestRect.Bottom > pBoundingRect.Bottom)
            {
                // This type of clipping only works when we aren't scaling an image...
                // If we are scaling an image, the source and dest sizes won't match
                if (pSourceRect.Height != pDestRect.Height)
                {
                    throw new Exception("source and dest rects must have the same height");
                }

                pSourceRect.Bottom -= pDestRect.Bottom - pBoundingRect.Bottom;
                pDestRect.Bottom    = pBoundingRect.Bottom;
                if (pDestRect.Bottom <= pDestRect.Top)
                {
                    return(false);
                }
            }

            // clip off the left
            if (pDestRect.Left < pBoundingRect.Left)
            {
                // This type of clipping only works when we aren't scaling an image...
                // If we are scaling an image, the source and dest sizes won't match
                if (pSourceRect.Width != pDestRect.Width)
                {
                    throw new Exception("source and dest rects must have the same width");
                }

                pSourceRect.Left += pBoundingRect.Left - pDestRect.Left;
                pDestRect.Left    = pBoundingRect.Left;
                if (pDestRect.Left >= pDestRect.Right)
                {
                    return(false);
                }
            }
            // clip off the right
            if (pDestRect.Right > pBoundingRect.Right)
            {
                // This type of clipping only works when we aren't scaling an image...
                // If we are scaling an image, the source and dest sizes won't match
                if (pSourceRect.Width != pDestRect.Width)
                {
                    throw new Exception("source and dest rects must have the same width");
                }

                pSourceRect.Right -= pDestRect.Right - pBoundingRect.Right;
                pDestRect.Right    = pBoundingRect.Right;
                if (pDestRect.Right <= pDestRect.Left)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #12
0
 public void Rectangle(RectangleInt rect, RGBA_Bytes color)
 {
     Rectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, color);
 }
예제 #13
0
        public override void Render(IImageByte source,
                                    double destX, double destY,
                                    double angleRadians,
                                    double inScaleX, double inScaleY)
        {
            {             // exit early if the dest and source bounds don't touch.
                // TODO: <BUG> make this do rotation and scaling
                RectangleInt sourceBounds = source.GetBounds();
                RectangleInt destBounds   = this.destImageByte.GetBounds();
                sourceBounds.Offset((int)destX, (int)destY);

                if (!RectangleInt.DoIntersect(sourceBounds, destBounds))
                {
                    if (inScaleX != 1 || inScaleY != 1 || angleRadians != 0)
                    {
                        throw new NotImplementedException();
                    }
                    return;
                }
            }

            double scaleX = inScaleX;
            double scaleY = inScaleY;

            Affine graphicsTransform = GetTransform();

            if (!graphicsTransform.is_identity())
            {
                if (scaleX != 1 || scaleY != 1 || angleRadians != 0)
                {
                    throw new NotImplementedException();
                }
                graphicsTransform.transform(ref destX, ref destY);
            }

#if false // this is an optimization that eliminates the drawing of images that have their alpha set to all 0 (happens with generated images like explosions).
            MaxAlphaFrameProperty maxAlphaFrameProperty = MaxAlphaFrameProperty::GetMaxAlphaFrameProperty(source);

            if ((maxAlphaFrameProperty.GetMaxAlpha() * color.A_Byte) / 256 <= ALPHA_CHANNEL_BITS_DIVISOR)
            {
                m_OutFinalBlitBounds.SetRect(0, 0, 0, 0);
            }
#endif
            bool IsScaled = (scaleX != 1 || scaleY != 1);

            bool IsRotated = true;
            if (Math.Abs(angleRadians) < (0.1 * MathHelper.Tau / 360))
            {
                IsRotated    = false;
                angleRadians = 0;
            }

            //bool IsMipped = false;
            double sourceOriginOffsetX = source.OriginOffset.x;
            double sourceOriginOffsetY = source.OriginOffset.y;
            bool   CanUseMipMaps       = IsScaled;
            if (scaleX > 0.5 || scaleY > 0.5)
            {
                CanUseMipMaps = false;
            }

            bool renderRequriesSourceSampling = IsScaled || IsRotated || destX != (int)destX || destY != (int)destY;

            // this is the fast drawing path
            if (renderRequriesSourceSampling)
            {
#if false // if the scaling is small enough the results can be improved by using mip maps
                if (CanUseMipMaps)
                {
                    CMipMapFrameProperty *pMipMapFrameProperty = CMipMapFrameProperty::GetMipMapFrameProperty(source);
                    double OldScaleX = scaleX;
                    double OldScaleY = scaleY;
                    const CFrameInterface *pMippedFrame = pMipMapFrameProperty.GetMipMapFrame(ref scaleX, ref scaleY);
                    if (pMippedFrame != source)
                    {
                        IsMipped             = true;
                        source               = pMippedFrame;
                        sourceOriginOffsetX *= (OldScaleX / scaleX);
                        sourceOriginOffsetY *= (OldScaleY / scaleY);
                    }

                    HotspotOffsetX *= (inScaleX / scaleX);
                    HotspotOffsetY *= (inScaleY / scaleY);
                }
#endif
                switch (ImageRenderQuality)
                {
                case TransformQuality.Fastest:
                {
                    Affine destRectTransform;
                    DrawImageGetDestBounds(source, destX, destY, sourceOriginOffsetX, sourceOriginOffsetY, scaleX, scaleY, angleRadians, out destRectTransform);

                    Affine sourceRectTransform = new Affine(destRectTransform);
                    // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004]
                    sourceRectTransform.invert();

                    span_image_filter        spanImageFilter;
                    span_interpolator_linear interpolator   = new span_interpolator_linear(sourceRectTransform);
                    ImageBufferAccessorClip  sourceAccessor = new ImageBufferAccessorClip(source, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes());

                    spanImageFilter = new span_image_filter_rgba_bilinear_clip(sourceAccessor, RGBA_Floats.rgba_pre(0, 0, 0, 0), interpolator);

                    DrawImage(source, spanImageFilter, destRectTransform);
                }
                break;

                case TransformQuality.Best:
                {
                    Affine destRectTransform;
                    DrawImageGetDestBounds(source, destX, destY, sourceOriginOffsetX, sourceOriginOffsetY, scaleX, scaleY, angleRadians, out destRectTransform);

                    Affine sourceRectTransform = new Affine(destRectTransform);
                    // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004]
                    sourceRectTransform.invert();

                    span_interpolator_linear interpolator   = new span_interpolator_linear(sourceRectTransform);
                    ImageBufferAccessorClip  sourceAccessor = new ImageBufferAccessorClip(source, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes());

                    //spanImageFilter = new span_image_filter_rgba_bilinear_clip(sourceAccessor, RGBA_Floats.rgba_pre(0, 0, 0, 0), interpolator);

                    IImageFilterFunction filterFunction = null;
                    filterFunction = new image_filter_blackman(4);
                    ImageFilterLookUpTable filter = new ImageFilterLookUpTable();
                    filter.calculate(filterFunction, true);

                    span_image_filter spanGenerator = new span_image_filter_rgba(sourceAccessor, interpolator, filter);

                    DrawImage(source, spanGenerator, destRectTransform);
                }
                break;
                }
#if false // this is some debug you can enable to visualize the dest bounding box
                LineFloat(BoundingRect.left, BoundingRect.top, BoundingRect.right, BoundingRect.top, WHITE);
                LineFloat(BoundingRect.right, BoundingRect.top, BoundingRect.right, BoundingRect.bottom, WHITE);
                LineFloat(BoundingRect.right, BoundingRect.bottom, BoundingRect.left, BoundingRect.bottom, WHITE);
                LineFloat(BoundingRect.left, BoundingRect.bottom, BoundingRect.left, BoundingRect.top, WHITE);
#endif
            }
            else             // TODO: this can be even faster if we do not use an intermediate buffer
            {
                Affine destRectTransform;
                DrawImageGetDestBounds(source, destX, destY, sourceOriginOffsetX, sourceOriginOffsetY, scaleX, scaleY, angleRadians, out destRectTransform);

                Affine sourceRectTransform = new Affine(destRectTransform);
                // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004]
                sourceRectTransform.invert();

                span_interpolator_linear interpolator   = new span_interpolator_linear(sourceRectTransform);
                ImageBufferAccessorClip  sourceAccessor = new ImageBufferAccessorClip(source, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes());

                span_image_filter spanImageFilter = null;
                switch (source.BitDepth)
                {
                case 32:
                    spanImageFilter = new span_image_filter_rgba_nn_stepXby1(sourceAccessor, interpolator);
                    break;

                case 24:
                    spanImageFilter = new span_image_filter_rgb_nn_stepXby1(sourceAccessor, interpolator);
                    break;

                case 8:
                    spanImageFilter = new span_image_filter_gray_nn_stepXby1(sourceAccessor, interpolator);
                    break;

                default:
                    throw new NotImplementedException();
                }
                //spanImageFilter = new span_image_filter_rgba_nn(sourceAccessor, interpolator);

                DrawImage(source, spanImageFilter, destRectTransform);
                DestImage.MarkImageChanged();
            }
        }
예제 #14
0
 //--------------------------------------------------------------------
 public void clip_box(int x1, int y1, int x2, int y2)
 {
     clipBox = new RectangleInt(x1, y1, x2, y2);
     clipBox.normalize();
     m_clipping = true;
 }
		public void DoTrace()
		{
			CreateScene();
			RectangleInt rect = new RectangleInt(0, 0, size.x, size.y);
			if (destImage == null || destImage.Width != rect.Width || destImage.Height != rect.Height)
			{
				destImage = new ImageBuffer(rect.Width, rect.Height);
			}

			rayTracer.MultiThreaded = !PrinterConnectionAndCommunication.Instance.PrinterIsPrinting;

			rayTracer.RayTraceScene(rect, scene);
			rayTracer.CopyColorBufferToImage(destImage, rect);
		}
예제 #16
0
		//--------------------------------------------------------------------
		public void clip_box(int x1, int y1, int x2, int y2)
		{
			clipBox = new RectangleInt(x1, y1, x2, y2);
			clipBox.normalize();
			m_clipping = true;
		}
예제 #17
0
		private void rayTraceScene()
		{
			RectangleInt rect = new RectangleInt(0, 0, (int)Width, (int)Height);
			if (destImage == null || destImage.Width != rect.Width || destImage.Height != rect.Height)
			{
				destImage = new ImageBuffer(rect.Width, rect.Height, 32, new BlenderBGRA());
			}

			//rect_i rect = new rect_i(0, 0, (int)32, (int)32);

			renderTime.Restart();
			raytracer.RayTraceScene(rect, scene);
			raytracer.CopyColorBufferToImage(destImage, rect);
			//raytracer.CopyDepthBufferToImage(destImage, rect);
			//raytracer.CopyNoramlBufferToImage(destImage, rect);
			//raytracer.AntiAliasScene(graphics2D, rect, scene, raytracer.RayTraceColorBuffer, 13);
			renderTime.Stop();

			//graphics2D.Rect(new rect_d(bitmap.GetBoundingRect()), RGBA_Bytes.Black);
		}
예제 #18
0
        public void AntiAliasScene(Graphics2D graphics2D, RectangleInt viewport, Scene scene, RGBA_Floats[][] buffer, int maxSamples)
        {
            IImageByte destImage = (IImageByte)graphics2D.DestImage;

            if (destImage.BitDepth != 32)
            {
                throw new Exception("We can only render to 32 bit dest at the moment.");
            }

            Byte[] destBuffer = destImage.GetBuffer();

#if MULTI_THREAD
            System.Threading.Tasks.Parallel.For(1, viewport.Height - 1, y => //  
#else
            for (int y = 1; y < viewport.Height - 1; y++)
#endif
            {
                int fillY = viewport.Top - (viewport.Bottom + y);
                int bufferOffset = 0;
                if (y > 0 && y < destImage.Height)
                {
                    bufferOffset = destImage.GetBufferOffsetY(y);
                }

                for (int x = 1; x < viewport.Width - 1; x++)
                {
                    RGBA_Floats avg = (buffer[x - 1][y - 1] + buffer[x][y - 1] + buffer[x + 1][y - 1] +
                                 buffer[x - 1][y] + buffer[x][y] + buffer[x + 1][y] +
                                 buffer[x - 1][y + 1] + buffer[x][y + 1] + buffer[x + 1][y + 1]) / 9;

                    // use a more accurate antialasing method (MonteCarlo implementation)
                    // this will fire multiple rays per pixel
                    double sumOfDifferencesThreshold = .05; // TODO: figure out a good way to determin this.
                    if (avg.SumOfDistances(buffer[x][y]) > sumOfDifferencesThreshold)
                    {
                        RGBA_Floats accumulatedColor = buffer[x][y];
                        for (int i = 0; i < maxSamples; i++)
                        {
                            // get some 'random' samples
                            double rx = Math.Sign(i % 4 - 1.5) * (IntNoise(x + y * viewport.Width * maxSamples * 2 + i) + 1) / 4;
                            double ry = Math.Sign(i % 2 - 0.5) * (IntNoise(x + y * viewport.Width * maxSamples * 2 + 1 + i) + 1) / 4;

                            double xp = x + rx;
                            double yp = y + ry;

                            Ray ray = scene.camera.GetRay(xp, yp);
                            accumulatedColor += FullyTraceRay(ray, scene);
                        }
                        buffer[x][y] = accumulatedColor / (maxSamples + 1);

                        // this is the slow part of the painting algorithm, it can be greatly speed up
                        // by directly accessing the bitmap data
                        int fillX = viewport.Left + x;
                        int totalOffset = bufferOffset + fillX * 4;
                        destBuffer[totalOffset++] = (byte)buffer[x][y].Blue0To255;
                        destBuffer[totalOffset++] = (byte)buffer[x][y].Green0To255;
                        destBuffer[totalOffset++] = (byte)buffer[x][y].Red0To255;
                        destBuffer[totalOffset] = 255;
                    }
                }
            }
#if MULTI_THREAD
);
#endif

        }
예제 #19
0
        public void RayTraceScene(Graphics2D graphics2D, RectangleInt viewport, Scene scene)
        {
            int maxsamples = (int)AntiAliasing;

            //graphics2D.FillRectangle(viewport, RGBA_Floats.Black);

            if (imageBufferAsDoubles == null || imageBufferAsDoubles.Length < viewport.Width || imageBufferAsDoubles[0].Length < viewport.Height)
            {
                imageBufferAsDoubles = new RGBA_Floats[viewport.Width][];
                for (int i = 0; i < viewport.Width; i++)
                {
                    imageBufferAsDoubles[i] = new RGBA_Floats[viewport.Height];
                }
            }

            IImageByte destImage = (IImageByte)graphics2D.DestImage;

            if (destImage.BitDepth != 32)
            {
                throw new Exception("We can only render to 32 bit dest at the moment.");
            }

            Byte[] destBuffer = destImage.GetBuffer();

            viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom));
            viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top));

#if MULTI_THREAD
            System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => //  
#else
            for (int y = viewport.Bottom; y < viewport.Height; y++)
#endif
            {
                for (int x = viewport.Left; x < viewport.Right; x++)
                {
                    if (traceWithRayBundles)
                    {
                        int width = Math.Min(8, viewport.Right - x);
                        int height = Math.Min(8, viewport.Top - y);
                        FrustumRayBundle rayBundle = new FrustumRayBundle(width * height);
                        IntersectInfo[] intersectionsForBundle = new IntersectInfo[width * height];
                        for (int rayY = 0; rayY < height; rayY++)
                        {
                            for (int rayX = 0; rayX < width; rayX++)
                            {
                                rayBundle.rayArray[rayX + rayY * width] = scene.camera.GetRay(x + rayX, y + rayY);
                                intersectionsForBundle[rayX + rayY * width] = new IntersectInfo();
                            }
                        }

                        rayBundle.CalculateFrustum(width, height,  scene.camera.Origin);
                        
                        FullyTraceRayBundle(rayBundle, intersectionsForBundle, scene);

                        for (int rayY = 0; rayY < height; rayY++)
                        {
                            int bufferOffset = destImage.GetBufferOffsetY(y + rayY);

                            for (int rayX = 0; rayX < width; rayX++)
                            {
                                imageBufferAsDoubles[x + rayX][y + rayY] = intersectionsForBundle[rayX + rayY * width].totalColor;

                                // we don't need to set this if we are anti-aliased
                                int totalOffset = bufferOffset + (x + rayX) * 4;
                                destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Blue0To255;
                                destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Green0To255;
                                destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Red0To255;
                                destBuffer[totalOffset] = 255;
                            }
                        }
                        x += width - 1; // skip all the pixels we bundled
                        y += height - 1; // skip all the pixels we bundled
                    }
                    else
                    {
                        int bufferOffset = destImage.GetBufferOffsetY(y);

                        Ray ray = scene.camera.GetRay(x, y);

                        imageBufferAsDoubles[x][y] = FullyTraceRay(ray, scene);

                        // we don't need to set this if we are anti-aliased
                        int totalOffset = bufferOffset + x * 4;
                        destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Blue0To255;
                        destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Green0To255;
                        destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Red0To255;
                        destBuffer[totalOffset] = 255;
                    }
                }
            }
#if MULTI_THREAD
);
#endif
            if (AntiAliasing != AntiAliasing.None)
            {
                AntiAliasScene(graphics2D, viewport, scene, imageBufferAsDoubles, (int)AntiAliasing);
            }

            destImage.MarkImageChanged();
        }
예제 #20
0
		public override void Render(IImageByte source,
			double x, double y,
			double angleRadians,
			double scaleX, double scaleY)
		{
#if true
			Affine transform = GetTransform();
			if (!transform.is_identity())
			{
				if (scaleX != 1 || scaleY != 1)// || angleDegrees != 0)
				{
					throw new NotImplementedException();
				}
				// TODO: <BUG> make this do rotation and scalling
				transform.transform(ref x, ref y);
				scaleX *= transform.sx;
				scaleY *= transform.sy;
			}
#endif

#if true
			// TODO: <BUG> make this do rotation and scalling
			RectangleInt sourceBounds = source.GetBounds();
			sourceBounds.Offset((int)x, (int)y);
			RectangleInt destBounds = new RectangleInt((int)cachedClipRect.Left, (int)cachedClipRect.Bottom, (int)cachedClipRect.Right, (int)cachedClipRect.Top);

			if (!RectangleInt.DoIntersect(sourceBounds, destBounds))
			{
				if (scaleX != 1 || scaleY != 1)// || angleDegrees != 0)
				{
					//throw new NotImplementedException();
				}
				//return;
			}
#endif

			ImageBuffer sourceAsImageBuffer = (ImageBuffer)source;
			ImageGlPlugin glPlugin = ImageGlPlugin.GetImageGlPlugin(sourceAsImageBuffer, false);

			// Prepare openGL for rendering
			PushOrthoProjection();
			GL.Disable(EnableCap.Lighting);
			GL.Enable(EnableCap.Texture2D);
			GL.Disable(EnableCap.DepthTest);

			GL.Enable(EnableCap.Blend);
			GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

			GL.Translate(x, y, 0);
			GL.Rotate(MathHelper.RadiansToDegrees(angleRadians), 0, 0, 1);
			GL.Scale(scaleX, scaleY, 1);

			RGBA_Bytes color = RGBA_Bytes.White;
			GL.Color4((byte)color.Red0To255, (byte)color.Green0To255, (byte)color.Blue0To255, (byte)color.Alpha0To255);

			glPlugin.DrawToGL();

			//Restore openGL state
			PopOrthoProjection();
		}
예제 #21
0
 public RectangleInt GetBoundingRect()
 {
     RectangleInt boundingRect = new RectangleInt(0, 0, Width, Height);
     boundingRect.Offset((int)OriginOffset.x, (int)OriginOffset.y);
     return boundingRect;
 }
예제 #22
0
 public void Rectangle(RectangleInt rect, Color color)
 {
     Rectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, color);
 }
예제 #23
0
        private void Initialize(ImageBuffer sourceImage, RectangleInt boundsToCopyFrom)
        {
            if (sourceImage == this)
            {
                throw new Exception("We do not create a temp buffer for this to work.  You must have a source distinct from the dest.");
            }
            Deallocate();
            Allocate(boundsToCopyFrom.Width, boundsToCopyFrom.Height, boundsToCopyFrom.Width * sourceImage.BitDepth/8, sourceImage.BitDepth);
            SetRecieveBlender(sourceImage.GetRecieveBlender());

            if (width != 0 && height != 0)
            {
                RectangleInt DestRect = new RectangleInt(0, 0, boundsToCopyFrom.Width, boundsToCopyFrom.Height);
                RectangleInt AbsoluteSourceRect = boundsToCopyFrom;
                // The first thing we need to do is make sure the frame is cleared. LBB [3/15/2004]
                MatterHackers.Agg.Graphics2D graphics2D = NewGraphics2D();
                graphics2D.Clear(new RGBA_Bytes(0, 0, 0, 0));

                int x = - boundsToCopyFrom.Left -(int)sourceImage.OriginOffset.x;
                int y = - boundsToCopyFrom.Bottom -(int)sourceImage.OriginOffset.y;

                graphics2D.Render(sourceImage, x, y, 0, 1, 1);
            }
        }
예제 #24
0
        public override void Clear(IColorType iColor)
        {
            RectangleDouble clippingRect    = GetClippingRect();
            RectangleInt    clippingRectInt = new RectangleInt((int)clippingRect.Left, (int)clippingRect.Bottom, (int)clippingRect.Right, (int)clippingRect.Top);

            if (DestImage != null)
            {
                RGBA_Bytes color  = iColor.GetAsRGBA_Bytes();
                int        width  = DestImage.Width;
                int        height = DestImage.Height;
                byte[]     buffer = DestImage.GetBuffer();
                switch (DestImage.BitDepth)
                {
                case 8:
                {
                    byte byteColor = (byte)iColor.Red0To255;
                    for (int y = clippingRectInt.Bottom; y < clippingRectInt.Top; y++)
                    {
                        int bufferOffset       = DestImage.GetBufferOffsetXY((int)clippingRect.Left, y);
                        int bytesBetweenPixels = DestImage.GetBytesBetweenPixelsInclusive();
                        for (int x = 0; x < clippingRectInt.Width; x++)
                        {
                            buffer[bufferOffset] = color.blue;
                            bufferOffset        += bytesBetweenPixels;
                        }
                    }
                }
                break;

                case 24:
                    for (int y = clippingRectInt.Bottom; y < clippingRectInt.Top; y++)
                    {
                        int bufferOffset       = DestImage.GetBufferOffsetXY((int)clippingRect.Left, y);
                        int bytesBetweenPixels = DestImage.GetBytesBetweenPixelsInclusive();
                        for (int x = 0; x < clippingRectInt.Width; x++)
                        {
                            buffer[bufferOffset + 0] = color.blue;
                            buffer[bufferOffset + 1] = color.green;
                            buffer[bufferOffset + 2] = color.red;
                            bufferOffset            += bytesBetweenPixels;
                        }
                    }
                    break;

                case 32:
                {
                    for (int y = clippingRectInt.Bottom; y < clippingRectInt.Top; y++)
                    {
                        int bufferOffset       = DestImage.GetBufferOffsetXY((int)clippingRect.Left, y);
                        int bytesBetweenPixels = DestImage.GetBytesBetweenPixelsInclusive();
                        for (int x = 0; x < clippingRectInt.Width; x++)
                        {
                            buffer[bufferOffset + 0] = color.blue;
                            buffer[bufferOffset + 1] = color.green;
                            buffer[bufferOffset + 2] = color.red;
                            buffer[bufferOffset + 3] = color.alpha;
                            bufferOffset            += bytesBetweenPixels;
                        }
                    }
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }
            else             // it is a float
            {
                if (DestImageFloat == null)
                {
                    throw new Exception("You have to have either a byte or float DestImage.");
                }

                RGBA_Floats color  = iColor.GetAsRGBA_Floats();
                int         width  = DestImageFloat.Width;
                int         height = DestImageFloat.Height;
                float[]     buffer = DestImageFloat.GetBuffer();
                switch (DestImageFloat.BitDepth)
                {
                case 128:
                    for (int y = 0; y < height; y++)
                    {
                        int bufferOffset       = DestImageFloat.GetBufferOffsetXY(clippingRectInt.Left, y);
                        int bytesBetweenPixels = DestImageFloat.GetFloatsBetweenPixelsInclusive();
                        for (int x = 0; x < clippingRectInt.Width; x++)
                        {
                            buffer[bufferOffset + 0] = color.blue;
                            buffer[bufferOffset + 1] = color.green;
                            buffer[bufferOffset + 2] = color.red;
                            buffer[bufferOffset + 3] = color.alpha;
                            bufferOffset            += bytesBetweenPixels;
                        }
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
예제 #25
0
        public bool Attach(IImageByte sourceImage, int x1, int y1, int x2, int y2)
        {
            m_ByteBuffer = null;
            DettachBuffer();

            if (x1 > x2 || y1 > y2)
            {
                throw new Exception("You need to have your x1 and y1 be the lower left corner of your sub image.");
            }
            RectangleInt boundsRect = new RectangleInt(x1, y1, x2, y2);
            if (boundsRect.clip(new RectangleInt(0, 0, (int)sourceImage.Width - 1, (int)sourceImage.Height - 1)))
            {
                SetDimmensionAndFormat(boundsRect.Width, boundsRect.Height, sourceImage.StrideInBytes(), sourceImage.BitDepth, sourceImage.GetBytesBetweenPixelsInclusive(), false);
                int bufferOffset = sourceImage.GetBufferOffsetXY(boundsRect.Left, boundsRect.Bottom);
                byte[] buffer = sourceImage.GetBuffer();
                SetBuffer(buffer, bufferOffset);
                return true;
            }

            return false;
        }
예제 #26
0
 public void FillRectangle(RectangleInt rect, IColorType fillColor)
 {
     FillRectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, fillColor);
 }
예제 #27
0
        protected void CopyFromNoClipping(IImageByte sourceImage, RectangleInt clippedSourceImageRect, int destXOffset, int destYOffset)
        {
            if (GetBytesBetweenPixelsInclusive() != BitDepth / 8
                || sourceImage.GetBytesBetweenPixelsInclusive() != sourceImage.BitDepth / 8)
            {
                throw new Exception("WIP we only support packed pixel formats at this time.");
            }

            if (BitDepth == sourceImage.BitDepth)
            {
                int lengthInBytes = clippedSourceImageRect.Width * GetBytesBetweenPixelsInclusive();

                int sourceOffset = sourceImage.GetBufferOffsetXY(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom);
                byte[] sourceBuffer = sourceImage.GetBuffer();
                int destOffset;
                byte[] destBuffer = GetPixelPointerXY(clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + destYOffset, out destOffset);

                for (int i = 0; i < clippedSourceImageRect.Height; i++)
                {
                    agg_basics.memmove(destBuffer, destOffset, sourceBuffer, sourceOffset, lengthInBytes);
                    sourceOffset += sourceImage.StrideInBytes();
                    destOffset += StrideInBytes();
                }
            }
            else
            {
                bool haveConversion = true;
                switch (sourceImage.BitDepth)
                {
                    case 24:
                        switch (BitDepth)
                        {
                            case 32:
                                {
                                    int numPixelsToCopy = clippedSourceImageRect.Width;
                                    for (int i = clippedSourceImageRect.Bottom; i < clippedSourceImageRect.Top; i++)
                                    {
                                        int sourceOffset = sourceImage.GetBufferOffsetXY(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom + i);
                                        byte[] sourceBuffer = sourceImage.GetBuffer();
                                        int destOffset;
                                        byte[] destBuffer = GetPixelPointerXY(
                                            clippedSourceImageRect.Left + destXOffset,
                                            clippedSourceImageRect.Bottom + i + destYOffset,
                                            out destOffset);
                                        for (int x = 0; x < numPixelsToCopy; x++)
                                        {
                                            destBuffer[destOffset++] = sourceBuffer[sourceOffset++];
                                            destBuffer[destOffset++] = sourceBuffer[sourceOffset++];
                                            destBuffer[destOffset++] = sourceBuffer[sourceOffset++];
                                            destBuffer[destOffset++] = 255;
                                        }
                                    }
                                }
                                break;

                            default:
                                haveConversion = false;
                                break;
                        }
                        break;

                    default:
                        haveConversion = false;
                        break;
                }

                if (!haveConversion)
                {
                    throw new NotImplementedException("You need to write the " + sourceImage.BitDepth.ToString() + " to " + BitDepth.ToString() + " conversion");
                }
            }
        }
예제 #28
0
 public void CopyFrom(IImageByte sourceImage, RectangleInt sourceImageRect, int destXOffset, int destYOffset)
 {
     RectangleInt sourceImageBounds = sourceImage.GetBounds();
     RectangleInt clippedSourceImageRect = new RectangleInt();
     if (clippedSourceImageRect.IntersectRectangles(sourceImageRect, sourceImageBounds))
     {
         RectangleInt destImageRect = clippedSourceImageRect;
         destImageRect.Offset(destXOffset, destYOffset);
         RectangleInt destImageBounds = GetBounds();
         RectangleInt clippedDestImageRect = new RectangleInt();
         if (clippedDestImageRect.IntersectRectangles(destImageRect, destImageBounds))
         {
             // we need to make sure the source is also clipped to the dest. So, we'll copy this back to source and offset it.
             clippedSourceImageRect = clippedDestImageRect;
             clippedSourceImageRect.Offset(-destXOffset, -destYOffset);
             CopyFromNoClipping(sourceImage, clippedSourceImageRect, destXOffset, destYOffset);
         }
     }
 }
예제 #29
0
        public void GetVisibleBounds(out RectangleInt visibleBounds)
        {
            visibleBounds = new RectangleInt(0, 0, Width, Height);

	        // trim the bottom
	        bool aPixelsIsVisible = false;
            for (int y = 0; y < height; y++) 
	        {
                for (int x = 0; x < width; x++)
		        {
			        if(IsPixelVisible(x, y))
			        {
                        visibleBounds.Bottom = y;
                        y = height;
                        x = width;
				        aPixelsIsVisible = true;
			        }
		        }
	        }

	        // if we don't run into any pixels set for the top trim than there are no pixels set at all
            if (!aPixelsIsVisible)
	        {
                visibleBounds.SetRect(0, 0, 0, 0);
		        return;
	        }

	        // trim the bottom
            for (int y = height - 1; y >= 0; y--)
	        {
                for (int x = 0; x < width; x++)
		        {
                    if (IsPixelVisible(x, y))
                    {
                        visibleBounds.Top = y + 1;
				        y = -1;
                        x = width;
			        }
		        }
	        }

	        // trim the left
            for (int x = 0; x < width; x++)
	        {
                for (int y = 0; y < height; y++)
		        {
			        if(IsPixelVisible(x, y))
			        {
				        visibleBounds.Left=x;
                        y = height;
                        x = width;
			        }
		        }
	        }

	        // trim the right
            for (int x = width - 1; x >= 0; x--)
	        {
                for (int y = 0; y < height; y++)
		        {
                    if (IsPixelVisible(x, y))
                    {
                        visibleBounds.Right = x + 1;
                        y = height;
				        x = -1;
			        }
		        }
	        }
        }
예제 #30
0
		public static bool DoIntersect(RectangleInt rect1, RectangleInt rect2)
		{
			int x1 = rect1.Left;
			int y1 = rect1.Bottom;
			int x2 = rect1.Right;
			int y2 = rect1.Top;

			if (x1 < rect2.Left) x1 = rect2.Left;
			if (y1 < rect2.Bottom) y1 = rect2.Bottom;
			if (x2 > rect2.Right) x2 = rect2.Right;
			if (y2 > rect2.Top) y2 = rect2.Top;

			if (x1 < x2 && y1 < y2)
			{
				return true;
			}

			return false;
		}
예제 #31
0
		public void SetDirty(RectangleInt areaToSetDirty)
		{
			if (areaToSetDirty.Left >= areaToSetDirty.Right || areaToSetDirty.Bottom >= areaToSetDirty.Top)
			{
				return;
			}

			RectangleInt BoundRect = new RectangleInt(0, 0, numCellsX << xCellFactor, numCellsY << yCellFactor);
			RectangleInt Area = areaToSetDirty;
			if (Area.IntersectWithRectangle(BoundRect))
			{
				Area.Right--;
				Area.Top--;
				Area.Left = Area.Left >> xCellFactor;
				Area.Right = Area.Right >> xCellFactor;
				Area.Bottom = Area.Bottom >> yCellFactor;
				Area.Top = Area.Top >> yCellFactor;

				int offsetForY = yTable[Area.Bottom];

				for (int y = Area.Bottom; y <= Area.Top; y++)
				{
					for (int x = Area.Left; x <= Area.Right; x++)
					{
						DirtyCell currCell = dirtyCells[offsetForY + x];

						// if it's not set or it's not totaly covered
						RectangleInt CurCellBounds = new RectangleInt((x << xCellFactor), (y << yCellFactor),
							((x << xCellFactor) + xCellSize), ((y << yCellFactor) + yCellSize));
						// if we are setting it for the first time
						if (!currCell.isDirty)
						{
							currCell.coverage.Left = Math.Max(Math.Min((areaToSetDirty.Left - CurCellBounds.Left), xCellSize), 0);
							currCell.coverage.Bottom = Math.Max(Math.Min((areaToSetDirty.Bottom - CurCellBounds.Bottom), yCellSize), 0);
							currCell.coverage.Right = Math.Max(Math.Min((areaToSetDirty.Right - CurCellBounds.Left), xCellSize), 0);
							currCell.coverage.Top = Math.Max(Math.Min((areaToSetDirty.Top - CurCellBounds.Bottom), yCellSize), 0);
						}
						else // we are adding to it's coverage
						{
							currCell.coverage.Left = Math.Max(Math.Min(Math.Min(currCell.coverage.Left, (areaToSetDirty.Left - CurCellBounds.Left)), xCellSize), 0);
							currCell.coverage.Bottom = Math.Max(Math.Min(Math.Min(currCell.coverage.Bottom, (areaToSetDirty.Bottom - CurCellBounds.Bottom)), yCellSize), 0);
							currCell.coverage.Right = Math.Max(Math.Min(Math.Max(currCell.coverage.Right, (areaToSetDirty.Right - CurCellBounds.Left)), xCellSize), 0);
							currCell.coverage.Top = Math.Max(Math.Min(Math.Max(currCell.coverage.Top, (areaToSetDirty.Top - CurCellBounds.Bottom)), yCellSize), 0);
						}

						currCell.isDirty = true;
					}

					offsetForY += numCellsX;
				}
			}
		}
예제 #32
0
		public static bool ClipRects(RectangleInt pBoundingRect, ref RectangleInt pSourceRect, ref RectangleInt pDestRect)
		{
			// clip off the top so we don't write into random memory
			if (pDestRect.Top < pBoundingRect.Top)
			{
				// This type of clipping only works when we aren't scaling an image...
				// If we are scaling an image, the source and dest sizes won't match
				if (pSourceRect.Height != pDestRect.Height)
				{
					throw new Exception("source and dest rects must have the same height");
				}

				pSourceRect.Top += pBoundingRect.Top - pDestRect.Top;
				pDestRect.Top = pBoundingRect.Top;
				if (pDestRect.Top >= pDestRect.Bottom)
				{
					return false;
				}
			}
			// clip off the bottom
			if (pDestRect.Bottom > pBoundingRect.Bottom)
			{
				// This type of clipping only works when we aren't scaling an image...
				// If we are scaling an image, the source and dest sizes won't match
				if (pSourceRect.Height != pDestRect.Height)
				{
					throw new Exception("source and dest rects must have the same height");
				}

				pSourceRect.Bottom -= pDestRect.Bottom - pBoundingRect.Bottom;
				pDestRect.Bottom = pBoundingRect.Bottom;
				if (pDestRect.Bottom <= pDestRect.Top)
				{
					return false;
				}
			}

			// clip off the left
			if (pDestRect.Left < pBoundingRect.Left)
			{
				// This type of clipping only works when we aren't scaling an image...
				// If we are scaling an image, the source and dest sizes won't match
				if (pSourceRect.Width != pDestRect.Width)
				{
					throw new Exception("source and dest rects must have the same width");
				}

				pSourceRect.Left += pBoundingRect.Left - pDestRect.Left;
				pDestRect.Left = pBoundingRect.Left;
				if (pDestRect.Left >= pDestRect.Right)
				{
					return false;
				}
			}
			// clip off the right
			if (pDestRect.Right > pBoundingRect.Right)
			{
				// This type of clipping only works when we aren't scaling an image...
				// If we are scaling an image, the source and dest sizes won't match
				if (pSourceRect.Width != pDestRect.Width)
				{
					throw new Exception("source and dest rects must have the same width");
				}

				pSourceRect.Right -= pDestRect.Right - pBoundingRect.Right;
				pDestRect.Right = pBoundingRect.Right;
				if (pDestRect.Right <= pDestRect.Left)
				{
					return false;
				}
			}

			return true;
		}
예제 #33
0
		public void SetClean(RectangleInt areaToSetClean)
		{
			int curRow;

			RectangleInt BoundRect = new RectangleInt(0, 0, numCellsX << xCellFactor, numCellsY << yCellFactor);
			RectangleInt Area = areaToSetClean;
			if (Area.IntersectWithRectangle(BoundRect))
			{
				Area.Right--;
				Area.Top--;
				Area.Left = Area.Left >> xCellFactor;
				Area.Right = Area.Right >> xCellFactor;
				Area.Bottom = Area.Bottom >> yCellFactor;
				Area.Top = Area.Top >> yCellFactor;

				curRow = yTable[Area.Bottom];

				for (int y = Area.Bottom; y <= Area.Top; y++)
				{
					for (int x = Area.Left; x <= Area.Right; x++)
					{
						dirtyCells[curRow + x].isDirty = false;
					}
					curRow += numCellsX;
				}
			}
		}
예제 #34
0
		public override void Clear(IColorType iColor)
		{
			RectangleDouble clippingRect = GetClippingRect();
			RectangleInt clippingRectInt = new RectangleInt((int)clippingRect.Left, (int)clippingRect.Bottom, (int)clippingRect.Right, (int)clippingRect.Top);

			if (DestImage != null)
			{
				RGBA_Bytes color = iColor.GetAsRGBA_Bytes();
				int width = DestImage.Width;
				int height = DestImage.Height;
				byte[] buffer = DestImage.GetBuffer();
				switch (DestImage.BitDepth)
				{
					case 8:
						{
							byte byteColor = (byte)iColor.Red0To255;
							for (int y = clippingRectInt.Bottom; y < clippingRectInt.Top; y++)
							{
								int bufferOffset = DestImage.GetBufferOffsetXY((int)clippingRect.Left, y);
								int bytesBetweenPixels = DestImage.GetBytesBetweenPixelsInclusive();
								for (int x = 0; x < clippingRectInt.Width; x++)
								{
									buffer[bufferOffset] = color.blue;
									bufferOffset += bytesBetweenPixels;
								}
							}
						}
						break;

					case 24:
						for (int y = clippingRectInt.Bottom; y < clippingRectInt.Top; y++)
						{
							int bufferOffset = DestImage.GetBufferOffsetXY((int)clippingRect.Left, y);
							int bytesBetweenPixels = DestImage.GetBytesBetweenPixelsInclusive();
							for (int x = 0; x < clippingRectInt.Width; x++)
							{
								buffer[bufferOffset + 0] = color.blue;
								buffer[bufferOffset + 1] = color.green;
								buffer[bufferOffset + 2] = color.red;
								bufferOffset += bytesBetweenPixels;
							}
						}
						break;

					case 32:
						{
							for (int y = clippingRectInt.Bottom; y < clippingRectInt.Top; y++)
							{
								int bufferOffset = DestImage.GetBufferOffsetXY((int)clippingRect.Left, y);
								int bytesBetweenPixels = DestImage.GetBytesBetweenPixelsInclusive();
								for (int x = 0; x < clippingRectInt.Width; x++)
								{
									buffer[bufferOffset + 0] = color.blue;
									buffer[bufferOffset + 1] = color.green;
									buffer[bufferOffset + 2] = color.red;
									buffer[bufferOffset + 3] = color.alpha;
									bufferOffset += bytesBetweenPixels;
								}
							}
						}
						break;

					default:
						throw new NotImplementedException();
				}
			}
			else // it is a float
			{
				if (DestImageFloat == null)
				{
					throw new Exception("You have to have either a byte or float DestImage.");
				}

				RGBA_Floats color = iColor.GetAsRGBA_Floats();
				int width = DestImageFloat.Width;
				int height = DestImageFloat.Height;
				float[] buffer = DestImageFloat.GetBuffer();
				switch (DestImageFloat.BitDepth)
				{
					case 128:
						for (int y = 0; y < height; y++)
						{
							int bufferOffset = DestImageFloat.GetBufferOffsetXY(clippingRectInt.Left, y);
							int bytesBetweenPixels = DestImageFloat.GetFloatsBetweenPixelsInclusive();
							for (int x = 0; x < clippingRectInt.Width; x++)
							{
								buffer[bufferOffset + 0] = color.blue;
								buffer[bufferOffset + 1] = color.green;
								buffer[bufferOffset + 2] = color.red;
								buffer[bufferOffset + 3] = color.alpha;
								bufferOffset += bytesBetweenPixels;
							}
						}
						break;

					default:
						throw new NotImplementedException();
				}
			}
		}
예제 #35
0
		//---------------------------------------------------------------------
		public OutlineRenderer(IImageByte destImage, LineProfileAnitAlias profile)
		{
			destImageSurface = destImage;
			lineProfile = profile;
			clippingRectangle = new RectangleInt(0, 0, 0, 0);
			doClipping = false;
		}
예제 #36
0
		public void FillRectangle(RectangleInt rect, IColorType fillColor)
		{
			FillRectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, fillColor);
		}
예제 #37
0
        public override void CopyBackBufferToScreen(Graphics displayGraphics)
        {
            WidgetForWindowsFormsBitmap aggBitmapAppWidget = ((WidgetForWindowsFormsBitmap)aggAppWidget);

            RectangleInt intRect = new RectangleInt(0, 0, (int)aggAppWidget.Width, (int)aggAppWidget.Height);
            aggBitmapAppWidget.bitmapBackBuffer.UpdateHardwareSurface(intRect);

            WidgetForWindowsFormsBitmap.copyTime.Restart();

            if (OsInformation.OperatingSystem != OSType.Windows)
			{
	            //displayGraphics.DrawImage(aggBitmapAppWidget.bitmapBackBuffer.windowsBitmap, windowsRect, windowsRect, GraphicsUnit.Pixel);  // around 250 ms for full screen
	            displayGraphics.DrawImageUnscaled(aggBitmapAppWidget.bitmapBackBuffer.windowsBitmap, 0, 0); // around 200 ms for full screnn
			}
			else
			{
	            // or the code below which calls BitBlt directly running at 17 ms for full screnn.
	            const int SRCCOPY = 0xcc0020;

	            using (Graphics bitmapGraphics = Graphics.FromImage(aggBitmapAppWidget.bitmapBackBuffer.windowsBitmap))
	            {
	                IntPtr displayHDC = displayGraphics.GetHdc();
	                IntPtr bitmapHDC = bitmapGraphics.GetHdc();

	                IntPtr hBitmap = aggBitmapAppWidget.bitmapBackBuffer.windowsBitmap.GetHbitmap();
	                IntPtr hOldObject = SelectObject(bitmapHDC, hBitmap);

	                int result = BitBlt(displayHDC, 0, 0, aggBitmapAppWidget.bitmapBackBuffer.windowsBitmap.Width, aggBitmapAppWidget.bitmapBackBuffer.windowsBitmap.Height, bitmapHDC, 0, 0, SRCCOPY);

	                SelectObject(bitmapHDC, hOldObject);
	                DeleteObject(hBitmap);

	                bitmapGraphics.ReleaseHdc(bitmapHDC);
	                displayGraphics.ReleaseHdc(displayHDC);
	            }
			}
            WidgetForWindowsFormsBitmap.copyTime.Stop();
        }