public override void OnDraw(Graphics2D graphics2D) { ImageBuffer widgetsSubImage = ImageBuffer.NewSubImageReference(graphics2D.DestImage, graphics2D.GetClippingRect()); if (orignialSize.x == 0) { orignialSize.x = WindowSize.x; orignialSize.y = WindowSize.y; } ImageBuffer destImageWithPreMultBlender = new ImageBuffer(); switch (widgetsSubImage.BitDepth) { case 24: destImageWithPreMultBlender.Attach(widgetsSubImage, new BlenderPreMultBGR()); break; case 32: destImageWithPreMultBlender.Attach(widgetsSubImage, new BlenderPreMultBGRA()); break; default: throw new Exception("Unknown bit depth"); } ImageClippingProxy clippingProxy_pre = new ImageClippingProxy(destImageWithPreMultBlender); clippingProxy_pre.clear(new RGBA_Floats(1.0, 1.0, 1.0)); Affine src_mtx = Affine.NewIdentity(); src_mtx *= Affine.NewTranslation(-orignialSize.x / 2 - 10, -orignialSize.y / 2 - 20 - 10); src_mtx *= Affine.NewRotation(drawAngle.Value * Math.PI / 180.0); src_mtx *= Affine.NewScaling(drawScale.Value); src_mtx *= Affine.NewTranslation(orignialSize.x / 2, orignialSize.y / 2 + 20); Affine img_mtx = Affine.NewIdentity(); img_mtx *= Affine.NewTranslation(-orignialSize.x / 2 + 10, -orignialSize.y / 2 + 20 + 10); img_mtx *= Affine.NewRotation(drawAngle.Value * Math.PI / 180.0); img_mtx *= Affine.NewScaling(drawScale.Value); img_mtx *= Affine.NewTranslation(orignialSize.x / 2, orignialSize.y / 2 + 20); img_mtx.invert(); MatterHackers.Agg.span_allocator sa = new span_allocator(); span_interpolator_linear interpolator = new span_interpolator_linear(img_mtx); span_image_filter sg; switch (sourceImage.BitDepth) { case 24: { ImageBufferAccessorClip source = new ImageBufferAccessorClip(sourceImage, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes()); sg = new span_image_filter_rgb_bilinear_clip(source, RGBA_Floats.rgba_pre(0, 0.4, 0, 0.5), interpolator); } break; case 32: { ImageBufferAccessorClip source = new ImageBufferAccessorClip(sourceImage, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes()); sg = new span_image_filter_rgba_bilinear_clip(source, RGBA_Floats.rgba_pre(0, 0.4, 0, 0.5), interpolator); } break; default: throw new Exception("Bad sourc depth"); } ScanlineRasterizer ras = new ScanlineRasterizer(); ras.SetVectorClipBox(0, 0, Width, Height); ScanlineCachePacked8 sl = new ScanlineCachePacked8(); //scanline_unpacked_8 sl = new scanline_unpacked_8(); double r = orignialSize.x; if (orignialSize.y - 60 < r) { r = orignialSize.y - 60; } VertexSource.Ellipse ell = new VertexSource.Ellipse(orignialSize.x / 2.0 + 10, orignialSize.y / 2.0 + 20 + 10, r / 2.0 + 16.0, r / 2.0 + 16.0, 200); VertexSourceApplyTransform tr = new VertexSourceApplyTransform(ell, src_mtx); ras.add_path(tr); //clippingProxy_pre.SetClippingBox(30, 0, (int)width(), (int)height()); ScanlineRenderer scanlineRenderer = new ScanlineRenderer(); scanlineRenderer.GenerateAndRender(ras, sl, clippingProxy_pre, sa, sg); if (false) // this is test code to check different quality settings for scalling { Vector2 screenCenter = new Vector2(Width / 2, Height / 2); Vector2 deltaToMouse = mousePosition - screenCenter; double angleToMouse = Math.Atan2(deltaToMouse.y, deltaToMouse.x); double diagonalSize = Math.Sqrt(sourceImage.Width * sourceImage.Width + sourceImage.Height * sourceImage.Height); double distToMouse = deltaToMouse.Length; double scalling = distToMouse / diagonalSize; graphics2D.Render(sourceImage, Width / 2, Height / 2, angleToMouse - MathHelper.Tau / 8, scalling, scalling); } base.OnDraw(graphics2D); }
public override void OnDraw(Graphics2D graphics2D) { ImageBuffer widgetsSubImage = ImageBuffer.NewSubImageReference(graphics2D.DestImage, graphics2D.GetClippingRect()); ScanlineRasterizer ras = new ScanlineRasterizer(); scanline_unpacked_8 sl = new scanline_unpacked_8(); ImageClippingProxy clippingProxy = new ImageClippingProxy(widgetsSubImage); clippingProxy.clear(new RGBA_Floats(0, 0, 0)); m_profile.text_size(8.0); // draw a background to show how the alpha is working int RectWidth = 32; int xoffset = 238; int yoffset = 171; ScanlineRenderer scanlineRenderer = new ScanlineRenderer(); for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { if ((i + j) % 2 != 0) { VertexSource.RoundedRect rect = new VertexSource.RoundedRect(i * RectWidth + xoffset, j * RectWidth + yoffset, (i + 1) * RectWidth + xoffset, (j + 1) * RectWidth + yoffset, 2); rect.normalize_radius(); ras.add_path(rect); scanlineRenderer.RenderSolid(clippingProxy, ras, sl, new RGBA_Bytes(.9, .9, .9)); } } } double ini_scale = 1.0; Transform.Affine mtx1 = Affine.NewIdentity(); mtx1 *= Affine.NewScaling(ini_scale, ini_scale); mtx1 *= Affine.NewTranslation(center_x, center_y); VertexSource.Ellipse e1 = new MatterHackers.Agg.VertexSource.Ellipse(); e1.init(0.0, 0.0, 110.0, 110.0, 64); Transform.Affine mtx_g1 = Affine.NewIdentity(); mtx_g1 *= Affine.NewScaling(ini_scale, ini_scale); mtx_g1 *= Affine.NewScaling(m_SaveData.m_scale, m_SaveData.m_scale); mtx_g1 *= Affine.NewScaling(m_scale_x, m_scale_y); mtx_g1 *= Affine.NewRotation(m_SaveData.m_angle); mtx_g1 *= Affine.NewTranslation(m_SaveData.m_center_x, m_SaveData.m_center_y); mtx_g1.invert(); RGBA_Bytes[] color_profile = new RGBA_Bytes[256]; // color_type is defined in pixel_formats.h for (int i = 0; i < 256; i++) { color_profile[i] = new RGBA_Bytes(m_spline_r.spline()[i], m_spline_g.spline()[i], m_spline_b.spline()[i], m_spline_a.spline()[i]); } VertexSourceApplyTransform t1 = new VertexSourceApplyTransform(e1, mtx1); IGradient innerGradient = null; switch (m_GradTypeRBox.SelectedIndex) { case 0: innerGradient = new gradient_radial(); break; case 1: innerGradient = new gradient_diamond(); break; case 2: innerGradient = new gradient_x(); break; case 3: innerGradient = new gradient_xy(); break; case 4: innerGradient = new gradient_sqrt_xy(); break; case 5: innerGradient = new gradient_conic(); break; } IGradient outerGradient = null; switch (m_GradWrapRBox.SelectedIndex) { case 0: outerGradient = new gradient_reflect_adaptor(innerGradient); break; case 1: outerGradient = new gradient_repeat_adaptor(innerGradient); break; case 2: outerGradient = new gradient_clamp_adaptor(innerGradient); break; } span_allocator span_alloc = new span_allocator(); color_function_profile colors = new color_function_profile(color_profile, m_profile.gamma()); span_interpolator_linear inter = new span_interpolator_linear(mtx_g1); span_gradient span_gen = new span_gradient(inter, outerGradient, colors, 0, 150); ras.add_path(t1); scanlineRenderer.GenerateAndRender(ras, sl, clippingProxy, span_alloc, span_gen); base.OnDraw(graphics2D); }
private void transform_image(double angle) { double width = m_TempDestImage.Width; double height = m_TempDestImage.Height; #if SourceDepthFloat ImageClippingProxyFloat clippedDest = new ImageClippingProxyFloat(m_TempDestImage); #else ImageClippingProxy clippedDest = new ImageClippingProxy(m_TempDestImage); #endif clippedDest.clear(new ColorF(1.0, 1.0, 1.0)); Affine src_mtx = Affine.NewIdentity(); src_mtx *= Affine.NewTranslation(-width / 2.0, -height / 2.0); src_mtx *= Affine.NewRotation(angle * Math.PI / 180.0); src_mtx *= Affine.NewTranslation(width / 2.0, height / 2.0); Affine img_mtx = new Affine(src_mtx); img_mtx.invert(); double r = width; if (height < r) { r = height; } r *= 0.5; r -= 4.0; VertexSource.Ellipse ell = new MatterHackers.Agg.VertexSource.Ellipse(width / 2.0, height / 2.0, r, r, 200); VertexSourceApplyTransform tr = new VertexSourceApplyTransform(ell, src_mtx); m_num_pix += r * r * Math.PI; #if SourceDepthFloat span_interpolator_linear_float interpolator = new span_interpolator_linear_float(img_mtx); #else span_interpolator_linear interpolator = new span_interpolator_linear(img_mtx); #endif ImageFilterLookUpTable filter = new ImageFilterLookUpTable(); bool norm = m_normalize.Checked; #if SourceDepthFloat ImageBufferAccessorClipFloat source = new ImageBufferAccessorClipFloat(m_RotatedImage, RGBA_Floats.rgba_pre(0, 0, 0, 0).ToColorF()); #else ImageBufferAccessorClip source = new ImageBufferAccessorClip(m_RotatedImage, ColorF.rgba_pre(0, 0, 0, 0).ToColor()); #endif IImageFilterFunction filterFunction = null; ScanlineRenderer scanlineRenderer = new ScanlineRenderer(); switch (filterSelectionButtons.SelectedIndex) { case 0: { #if SourceDepthFloat span_image_filter_float spanGenerator; #else span_image_filter spanGenerator; #endif switch (source.SourceImage.BitDepth) { case 24: #if SourceDepthFloat throw new NotImplementedException(); #else spanGenerator = new span_image_filter_rgb_nn(source, interpolator); #endif break; case 32: #if SourceDepthFloat throw new NotImplementedException(); #else spanGenerator = new span_image_filter_rgba_nn(source, interpolator); #endif break; default: throw new NotImplementedException("only support 24 and 32 bit"); } m_Rasterizer.add_path(tr); scanlineRenderer.GenerateAndRender(m_Rasterizer, m_ScanlineUnpacked, clippedDest, m_SpanAllocator, spanGenerator); } break; case 1: { #if SourceDepthFloat span_image_filter_float spanGenerator; #else span_image_filter spanGenerator; #endif switch (source.SourceImage.BitDepth) { case 24: #if SourceDepthFloat throw new NotImplementedException(); #else spanGenerator = new span_image_filter_rgb_bilinear(source, interpolator); #endif break; case 32: #if SourceDepthFloat throw new NotImplementedException(); #else spanGenerator = new span_image_filter_rgba_bilinear(source, interpolator); #endif break; #if SourceDepthFloat case 128: spanGenerator = new span_image_filter_rgba_bilinear_float(source, interpolator); break; #endif default: throw new NotImplementedException("only support 24 and 32 bit"); } m_Rasterizer.add_path(tr); scanlineRenderer.GenerateAndRender(m_Rasterizer, m_ScanlineUnpacked, clippedDest, m_SpanAllocator, spanGenerator); } break; case 5: case 6: case 7: { switch (filterSelectionButtons.SelectedIndex) { case 5: filter.calculate(new image_filter_hanning(), norm); break; case 6: filter.calculate(new image_filter_hamming(), norm); break; case 7: filter.calculate(new image_filter_hermite(), norm); break; } #if SourceDepthFloat throw new NotImplementedException(); #else span_image_filter_rgb_2x2 spanGenerator = new span_image_filter_rgb_2x2(source, interpolator, filter); #endif m_Rasterizer.add_path(tr); #if SourceDepthFloat throw new NotImplementedException(); #else scanlineRenderer.GenerateAndRender(m_Rasterizer, m_ScanlineUnpacked, clippedDest, m_SpanAllocator, spanGenerator); #endif } break; case 2: case 3: case 4: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: { switch (filterSelectionButtons.SelectedIndex) { case 2: filter.calculate(new image_filter_bicubic(), norm); break; case 3: filter.calculate(new image_filter_spline16(), norm); break; case 4: filter.calculate(new image_filter_spline36(), norm); break; case 8: filter.calculate(new image_filter_kaiser(), norm); break; case 9: filter.calculate(new image_filter_quadric(), norm); break; case 10: filter.calculate(new image_filter_catrom(), norm); break; case 11: filter.calculate(new image_filter_gaussian(), norm); break; case 12: filter.calculate(new image_filter_bessel(), norm); break; case 13: filter.calculate(new image_filter_mitchell(), norm); break; case 14: filter.calculate(new image_filter_sinc(m_radius.Value), norm); break; case 15: filter.calculate(new image_filter_lanczos(m_radius.Value), norm); break; case 16: filterFunction = new image_filter_blackman(m_radius.Value); //filterFunction = new image_filter_bilinear(); filter.calculate(filterFunction, norm); break; } #if SourceDepthFloat span_image_filter_float spanGenerator; #else span_image_filter spanGenerator; #endif switch (source.SourceImage.BitDepth) { case 24: #if SourceDepthFloat throw new NotImplementedException(); #else spanGenerator = new span_image_filter_rgb(source, interpolator, filter); #endif break; case 32: #if SourceDepthFloat throw new NotImplementedException(); #else spanGenerator = new span_image_filter_rgba(source, interpolator, filter); #endif break; #if SourceDepthFloat case 128: spanGenerator = new span_image_filter_rgba_float(source, interpolator, filterFunction); break; #endif default: throw new NotImplementedException("only support 24 and 32 bit"); } m_Rasterizer.add_path(tr); scanlineRenderer.GenerateAndRender(m_Rasterizer, m_ScanlineUnpacked, clippedDest, m_SpanAllocator, spanGenerator); } break; } }
public override void Render(IImageByte source, double destX, double destY, double angleRadians, double inScaleX, double inScaleY) { Affine graphicsTransform = GetTransform(); // 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 + graphicsTransform.tx), (int)(destY + graphicsTransform.ty)); if (!RectangleInt.DoIntersect(sourceBounds, destBounds)) { if (inScaleX != 1 || inScaleY != 1 || angleRadians != 0) { //throw new NotImplementedException(); } //return; } double scaleX = inScaleX; double scaleY = inScaleY; 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: { DrawImageGetDestBounds(source, destX, destY, sourceOriginOffsetX, sourceOriginOffsetY, scaleX, scaleY, angleRadians, out Affine destRectTransform); var 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; var interpolator = new span_interpolator_linear(sourceRectTransform); var sourceAccessor = new ImageBufferAccessorClip(source, ColorF.rgba_pre(0, 0, 0, 0).ToColor()); spanImageFilter = new span_image_filter_rgba_bilinear_clip(sourceAccessor, ColorF.rgba_pre(0, 0, 0, 0), interpolator); DrawImage(spanImageFilter, destRectTransform); } break; case TransformQuality.Best: { DrawImageGetDestBounds(source, destX, destY, sourceOriginOffsetX, sourceOriginOffsetY, scaleX, scaleY, angleRadians, out Affine destRectTransform); var 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(); var interpolator = new span_interpolator_linear(sourceRectTransform); var sourceAccessor = new ImageBufferAccessorClip(source, ColorF.rgba_pre(0, 0, 0, 0).ToColor()); // 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); var filter = new ImageFilterLookUpTable(); filter.calculate(filterFunction, true); span_image_filter spanGenerator = new span_image_filter_rgba(sourceAccessor, interpolator, filter); DrawImage(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 { DrawImageGetDestBounds(source, destX, destY, sourceOriginOffsetX, sourceOriginOffsetY, scaleX, scaleY, angleRadians, out Affine destRectTransform); var 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(); var interpolator = new span_interpolator_linear(sourceRectTransform); var sourceAccessor = new ImageBufferAccessorClip(source, ColorF.rgba_pre(0, 0, 0, 0).ToColor()); 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(spanImageFilter, destRectTransform); DestImage.MarkImageChanged(); } }
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 scalling 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 optomization 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 scalling 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 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); #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 intermediat 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 override void OnDraw(Graphics2D graphics2D) { ImageBuffer widgetsSubImage = ImageBuffer.NewSubImageReference(graphics2D.DestImage, graphics2D.GetClippingRect()); if (orignialSize.x == 0) { orignialSize.x = WindowSize.x; orignialSize.y = WindowSize.y; } ImageBuffer destImageWithPreMultBlender = new ImageBuffer(); switch (widgetsSubImage.BitDepth) { case 24: destImageWithPreMultBlender.Attach(widgetsSubImage, new BlenderPreMultBGR()); break; case 32: destImageWithPreMultBlender.Attach(widgetsSubImage, new BlenderPreMultBGRA()); break; default: throw new Exception("Unknown bit depth"); } ImageClippingProxy clippingProxy_pre = new ImageClippingProxy(destImageWithPreMultBlender); clippingProxy_pre.clear(new RGBA_Floats(1.0, 1.0, 1.0)); Affine src_mtx = Affine.NewIdentity(); src_mtx *= Affine.NewTranslation(-orignialSize.x / 2 - 10, -orignialSize.y / 2 - 20 - 10); src_mtx *= Affine.NewRotation(drawAngle.Value * Math.PI / 180.0); src_mtx *= Affine.NewScaling(drawScale.Value); src_mtx *= Affine.NewTranslation(orignialSize.x / 2, orignialSize.y / 2 + 20); Affine img_mtx = Affine.NewIdentity(); img_mtx *= Affine.NewTranslation(-orignialSize.x / 2 + 10, -orignialSize.y / 2 + 20 + 10); img_mtx *= Affine.NewRotation(drawAngle.Value * Math.PI / 180.0); img_mtx *= Affine.NewScaling(drawScale.Value); img_mtx *= Affine.NewTranslation(orignialSize.x / 2, orignialSize.y / 2 + 20); img_mtx.invert(); MatterHackers.Agg.span_allocator sa = new span_allocator(); span_interpolator_linear interpolator = new span_interpolator_linear(img_mtx); span_image_filter sg; switch (sourceImage.BitDepth) { case 24: { ImageBufferAccessorClip source = new ImageBufferAccessorClip(sourceImage, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes()); sg = new span_image_filter_rgb_bilinear_clip(source, RGBA_Floats.rgba_pre(0, 0.4, 0, 0.5), interpolator); } break; case 32: { ImageBufferAccessorClip source = new ImageBufferAccessorClip(sourceImage, RGBA_Floats.rgba_pre(0, 0, 0, 0).GetAsRGBA_Bytes()); sg = new span_image_filter_rgba_bilinear_clip(source, RGBA_Floats.rgba_pre(0, 0.4, 0, 0.5), interpolator); } break; default: throw new Exception("Bad sourc depth"); } ScanlineRasterizer ras = new ScanlineRasterizer(); ras.SetVectorClipBox(0, 0, Width, Height); ScanlineCachePacked8 sl = new ScanlineCachePacked8(); //scanline_unpacked_8 sl = new scanline_unpacked_8(); double r = orignialSize.x; if (orignialSize.y - 60 < r) { r = orignialSize.y - 60; } VertexSource.Ellipse ell = new VertexSource.Ellipse(orignialSize.x / 2.0 + 10, orignialSize.y / 2.0 + 20 + 10, r / 2.0 + 16.0, r / 2.0 + 16.0, 200); VertexSourceApplyTransform tr = new VertexSourceApplyTransform(ell, src_mtx); ras.add_path(tr); //clippingProxy_pre.SetClippingBox(30, 0, (int)width(), (int)height()); ScanlineRenderer scanlineRenderer = new ScanlineRenderer(); scanlineRenderer.GenerateAndRender(ras, sl, clippingProxy_pre, sa, sg); base.OnDraw(graphics2D); }
public override void OnDraw(Graphics2D graphics2D) { ImageBuffer widgetsSubImage = ImageBuffer.NewSubImageReference(graphics2D.DestImage, graphics2D.GetClippingRect()); ScanlineRasterizer ras = new ScanlineRasterizer(); scanline_unpacked_8 sl = new scanline_unpacked_8(); ImageClippingProxy clippingProxy = new ImageClippingProxy(widgetsSubImage); clippingProxy.clear(new RGBA_Floats(0, 0, 0)); m_profile.text_size(8.0); // draw a background to show how the alpha is working int RectWidth = 32; int xoffset = 238; int yoffset = 171; ScanlineRenderer scanlineRenderer = new ScanlineRenderer(); for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { if ((i + j) % 2 != 0) { VertexSource.RoundedRect rect = new VertexSource.RoundedRect(i * RectWidth + xoffset, j * RectWidth + yoffset, (i + 1) * RectWidth + xoffset, (j + 1) * RectWidth + yoffset, 2); rect.normalize_radius(); ras.add_path(rect); scanlineRenderer.render_scanlines_aa_solid(clippingProxy, ras, sl, new RGBA_Bytes(.9, .9, .9)); } } } double ini_scale = 1.0; Transform.Affine mtx1 = Affine.NewIdentity(); mtx1 *= Affine.NewScaling(ini_scale, ini_scale); mtx1 *= Affine.NewTranslation(center_x, center_y); VertexSource.Ellipse e1 = new MatterHackers.Agg.VertexSource.Ellipse(); e1.init(0.0, 0.0, 110.0, 110.0, 64); Transform.Affine mtx_g1 = Affine.NewIdentity(); mtx_g1 *= Affine.NewScaling(ini_scale, ini_scale); mtx_g1 *= Affine.NewScaling(m_SaveData.m_scale, m_SaveData.m_scale); mtx_g1 *= Affine.NewScaling(m_scale_x, m_scale_y); mtx_g1 *= Affine.NewRotation(m_SaveData.m_angle); mtx_g1 *= Affine.NewTranslation(m_SaveData.m_center_x, m_SaveData.m_center_y); mtx_g1.invert(); RGBA_Bytes[] color_profile = new RGBA_Bytes[256]; // color_type is defined in pixel_formats.h for (int i = 0; i < 256; i++) { color_profile[i] = new RGBA_Bytes(m_spline_r.spline()[i], m_spline_g.spline()[i], m_spline_b.spline()[i], m_spline_a.spline()[i]); } VertexSourceApplyTransform t1 = new VertexSourceApplyTransform(e1, mtx1); IGradient innerGradient = null; switch (m_GradTypeRBox.SelectedIndex) { case 0: innerGradient = new gradient_radial(); break; case 1: innerGradient = new gradient_diamond(); break; case 2: innerGradient = new gradient_x(); break; case 3: innerGradient = new gradient_xy(); break; case 4: innerGradient = new gradient_sqrt_xy(); break; case 5: innerGradient = new gradient_conic(); break; } IGradient outerGradient = null; switch (m_GradWrapRBox.SelectedIndex) { case 0: outerGradient = new gradient_reflect_adaptor(innerGradient); break; case 1: outerGradient = new gradient_repeat_adaptor(innerGradient); break; case 2: outerGradient = new gradient_clamp_adaptor(innerGradient); break; } span_allocator span_alloc = new span_allocator(); color_function_profile colors = new color_function_profile(color_profile, m_profile.gamma()); span_interpolator_linear inter = new span_interpolator_linear(mtx_g1); span_gradient span_gen = new span_gradient(inter, outerGradient, colors, 0, 150); ras.add_path(t1); scanlineRenderer.GenerateAndRender(ras, sl, clippingProxy, span_alloc, span_gen); base.OnDraw(graphics2D); }