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; }
public RectangleDouble(RectangleInt intRect) { Left = intRect.Left; Bottom = intRect.Bottom; Right = intRect.Right; Top = intRect.Top; }
//-------------------------------------------------------------------- public VectorClipper() { clipBox = new RectangleInt(0, 0, 0, 0); m_x1 = (0); m_y1 = (0); m_f1 = (0); m_clipping = (false); }
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; }
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); }
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; }
//--------------------------------------------------------------------- //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); }
public void Rectangle(RectangleInt rect, RGBA_Bytes color) { Rectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, color); }
//*************************************************************************************************************************************************** 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; }
//---------------------------------------------------------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; }
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); }
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(); } }
//-------------------------------------------------------------------- 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); }
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); }
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 }
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(); }
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(); }
public RectangleInt GetBoundingRect() { RectangleInt boundingRect = new RectangleInt(0, 0, Width, Height); boundingRect.Offset((int)OriginOffset.x, (int)OriginOffset.y); return boundingRect; }
public void Rectangle(RectangleInt rect, Color color) { Rectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, color); }
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); } }
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(); } } }
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; }
public void FillRectangle(RectangleInt rect, IColorType fillColor) { FillRectangle(rect.Left, rect.Bottom, rect.Right, rect.Top, fillColor); }
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"); } } }
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); } } }
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; } } } }
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; }
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; } } }
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; }
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; } } }
//--------------------------------------------------------------------- public OutlineRenderer(IImageByte destImage, LineProfileAnitAlias profile) { destImageSurface = destImage; lineProfile = profile; clippingRectangle = new RectangleInt(0, 0, 0, 0); doClipping = false; }
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(); }