Added initial load page count.

Added cancellation token support for rendering.
This commit is contained in:
DJGosnell 2020-10-12 17:16:40 -04:00
Родитель 7054729986
Коммит 6e618ab1a9
4 изменённых файлов: 66 добавлений и 33 удалений

Просмотреть файл

@ -1,6 +1,7 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using DtronixPdf.Renderer.Dispatcher;
using PDFiumCore;
@ -14,16 +15,18 @@ namespace DtronixPdf.Actions
private readonly RenderFlags _flags;
private readonly Color? _backgroundColor;
private readonly bool _includeAlpha;
private readonly CancellationToken _cancellationToken;
private readonly ThreadDispatcher _dispatcher;
private FpdfBitmapT _bitmap;
public RenderPageAction(
ThreadDispatcher dispatcher,
public RenderPageAction(ThreadDispatcher dispatcher,
FpdfPageT pageInstance,
float scale,
Viewport viewport,
RenderFlags flags,
Color? backgroundColor,
bool includeAlpha)
bool includeAlpha,
CancellationToken cancellationToken)
{
_pageInstance = pageInstance;
_scale = scale;
@ -31,28 +34,36 @@ namespace DtronixPdf.Actions
_flags = flags;
_backgroundColor = backgroundColor;
_includeAlpha = includeAlpha;
_cancellationToken = cancellationToken;
_dispatcher = dispatcher;
}
protected override PdfBitmap OnExecute()
{
var bitmap = fpdfview.FPDFBitmapCreateEx(
(int)_viewport.Size.Width,
(int)_viewport.Size.Height,
(int) (_includeAlpha ? FPDFBitmapFormat.BGRA : FPDFBitmapFormat.BGR) ,
IntPtr.Zero,
0);
if (bitmap == null)
throw new Exception("failed to create a bitmap object");
if(_backgroundColor.HasValue)
fpdfview.FPDFBitmapFillRect(
bitmap, 0, 0, (int)_viewport.Size.Width, (int)_viewport.Size.Height, (uint) _backgroundColor.Value.ToArgb());
try
{
_cancellationToken.ThrowIfCancellationRequested();
_bitmap = fpdfview.FPDFBitmapCreateEx(
(int) _viewport.Size.Width,
(int) _viewport.Size.Height,
(int) (_includeAlpha ? FPDFBitmapFormat.BGRA : FPDFBitmapFormat.BGR),
IntPtr.Zero,
0);
if (_bitmap == null)
throw new Exception("failed to create a bitmap object");
_cancellationToken.ThrowIfCancellationRequested();
if (_backgroundColor.HasValue)
{
fpdfview.FPDFBitmapFillRect(
_bitmap, 0, 0, (int) _viewport.Size.Width, (int) _viewport.Size.Height, (uint) _backgroundColor.Value.ToArgb());
_cancellationToken.ThrowIfCancellationRequested();
}
// | | a b 0 |
// | matrix = | c d 0 |
// | | e f 1 |
@ -89,21 +100,29 @@ namespace DtronixPdf.Actions
clipping.Bottom = 0;
clipping.Top = _viewport.Size.Height;
fpdfview.FPDF_RenderPageBitmapWithMatrix(bitmap, _pageInstance, matrix, clipping, (int) _flags);
fpdfview.FPDF_RenderPageBitmapWithMatrix(_bitmap, _pageInstance, matrix, clipping, (int) _flags);
// Cancellation check;
_cancellationToken.ThrowIfCancellationRequested();
return new PdfBitmap(
bitmap,
(int)_viewport.Size.Width,
(int)_viewport.Size.Height,
_bitmap,
(int) _viewport.Size.Width,
(int) _viewport.Size.Height,
_dispatcher,
_includeAlpha ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb,
_scale,
_viewport);
}
catch (OperationCanceledException)
{
fpdfview.FPDFBitmapDestroy(_bitmap);
throw;
}
catch (Exception ex)
{
fpdfview.FPDFBitmapDestroy(bitmap);
throw new Exception("error rendering page", ex);
fpdfview.FPDFBitmapDestroy(_bitmap);
throw new Exception("Error rendering page. Check inner exception.", ex);
}
}
}

Просмотреть файл

@ -23,8 +23,6 @@ namespace DtronixPdf
public IntPtr Scan0 { get; }
public Bitmap Bitmap { get; }
public float Scale { get; }
public Viewport Viewport { get; }
@ -59,7 +57,11 @@ namespace DtronixPdf
Scale = scale;
Viewport = viewport;
Width = width;
Bitmap = new Bitmap(width, height, Stride, format, Scan0);
}
public Bitmap ToBitmap()
{
return new Bitmap(Width, Height, Stride, Format, Scan0);
}
public async ValueTask DisposeAsync()
@ -68,7 +70,6 @@ namespace DtronixPdf
return;
IsDisposed = true;
Bitmap?.Dispose();
await _dispatcher.QueueForCompletion(() =>
{

Просмотреть файл

@ -17,6 +17,8 @@ namespace DtronixPdf
private static readonly ThreadDispatcher Dispatcher;
public int Pages { get; private set; }
static PdfDocument()
{
Dispatcher = new ThreadDispatcher();
@ -33,14 +35,23 @@ namespace DtronixPdf
public static async Task<PdfDocument> Load(string path, string password)
{
int pages = -1;
var result = await Dispatcher.QueueWithResult(() =>
fpdfview.FPDF_LoadDocument(path, password));
{
var document = fpdfview.FPDF_LoadDocument(path, password);
pages = fpdfview.FPDF_GetPageCount(document);
return document;
});
if (result == null)
return null;
var renderer = new PdfDocument(result);
return renderer;
var pdfDocument = new PdfDocument(result)
{
Pages = pages
};
return pdfDocument;
}
public static async Task<PdfDocument> Create()

Просмотреть файл

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DtronixPdf.Actions;
using DtronixPdf.Renderer.Dispatcher;
@ -95,13 +96,14 @@ namespace DtronixPdf
float scale,
Viewport viewport,
bool alpha,
Color? backgroundColor)
Color? backgroundColor,
CancellationToken cancellationToken)
{
if(viewport.IsEmpty)
throw new ArgumentException("Viewport is empty", nameof(viewport));
return await _dispatcher.QueueWithResult(
new RenderPageAction(_dispatcher, _pageInstance, scale, viewport, flags, backgroundColor, alpha));
new RenderPageAction(_dispatcher, _pageInstance, scale, viewport, flags, backgroundColor, alpha, cancellationToken));
}