public unsafe void Render(ISurface <ColorAlpha8> dst, PointInt32 renderOffset) { int width = dst.Width; int height = dst.Height; int stride = dst.Stride; using (ISurface <ColorAlpha8> surface = SurfaceAllocator.Alpha8.Allocate(width, height, AllocationOptions.ZeroFillNotRequired)) { this.first.Render(dst, renderOffset); this.second.Render(surface, renderOffset); int num4 = surface.Stride; if ((stride == width) && (stride == num4)) { RenderingKernels.MultiplyAlpha8ByAlpha8Extent((byte *)dst.Scan0, (byte *)surface.Scan0, width * height); } else { for (int i = 0; i < height; i++) { byte *rowPointer = (byte *)dst.GetRowPointer <ColorAlpha8>(i); byte *numPtr2 = (byte *)surface.GetRowPointer <ColorAlpha8>(i); RenderingKernels.MultiplyAlpha8ByAlpha8Extent(rowPointer, numPtr2, width); } } } }
public unsafe void Render(ISurface <ColorAlpha8> dst, PointInt32 renderOffset) { int width = dst.Width; int height = dst.Height; int stride = dst.Stride; int x = renderOffset.X * 3; int y = renderOffset.Y * 3; int dstWidth = width * 3; int dstHeight = height * 3; IMaskFromScansRenderer source = this.source as IMaskFromScansRenderer; if (source != null) { ISurface <ColorAlpha8> surface = null; try { int?nullable; source.Render(alpha8Allocator, dstWidth, dstHeight, new PointInt32(x, y), ref surface, out nullable); if (nullable.HasValue) { if (nullable.GetValueOrDefault() != 0) { if (nullable.GetValueOrDefault() != (dstWidth * dstHeight)) { throw new UnreachableCodeException(); } dst.Clear(ColorAlpha8.Opaque); } else { dst.Clear(ColorAlpha8.Transparent); } } else { RenderingKernels.ResizeBoxFilterOneThirdAlpha8((byte *)dst.Scan0, width, height, stride, (byte *)surface.Scan0, dstWidth, dstHeight, surface.Stride); } } finally { DisposableUtil.Free <ISurface <ColorAlpha8> >(ref surface); } } else { using (ISurface <ColorAlpha8> surface2 = this.source.UseTileOrToSurface(new RectInt32(x, y, dstWidth, dstHeight))) { RenderingKernels.ResizeBoxFilterOneThirdAlpha8((byte *)dst.Scan0, width, height, stride, (byte *)surface2.Scan0, dstWidth, dstHeight, surface2.Stride); } } }
private unsafe void RenderTileWorkItem(PointInt32 tileOffset) { IBitmap <ColorPbgra32> bitmap; bool isCancelled = false; bool flag = false; Exception error = null; isCancelled |= this.IsTileRenderingCancelled(tileOffset); if (isCancelled) { bitmap = null; } else { RectInt32 tileSourceRect = this.tileMathHelper.GetTileSourceRect(tileOffset); SizeInt32 tileBufferSize = this.GetTileBufferSize(tileOffset); bitmap = RetryManager.Eval <IBitmap <ColorPbgra32> >(3, () => BitmapAllocator.Pbgra32.Allocate(tileBufferSize, AllocationOptions.Default), delegate(Exception _) { CleanupManager.RequestCleanup(); Thread.Sleep(200); CleanupManager.WaitForPendingCleanup(); }, delegate(AggregateException ex) { throw new AggregateException($"could not allocate a bitmap of size {tileBufferSize.Width} x {tileBufferSize.Height}", ex).Flatten(); }); if (this.source != null) { try { isCancelled |= this.IsTileRenderingCancelled(tileOffset); if (!isCancelled) { using (IBitmapLock <ColorPbgra32> @lock = bitmap.Lock <ColorPbgra32>(BitmapLockOptions.ReadWrite)) { if (this.mipLevel == 0) { this.source.CopyPixels(new RectInt32?(tileSourceRect), @lock); RenderingKernels.ConvertBgra32ToPbgra32((uint *)@lock.Scan0, tileBufferSize.Width, tileBufferSize.Height, @lock.Stride); flag = true; } else { BitmapInterpolationMode linear; if (!this.isHighQuality) { linear = BitmapInterpolationMode.Linear; } else if (this.mipLevel == 1) { linear = BitmapInterpolationMode.Linear; } else { linear = BitmapInterpolationMode.Fant; } IImagingFactory instance = ImagingFactory.Instance; ICancellationToken cancelToken = CancellationTokenUtil.Create((Func <bool>)(() => (isCancelled | this.IsTileRenderingCancelled(tileOffset)))); int copyHeightLog2 = Math.Max(3, 7 - this.mipLevel); using (ClippedBitmapSource <ColorBgra32> source2 = new ClippedBitmapSource <ColorBgra32>(this.source, tileSourceRect)) { using (CancellableBitmapSource <ColorBgra32> source3 = new CancellableBitmapSource <ColorBgra32>(source2, r => this.tileMathHelper.EnumerateTilesClippedToSourceRect(r), null, cancelToken)) { using (IBitmapSource <ColorPbgra32> source4 = CreateBufferedTileScaler(instance, source3, tileBufferSize.Width, tileBufferSize.Height, linear)) { using (CancellableBitmapSource <ColorPbgra32> source5 = new CancellableBitmapSource <ColorPbgra32>(source4, r => TileRectSplitter(r, ((int)1) << copyHeightLog2), null, cancelToken)) { try { source5.CopyPixels <ColorPbgra32>(@lock); flag = true; } catch (OperationCanceledException exception2) { error = exception2; isCancelled = true; } catch (Exception exception3) { error = exception3; throw; } } } } } } isCancelled |= this.IsTileRenderingCancelled(tileOffset); if (isCancelled) { flag = false; } } if (!flag) { DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref bitmap); } } } catch (OperationCanceledException exception4) { error = exception4; isCancelled = true; } catch (Exception exception5) { error = exception5; isCancelled |= this.IsTileRenderingCancelled(tileOffset); if (!isCancelled) { using (IDrawingContext context = DrawingContext.FromBitmap(bitmap, FactorySource.PerThread)) { context.Clear(new ColorRgba128Float?((ColorRgba128Float)Colors.White)); string text = exception5.ToString(); using (ISystemFonts fonts = new SystemFonts(true)) { TextLayout textLayout = UIText.CreateLayout(context, text, fonts.Caption, null, HotkeyRenderMode.Ignore, (double)bitmap.Size.Width, 65535.0); textLayout.FontSize *= 0.6; textLayout.WordWrapping = WordWrapping.Wrap; context.DrawTextLayout(PointDouble.Zero, textLayout, SolidColorBrushCache.Get((ColorRgba128Float)Colors.Black), DrawTextOptions.None); } } flag = true; } } } } isCancelled |= this.IsTileRenderingCancelled(tileOffset); if (isCancelled) { DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref bitmap); } RenderedTileInfo info = new RenderedTileInfo(bitmap, !isCancelled && (bitmap > null), error); if (!this.tilesRenderedQueue.TryEnqueue(tileOffset, info)) { ExceptionUtil.ThrowInternalErrorException("Could not enqueue to this.tilesRenderedQueue"); } if (Interlocked.Exchange(ref this.isProcessTileRenderedQueueQueued, 1) == 0) { this.syncContext.Post(this.processTileRenderedQueueCallback); } }