123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- using System.Diagnostics;
- using System.Drawing;
- namespace PaintDotNet
- {
- public sealed class StitchSurfaceBoxBaseRenderer : StitchSurfaceBoxRenderer
- {
- private StitchSurface source;
- private RenderDelegate renderDelegate;
- public StitchSurface Source
- {
- set
- {
- this.source = value;
- Flush();
- }
- }
- private void Flush()
- {
- this.renderDelegate = null;
- }
- protected override void OnVisibleChanged()
- {
- Invalidate();
- }
- private void ChooseRenderDelegate()
- {
- if (SourceSize.Width > DestinationSize.Width)
- {
- // zoom out
- this.renderDelegate = new RenderDelegate(RenderZoomOutRotatedGridMultisampling);
- }
- else if (SourceSize == DestinationSize)
- {
- // zoom 100%
- this.renderDelegate = new RenderDelegate(RenderOneToOne);
- }
- else if (SourceSize.Width < DestinationSize.Width)
- {
- // zoom in
- this.renderDelegate = new RenderDelegate(RenderZoomInNearestNeighbor);
- }
- }
- public override void OnDestinationSizeChanged()
- {
- ChooseRenderDelegate();
- this.OwnerList.InvalidateLookups();
- base.OnDestinationSizeChanged();
- }
- public override void OnSourceSizeChanged()
- {
- ChooseRenderDelegate();
- this.OwnerList.InvalidateLookups();
- base.OnSourceSizeChanged();
- }
- public static void RenderOneToOne(StitchSurface dst, StitchSurface source, Point offset)
- {
- unsafe
- {
- if (source == null) return;
- Rectangle srcRect = new Rectangle(offset, dst.Size);
- srcRect.Intersect(source.Bounds);
- for (int dstRow = 0; dstRow < srcRect.Height; ++dstRow)
- {
- ColorBgrB* dstRowPtr = dst.GetRowAddressUnchecked(dstRow);
- ColorBgrB* srcRowPtr = source.GetPointAddressUnchecked(offset.X, dstRow + offset.Y);
- //source.stitchBounds;
- int dstCol = offset.X;
- int dstColEnd = offset.X + srcRect.Width;
- int checkerY = dstRow + offset.Y;
- while (dstCol < dstColEnd)
- {
- int b;// = srcRowPtr->B;
- int g;// = srcRowPtr->G;
- int r;// = srcRowPtr->R;
- int a = 255;// srcRowPtr->A;
- if (!source.stitchBounds.Contains(new Point(dstCol, checkerY)))// a = 0;
- {
- r = source.stitchBackColor.R;// 0;// p1->R;//
- g = source.stitchBackColor.G;// 0;// p1->G;//
- b = source.stitchBackColor.B;// 0;// p1->B;//
- }
- else
- {
- b = srcRowPtr->B;
- g = srcRowPtr->G;
- r = srcRowPtr->R;
- }
- // Blend it over the checkerboard background
- int v = (((dstCol ^ checkerY) & 8) << 3) + 191;
- a = a + (a >> 7);
- int vmia = v * (256 - a);
- r = ((r * a) + vmia) >> 8;
- g = ((g * a) + vmia) >> 8;
- b = ((b * a) + vmia) >> 8;
- dstRowPtr->setBGR((byte)b, (byte)g, (byte)r);
- ++dstRowPtr;
- ++srcRowPtr;
- ++dstCol;
- }
- }
- }
- }
- private void RenderOneToOne(StitchSurface dst, Point offset)
- {
- RenderOneToOne(dst, this.source, offset);
- }
- private void RenderZoomInNearestNeighbor(StitchSurface dst, Point offset)
- {
- unsafe
- {
- if (this.source == null) return;
- int[] d2SLookupY = OwnerList.Dst2SrcLookupY;
- int[] d2SLookupX = OwnerList.Dst2SrcLookupX;
- for (int dstRow = 0; dstRow < dst.Height; ++dstRow)
- {
- int nnY = dstRow + offset.Y;
- int srcY = d2SLookupY[nnY];
- ColorBgrB* dstPtr = dst.GetRowAddressUnchecked(dstRow);
- ColorBgrB* srcRow = this.source.GetRowAddressUnchecked(srcY);
- //source.stitchBounds;
- for (int dstCol = 0; dstCol < dst.Width; ++dstCol)
- {
- int nnX = dstCol + offset.X;
- int srcX = d2SLookupX[nnX];
- ColorBgrB src = *(srcRow + srcX);
- int b;// = src.B;
- int g;// = src.G;
- int r;// = src.R;
- int a = 255;// src.A;
- if (!source.stitchBounds.Contains(new Point(srcX, srcY)))// a = 0;
- {
- r = source.stitchBackColor.R;// 0;// p1->R;//
- g = source.stitchBackColor.G;// 0;// p1->G;//
- b = source.stitchBackColor.B;// 0;// p1->B;//
- }
- else
- {
- b = src.B;
- g = src.G;
- r = src.R;
- }
- // Blend it over the checkerboard background
- int v = (((dstCol + offset.X) ^ (dstRow + offset.Y)) & 8) * 8 + 191;
- a = a + (a >> 7);
- int vmia = v * (256 - a);
- r = ((r * a) + vmia) >> 8;
- g = ((g * a) + vmia) >> 8;
- b = ((b * a) + vmia) >> 8;
- dstPtr->setBGR((byte)b, (byte)g, (byte)r);
- ++dstPtr;
- }
- }
- }
- }
- public static void RenderZoomOutRotatedGridMultisampling(StitchSurface dst, StitchSurface source, Point offset, Size destinationSize)
- {
- unsafe
- {
- if (source == null) return;
- /* OpenCvSharp.Mat temp1 = new OpenCvSharp.Mat(dst.mat.Size(), OpenCvSharp.MatType.CV_8UC4);
- OpenCvSharp.Cv2.CvtColor(dst.mat, temp1, OpenCvSharp.ColorConversionCodes.BGR2BGRA);
- dst.mat = temp1;
- dst.Stride = temp1.Width * 4;
- dst.scan0.VoidStar = (void*)temp1.Data;
- OpenCvSharp.Mat temp2 = new OpenCvSharp.Mat(source.mat.Size(), OpenCvSharp.MatType.CV_8UC4);
- OpenCvSharp.Cv2.CvtColor(source.mat, temp2, OpenCvSharp.ColorConversionCodes.BGR2BGRA);
- source.mat = temp2;
- source.Stride = temp2.Width * 4;
- source.scan0.VoidStar = (void*)temp2.Data;
- */
- //if (source.mat != null)
- //{
- // OpenCvSharp.Cv2.ImShow("dst", source.mat);
- // OpenCvSharp.Cv2.WaitKey();
- //}
- //OpenCvSharp.Cv2.ImShow("dst", dst.mat);
- //if (dst.mat != null)
- //OpenCvSharp.Cv2.CvtColor(dst.mat, dst.mat, OpenCvSharp.ColorConversionCodes.BGR2BGRA);
- //OpenCvSharp.Cv2.ImShow("src", source.mat);
- //OpenCvSharp.Cv2.WaitKey();
- const int fpShift = 12;
- const int fpFactor = (1 << fpShift);
- Size sourceSize = source.Size;
- long fDstLeftLong = ((long)offset.X * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width;
- long fDstTopLong = ((long)offset.Y * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height;
- long fDstRightLong = ((long)(offset.X + dst.Width) * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width;
- long fDstBottomLong = ((long)(offset.Y + dst.Height) * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height;
- int fDstLeft = (int)fDstLeftLong;
- int fDstTop = (int)fDstTopLong;
- int fDstRight = (int)fDstRightLong;
- int fDstBottom = (int)fDstBottomLong;
- int dx = (fDstRight - fDstLeft) / dst.Width;
- int dy = (fDstBottom - fDstTop) / dst.Height;
- //int dstSum = 0;
- for (int dstRow = 0, fDstY = fDstTop;
- dstRow < dst.Height && fDstY < fDstBottom;
- ++dstRow, fDstY += dy)
- {
- int srcY1 = fDstY >> fpShift; // y
- int srcY2 = (fDstY + (dy >> 2)) >> fpShift; // y + 0.25
- int srcY3 = (fDstY + (dy >> 1)) >> fpShift; // y + 0.50
- int srcY4 = (fDstY + (dy >> 1) + (dy >> 2)) >> fpShift; // y + 0.75
- #if DEBUG
- Debug.Assert(source.IsRowVisible(srcY1));
- Debug.Assert(source.IsRowVisible(srcY2));
- Debug.Assert(source.IsRowVisible(srcY3));
- Debug.Assert(source.IsRowVisible(srcY4));
- Debug.Assert(dst.IsRowVisible(dstRow));
- #endif
- ColorBgrB* src1 = source.GetRowAddressUnchecked(srcY1);
- ColorBgrB* src2 = source.GetRowAddressUnchecked(srcY2);
- ColorBgrB* src3 = source.GetRowAddressUnchecked(srcY3);
- ColorBgrB* src4 = source.GetRowAddressUnchecked(srcY4);
- ColorBgrB* dstPtr = dst.GetRowAddressUnchecked(dstRow);
- int checkerY = dstRow + offset.Y;
- int checkerX = offset.X;
- int maxCheckerX = checkerX + dst.Width;
- for (int fDstX = fDstLeft;
- checkerX < maxCheckerX && fDstX < fDstRight;
- ++checkerX, fDstX += dx)
- {
- int srcX1 = (fDstX + (dx >> 2)) >> fpShift; // x + 0.25// fDstX >> fpShift; //
- int srcX2 = (fDstX + (dx >> 1) + (dx >> 2)) >> fpShift; // x + 0.75
- int srcX3 = fDstX >> fpShift; // x
- int srcX4 = (fDstX + (dx >> 1)) >> fpShift; // x + 0.50
- #if DEBUG
- Debug.Assert(source.IsColumnVisible(srcX1));
- Debug.Assert(source.IsColumnVisible(srcX2));
- Debug.Assert(source.IsColumnVisible(srcX3));
- Debug.Assert(source.IsColumnVisible(srcX4));
- #endif
- ColorBgrB* p1 = src1 + srcX1;
- ColorBgrB* p2 = src2 + srcX2;
- ColorBgrB* p3 = src3 + srcX3;
- ColorBgrB* p4 = src4 + srcX4;
- // / 4;//
- int r;// = (2 + p1->R + p2->R + p3->R + p4->R) >> 2;// p1->R;//
- int g;// = (2 + p1->G + p2->G + p3->G + p4->G) >> 2;// p1->G;//
- int b;// = (2 + p1->B + p2->B + p3->B + p4->B) >> 2;// p1->B;//
- int a = 255;// (2 + p1->A + p2->A + p3->A + p4->A) >> 2;
- if (!source.stitchBounds.Contains(new Point(srcX3, srcY1)))// a = 0;
- {
- r = source.stitchBackColor.R;// 0;// p1->R;//
- g = source.stitchBackColor.G;// 0;// p1->G;//
- b = source.stitchBackColor.B;// 0;// p1->B;//
- }
- else
- {
- r = (2 + p1->R + p2->R + p3->R + p4->R) >> 2;// p1->R;//
- g = (2 + p1->G + p2->G + p3->G + p4->G) >> 2;// p1->G;//
- b = (2 + p1->B + p2->B + p3->B + p4->B) >> 2;// p1->B;//
- }
- int apopacity = a;
- //
- //source.stitchBounds;
- // Blend it over the checkerboard background
- int v = ((checkerX ^ checkerY) & 8) * 8 + 191;
- a = a + (a >> 7);
- int vmia = v * (256 - a);
- r = ((r * a) + vmia) >> 8;
- g = ((g * a) + vmia) >> 8;
- b = ((b * a) + vmia) >> 8;
- dstPtr->setBGR((byte)b, (byte)g, (byte)r);
- //dstPtr->setBGR((byte)240, (byte)240, (byte)240);
- ++dstPtr;
- //++dstSum;
- }
- }
- //System.Console.WriteLine("dstSum:" + dstSum);
- }
- }
- private void RenderZoomOutRotatedGridMultisampling(StitchSurface dst, Point offset)
- {
- RenderZoomOutRotatedGridMultisampling(dst, this.source, offset, this.DestinationSize);
- }
- public override void Render(StitchSurface dst, Point offset)
- {
- if (this.renderDelegate == null)
- {
- ChooseRenderDelegate();
- }
- this.renderDelegate(dst, offset);
- }
- public StitchSurfaceBoxBaseRenderer(StitchSurfaceBoxRendererList ownerList)
- : base(ownerList)
- {
- ChooseRenderDelegate();
- }
- }
- }
|