Enhanced the PDF/XPS implementation and features

This commit is contained in:
Matthew Leibowitz 2018-11-17 00:55:17 +02:00
Родитель 98948aedc0
Коммит a2f2d35609
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 3650EBE4AA155AF9
4 изменённых файлов: 214 добавлений и 55 удалений

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

@ -554,9 +554,71 @@ namespace SkiaSharp
public sk_string_t Producer;
public SKTimeDateTimeInternal* Creation;
public SKTimeDateTimeInternal* Modified;
public float RasterDPI;
public byte PDFA;
public int EncodingQuality;
}
public struct SKDocumentPdfMetadata {
public const float DefaultRasterDpi = 72.0f;
public const int DefaultEncodingQuality = 101;
public static readonly SKDocumentPdfMetadata Default;
static SKDocumentPdfMetadata ()
{
Default = new SKDocumentPdfMetadata () {
RasterDpi = DefaultRasterDpi,
PdfA = false,
EncodingQuality = 101,
};
}
public SKDocumentPdfMetadata (float rasterDpi)
{
Title = null;
Author = null;
Subject = null;
Keywords = null;
Creator = null;
Producer = null;
Creation = null;
Modified = null;
RasterDpi = rasterDpi;
PdfA = false;
EncodingQuality = DefaultEncodingQuality;
}
public SKDocumentPdfMetadata (int encodingQuality)
{
Title = null;
Author = null;
Subject = null;
Keywords = null;
Creator = null;
Producer = null;
Creation = null;
Modified = null;
RasterDpi = DefaultRasterDpi;
PdfA = false;
EncodingQuality = encodingQuality;
}
public SKDocumentPdfMetadata (float rasterDpi, int encodingQuality)
{
Title = null;
Author = null;
Subject = null;
Keywords = null;
Creator = null;
Producer = null;
Creation = null;
Modified = null;
RasterDpi = rasterDpi;
PdfA = false;
EncodingQuality = encodingQuality;
}
public string Title { get; set; }
public string Author { get; set; }
public string Subject { get; set; }
@ -565,6 +627,9 @@ namespace SkiaSharp
public string Producer { get; set; }
public DateTime? Creation { get; set; }
public DateTime? Modified { get; set; }
public float RasterDpi { get; set; }
public bool PdfA { get; set; }
public int EncodingQuality { get; set; }
}
public enum SKColorSpaceGamut {

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

@ -1,10 +1,11 @@
using System;
using System.IO;
namespace SkiaSharp
{
public class SKDocument : SKObject
{
public const float DefaultRasterDpi = 72.0f;
public const float DefaultRasterDpi = SKDocumentPdfMetadata.DefaultRasterDpi;
[Preserve]
internal SKDocument (IntPtr handle, bool owns)
@ -21,48 +22,53 @@ namespace SkiaSharp
base.Dispose (disposing);
}
public void Abort ()
{
public void Abort () =>
SkiaApi.sk_document_abort (Handle);
}
public SKCanvas BeginPage (float width, float height)
{
return GetObject<SKCanvas> (SkiaApi.sk_document_begin_page (Handle, width, height, IntPtr.Zero), false);
}
public SKCanvas BeginPage (float width, float height) =>
GetObject<SKCanvas> (SkiaApi.sk_document_begin_page (Handle, width, height, IntPtr.Zero), false);
public SKCanvas BeginPage (float width, float height, SKRect content)
{
return GetObject<SKCanvas> (SkiaApi.sk_document_begin_page (Handle, width, height, ref content), false);
}
public SKCanvas BeginPage (float width, float height, SKRect content) =>
GetObject<SKCanvas> (SkiaApi.sk_document_begin_page (Handle, width, height, ref content), false);
public void EndPage ()
{
public void EndPage () =>
SkiaApi.sk_document_end_page (Handle);
}
public void Close ()
{
public void Close () =>
SkiaApi.sk_document_close (Handle);
}
[Obsolete ("Use CreateXps(SKWStream, float) instead.")]
public static SKDocument CreateXps (string path, float dpi = DefaultRasterDpi)
// CreateXps
public static SKDocument CreateXps (string path) =>
CreateXps (path, DefaultRasterDpi);
public static SKDocument CreateXps (Stream stream) =>
CreateXps (stream, DefaultRasterDpi);
public static SKDocument CreateXps (SKWStream stream) =>
CreateXps (stream, DefaultRasterDpi);
public static SKDocument CreateXps (string path, float dpi)
{
if (path == null) {
throw new ArgumentNullException (nameof (path));
}
var stream = SKFileWStream.OpenStream (path);
var doc = CreateXps (stream, dpi);
if (doc != null)
doc.SetDisposeChild (stream);
else
stream.Dispose();
return doc;
return Owned (CreateXps (stream, dpi), stream);
}
public static SKDocument CreateXps (SKWStream stream, float dpi = DefaultRasterDpi)
public static SKDocument CreateXps (Stream stream, float dpi)
{
if (stream == null) {
throw new ArgumentNullException (nameof (stream));
}
var managed = new SKManagedWStream (stream);
return Owned (CreateXps (managed, dpi), managed);
}
public static SKDocument CreateXps (SKWStream stream, float dpi)
{
if (stream == null) {
throw new ArgumentNullException (nameof (stream));
@ -71,26 +77,33 @@ namespace SkiaSharp
return GetObject<SKDocument> (SkiaApi.sk_document_create_xps_from_stream (stream.Handle, dpi));
}
[Obsolete ("Use CreatePdf(SKWStream) instead.")]
public static SKDocument CreatePdf (string path, float dpi = DefaultRasterDpi)
// CreatePdf
[Obsolete ("Use CreatePdf(SKWStream, SKDocumentPdfMetadata) instead.")]
public static SKDocument CreatePdf (SKWStream stream, SKDocumentPdfMetadata metadata, float dpi)
{
metadata.RasterDpi = dpi;
return CreatePdf (stream, metadata);
}
public static SKDocument CreatePdf (string path)
{
if (path == null) {
throw new ArgumentNullException (nameof (path));
}
var stream = SKFileWStream.OpenStream (path);
var doc = CreatePdf (stream, dpi);
if (doc != null)
doc.SetDisposeChild (stream);
else
stream.Dispose();
return doc;
return Owned (CreatePdf (stream), stream);
}
[Obsolete("Use CreatePdf(SKWStream) instead.")]
public static SKDocument CreatePdf (SKWStream stream, float dpi)
public static SKDocument CreatePdf (Stream stream)
{
return CreatePdf (stream);
if (stream == null) {
throw new ArgumentNullException (nameof (stream));
}
var managed = new SKManagedWStream (stream);
return Owned (CreatePdf (managed), managed);
}
public static SKDocument CreatePdf (SKWStream stream)
@ -102,10 +115,33 @@ namespace SkiaSharp
return GetObject<SKDocument> (SkiaApi.sk_document_create_pdf_from_stream (stream.Handle));
}
[Obsolete("Use CreatePdf(SKWStream, SKDocumentPdfMetadata) instead.")]
public static SKDocument CreatePdf (SKWStream stream, SKDocumentPdfMetadata metadata, float dpi)
public static SKDocument CreatePdf (string path, float dpi) =>
CreatePdf (path, new SKDocumentPdfMetadata (dpi));
public static SKDocument CreatePdf (Stream stream, float dpi) =>
CreatePdf (stream, new SKDocumentPdfMetadata (dpi));
public static SKDocument CreatePdf (SKWStream stream, float dpi) =>
CreatePdf (stream, new SKDocumentPdfMetadata (dpi));
public static SKDocument CreatePdf (string path, SKDocumentPdfMetadata metadata)
{
return CreatePdf (stream, metadata);
if (path == null) {
throw new ArgumentNullException (nameof (path));
}
var stream = SKFileWStream.OpenStream (path);
return Owned (CreatePdf (stream, metadata), stream);
}
public static SKDocument CreatePdf (Stream stream, SKDocumentPdfMetadata metadata)
{
if (stream == null) {
throw new ArgumentNullException (nameof (stream));
}
var managed = new SKManagedWStream (stream);
return Owned (CreatePdf (managed, metadata), managed);
}
public static SKDocument CreatePdf (SKWStream stream, SKDocumentPdfMetadata metadata)
@ -127,7 +163,10 @@ namespace SkiaSharp
Subject = subject?.Handle ?? IntPtr.Zero,
Keywords = keywords?.Handle ?? IntPtr.Zero,
Creator = creator?.Handle ?? IntPtr.Zero,
Producer = producer?.Handle ?? IntPtr.Zero
Producer = producer?.Handle ?? IntPtr.Zero,
RasterDPI = metadata.RasterDpi,
PDFA = metadata.PdfA ? (byte)1 : (byte)0,
EncodingQuality = metadata.EncodingQuality,
};
unsafe {
@ -144,6 +183,17 @@ namespace SkiaSharp
}
}
}
}
private static SKDocument Owned (SKDocument doc, SKWStream stream)
{
if (stream != null) {
if (doc != null)
doc.SetDisposeChild (stream);
else
stream.Dispose ();
}
return doc;
}
}
}

2
externals/skia поставляемый

@ -1 +1 @@
Subproject commit 0d23e1f29cf40a90dc281013720b3d76219da9c6
Subproject commit 512ec450f7fa2d7baaf0c8eba768126b09dcf2f7

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

@ -8,7 +8,6 @@ namespace SkiaSharp.Tests
public class SKDocumentTest : SKTest
{
[SkippableFact]
[Obsolete]
public void PdfFileIsClosed()
{
var path = Path.Combine(PathToImages, Guid.NewGuid().ToString("D") + ".pdf");
@ -26,7 +25,6 @@ namespace SkiaSharp.Tests
}
[SkippableFact]
[Obsolete]
public void PdfFileWithNonASCIIPathIsClosed()
{
var path = Path.Combine(PathToImages, Guid.NewGuid().ToString("D") + "上田雅美.pdf");
@ -44,7 +42,6 @@ namespace SkiaSharp.Tests
}
[SkippableFact]
[Obsolete]
public void XpsFileIsClosed()
{
var path = Path.Combine(PathToImages, Guid.NewGuid().ToString("D") + ".xps");
@ -69,9 +66,8 @@ namespace SkiaSharp.Tests
public void CanCreatePdf()
{
using (var stream = new MemoryStream())
using (var managed = new SKManagedWStream(stream, false))
{
using (var doc = SKDocument.CreatePdf(managed))
using (var doc = SKDocument.CreatePdf(stream))
{
Assert.NotNull(doc);
Assert.NotNull(doc.BeginPage(100, 100));
@ -85,16 +81,64 @@ namespace SkiaSharp.Tests
}
}
[SkippableFact]
public void CanCreatePdfWithMetadata()
{
var metadata = SKDocumentPdfMetadata.Default;
metadata.Author = "SkiaSharp Team";
using (var stream = new MemoryStream())
{
using (var doc = SKDocument.CreatePdf(stream, metadata))
{
Assert.NotNull(doc);
Assert.NotNull(doc.BeginPage(100, 100));
doc.EndPage();
doc.Close();
}
Assert.True(stream.Length > 0);
Assert.True(stream.Position > 0);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var contents = reader.ReadToEnd();
Assert.Contains("/Author (SkiaSharp Team)", contents);
}
}
}
[SkippableFact]
public void ManagedStreamDisposeOrder()
{
using (var stream = new MemoryStream())
using (var doc = SKDocument.CreatePdf(stream))
{
Assert.NotNull(doc);
Assert.NotNull(doc.BeginPage(100, 100));
doc.EndPage();
doc.Close();
doc.Dispose();
stream.Flush();
Assert.True(stream.Length > 0);
Assert.True(stream.Position > 0);
}
}
[SkippableFact]
public void CanCreateXps()
{
// XPS is only supported on Windows
using (var stream = new MemoryStream())
using (var managed = new SKManagedWStream(stream, false))
{
using (new SKAutoCoInitialize())
using (var doc = SKDocument.CreateXps(managed))
using (var doc = SKDocument.CreateXps(stream))
{
if (IsWindows)
{