mirror of
https://github.com/wmjordan/PDFPatcher.git
synced 2026-10-19 23:01:48 +08:00
113 lines
2.5 KiB
C#
113 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using PDFPatcher.Common;
|
|
|
|
namespace MuPDF
|
|
{
|
|
public sealed class RenderResultCache : IDisposable
|
|
{
|
|
const int __bufferSize = 10;
|
|
readonly Document _document;
|
|
Dictionary<int, RenderResult> _buffer = new Dictionary<int, RenderResult>(__bufferSize);
|
|
readonly object _SyncObj = new object();
|
|
public object SyncObj => _SyncObj;
|
|
|
|
public RenderResultCache(Document document) {
|
|
_document = document;
|
|
}
|
|
|
|
public Page LoadPage(int pageNumber) {
|
|
if (_buffer.TryGetValue(pageNumber, out var r)) {
|
|
return r.Page;
|
|
}
|
|
var p = _document.LoadPage(pageNumber - 1);
|
|
_buffer.Add(pageNumber, new RenderResult(p));
|
|
return p;
|
|
}
|
|
|
|
public Bitmap GetBitmap(int pageNumber) {
|
|
return TryGetRenderResult(pageNumber, out RenderResult result)
|
|
? result.Image
|
|
: null;
|
|
}
|
|
public TextPage GetTextPage(int pageNumber) {
|
|
return TryGetRenderResult(pageNumber, out RenderResult result)
|
|
? result.TextPage
|
|
: null;
|
|
}
|
|
|
|
bool TryGetRenderResult(int pageNumber, out RenderResult result) {
|
|
result = null;
|
|
return _buffer != null
|
|
&& !_document.IsDisposed
|
|
&& _buffer.TryGetValue(pageNumber, out result);
|
|
}
|
|
|
|
public void SetBitmap(int pageNumber, Bitmap bmp) {
|
|
if (_buffer.TryGetValue(pageNumber, out var image)) {
|
|
image.Image?.Dispose();
|
|
}
|
|
_buffer[pageNumber].Image = bmp;
|
|
TrimBitmapBuffer(pageNumber);
|
|
}
|
|
|
|
public void SetTextPage(int pageNumber, TextPage textPage) {
|
|
if (_buffer.TryGetValue(pageNumber, out var image)) {
|
|
image.TextPage?.Dispose();
|
|
}
|
|
_buffer[pageNumber].TextPage = textPage;
|
|
}
|
|
|
|
void TrimBitmapBuffer(int pageNumber) {
|
|
if (__bufferSize >= _buffer.Count) {
|
|
return;
|
|
}
|
|
|
|
int x = 0;
|
|
int i = 0;
|
|
foreach (var item in _buffer.Keys) {
|
|
if (Math.Abs(item - pageNumber) > x) {
|
|
x = Math.Abs(item - pageNumber);
|
|
i = item;
|
|
}
|
|
}
|
|
_buffer[i].Dispose();
|
|
_buffer.Remove(i);
|
|
}
|
|
|
|
public void Clear() {
|
|
if (!_buffer.HasContent()) {
|
|
return;
|
|
}
|
|
foreach (var item in _buffer) {
|
|
item.Value.Dispose();
|
|
}
|
|
_buffer.Clear();
|
|
}
|
|
|
|
public void Dispose() {
|
|
Clear();
|
|
_buffer = null;
|
|
}
|
|
|
|
sealed class RenderResult : IDisposable
|
|
{
|
|
public Page Page { get; private set; }
|
|
public Bitmap Image { get; internal set; }
|
|
public TextPage TextPage { get; internal set; }
|
|
|
|
public RenderResult(Page page) {
|
|
Page = page;
|
|
}
|
|
|
|
public void Dispose() {
|
|
Page?.Dispose();
|
|
Image?.Dispose();
|
|
TextPage?.Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|