public VectorClipper(CellAARasterizer ras) { _ras = ras; _clipBox = new Q1Rect(0, 0, 0, 0); _x1 = _y1 = _f1 = 0; _clipping = false; }
public Q1Rect GetClipArea(ref Q1Rect destRect, ref Q1Rect sourceRect, int sourceWidth, int sourceHeight) { Q1Rect rc = new Q1Rect(0, 0, 0, 0); Q1Rect cb = ClipBox; ++cb.Right; ++cb.Top; if (sourceRect.Left < 0) { destRect.Left -= sourceRect.Left; sourceRect.Left = 0; } if (sourceRect.Bottom < 0) { destRect.Bottom -= sourceRect.Bottom; sourceRect.Bottom = 0; } if (sourceRect.Right > sourceWidth) { sourceRect.Right = sourceWidth; } if (sourceRect.Top > sourceHeight) { sourceRect.Top = sourceHeight; } if (destRect.Left < cb.Left) { sourceRect.Left += cb.Left - destRect.Left; destRect.Left = cb.Left; } if (destRect.Bottom < cb.Bottom) { sourceRect.Bottom += cb.Bottom - destRect.Bottom; destRect.Bottom = cb.Bottom; } if (destRect.Right > cb.Right) { destRect.Right = cb.Right; } if (destRect.Top > cb.Top) { destRect.Top = cb.Top; } rc.Right = destRect.Right - destRect.Left; rc.Top = destRect.Top - destRect.Bottom; if (rc.Right > sourceRect.Right - sourceRect.Left) { rc.Right = sourceRect.Right - sourceRect.Left; } if (rc.Top > sourceRect.Top - sourceRect.Bottom) { rc.Top = sourceRect.Top - sourceRect.Bottom; } return(rc); }
//--------------------------------------------------------------------- //typedef renderer_outline_image<BaseRenderer, ImagePattern> self_type; //--------------------------------------------------------------------- public ImageLineRenderer(PixelProcessing.IBitmapBlender ren, LineImagePattern patt) { _ren = ren; _pattern = patt; _start = (0); _scale_x = (1.0); _clip_box = new Q1Rect(0, 0, 0, 0); _clipping = (false); }
public override void CopyFrom(IBitmapSrc sourceImage, Q1Rect sourceImageRect, int destXOffset, int destYOffset) { Q1Rect destRect = sourceImageRect.CreateNewFromOffset(destXOffset, destYOffset); if (Q1Rect.IntersectRectangles(destRect, _clippingRect, out Q1Rect clippedSourceRect)) { // move it back relative to the source base.CopyFrom(sourceImage, clippedSourceRect.CreateNewFromOffset(-destXOffset, -destYOffset), destXOffset, destYOffset); } }
public bool SetClippingBox(int x1, int y1, int x2, int y2) { Q1Rect cb = new Q1Rect(x1, y1, x2, y2, true); if (Q1Rect.Clip(cb, new Q1Rect(0, 0, (int)Width - 1, (int)Height - 1), out cb)) { _clippingRect = cb; return(true); } _clippingRect = new Q1Rect(1, 1, 0, 0); return(false); }
public void CopyFrom(IBitmapSrc srcimg, Q1Rect srcImgRect, int destXOffset, int destYOffset) { if (Q1Rect.IntersectRectangles(srcimg.GetBounds(), srcImgRect, out Q1Rect clipped_srcRect)) { Q1Rect dstImgRect = clipped_srcRect.CreateNewFromOffset(destXOffset, destYOffset); if (Q1Rect.IntersectRectangles(dstImgRect, GetBounds(), out Q1Rect clipped_dstRect)) { // we need to make sure the source is also clipped to the dest. So, we'll copy this back to source and offset it. clipped_srcRect = clipped_dstRect.CreateNewFromOffset(-destXOffset, -destYOffset); CopyFromNoClipping(srcimg, clipped_srcRect, destXOffset, destYOffset); } } }
public void SetClipBox(int left, int bottom, int right, int top) { left += (int)OffsetOriginX; bottom += (int)OffsetOriginY; right += (int)OffsetOriginX; top += (int)OffsetOriginY; _userModeClipBox = new Q1Rect(left, bottom, right, top); Reset(); _vectorClipper.SetClipBox( upscale(left), upscale(bottom), upscale(right), upscale(top)); }
public bool SetClippingBox(int x1, int y1, int x2, int y2) { Q1Rect cb = new Q1Rect(x1, y1, x2, y2); cb.Normalize(); if (cb.Clip(new Q1Rect(0, 0, (int)Width - 1, (int)Height - 1))) { _clippingRect = cb; return(true); } _clippingRect.Left = 1; _clippingRect.Bottom = 1; _clippingRect.Right = 0; _clippingRect.Top = 0; return(false); }
public override void CopyFrom(IBitmapSrc sourceImage, Q1Rect sourceImageRect, int destXOffset, int destYOffset) { Q1Rect destRect = sourceImageRect; destRect.Offset(destXOffset, destYOffset); Q1Rect clippedSourceRect = new Q1Rect(); if (clippedSourceRect.IntersectRectangles(destRect, _clippingRect)) { // move it back relative to the source clippedSourceRect.Offset(-destXOffset, -destYOffset); base.CopyFrom(sourceImage, clippedSourceRect, destXOffset, destYOffset); } }
public void CopyFrom(IBitmapSrc sourceImage, Q1Rect sourceImageRect, int destXOffset, int destYOffset) { Q1Rect sourceImageBounds = sourceImage.GetBounds(); Q1Rect clippedSourceImageRect = new Q1Rect(); if (clippedSourceImageRect.IntersectRectangles(sourceImageRect, sourceImageBounds)) { Q1Rect destImageRect = clippedSourceImageRect; destImageRect.Offset(destXOffset, destYOffset); Q1Rect destImageBounds = GetBounds(); Q1Rect clippedDestImageRect = new Q1Rect(); 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); } } }
bool _clipBoxWidthX3ForSubPixelLcdEffect = false; //default /// <summary> /// when we render in subpixel rendering, we extend a row length 3 times (expand RGB) /// </summary> /// <param name="value"></param> public void SetClipBoxWidthX3ForSubPixelLcdEffect(bool value) { //----------------------------------------------------------------------------- //if we don't want to expand our img buffer 3 times (larger than normal) //we should use this method to extend only a cliper box's width x3 //----------------------------------------------------------------------------- //special method for our need if (value != _clipBoxWidthX3ForSubPixelLcdEffect) { //changed if (value) { _clipBox = new Q1Rect(_clipBox.Left, _clipBox.Bottom, _clipBox.Left + (_clipBox.Width * 3), _clipBox.Height); } else { //set back _clipBox = new Q1Rect(_clipBox.Left, _clipBox.Bottom, _clipBox.Left + (_clipBox.Width / 3), _clipBox.Height); } _clipBoxWidthX3ForSubPixelLcdEffect = value; } }
public void SetClipBox(Q1Rect clippingRect) { SetClipBox(clippingRect.Left, clippingRect.Bottom, clippingRect.Right, clippingRect.Top); }
public void Render(IBitmapSrc 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 Q1Rect sourceBounds = source.GetBounds(); Q1Rect destBounds = _destBitmapBlender.GetBounds(); sourceBounds.Offset((int)destX, (int)destY); if (!Q1Rect.DoIntersect(sourceBounds, destBounds)) { if (inScaleX != 1 || inScaleY != 1 || angleRadians != 0) { throw new NotImplementedException(); } return; } } double scaleX = inScaleX; double scaleY = inScaleY; ICoordTransformer graphicsTransform = this.CurrentTransformMatrix; if (!graphicsTransform.IsIdentity) { 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 isScale = (scaleX != 1 || scaleY != 1); bool isRotated = true; if (Math.Abs(angleRadians) < (0.1 * MathHelper.Tau / 360)) { isRotated = false; angleRadians = 0; } //bool IsMipped = false; //double ox, oy; //source.GetOriginOffset(out ox, out oy); bool canUseMipMaps = isScale; if (scaleX > 0.5 || scaleY > 0.5) { canUseMipMaps = false; } bool renderRequriesSourceSampling = isScale || isRotated || destX != (int)destX || destY != (int)destY; using (VxsTemp.Borrow(out var v1, out var imgBoundsPath)) { // this is the fast drawing path if (renderRequriesSourceSampling) { // 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); //} //Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, // destX, destY, ox, oy, scaleX, scaleY, angleRadians, imgBoundsPath); //1. BuildOrgImgRectVxs(source.Width, source.Height, imgBoundsPath); //2. AffineMat destRectTransform = AffineMat.Iden(); destRectTransform.Translate(-_ox, -_oy); destRectTransform.Scale(scaleX, scaleY); destRectTransform.Rotate(angleRadians); //TODO: review reusable span generator an interpolator *** // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] _reuseableAffine.SetElements(destRectTransform.CreateInvert()); _spanInterpolator.Transformer = _reuseableAffine; _currentImgSpanGen.BackgroundColor = Drawing.Color.Black; _currentImgSpanGen.SetInterpolator(_spanInterpolator); _currentImgSpanGen.SetSrcBitmap(source); destRectTransform.TransformToVxs(imgBoundsPath, v1); //not inverted version Render(v1, _currentImgSpanGen); _currentImgSpanGen.ReleaseSrcBitmap(); // 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); } else // TODO: this can be even faster if we do not use an intermediat buffer { //Affine destRectTransform = BuildImageBoundsPath(source.Width, source.Height, destX, destY, imgBoundsPath); BuildOrgImgRectVxs(source.Width, source.Height, imgBoundsPath); // var destRectTransform = new AffineMat(); destRectTransform.Translate(destX, destY); //TODO: review reusable span generator an interpolator *** // We invert it because it is the transform to make the image go to the same position as the polygon. LBB [2/24/2004] _reuseableAffine.SetElements(destRectTransform.CreateInvert()); _spanInterpolator.Transformer = _reuseableAffine; ImgSpanGen imgSpanGen = null; switch (source.BitDepth) { case 32: if (_imgSpanGenCustom != null) { //use custom span gen _imgSpanGenCustom.SetInterpolator(_spanInterpolator); _imgSpanGenCustom.SetSrcBitmap(source); imgSpanGen = _imgSpanGenCustom; } else { _imgSpanGenNNStepXBy1.SetInterpolator(_spanInterpolator); _imgSpanGenNNStepXBy1.SetSrcBitmap(source); imgSpanGen = _imgSpanGenNNStepXBy1; } break; //case 24: // imgSpanGen = new ImgSpanGenRGB_NNStepXby1(source, interpolator); // break; //case 8: // imgSpanGen = new ImgSpanGenGray_NNStepXby1(source, interpolator); // break; default: throw new NotImplementedException(); } TransformToVxs(destRectTransform, imgBoundsPath, v1); Render(v1, imgSpanGen); unchecked { _destImageChanged++; }; } } }
public void SetClipBox(int x1, int y1, int x2, int y2) { _clipBox = new Q1Rect(x1, y1, x2, y2); _clipBox.Normalize(); _clipping = true; }
public ClipProxyImage(PixelProcessing.IBitmapBlender refImage) : base(refImage) { _clippingRect = new Q1Rect(0, 0, (int)refImage.Width - 1, (int)refImage.Height - 1); }
void CopyFromNoClipping(IBitmapSrc sourceImage, Q1Rect clippedSourceImageRect, int destXOffset, int destYOffset) { if (BytesBetweenPixelsInclusive != BitDepth / 8 || sourceImage.BytesBetweenPixelsInclusive != sourceImage.BitDepth / 8) { throw new Exception("WIP we only support packed pixel formats at this time."); } if (BitDepth == sourceImage.BitDepth) { int lengthInBytes = clippedSourceImageRect.Width * BytesBetweenPixelsInclusive; int sourceOffset = sourceImage.GetBufferOffsetXY32(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom); unsafe { using (TempMemPtr memPtr = sourceImage.GetBufferPtr()) using (TempMemPtr destPtr = this.GetBufferPtr()) { byte *sourceBuffer = (byte *)memPtr.Ptr; byte *destBuffer = (byte *)destPtr.Ptr; int destOffset = GetBufferOffsetXY32(clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + destYOffset); for (int i = 0; i < clippedSourceImageRect.Height; i++) { PixelFarm.Drawing.Internal.MemMx.memmove(destBuffer, destOffset * 4, sourceBuffer, sourceOffset, lengthInBytes); sourceOffset += sourceImage.Stride; destOffset += Stride; } } } } else { bool haveConversion = true; switch (sourceImage.BitDepth) { case 24: switch (BitDepth) { case 32: { //TODO: review here, this may not correct int numPixelsToCopy = clippedSourceImageRect.Width; for (int i = clippedSourceImageRect.Bottom; i < clippedSourceImageRect.Top; i++) { int sourceOffset = sourceImage.GetBufferOffsetXY32(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom + i); //byte[] sourceBuffer = sourceImage.GetBuffer(); //byte[] destBuffer = GetBuffer(); using (TempMemPtr srcMemPtr = sourceImage.GetBufferPtr()) using (TempMemPtr destBufferPtr = this.GetBufferPtr()) { int destOffset = GetBufferOffsetXY32( clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + i + destYOffset); unsafe { int *destBuffer = (int *)destBufferPtr.Ptr; int *sourceBuffer = (int *)srcMemPtr.Ptr; for (int x = 0; x < numPixelsToCopy; x++) { int color = sourceBuffer[sourceOffset++]; destBuffer[destOffset++] = (255 << 24) | //a (color & 0xff0000) | //b (color & 0x00ff00) | //g (color & 0xff); //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 SetClipBox(int x1, int y1, int x2, int y2) { _clipBox = new Q1Rect(x1, y1, x2, y2, true); _clipping = true; }