Test
This commit is contained in:
48
PrintPDF/PdfSharp/Pdf.Advanced/IContentStream.cs
Normal file
48
PrintPDF/PdfSharp/Pdf.Advanced/IContentStream.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
internal interface IContentStream
|
||||
{
|
||||
PdfResources Resources { get; }
|
||||
|
||||
string GetFontName(XFont font, out PdfFont pdfFont);
|
||||
|
||||
string GetFontName(string idName, byte[] fontData, out PdfFont pdfFont);
|
||||
|
||||
string GetImageName(XImage image);
|
||||
|
||||
string GetFormName(XForm form);
|
||||
}
|
||||
}
|
230
PrintPDF/PdfSharp/Pdf.Advanced/PdfCIDFont.cs
Normal file
230
PrintPDF/PdfSharp/Pdf.Advanced/PdfCIDFont.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using PdfSharp.Drawing;
|
||||
using PdfSharp.Pdf.Filters;
|
||||
using PdfSharp.Fonts.OpenType;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a CIDFont dictionary.
|
||||
/// </summary>
|
||||
internal class PdfCIDFont : PdfFont
|
||||
{
|
||||
public PdfCIDFont(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
public PdfCIDFont(PdfDocument document, PdfFontDescriptor fontDescriptor, XFont font)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Font");
|
||||
Elements.SetName(Keys.Subtype, "/CIDFontType2");
|
||||
PdfDictionary cid = new PdfDictionary();
|
||||
cid.Elements.SetString("/Ordering", "Identity");
|
||||
cid.Elements.SetString("/Registry", "Adobe");
|
||||
cid.Elements.SetInteger("/Supplement", 0);
|
||||
Elements.SetValue(Keys.CIDSystemInfo, cid);
|
||||
|
||||
FontDescriptor = fontDescriptor;
|
||||
// ReSharper disable once DoNotCallOverridableMethodsInConstructor
|
||||
Owner._irefTable.Add(fontDescriptor);
|
||||
Elements[Keys.FontDescriptor] = fontDescriptor.Reference;
|
||||
|
||||
FontEncoding = font.PdfOptions.FontEncoding;
|
||||
}
|
||||
|
||||
public PdfCIDFont(PdfDocument document, PdfFontDescriptor fontDescriptor, byte[] fontData)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Font");
|
||||
Elements.SetName(Keys.Subtype, "/CIDFontType2");
|
||||
PdfDictionary cid = new PdfDictionary();
|
||||
cid.Elements.SetString("/Ordering", "Identity");
|
||||
cid.Elements.SetString("/Registry", "Adobe");
|
||||
cid.Elements.SetInteger("/Supplement", 0);
|
||||
Elements.SetValue(Keys.CIDSystemInfo, cid);
|
||||
|
||||
FontDescriptor = fontDescriptor;
|
||||
// ReSharper disable once DoNotCallOverridableMethodsInConstructor
|
||||
Owner._irefTable.Add(fontDescriptor);
|
||||
Elements[Keys.FontDescriptor] = fontDescriptor.Reference;
|
||||
|
||||
FontEncoding = PdfFontEncoding.Unicode;
|
||||
}
|
||||
|
||||
public string BaseFont
|
||||
{
|
||||
get { return Elements.GetName(Keys.BaseFont); }
|
||||
set { Elements.SetName(Keys.BaseFont, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the object to get saved.
|
||||
/// </summary>
|
||||
internal override void PrepareForSave()
|
||||
{
|
||||
base.PrepareForSave();
|
||||
|
||||
#if DEBUG_
|
||||
if (FontDescriptor._descriptor.FontFace.loca == null)
|
||||
{
|
||||
GetType();
|
||||
}
|
||||
#endif
|
||||
// CID fonts must be always embedded. PDFsharp embeds automatically a subset.
|
||||
OpenTypeFontface subSet = null;
|
||||
if (FontDescriptor._descriptor.FontFace.loca == null)
|
||||
subSet = FontDescriptor._descriptor.FontFace;
|
||||
else
|
||||
subSet = FontDescriptor._descriptor.FontFace.CreateFontSubSet(_cmapInfo.GlyphIndices, true);
|
||||
byte[] fontData = subSet.FontSource.Bytes;
|
||||
PdfDictionary fontStream = new PdfDictionary(Owner);
|
||||
Owner.Internals.AddObject(fontStream);
|
||||
FontDescriptor.Elements[PdfFontDescriptor.Keys.FontFile2] = fontStream.Reference;
|
||||
|
||||
fontStream.Elements["/Length1"] = new PdfInteger(fontData.Length);
|
||||
if (!Owner.Options.NoCompression)
|
||||
{
|
||||
fontData = Filtering.FlateDecode.Encode(fontData, _document.Options.FlateEncodeMode);
|
||||
fontStream.Elements["/Filter"] = new PdfName("/FlateDecode");
|
||||
}
|
||||
fontStream.Elements["/Length"] = new PdfInteger(fontData.Length);
|
||||
fontStream.CreateStream(fontData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public new sealed class Keys : PdfFont.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be Font for a CIDFont dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Font")]
|
||||
public new const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of CIDFont; CIDFontType0 or CIDFontType2.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string Subtype = "/Subtype";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The PostScript name of the CIDFont. For Type 0 CIDFonts, this
|
||||
/// is usually the value of the CIDFontName entry in the CIDFont program. For
|
||||
/// Type 2 CIDFonts, it is derived the same way as for a simple TrueType font;
|
||||
/// In either case, the name can have a subset prefix if appropriate.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string BaseFont = "/BaseFont";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A dictionary containing entries that define the character collection
|
||||
/// of the CIDFont.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
|
||||
public const string CIDSystemInfo = "/CIDSystemInfo";
|
||||
|
||||
/// <summary>
|
||||
/// (Required; must be an indirect reference) A font descriptor describing the
|
||||
/// CIDFont’s default metrics other than its glyph widths.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.MustBeIndirect, typeof(PdfFontDescriptor))]
|
||||
public new const string FontDescriptor = "/FontDescriptor";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The default width for glyphs in the CIDFont.
|
||||
/// Default value: 1000.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer)]
|
||||
public const string DW = "/DW";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A description of the widths for the glyphs in the CIDFont. The
|
||||
/// array’s elements have a variable format that can specify individual widths
|
||||
/// for consecutive CIDs or one width for a range of CIDs.
|
||||
/// Default value: none (the DW value is used for all glyphs).
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array, typeof(PdfArray))]
|
||||
public const string W = "/W";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; applies only to CIDFonts used for vertical writing) An array of two
|
||||
/// numbers specifying the default metrics for vertical writing.
|
||||
/// Default value: [880 −1000].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array)]
|
||||
public const string DW2 = "/DW2";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; applies only to CIDFonts used for vertical writing) A description
|
||||
/// of the metrics for vertical writing for the glyphs in the CIDFont.
|
||||
/// Default value: none (the DW2 value is used for all glyphs).
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array, typeof(PdfArray))]
|
||||
public const string W2 = "/W2";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; Type 2 CIDFonts only) A specification of the mapping from CIDs
|
||||
/// to glyph indices. If the value is a stream, the bytes in the stream contain the
|
||||
/// mapping from CIDs to glyph indices: the glyph index for a particular CID
|
||||
/// value c is a 2-byte value stored in bytes 2 × c and 2 × c + 1, where the first
|
||||
/// byte is the high-order byte. If the value of CIDToGIDMap is a name, it must
|
||||
/// be Identity, indicating that the mapping between CIDs and glyph indices is
|
||||
/// the identity mapping.
|
||||
/// Default value: Identity.
|
||||
/// This entry may appear only in a Type 2 CIDFont whose associated True-Type font
|
||||
/// program is embedded in the PDF file.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.StreamOrName)]
|
||||
public const string CIDToGIDMap = "/CIDToGIDMap";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
463
PrintPDF/PdfSharp/Pdf.Advanced/PdfCatalog.cs
Normal file
463
PrintPDF/PdfSharp/Pdf.Advanced/PdfCatalog.cs
Normal file
@@ -0,0 +1,463 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using PdfSharp.Pdf.IO;
|
||||
using PdfSharp.Pdf.AcroForms;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the catalog dictionary.
|
||||
/// </summary>
|
||||
public sealed class PdfCatalog : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfCatalog"/> class.
|
||||
/// </summary>
|
||||
public PdfCatalog(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Catalog");
|
||||
|
||||
_version = "1.4"; // HACK in PdfCatalog
|
||||
}
|
||||
|
||||
internal PdfCatalog(PdfDictionary dictionary)
|
||||
: base(dictionary)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Get or sets the version of the PDF specification to which the document conforms.
|
||||
/// </summary>
|
||||
public string Version
|
||||
{
|
||||
get { return _version; }
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case "1.0":
|
||||
case "1.1":
|
||||
case "1.2":
|
||||
throw new InvalidOperationException("Unsupported PDF version.");
|
||||
|
||||
case "1.3":
|
||||
case "1.4":
|
||||
_version = value;
|
||||
break;
|
||||
|
||||
case "1.5":
|
||||
case "1.6":
|
||||
throw new InvalidOperationException("Unsupported PDF version.");
|
||||
|
||||
default:
|
||||
throw new ArgumentException("Invalid version.");
|
||||
}
|
||||
}
|
||||
}
|
||||
string _version = "1.3";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pages collection of this document.
|
||||
/// </summary>
|
||||
public PdfPages Pages
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pages == null)
|
||||
{
|
||||
_pages = (PdfPages)Elements.GetValue(Keys.Pages, VCF.CreateIndirect);
|
||||
if (Owner.IsImported)
|
||||
_pages.FlattenPageTree();
|
||||
}
|
||||
return _pages;
|
||||
}
|
||||
}
|
||||
PdfPages _pages;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of PdfDocument.PageLayout.
|
||||
/// </summary>
|
||||
internal PdfPageLayout PageLayout
|
||||
{
|
||||
get { return (PdfPageLayout)Elements.GetEnumFromName(Keys.PageLayout, PdfPageLayout.SinglePage); }
|
||||
set { Elements.SetEnumAsName(Keys.PageLayout, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of PdfDocument.PageMode.
|
||||
/// </summary>
|
||||
internal PdfPageMode PageMode
|
||||
{
|
||||
get { return (PdfPageMode)Elements.GetEnumFromName(Keys.PageMode, PdfPageMode.UseNone); }
|
||||
set { Elements.SetEnumAsName(Keys.PageMode, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of PdfDocument.ViewerPreferences.
|
||||
/// </summary>
|
||||
internal PdfViewerPreferences ViewerPreferences
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_viewerPreferences == null)
|
||||
_viewerPreferences = (PdfViewerPreferences)Elements.GetValue(Keys.ViewerPreferences, VCF.CreateIndirect);
|
||||
return _viewerPreferences;
|
||||
}
|
||||
}
|
||||
PdfViewerPreferences _viewerPreferences;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of PdfDocument.Outlines.
|
||||
/// </summary>
|
||||
internal PdfOutlineCollection Outlines
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_outline == null)
|
||||
{
|
||||
////// Ensure that the page tree exists.
|
||||
////// ReSharper disable once UnusedVariable because we need dummy to call the getter.
|
||||
////PdfPages dummy = Pages;
|
||||
|
||||
// Now create the outline item tree.
|
||||
_outline = (PdfOutline)Elements.GetValue(Keys.Outlines, VCF.CreateIndirect);
|
||||
}
|
||||
return _outline.Outlines;
|
||||
}
|
||||
}
|
||||
PdfOutline _outline;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AcroForm dictionary of this document.
|
||||
/// </summary>
|
||||
public PdfAcroForm AcroForm
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_acroForm == null)
|
||||
_acroForm = (PdfAcroForm)Elements.GetValue(Keys.AcroForm);
|
||||
return _acroForm;
|
||||
}
|
||||
}
|
||||
PdfAcroForm _acroForm;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the language identifier specifying the natural language for all text in the document.
|
||||
/// Sample values are 'en-US' for 'English United States' or 'de-DE' for 'deutsch Deutschland' (i.e. 'German Germany').
|
||||
/// </summary>
|
||||
public string Language
|
||||
{
|
||||
get { return Elements.GetString(Keys.Lang); }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
Elements.Remove(Keys.Lang);
|
||||
else
|
||||
Elements.SetString(Keys.Lang, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches PrepareForSave to the objects that need it.
|
||||
/// </summary>
|
||||
internal override void PrepareForSave()
|
||||
{
|
||||
// Prepare pages.
|
||||
if (_pages != null)
|
||||
_pages.PrepareForSave();
|
||||
|
||||
// Create outline objects.
|
||||
if (_outline != null && _outline.Outlines.Count > 0)
|
||||
{
|
||||
if (Elements[Keys.PageMode] == null)
|
||||
PageMode = PdfPageMode.UseOutlines;
|
||||
_outline.PrepareForSave();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteObject(PdfWriter writer)
|
||||
{
|
||||
if (_outline != null && _outline.Outlines.Count > 0)
|
||||
{
|
||||
if (Elements[Keys.PageMode] == null)
|
||||
PageMode = PdfPageMode.UseOutlines;
|
||||
}
|
||||
base.WriteObject(writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
internal sealed class Keys : KeysBase
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be Catalog for the catalog dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Catalog")]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) The version of the PDF specification to which the document
|
||||
/// conforms (for example, 1.4) if later than the version specified in the file<6C>s header.
|
||||
/// If the header specifies a later version, or if this entry is absent, the document
|
||||
/// conforms to the version specified in the header. This entry enables a PDF producer
|
||||
/// application to update the version using an incremental update.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.Name | KeyType.Optional)]
|
||||
public const string Version = "/Version";
|
||||
|
||||
/// <summary>
|
||||
/// (Required; must be an indirect reference) The page tree node that is the root of
|
||||
/// the document<6E>s page tree.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Required | KeyType.MustBeIndirect, typeof(PdfPages))]
|
||||
public const string Pages = "/Pages";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) A number tree defining the page labeling for the document.
|
||||
/// The keys in this tree are page indices; the corresponding values are page label dictionaries.
|
||||
/// Each page index denotes the first page in a labeling range to which the specified page
|
||||
/// label dictionary applies. The tree must include a value for pageindex 0.
|
||||
/// </summary>
|
||||
[KeyInfo("1.3", KeyType.NumberTree | KeyType.Optional)]
|
||||
public const string PageLabels = "/PageLabels";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) The document<6E>s name dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo("1.2", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string Names = "/Names";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.1; must be an indirect reference) A dictionary of names and
|
||||
/// corresponding destinations.
|
||||
/// </summary>
|
||||
[KeyInfo("1.1", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string Dests = "/Dests";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) A viewer preferences dictionary specifying the way the document
|
||||
/// is to be displayed on the screen. If this entry is absent, applications should use
|
||||
/// their own current user preference settings.
|
||||
/// </summary>
|
||||
[KeyInfo("1.2", KeyType.Dictionary | KeyType.Optional, typeof(PdfViewerPreferences))]
|
||||
public const string ViewerPreferences = "/ViewerPreferences";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A name object specifying the page layout to be used when the document is
|
||||
/// opened:
|
||||
/// SinglePage - Display one page at a time.
|
||||
/// OneColumn - Display the pages in one column.
|
||||
/// TwoColumnLeft - Display the pages in two columns, with oddnumbered pages on the left.
|
||||
/// TwoColumnRight - Display the pages in two columns, with oddnumbered pages on the right.
|
||||
/// TwoPageLeft - (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left
|
||||
/// TwoPageRight - (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string PageLayout = "/PageLayout";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A name object specifying how the document should be displayed when opened:
|
||||
/// UseNone - Neither document outline nor thumbnail images visible.
|
||||
/// UseOutlines - Document outline visible.
|
||||
/// UseThumbs - Thumbnail images visible.
|
||||
/// FullScreen - Full-screen mode, with no menu bar, windowcontrols, or any other window visible.
|
||||
/// UseOC - (PDF 1.5) Optional content group panel visible.
|
||||
/// UseAttachments (PDF 1.6) Attachments panel visible.
|
||||
/// Default value: UseNone.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string PageMode = "/PageMode";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; must be an indirect reference) The outline dictionary that is the root
|
||||
/// of the document<6E>s outline hierarchy.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfOutline))]
|
||||
public const string Outlines = "/Outlines";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.1; must be an indirect reference) An array of thread dictionaries
|
||||
/// representing the document<6E>s article threads.
|
||||
/// </summary>
|
||||
[KeyInfo("1.1", KeyType.Array | KeyType.Optional)]
|
||||
public const string Threads = "/Threads";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.1) A value specifying a destination to be displayed or an action to be
|
||||
/// performed when the document is opened. The value is either an array defining a destination
|
||||
/// or an action dictionary representing an action. If this entry is absent, the document
|
||||
/// should be opened to the top of the first page at the default magnification factor.
|
||||
/// </summary>
|
||||
[KeyInfo("1.1", KeyType.ArrayOrDictionary | KeyType.Optional)]
|
||||
public const string OpenAction = "/OpenAction";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) An additional-actions dictionary defining the actions to be taken
|
||||
/// in response to various trigger events affecting the document as a whole.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string AA = "/AA";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.1) A URI dictionary containing document-level information for URI
|
||||
/// (uniform resource identifier) actions.
|
||||
/// </summary>
|
||||
[KeyInfo("1.1", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string URI = "/URI";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) The document<6E>s interactive form (AcroForm) dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo("1.2", KeyType.Dictionary | KeyType.Optional, typeof(PdfAcroForm))]
|
||||
public const string AcroForm = "/AcroForm";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4; must be an indirect reference) A metadata stream
|
||||
/// containing metadata for the document.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.Dictionary | KeyType.Optional | KeyType.MustBeIndirect)]
|
||||
public const string Metadata = "/Metadata";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The document<6E>s structure tree root dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo("1.3", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string StructTreeRoot = "/StructTreeRoot";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) A mark information dictionary containing information
|
||||
/// about the document<6E>s usage of Tagged PDF conventions.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string MarkInfo = "/MarkInfo";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) A language identifier specifying the natural language for all
|
||||
/// text in the document except where overridden by language specifications for structure
|
||||
/// elements or marked content. If this entry is absent, the language is considered unknown.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.String | KeyType.Optional)]
|
||||
public const string Lang = "/Lang";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) A Web Capture information dictionary containing state information
|
||||
/// used by the Acrobat Web Capture (AcroSpider) plugin extension.
|
||||
/// </summary>
|
||||
[KeyInfo("1.3", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string SpiderInfo = "/SpiderInfo";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) An array of output intent dictionaries describing the color
|
||||
/// characteristics of output devices on which the document might be rendered.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.Array | KeyType.Optional)]
|
||||
public const string OutputIntents = "/OutputIntents";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) A page-piece dictionary associated with the document.
|
||||
/// </summary>
|
||||
[KeyInfo("1.4", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string PieceInfo = "/PieceInfo";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.5; required if a document contains optional content) The document<6E>s
|
||||
/// optional content properties dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo("1.5", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string OCProperties = "/OCProperties";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.5) A permissions dictionary that specifies user access permissions
|
||||
/// for the document.
|
||||
/// </summary>
|
||||
[KeyInfo("1.5", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string Perms = "/Perms";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.5) A dictionary containing attestations regarding the content of a
|
||||
/// PDF document, as it relates to the legality of digital signatures.
|
||||
/// </summary>
|
||||
[KeyInfo("1.5", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string Legal = "/Legal";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.7) An array of requirement dictionaries representing
|
||||
/// requirements for the document.
|
||||
/// </summary>
|
||||
[KeyInfo("1.7", KeyType.Array | KeyType.Optional)]
|
||||
public const string Requirements = "/Requirements";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.7) A collection dictionary that a PDF consumer uses to enhance
|
||||
/// the presentation of file attachments stored in the PDF document.
|
||||
/// </summary>
|
||||
[KeyInfo("1.7", KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string Collection = "/Collection";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.7) A flag used to expedite the display of PDF documents containing XFA forms.
|
||||
/// It specifies whether the document must be regenerated when the document is first opened.
|
||||
/// If true, the viewer application treats the document as a shell and regenerates the content
|
||||
/// when the document is opened, regardless of any dynamic forms settings that appear in the XFA
|
||||
/// stream itself. This setting is used to expedite the display of documents whose layout varies
|
||||
/// depending on the content of the XFA streams.
|
||||
/// If false, the viewer application does not regenerate the content when the document is opened.
|
||||
/// See the XML Forms Architecture (XFA) Specification (Bibliography).
|
||||
/// Default value: false.
|
||||
/// </summary>
|
||||
[KeyInfo("1.7", KeyType.Boolean | KeyType.Optional)]
|
||||
public const string NeedsRendering = "/NeedsRendering";
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
public static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
192
PrintPDF/PdfSharp/Pdf.Advanced/PdfContent.cs
Normal file
192
PrintPDF/PdfSharp/Pdf.Advanced/PdfContent.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using PdfSharp.Drawing.Pdf;
|
||||
using PdfSharp.Pdf.Filters;
|
||||
using PdfSharp.Pdf.IO;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the content of a page. PDFsharp supports only one content stream per page.
|
||||
/// If an imported page has an array of content streams, the streams are concatenated to
|
||||
/// one single stream.
|
||||
/// </summary>
|
||||
public sealed class PdfContent : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfContent"/> class.
|
||||
/// </summary>
|
||||
public PdfContent(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfContent"/> class.
|
||||
/// </summary>
|
||||
internal PdfContent(PdfPage page)
|
||||
: base(page != null ? page.Owner : null)
|
||||
{
|
||||
//_pageContent = new PageContent(page);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfContent"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dict">The dict.</param>
|
||||
public PdfContent(PdfDictionary dict) // HACK PdfContent
|
||||
: base(dict)
|
||||
{
|
||||
// A PdfContent dictionary is always unfiltered.
|
||||
Decode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a value indicating whether the content is compressed with the ZIP algorithm.
|
||||
/// </summary>
|
||||
public bool Compressed
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
PdfItem filter = Elements["/Filter"];
|
||||
if (filter == null)
|
||||
{
|
||||
byte[] bytes = Filtering.FlateDecode.Encode(Stream.Value, _document.Options.FlateEncodeMode);
|
||||
Stream.Value = bytes;
|
||||
Elements.SetInteger("/Length", Stream.Length);
|
||||
Elements.SetName("/Filter", "/FlateDecode");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unfilters the stream.
|
||||
/// </summary>
|
||||
void Decode()
|
||||
{
|
||||
if (Stream != null && Stream.Value != null)
|
||||
{
|
||||
PdfItem item = Elements["/Filter"];
|
||||
if (item != null)
|
||||
{
|
||||
byte[] bytes = Filtering.Decode(Stream.Value, item);
|
||||
if (bytes != null)
|
||||
{
|
||||
Stream.Value = bytes;
|
||||
Elements.Remove("/Filter");
|
||||
Elements.SetInteger("/Length", Stream.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Surround content with q/Q operations if necessary.
|
||||
/// </summary>
|
||||
internal void PreserveGraphicsState()
|
||||
{
|
||||
// If a content stream is touched by PDFsharp it is typically because graphical operations are
|
||||
// prepended or appended. Some nasty PDF tools does not preserve the graphical state correctly.
|
||||
// Therefore we try to relieve the problem by surrounding the content stream with push/restore
|
||||
// graphic state operation.
|
||||
if (Stream != null)
|
||||
{
|
||||
byte[] value = Stream.Value;
|
||||
int length = value.Length;
|
||||
if (length != 0 && ((value[0] != (byte)'q' || value[1] != (byte)'\n')))
|
||||
{
|
||||
byte[] newValue = new byte[length + 2 + 3];
|
||||
newValue[0] = (byte)'q';
|
||||
newValue[1] = (byte)'\n';
|
||||
Array.Copy(value, 0, newValue, 2, length);
|
||||
newValue[length + 2] = (byte)' ';
|
||||
newValue[length + 3] = (byte)'Q';
|
||||
newValue[length + 4] = (byte)'\n';
|
||||
Stream.Value = newValue;
|
||||
Elements.SetInteger("/Length", Stream.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteObject(PdfWriter writer)
|
||||
{
|
||||
if (_pdfRenderer != null)
|
||||
{
|
||||
// GetContent also disposes the underlying XGraphics object, if one exists
|
||||
//Stream = new PdfStream(PdfEncoders.RawEncoding.GetBytes(pdfRenderer.GetContent()), this);
|
||||
_pdfRenderer.Close();
|
||||
Debug.Assert(_pdfRenderer == null);
|
||||
}
|
||||
|
||||
if (Stream != null)
|
||||
{
|
||||
//if (Owner.Options.CompressContentStreams)
|
||||
if (Owner.Options.CompressContentStreams && Elements.GetName("/Filter").Length == 0)
|
||||
{
|
||||
Stream.Value = Filtering.FlateDecode.Encode(Stream.Value, _document.Options.FlateEncodeMode);
|
||||
//Elements["/Filter"] = new PdfName("/FlateDecode");
|
||||
Elements.SetName("/Filter", "/FlateDecode");
|
||||
}
|
||||
Elements.SetInteger("/Length", Stream.Length);
|
||||
}
|
||||
|
||||
base.WriteObject(writer);
|
||||
}
|
||||
|
||||
internal XGraphicsPdfRenderer _pdfRenderer;
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
internal sealed class Keys : PdfStream.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
public static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
267
PrintPDF/PdfSharp/Pdf.Advanced/PdfContents.cs
Normal file
267
PrintPDF/PdfSharp/Pdf.Advanced/PdfContents.cs
Normal file
@@ -0,0 +1,267 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using PdfSharp.Pdf.Content.Objects;
|
||||
using PdfSharp.Pdf.IO;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an array of PDF content streams of a page.
|
||||
/// </summary>
|
||||
public sealed class PdfContents : PdfArray
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfContents"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">The document.</param>
|
||||
public PdfContents(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
internal PdfContents(PdfArray array)
|
||||
: base(array)
|
||||
{
|
||||
int count = Elements.Count;
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
// Convert the references from PdfDictionary to PdfContent
|
||||
PdfItem item = Elements[idx];
|
||||
PdfReference iref = item as PdfReference;
|
||||
if (iref != null && iref.Value is PdfDictionary)
|
||||
{
|
||||
// The following line is correct!
|
||||
new PdfContent((PdfDictionary)iref.Value);
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException("Unexpected item in a content stream array.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a new content stream and returns it.
|
||||
/// </summary>
|
||||
public PdfContent AppendContent()
|
||||
{
|
||||
Debug.Assert(Owner != null);
|
||||
|
||||
SetModified();
|
||||
PdfContent content = new PdfContent(Owner);
|
||||
Owner._irefTable.Add(content);
|
||||
Debug.Assert(content.Reference != null);
|
||||
Elements.Add(content.Reference);
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepends a new content stream and returns it.
|
||||
/// </summary>
|
||||
public PdfContent PrependContent()
|
||||
{
|
||||
Debug.Assert(Owner != null);
|
||||
|
||||
SetModified();
|
||||
PdfContent content = new PdfContent(Owner);
|
||||
Owner._irefTable.Add(content);
|
||||
Debug.Assert(content.Reference != null);
|
||||
Elements.Insert(0, content.Reference);
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a single content stream with the bytes from the array of the content streams.
|
||||
/// This operation does not modify any of the content streams in this array.
|
||||
/// </summary>
|
||||
public PdfContent CreateSingleContent()
|
||||
{
|
||||
byte[] bytes = new byte[0];
|
||||
byte[] bytes1;
|
||||
byte[] bytes2;
|
||||
foreach (PdfItem iref in Elements)
|
||||
{
|
||||
PdfDictionary cont = (PdfDictionary)((PdfReference)iref).Value;
|
||||
bytes1 = bytes;
|
||||
bytes2 = cont.Stream.UnfilteredValue;
|
||||
bytes = new byte[bytes1.Length + bytes2.Length + 1];
|
||||
bytes1.CopyTo(bytes, 0);
|
||||
bytes[bytes1.Length] = (byte)'\n';
|
||||
bytes2.CopyTo(bytes, bytes1.Length + 1);
|
||||
}
|
||||
PdfContent content = new PdfContent(Owner);
|
||||
content.Stream = new PdfDictionary.PdfStream(bytes, content);
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the current content of the page with the specified content sequence.
|
||||
/// </summary>
|
||||
public PdfContent ReplaceContent(CSequence cseq)
|
||||
{
|
||||
if (cseq == null)
|
||||
throw new ArgumentNullException(nameof(cseq));
|
||||
|
||||
return ReplaceContent(cseq.ToContent());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the current content of the page with the specified bytes.
|
||||
/// </summary>
|
||||
PdfContent ReplaceContent(byte[] contentBytes)
|
||||
{
|
||||
Debug.Assert(Owner != null);
|
||||
|
||||
PdfContent content = new PdfContent(Owner);
|
||||
|
||||
content.CreateStream(contentBytes);
|
||||
|
||||
Owner._irefTable.Add(content);
|
||||
Elements.Clear();
|
||||
Elements.Add(content.Reference);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
void SetModified()
|
||||
{
|
||||
if (!_modified)
|
||||
{
|
||||
_modified = true;
|
||||
int count = Elements.Count;
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
PdfContent content = (PdfContent)((PdfReference)Elements[0]).Value;
|
||||
content.PreserveGraphicsState();
|
||||
}
|
||||
else if (count > 1)
|
||||
{
|
||||
// Surround content streams with q/Q operations
|
||||
byte[] value;
|
||||
int length;
|
||||
PdfContent content = (PdfContent)((PdfReference)Elements[0]).Value;
|
||||
if (content != null && content.Stream != null)
|
||||
{
|
||||
length = content.Stream.Length;
|
||||
value = new byte[length + 2];
|
||||
value[0] = (byte)'q';
|
||||
value[1] = (byte)'\n';
|
||||
Array.Copy(content.Stream.Value, 0, value, 2, length);
|
||||
content.Stream.Value = value;
|
||||
content.Elements.SetInteger("/Length", length + 2);
|
||||
}
|
||||
content = (PdfContent)((PdfReference)Elements[count - 1]).Value;
|
||||
if (content != null && content.Stream != null)
|
||||
{
|
||||
length = content.Stream.Length;
|
||||
value = new byte[length + 3];
|
||||
Array.Copy(content.Stream.Value, 0, value, 0, length);
|
||||
value[length] = (byte)' ';
|
||||
value[length + 1] = (byte)'Q';
|
||||
value[length + 2] = (byte)'\n';
|
||||
content.Stream.Value = value;
|
||||
content.Elements.SetInteger("/Length", length + 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool _modified;
|
||||
|
||||
internal override void WriteObject(PdfWriter writer)
|
||||
{
|
||||
// Save two bytes in PDF stream...
|
||||
if (Elements.Count == 1)
|
||||
Elements[0].WriteObject(writer);
|
||||
else
|
||||
base.WriteObject(writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the enumerator.
|
||||
/// </summary>
|
||||
public new IEnumerator<PdfContent> GetEnumerator()
|
||||
{
|
||||
return new PdfPageContentEnumerator(this);
|
||||
}
|
||||
|
||||
class PdfPageContentEnumerator : IEnumerator<PdfContent>
|
||||
{
|
||||
internal PdfPageContentEnumerator(PdfContents list)
|
||||
{
|
||||
_contents = list;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_index < _contents.Elements.Count - 1)
|
||||
{
|
||||
_index++;
|
||||
_currentElement = (PdfContent)((PdfReference)_contents.Elements[_index]).Value;
|
||||
return true;
|
||||
}
|
||||
_index = _contents.Elements.Count;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_currentElement = null;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get { return Current; }
|
||||
}
|
||||
|
||||
public PdfContent Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_index == -1 || _index >= _contents.Elements.Count)
|
||||
throw new InvalidOperationException(PSSR.ListEnumCurrentOutOfRange);
|
||||
return _currentElement;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
PdfContent _currentElement;
|
||||
int _index;
|
||||
readonly PdfContents _contents;
|
||||
}
|
||||
}
|
||||
}
|
157
PrintPDF/PdfSharp/Pdf.Advanced/PdfCrossReferenceStream.cs
Normal file
157
PrintPDF/PdfSharp/Pdf.Advanced/PdfCrossReferenceStream.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF cross-reference stream.
|
||||
/// </summary>
|
||||
internal sealed class PdfCrossReferenceStream : PdfTrailer // Reference: 3.4.7 Cross-Reference Streams / Page 106
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfObjectStream"/> class.
|
||||
/// </summary>
|
||||
public PdfCrossReferenceStream(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
#if DEBUG && CORE
|
||||
if (Internal.PdfDiagnostics.TraceXrefStreams)
|
||||
{
|
||||
Debug.WriteLine("PdfCrossReferenceStream created.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public readonly List<CrossReferenceStreamEntry> Entries = new List<CrossReferenceStreamEntry>();
|
||||
|
||||
public struct CrossReferenceStreamEntry
|
||||
{
|
||||
// Reference: TABLE 3.16 Entries in a cross-reference stream / Page 109
|
||||
|
||||
public uint Type; // 0, 1, or 2.
|
||||
|
||||
public uint Field2;
|
||||
|
||||
public uint Field3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys for cross-reference dictionaries.
|
||||
/// </summary>
|
||||
public new class Keys : PdfTrailer.Keys // Reference: TABLE 3.15 Additional entries specific to a cross-reference stream dictionary / Page 107
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be XRef for a cross-reference stream.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "XRef")]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The number one greater than the highest object number
|
||||
/// used in this section or in any section for which this is an update.
|
||||
/// It is equivalent to the Size entry in a trailer dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public new const string Size = "/Size";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array containing a pair of integers for each subsection in this section.
|
||||
/// The first integer is the first object number in the subsection; the second integer
|
||||
/// is the number of entries in the subsection.
|
||||
/// The array is sorted in ascending order by object number. Subsections cannot overlap;
|
||||
/// an object number may have at most one entry in a section.
|
||||
/// Default value: [0 Size].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Index = "/Index";
|
||||
|
||||
/// <summary>
|
||||
/// (Present only if the file has more than one cross-reference stream; not meaningful in
|
||||
/// hybrid-reference files) The byte offset from the beginning of the file to the beginning
|
||||
/// of the previous cross-reference stream. This entry has the same function as the Prev
|
||||
/// entry in the trailer dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public new const string Prev = "/Prev";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) An array of integers representing the size of the fields in a single
|
||||
/// cross-reference entry. The table describes the types of entries and their fields.
|
||||
/// For PDF 1.5, W always contains three integers; the value of each integer is the
|
||||
/// number of bytes (in the decoded stream) of the corresponding field. For example,
|
||||
/// [1 2 1] means that the fields are one byte, two bytes, and one byte, respectively.
|
||||
///
|
||||
/// A value of zero for an element in the W array indicates that the corresponding field
|
||||
/// is not present in the stream, and the default value is used, if there is one. If the
|
||||
/// first element is zero, the type field is not present, and it defaults to type 1.
|
||||
///
|
||||
/// The sum of the items is the total length of each entry; it can be used with the
|
||||
/// Indexarray to determine the starting position of each subsection.
|
||||
///
|
||||
/// Note: Different cross-reference streams in a PDF file may use different values for W.
|
||||
///
|
||||
/// Entries in a cross-reference stream.
|
||||
///
|
||||
/// TYPE FIELD DESCRIPTION
|
||||
/// 0 1 The type of this entry, which must be 0. Type 0 entries define the linked list of free objects (corresponding to f entries in a cross-reference table).
|
||||
/// 2 The object number of the next free object.
|
||||
/// 3 The generation number to use if this object number is used again.
|
||||
/// 1 1 The type of this entry, which must be 1. Type 1 entries define objects that are in use but are not compressed (corresponding to n entries in a cross-reference table).
|
||||
/// 2 The byte offset of the object, starting from the beginning of the file.
|
||||
/// 3 The generation number of the object. Default value: 0.
|
||||
/// 2 1 The type of this entry, which must be 2. Type 2 entries define compressed objects.
|
||||
/// 2 The object number of the object stream in which this object is stored. (The generation number of the object stream is implicitly 0.)
|
||||
/// 3 The index of this object within the object stream.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Required)]
|
||||
public const string W = "/W";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
public static new DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
590
PrintPDF/PdfSharp/Pdf.Advanced/PdfCrossReferenceTable.cs
Normal file
590
PrintPDF/PdfSharp/Pdf.Advanced/PdfCrossReferenceTable.cs
Normal file
@@ -0,0 +1,590 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using PdfSharp.Pdf.IO;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the cross-reference table of a PDF document.
|
||||
/// It contains all indirect objects of a document.
|
||||
/// </summary>
|
||||
internal sealed class PdfCrossReferenceTable // Must not be derive from PdfObject.
|
||||
{
|
||||
public PdfCrossReferenceTable(PdfDocument document)
|
||||
{
|
||||
_document = document;
|
||||
}
|
||||
readonly PdfDocument _document;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the relation between PdfObjectID and PdfReference for a PdfDocument.
|
||||
/// </summary>
|
||||
public Dictionary<PdfObjectID, PdfReference> ObjectTable = new Dictionary<PdfObjectID, PdfReference>();
|
||||
|
||||
internal bool IsUnderConstruction
|
||||
{
|
||||
get { return _isUnderConstruction; }
|
||||
set { _isUnderConstruction = value; }
|
||||
}
|
||||
bool _isUnderConstruction;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a cross reference entry to the table. Used when parsing the trailer.
|
||||
/// </summary>
|
||||
public void Add(PdfReference iref)
|
||||
{
|
||||
#if DEBUG
|
||||
if (iref.ObjectID.ObjectNumber == 948)
|
||||
GetType();
|
||||
#endif
|
||||
if (iref.ObjectID.IsEmpty)
|
||||
iref.ObjectID = new PdfObjectID(GetNewObjectNumber());
|
||||
|
||||
if (ObjectTable.ContainsKey(iref.ObjectID))
|
||||
throw new InvalidOperationException("Object already in table.");
|
||||
|
||||
ObjectTable.Add(iref.ObjectID, iref);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a PdfObject to the table.
|
||||
/// </summary>
|
||||
public void Add(PdfObject value)
|
||||
{
|
||||
if (value.Owner == null)
|
||||
value.Document = _document;
|
||||
else
|
||||
Debug.Assert(value.Owner == _document);
|
||||
|
||||
if (value.ObjectID.IsEmpty)
|
||||
value.SetObjectID(GetNewObjectNumber(), 0);
|
||||
|
||||
if (ObjectTable.ContainsKey(value.ObjectID))
|
||||
throw new InvalidOperationException("Object already in table.");
|
||||
|
||||
ObjectTable.Add(value.ObjectID, value.Reference);
|
||||
}
|
||||
|
||||
public void Remove(PdfReference iref)
|
||||
{
|
||||
ObjectTable.Remove(iref.ObjectID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a cross reference entry from an object identifier.
|
||||
/// Returns null if no object with the specified ID exists in the object table.
|
||||
/// </summary>
|
||||
public PdfReference this[PdfObjectID objectID]
|
||||
{
|
||||
get
|
||||
{
|
||||
PdfReference iref;
|
||||
ObjectTable.TryGetValue(objectID, out iref);
|
||||
return iref;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the specified object identifier is in the table.
|
||||
/// </summary>
|
||||
public bool Contains(PdfObjectID objectID)
|
||||
{
|
||||
return ObjectTable.ContainsKey(objectID);
|
||||
}
|
||||
|
||||
//public PdfObject GetObject(PdfObjectID objectID)
|
||||
//{
|
||||
// return this[objectID].Value;
|
||||
//}
|
||||
|
||||
// /// <summary>
|
||||
// /// Gets the entry for the specified object, or null, if the object is not in
|
||||
// /// this XRef table.
|
||||
// /// </summary>
|
||||
// internal PdfReference GetEntry(PdfObjectID objectID)
|
||||
// {
|
||||
// return this[objectID];
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next free object number.
|
||||
/// </summary>
|
||||
public int GetNewObjectNumber()
|
||||
{
|
||||
// New objects are numbered consecutively. If a document is imported, maxObjectNumber is
|
||||
// set to the highest object number used in the document.
|
||||
return ++_maxObjectNumber;
|
||||
}
|
||||
internal int _maxObjectNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Writes the xref section in pdf stream.
|
||||
/// </summary>
|
||||
internal void WriteObject(PdfWriter writer)
|
||||
{
|
||||
writer.WriteRaw("xref\n");
|
||||
|
||||
PdfReference[] irefs = AllReferences;
|
||||
|
||||
int count = irefs.Length;
|
||||
writer.WriteRaw(String.Format("0 {0}\n", count + 1));
|
||||
writer.WriteRaw(String.Format("{0:0000000000} {1:00000} {2} \n", 0, 65535, "f"));
|
||||
//PdfEncoders.WriteAnsi(stream, text);
|
||||
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
PdfReference iref = irefs[idx];
|
||||
|
||||
// Acrobat is very pedantic; it must be exactly 20 bytes per line.
|
||||
writer.WriteRaw(String.Format("{0:0000000000} {1:00000} {2} \n", iref.Position, iref.GenerationNumber, "n"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of all object identifiers. For debugging purposes only.
|
||||
/// </summary>
|
||||
internal PdfObjectID[] AllObjectIDs
|
||||
{
|
||||
get
|
||||
{
|
||||
ICollection collection = ObjectTable.Keys;
|
||||
PdfObjectID[] objectIDs = new PdfObjectID[collection.Count];
|
||||
collection.CopyTo(objectIDs, 0);
|
||||
return objectIDs;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of all cross references in ascending order by their object identifier.
|
||||
/// </summary>
|
||||
internal PdfReference[] AllReferences
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<PdfObjectID, PdfReference>.ValueCollection collection = ObjectTable.Values;
|
||||
List<PdfReference> list = new List<PdfReference>(collection);
|
||||
list.Sort(PdfReference.Comparer);
|
||||
PdfReference[] irefs = new PdfReference[collection.Count];
|
||||
list.CopyTo(irefs, 0);
|
||||
return irefs;
|
||||
}
|
||||
}
|
||||
|
||||
internal void HandleOrphanedReferences()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Removes all objects that cannot be reached from the trailer.
|
||||
/// Returns the number of removed objects.
|
||||
/// </summary>
|
||||
internal int Compact()
|
||||
{
|
||||
// TODO: remove PdfBooleanObject, PdfIntegerObject etc.
|
||||
int removed = ObjectTable.Count;
|
||||
//CheckConsistence();
|
||||
// TODO: Is this really so easy?
|
||||
PdfReference[] irefs = TransitiveClosure(_document._trailer);
|
||||
|
||||
#if DEBUG
|
||||
// Have any two objects the same ID?
|
||||
Dictionary<int, int> ids = new Dictionary<int, int>();
|
||||
foreach (PdfObjectID objID in ObjectTable.Keys)
|
||||
{
|
||||
ids.Add(objID.ObjectNumber, 0);
|
||||
}
|
||||
|
||||
// Have any two irefs the same value?
|
||||
//Dictionary<int, int> ids = new Dictionary<int, int>();
|
||||
ids.Clear();
|
||||
foreach (PdfReference iref in ObjectTable.Values)
|
||||
{
|
||||
ids.Add(iref.ObjectNumber, 0);
|
||||
}
|
||||
|
||||
//
|
||||
Dictionary<PdfReference, int> refs = new Dictionary<PdfReference, int>();
|
||||
foreach (PdfReference iref in irefs)
|
||||
{
|
||||
refs.Add(iref, 0);
|
||||
}
|
||||
foreach (PdfReference value in ObjectTable.Values)
|
||||
{
|
||||
if (!refs.ContainsKey(value))
|
||||
value.GetType();
|
||||
}
|
||||
|
||||
foreach (PdfReference iref in ObjectTable.Values)
|
||||
{
|
||||
if (iref.Value == null)
|
||||
GetType();
|
||||
Debug.Assert(iref.Value != null);
|
||||
}
|
||||
|
||||
foreach (PdfReference iref in irefs)
|
||||
{
|
||||
if (!ObjectTable.ContainsKey(iref.ObjectID))
|
||||
GetType();
|
||||
Debug.Assert(ObjectTable.ContainsKey(iref.ObjectID));
|
||||
|
||||
if (iref.Value == null)
|
||||
GetType();
|
||||
Debug.Assert(iref.Value != null);
|
||||
}
|
||||
#endif
|
||||
|
||||
_maxObjectNumber = 0;
|
||||
ObjectTable.Clear();
|
||||
foreach (PdfReference iref in irefs)
|
||||
{
|
||||
// This if is needed for corrupt PDF files from the wild.
|
||||
// Without the if, an exception will be thrown if the file contains duplicate IDs ("An item with the same key has already been added to the dictionary.").
|
||||
// With the if, the first object with the ID will be used and later objects with the same ID will be ignored.
|
||||
if (!ObjectTable.ContainsKey(iref.ObjectID))
|
||||
{
|
||||
ObjectTable.Add(iref.ObjectID, iref);
|
||||
_maxObjectNumber = Math.Max(_maxObjectNumber, iref.ObjectNumber);
|
||||
}
|
||||
}
|
||||
//CheckConsistence();
|
||||
removed -= ObjectTable.Count;
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renumbers the objects starting at 1.
|
||||
/// </summary>
|
||||
internal void Renumber()
|
||||
{
|
||||
//CheckConsistence();
|
||||
PdfReference[] irefs = AllReferences;
|
||||
ObjectTable.Clear();
|
||||
// Give all objects a new number.
|
||||
int count = irefs.Length;
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
PdfReference iref = irefs[idx];
|
||||
#if DEBUG_
|
||||
if (iref.ObjectNumber == 1108)
|
||||
GetType();
|
||||
#endif
|
||||
iref.ObjectID = new PdfObjectID(idx + 1);
|
||||
// Rehash with new number.
|
||||
ObjectTable.Add(iref.ObjectID, iref);
|
||||
}
|
||||
_maxObjectNumber = count;
|
||||
//CheckConsistence();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the logical consistence for debugging purposes (useful after reconstruction work).
|
||||
/// </summary>
|
||||
[Conditional("DEBUG_")]
|
||||
public void CheckConsistence()
|
||||
{
|
||||
Dictionary<PdfReference, object> ht1 = new Dictionary<PdfReference, object>();
|
||||
foreach (PdfReference iref in ObjectTable.Values)
|
||||
{
|
||||
Debug.Assert(!ht1.ContainsKey(iref), "Duplicate iref.");
|
||||
Debug.Assert(iref.Value != null);
|
||||
ht1.Add(iref, null);
|
||||
}
|
||||
|
||||
Dictionary<PdfObjectID, object> ht2 = new Dictionary<PdfObjectID, object>();
|
||||
foreach (PdfReference iref in ObjectTable.Values)
|
||||
{
|
||||
Debug.Assert(!ht2.ContainsKey(iref.ObjectID), "Duplicate iref.");
|
||||
ht2.Add(iref.ObjectID, null);
|
||||
}
|
||||
|
||||
ICollection collection = ObjectTable.Values;
|
||||
int count = collection.Count;
|
||||
PdfReference[] irefs = new PdfReference[count];
|
||||
collection.CopyTo(irefs, 0);
|
||||
#if true
|
||||
for (int i = 0; i < count; i++)
|
||||
for (int j = 0; j < count; j++)
|
||||
if (i != j)
|
||||
{
|
||||
Debug.Assert(ReferenceEquals(irefs[i].Document, _document));
|
||||
Debug.Assert(irefs[i] != irefs[j]);
|
||||
Debug.Assert(!ReferenceEquals(irefs[i], irefs[j]));
|
||||
Debug.Assert(!ReferenceEquals(irefs[i].Value, irefs[j].Value));
|
||||
Debug.Assert(!Equals(irefs[i].ObjectID, irefs[j].Value.ObjectID));
|
||||
Debug.Assert(irefs[i].ObjectNumber != irefs[j].Value.ObjectNumber);
|
||||
Debug.Assert(ReferenceEquals(irefs[i].Document, irefs[j].Document));
|
||||
GetType();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// The garbage collector for PDF objects.
|
||||
///// </summary>
|
||||
//public sealed class GC
|
||||
//{
|
||||
// PdfXRefTable xrefTable;
|
||||
//
|
||||
// internal GC(PdfXRefTable xrefTable)
|
||||
// {
|
||||
// _xrefTable = xrefTable;
|
||||
// }
|
||||
//
|
||||
// public void Collect()
|
||||
// { }
|
||||
//
|
||||
// public PdfReference[] ReachableObjects()
|
||||
// {
|
||||
// Hash_table objects = new Hash_table();
|
||||
// TransitiveClosure(objects, _xrefTable.document.trailer);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the transitive closure of the specified PdfObject, i.e. all indirect objects
|
||||
/// recursively reachable from the specified object.
|
||||
/// </summary>
|
||||
public PdfReference[] TransitiveClosure(PdfObject pdfObject)
|
||||
{
|
||||
return TransitiveClosure(pdfObject, short.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the transitive closure of the specified PdfObject with the specified depth, i.e. all indirect objects
|
||||
/// recursively reachable from the specified object in up to maximally depth steps.
|
||||
/// </summary>
|
||||
public PdfReference[] TransitiveClosure(PdfObject pdfObject, int depth)
|
||||
{
|
||||
CheckConsistence();
|
||||
Dictionary<PdfItem, object> objects = new Dictionary<PdfItem, object>();
|
||||
_overflow = new Dictionary<PdfItem, object>();
|
||||
TransitiveClosureImplementation(objects, pdfObject);
|
||||
TryAgain:
|
||||
if (_overflow.Count > 0)
|
||||
{
|
||||
PdfObject[] array = new PdfObject[_overflow.Count];
|
||||
_overflow.Keys.CopyTo(array, 0);
|
||||
_overflow = new Dictionary<PdfItem, object>();
|
||||
for (int idx = 0; idx < array.Length; idx++)
|
||||
{
|
||||
PdfObject obj = array[idx];
|
||||
TransitiveClosureImplementation(objects, obj);
|
||||
}
|
||||
goto TryAgain;
|
||||
}
|
||||
|
||||
CheckConsistence();
|
||||
|
||||
ICollection collection = objects.Keys;
|
||||
int count = collection.Count;
|
||||
PdfReference[] irefs = new PdfReference[count];
|
||||
collection.CopyTo(irefs, 0);
|
||||
|
||||
#if true_
|
||||
for (int i = 0; i < count; i++)
|
||||
for (int j = 0; j < count; j++)
|
||||
if (i != j)
|
||||
{
|
||||
Debug.Assert(ReferenceEquals(irefs[i].Document, _document));
|
||||
Debug.Assert(irefs[i] != irefs[j]);
|
||||
Debug.Assert(!ReferenceEquals(irefs[i], irefs[j]));
|
||||
Debug.Assert(!ReferenceEquals(irefs[i].Value, irefs[j].Value));
|
||||
Debug.Assert(!Equals(irefs[i].ObjectID, irefs[j].Value.ObjectID));
|
||||
Debug.Assert(irefs[i].ObjectNumber != irefs[j].Value.ObjectNumber);
|
||||
Debug.Assert(ReferenceEquals(irefs[i].Document, irefs[j].Document));
|
||||
GetType();
|
||||
}
|
||||
#endif
|
||||
return irefs;
|
||||
}
|
||||
|
||||
static int _nestingLevel;
|
||||
Dictionary<PdfItem, object> _overflow = new Dictionary<PdfItem, object>();
|
||||
|
||||
void TransitiveClosureImplementation(Dictionary<PdfItem, object> objects, PdfObject pdfObject/*, ref int depth*/)
|
||||
{
|
||||
try
|
||||
{
|
||||
_nestingLevel++;
|
||||
if (_nestingLevel >= 1000)
|
||||
{
|
||||
if (!_overflow.ContainsKey(pdfObject))
|
||||
_overflow.Add(pdfObject, null);
|
||||
return;
|
||||
}
|
||||
#if DEBUG_
|
||||
//enterCount++;
|
||||
if (enterCount == 5400)
|
||||
GetType();
|
||||
//if (!Object.ReferenceEquals(pdfObject.Owner, _document))
|
||||
// GetType();
|
||||
//////Debug.Assert(Object.ReferenceEquals(pdfObject27.Document, _document));
|
||||
// if (item is PdfObject && ((PdfObject)item).ObjectID.ObjectNumber == 5)
|
||||
// Debug.WriteLine("items: " + ((PdfObject)item).ObjectID.ToString());
|
||||
//if (pdfObject.ObjectNumber == 5)
|
||||
// GetType();
|
||||
#endif
|
||||
|
||||
IEnumerable enumerable = null; //(IEnumerator)pdfObject;
|
||||
PdfDictionary dict;
|
||||
PdfArray array;
|
||||
if ((dict = pdfObject as PdfDictionary) != null)
|
||||
enumerable = dict.Elements.Values;
|
||||
else if ((array = pdfObject as PdfArray) != null)
|
||||
enumerable = array.Elements;
|
||||
else
|
||||
Debug.Assert(false, "Should not come here.");
|
||||
|
||||
if (enumerable != null)
|
||||
{
|
||||
foreach (PdfItem item in enumerable)
|
||||
{
|
||||
PdfReference iref = item as PdfReference;
|
||||
if (iref != null)
|
||||
{
|
||||
// Is this an indirect reference to an object that does not exist?
|
||||
//if (iref.Document == null)
|
||||
//{
|
||||
// Debug.WriteLine("Dead object detected: " + iref.ObjectID.ToString());
|
||||
// PdfReference dead = DeadObject;
|
||||
// iref.ObjectID = dead.ObjectID;
|
||||
// iref.Document = _document;
|
||||
// iref.SetObject(dead.Value);
|
||||
// PdfDictionary dict = (PdfDictionary)dead.Value;
|
||||
|
||||
// dict.Elements["/DeadObjectCount"] =
|
||||
// new PdfInteger(dict.Elements.GetInteger("/DeadObjectCount") + 1);
|
||||
|
||||
// iref = dead;
|
||||
//}
|
||||
|
||||
if (!ReferenceEquals(iref.Document, _document))
|
||||
{
|
||||
GetType();
|
||||
Debug.WriteLine(String.Format("Bad iref: {0}", iref.ObjectID.ToString()));
|
||||
}
|
||||
Debug.Assert(ReferenceEquals(iref.Document, _document) || iref.Document == null, "External object detected!");
|
||||
#if DEBUG_
|
||||
if (iref.ObjectID.ObjectNumber == 23)
|
||||
GetType();
|
||||
#endif
|
||||
if (!objects.ContainsKey(iref))
|
||||
{
|
||||
PdfObject value = iref.Value;
|
||||
|
||||
// Ignore unreachable objects.
|
||||
if (iref.Document != null)
|
||||
{
|
||||
// ... from trailer hack
|
||||
if (value == null)
|
||||
{
|
||||
iref = ObjectTable[iref.ObjectID];
|
||||
Debug.Assert(iref.Value != null);
|
||||
value = iref.Value;
|
||||
}
|
||||
Debug.Assert(ReferenceEquals(iref.Document, _document));
|
||||
objects.Add(iref, null);
|
||||
//Debug.WriteLine(String.Format("objects.Add('{0}', null);", iref.ObjectID.ToString()));
|
||||
if (value is PdfArray || value is PdfDictionary)
|
||||
TransitiveClosureImplementation(objects, value /*, ref depth*/);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// objects2.Add(this[iref.ObjectID], null);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PdfObject pdfObject28 = item as PdfObject;
|
||||
//if (pdfObject28 != null)
|
||||
// Debug.Assert(Object.ReferenceEquals(pdfObject28.Document, _document));
|
||||
if (pdfObject28 != null && (pdfObject28 is PdfDictionary || pdfObject28 is PdfArray))
|
||||
TransitiveClosureImplementation(objects, pdfObject28 /*, ref depth*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_nestingLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cross reference to an objects used for undefined indirect references.
|
||||
/// </summary>
|
||||
public PdfReference DeadObject
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_deadObject == null)
|
||||
{
|
||||
_deadObject = new PdfDictionary(_document);
|
||||
Add(_deadObject);
|
||||
_deadObject.Elements.Add("/DeadObjectCount", new PdfInteger());
|
||||
}
|
||||
return _deadObject.Reference;
|
||||
}
|
||||
}
|
||||
PdfDictionary _deadObject;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Represents the cross-reference table of a PDF document.
|
||||
///// It contains all indirect objects of a document.
|
||||
///// </summary>
|
||||
//internal sealed class PdfCrossReferenceStreamTable // Must not be derive from PdfObject.
|
||||
//{
|
||||
// public PdfCrossReferenceStreamTable(PdfDocument document)
|
||||
// {
|
||||
// _document = document;
|
||||
// }
|
||||
// readonly PdfDocument _document;
|
||||
|
||||
// public class Item
|
||||
// {
|
||||
// public PdfReference Reference;
|
||||
|
||||
// public readonly List<CrossReferenceStreamEntry> Entries = new List<CrossReferenceStreamEntry>();
|
||||
// }
|
||||
//}
|
||||
|
||||
//struct CrossReferenceStreamEntry
|
||||
//{
|
||||
// public int Type;
|
||||
|
||||
// public int Field2;
|
||||
|
||||
// public int Field3;
|
||||
//}
|
||||
}
|
169
PrintPDF/PdfSharp/Pdf.Advanced/PdfDictionaryWithContentStream.cs
Normal file
169
PrintPDF/PdfSharp/Pdf.Advanced/PdfDictionaryWithContentStream.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a base class for dictionaries with a content stream.
|
||||
/// Implement IContentStream for use with a content writer.
|
||||
/// </summary>
|
||||
public abstract class PdfDictionaryWithContentStream : PdfDictionary, IContentStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfDictionaryWithContentStream"/> class.
|
||||
/// </summary>
|
||||
public PdfDictionaryWithContentStream()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfDictionaryWithContentStream"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">The document.</param>
|
||||
public PdfDictionaryWithContentStream(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance from an existing dictionary. Used for object type transformation.
|
||||
/// </summary>
|
||||
protected PdfDictionaryWithContentStream(PdfDictionary dict)
|
||||
: base(dict)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resources dictionary of this dictionary. If no such dictionary exists, it is created.
|
||||
/// </summary>
|
||||
internal PdfResources Resources
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_resources == null)
|
||||
_resources = (PdfResources)Elements.GetValue(Keys.Resources, VCF.Create);
|
||||
return _resources;
|
||||
}
|
||||
}
|
||||
PdfResources _resources;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the interface because the primary function is internal.
|
||||
/// </summary>
|
||||
PdfResources IContentStream.Resources
|
||||
{
|
||||
get { return Resources; }
|
||||
}
|
||||
|
||||
internal string GetFontName(XFont font, out PdfFont pdfFont)
|
||||
{
|
||||
pdfFont = _document.FontTable.GetFont(font);
|
||||
Debug.Assert(pdfFont != null);
|
||||
string name = Resources.AddFont(pdfFont);
|
||||
return name;
|
||||
}
|
||||
|
||||
string IContentStream.GetFontName(XFont font, out PdfFont pdfFont)
|
||||
{
|
||||
return GetFontName(font, out pdfFont);
|
||||
}
|
||||
|
||||
internal string GetFontName(string idName, byte[] fontData, out PdfFont pdfFont)
|
||||
{
|
||||
pdfFont = _document.FontTable.GetFont(idName, fontData);
|
||||
Debug.Assert(pdfFont != null);
|
||||
string name = Resources.AddFont(pdfFont);
|
||||
return name;
|
||||
}
|
||||
|
||||
string IContentStream.GetFontName(string idName, byte[] fontData, out PdfFont pdfFont)
|
||||
{
|
||||
return GetFontName(idName, fontData, out pdfFont);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the specified image within this dictionary.
|
||||
/// </summary>
|
||||
internal string GetImageName(XImage image)
|
||||
{
|
||||
PdfImage pdfImage = _document.ImageTable.GetImage(image);
|
||||
Debug.Assert(pdfImage != null);
|
||||
string name = Resources.AddImage(pdfImage);
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the interface because the primary function is internal.
|
||||
/// </summary>
|
||||
string IContentStream.GetImageName(XImage image)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the specified form within this dictionary.
|
||||
/// </summary>
|
||||
internal string GetFormName(XForm form)
|
||||
{
|
||||
PdfFormXObject pdfForm = _document.FormTable.GetForm(form);
|
||||
Debug.Assert(pdfForm != null);
|
||||
string name = Resources.AddForm(pdfForm);
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the interface because the primary function is internal.
|
||||
/// </summary>
|
||||
string IContentStream.GetFormName(XForm form)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public class Keys : PdfDictionary.PdfStream.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Optional but strongly recommended; PDF 1.2) A dictionary specifying any
|
||||
/// resources (such as fonts and images) required by the form XObject.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResources))]
|
||||
public const string Resources = "/Resources";
|
||||
}
|
||||
}
|
||||
}
|
411
PrintPDF/PdfSharp/Pdf.Advanced/PdfExtGState.cs
Normal file
411
PrintPDF/PdfSharp/Pdf.Advanced/PdfExtGState.cs
Normal file
@@ -0,0 +1,411 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
#endif
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an extended graphics state object.
|
||||
/// </summary>
|
||||
public sealed class PdfExtGState : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfExtGState"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">The document.</param>
|
||||
public PdfExtGState(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/ExtGState");
|
||||
|
||||
#if true_
|
||||
//AIS false
|
||||
//BM /Normal
|
||||
//ca 1
|
||||
//CA 1
|
||||
//op false
|
||||
//OP false
|
||||
//OPM 1
|
||||
//SA true
|
||||
//SMask /None
|
||||
//Type /ExtGState
|
||||
|
||||
Elements.SetValue(Keys.AIS, new PdfBoolean(false)); // The alpha source
|
||||
Elements.SetName("/BM", "Normal");
|
||||
Elements.SetValue(Keys.op, new PdfBoolean(false));
|
||||
Elements.SetValue(Keys.OP, new PdfBoolean(false));
|
||||
Elements.SetValue(Keys.OPM, new PdfInteger(1));
|
||||
Elements.SetValue("/SA", new PdfBoolean(true));
|
||||
Elements.SetName("/SMask", "None");
|
||||
#endif
|
||||
//#if OP_HACK
|
||||
// Elements.SetValue(Keys.op, new PdfBoolean(false));
|
||||
// Elements.SetValue(Keys.OP, new PdfBoolean(false));
|
||||
// Elements.SetValue(Keys.OPM, new PdfInteger(1));
|
||||
//#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used in Edf.Xps.
|
||||
/// </summary>
|
||||
internal void SetDefault1()
|
||||
{
|
||||
//<<
|
||||
// /AIS false
|
||||
// /BM /Normal
|
||||
// /ca 1
|
||||
// /CA 1
|
||||
// /op false
|
||||
// /OP false
|
||||
// /OPM 1
|
||||
// /SA true
|
||||
// /SMask /None
|
||||
// /Type /ExtGState
|
||||
//>>
|
||||
Elements.SetBoolean(Keys.AIS, false);
|
||||
if (Elements.ContainsKey(Keys.BM)) Elements.SetName(Keys.BM, "/Normal");
|
||||
StrokeAlpha = 1;
|
||||
NonStrokeAlpha = 1;
|
||||
Elements.SetBoolean(Keys.op, false);
|
||||
Elements.SetBoolean(Keys.OP, false);
|
||||
Elements.SetBoolean(Keys.SA, true);
|
||||
Elements.SetName(Keys.SMask, "/None");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used in Edf.Xps.
|
||||
/// ...for shading patterns
|
||||
/// </summary>
|
||||
internal void SetDefault2()
|
||||
{
|
||||
//<<
|
||||
// /AIS false
|
||||
// /BM /Normal
|
||||
// /ca 1
|
||||
// /CA 1
|
||||
// /op true
|
||||
// /OP true
|
||||
// /OPM 1
|
||||
// /SA true
|
||||
// /SMask /None
|
||||
// /Type /ExtGState
|
||||
//>>
|
||||
Elements.SetBoolean(Keys.AIS, false);
|
||||
Elements.SetName(Keys.BM, "/Normal");
|
||||
StrokeAlpha = 1;
|
||||
NonStrokeAlpha = 1;
|
||||
Elements.SetBoolean(Keys.op, true);
|
||||
Elements.SetBoolean(Keys.OP, true);
|
||||
Elements.SetInteger(Keys.OPM, 1);
|
||||
Elements.SetBoolean(Keys.SA, true);
|
||||
Elements.SetName(Keys.SMask, "/None");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the alpha value for stroking operations.
|
||||
/// </summary>
|
||||
public double StrokeAlpha
|
||||
{
|
||||
set
|
||||
{
|
||||
_strokeAlpha = value;
|
||||
Elements.SetReal(Keys.CA, value);
|
||||
UpdateKey();
|
||||
}
|
||||
}
|
||||
double _strokeAlpha;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the alpha value for nonstroking operations.
|
||||
/// </summary>
|
||||
public double NonStrokeAlpha
|
||||
{
|
||||
set
|
||||
{
|
||||
_nonStrokeAlpha = value;
|
||||
Elements.SetReal(Keys.ca, value);
|
||||
UpdateKey();
|
||||
}
|
||||
}
|
||||
double _nonStrokeAlpha;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the overprint value for stroking operations.
|
||||
/// </summary>
|
||||
public bool StrokeOverprint
|
||||
{
|
||||
set
|
||||
{
|
||||
_strokeOverprint = value;
|
||||
Elements.SetBoolean(Keys.OP, value);
|
||||
UpdateKey();
|
||||
}
|
||||
}
|
||||
bool _strokeOverprint;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the overprint value for nonstroking operations.
|
||||
/// </summary>
|
||||
public bool NonStrokeOverprint
|
||||
{
|
||||
set
|
||||
{
|
||||
_nonStrokeOverprint = value;
|
||||
Elements.SetBoolean(Keys.op, value);
|
||||
UpdateKey();
|
||||
}
|
||||
}
|
||||
bool _nonStrokeOverprint;
|
||||
|
||||
/// <summary>
|
||||
/// Sets a soft mask object.
|
||||
/// </summary>
|
||||
public PdfSoftMask SoftMask
|
||||
{
|
||||
set { Elements.SetReference(Keys.SMask, value); }
|
||||
}
|
||||
|
||||
internal string Key
|
||||
{
|
||||
get { return _key; }
|
||||
}
|
||||
|
||||
void UpdateKey()
|
||||
{
|
||||
_key = ((int)(1000 * _strokeAlpha)).ToString(CultureInfo.InvariantCulture) +
|
||||
((int)(1000 * _nonStrokeAlpha)).ToString(CultureInfo.InvariantCulture) +
|
||||
(_strokeOverprint ? "S" : "s") + (_nonStrokeOverprint ? "N" : "n");
|
||||
}
|
||||
string _key;
|
||||
|
||||
internal static string MakeKey(double alpha, bool overPaint)
|
||||
{
|
||||
string key = ((int)(1000 * alpha)).ToString(CultureInfo.InvariantCulture) + (overPaint ? "O" : "0");
|
||||
return key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common keys for all streams.
|
||||
/// </summary>
|
||||
internal sealed class Keys : KeysBase
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The type of PDF object that this dictionary describes;
|
||||
/// must be ExtGState for a graphics state parameter dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The line width (see <20>Line Width<74> on page 185).
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string LW = "/LW";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The line cap style.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public const string LC = "/LC";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The line join style.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public const string LJ = "/LJ";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The miter limit.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string ML = "/ML";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The line dash pattern, expressed as an array of the form
|
||||
/// [dashArray dashPhase], where dashArray is itself an array and dashPhase is an integer.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string D = "/D";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The name of the rendering intent.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string RI = "/RI";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A flag specifying whether to apply overprint. In PDF 1.2 and earlier,
|
||||
/// there is a single overprint parameter that applies to all painting operations.
|
||||
/// Beginning with PDF 1.3, there are two separate overprint parameters: one for stroking
|
||||
/// and one for all other painting operations. Specifying an OP entry sets both parameters
|
||||
/// unless there is also an op entry in the same graphics state parameter dictionary, in
|
||||
/// which case the OP entry sets only the overprint parameter for stroking.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string OP = "/OP";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) A flag specifying whether to apply overprint for painting operations
|
||||
/// other than stroking. If this entry is absent, the OP entry, if any, sets this parameter.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string op = "/op";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) The overprint mode.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public const string OPM = "/OPM";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) An array of the form [font size], where font is an indirect
|
||||
/// reference to a font dictionary and size is a number expressed in text space units.
|
||||
/// These two objects correspond to the operands of the Tf operator; however,
|
||||
/// the first operand is an indirect object reference instead of a resource name.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Font = "/Font";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The black-generation function, which maps the interval [0.0 1.0]
|
||||
/// to the interval [0.0 1.0].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Function | KeyType.Optional)]
|
||||
public const string BG = "/BG";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) Same as BG except that the value may also be the name Default,
|
||||
/// denoting the black-generation function that was in effect at the start of the page.
|
||||
/// If both BG and BG2 are present in the same graphics state parameter dictionary,
|
||||
/// BG2 takes precedence.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.FunctionOrName | KeyType.Optional)]
|
||||
public const string BG2 = "/BG2";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The undercolor-removal function, which maps the interval
|
||||
/// [0.0 1.0] to the interval [-1.0 1.0].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Function | KeyType.Optional)]
|
||||
public const string UCR = "/UCR";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) Same as UCR except that the value may also be the name Default,
|
||||
/// denoting the undercolor-removal function that was in effect at the start of the page.
|
||||
/// If both UCR and UCR2 are present in the same graphics state parameter dictionary,
|
||||
/// UCR2 takes precedence.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.FunctionOrName | KeyType.Optional)]
|
||||
public const string UCR2 = "/UCR2";
|
||||
|
||||
//TR function, array, or name
|
||||
//TR2 function, array, or name
|
||||
//HT dictionary, stream, or name
|
||||
//FL number
|
||||
//SM number
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A flag specifying whether to apply automatic stroke adjustment.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string SA = "/SA";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) The current blend mode to be used in the transparent imaging model.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.NameOrArray | KeyType.Optional)]
|
||||
public const string BM = "/BM";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) The current soft mask, specifying the mask shape or
|
||||
/// mask opacity values to be used in the transparent imaging model.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.NameOrDictionary | KeyType.Optional)]
|
||||
public const string SMask = "/SMask";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) The current stroking alpha constant, specifying the constant
|
||||
/// shape or constant opacity value to be used for stroking operations in the transparent
|
||||
/// imaging model.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string CA = "/CA";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) Same as CA, but for nonstroking operations.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string ca = "/ca";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) The alpha source flag (<28>alpha is shape<70>), specifying whether
|
||||
/// the current soft mask and alpha constant are to be interpreted as shape values (true)
|
||||
/// or opacity values (false).
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string AIS = "/AIS";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) The text knockout flag, which determines the behavior of
|
||||
/// overlapping glyphs within a text object in the transparent imaging model.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string TK = "/TK";
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
95
PrintPDF/PdfSharp/Pdf.Advanced/PdfExtGStateTable.cs
Normal file
95
PrintPDF/PdfSharp/Pdf.Advanced/PdfExtGStateTable.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains all used ExtGState objects of a document.
|
||||
/// </summary>
|
||||
public sealed class PdfExtGStateTable : PdfResourceTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of this class, which is a singleton for each document.
|
||||
/// </summary>
|
||||
public PdfExtGStateTable(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PdfExtGState with the key 'CA' set to the specified alpha value.
|
||||
/// </summary>
|
||||
public PdfExtGState GetExtGStateStroke(double alpha, bool overprint)
|
||||
{
|
||||
string key = PdfExtGState.MakeKey(alpha, overprint);
|
||||
PdfExtGState extGState;
|
||||
if (!_strokeAlphaValues.TryGetValue(key, out extGState))
|
||||
{
|
||||
extGState = new PdfExtGState(Owner);
|
||||
//extGState.Elements[PdfExtGState.Keys.CA] = new PdfReal(alpha);
|
||||
extGState.StrokeAlpha = alpha;
|
||||
if (overprint)
|
||||
{
|
||||
extGState.StrokeOverprint = true;
|
||||
extGState.Elements.SetInteger(PdfExtGState.Keys.OPM, 1);
|
||||
}
|
||||
_strokeAlphaValues[key] = extGState;
|
||||
}
|
||||
return extGState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PdfExtGState with the key 'ca' set to the specified alpha value.
|
||||
/// </summary>
|
||||
public PdfExtGState GetExtGStateNonStroke(double alpha, bool overprint)
|
||||
{
|
||||
string key = PdfExtGState.MakeKey(alpha, overprint);
|
||||
PdfExtGState extGState;
|
||||
if (!_nonStrokeStates.TryGetValue(key, out extGState))
|
||||
{
|
||||
extGState = new PdfExtGState(Owner);
|
||||
//extGState.Elements[PdfExtGState.Keys.ca] = new PdfReal(alpha);
|
||||
extGState.NonStrokeAlpha = alpha;
|
||||
if (overprint)
|
||||
{
|
||||
extGState.NonStrokeOverprint = true;
|
||||
extGState.Elements.SetInteger(PdfExtGState.Keys.OPM, 1);
|
||||
}
|
||||
|
||||
_nonStrokeStates[key] = extGState;
|
||||
}
|
||||
return extGState;
|
||||
}
|
||||
|
||||
readonly Dictionary<string, PdfExtGState> _strokeAlphaValues = new Dictionary<string, PdfExtGState>();
|
||||
readonly Dictionary<string, PdfExtGState> _nonStrokeStates = new Dictionary<string, PdfExtGState>();
|
||||
}
|
||||
}
|
156
PrintPDF/PdfSharp/Pdf.Advanced/PdfFont.cs
Normal file
156
PrintPDF/PdfSharp/Pdf.Advanced/PdfFont.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using PdfSharp.Fonts;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF font.
|
||||
/// </summary>
|
||||
public class PdfFont : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfFont"/> class.
|
||||
/// </summary>
|
||||
public PdfFont(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
internal PdfFontDescriptor FontDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(_fontDescriptor != null);
|
||||
return _fontDescriptor;
|
||||
}
|
||||
set { _fontDescriptor = value; }
|
||||
}
|
||||
PdfFontDescriptor _fontDescriptor;
|
||||
|
||||
internal PdfFontEncoding FontEncoding;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is symbol font.
|
||||
/// </summary>
|
||||
public bool IsSymbolFont
|
||||
{
|
||||
get { return _fontDescriptor.IsSymbolFont; }
|
||||
}
|
||||
|
||||
internal void AddChars(string text)
|
||||
{
|
||||
if (_cmapInfo != null)
|
||||
_cmapInfo.AddChars(text);
|
||||
}
|
||||
|
||||
internal void AddGlyphIndices(string glyphIndices)
|
||||
{
|
||||
if (_cmapInfo != null)
|
||||
_cmapInfo.AddGlyphIndices(glyphIndices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CMapInfo.
|
||||
/// </summary>
|
||||
internal CMapInfo CMapInfo
|
||||
{
|
||||
get { return _cmapInfo; }
|
||||
set { _cmapInfo = value; }
|
||||
}
|
||||
internal CMapInfo _cmapInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets ToUnicodeMap.
|
||||
/// </summary>
|
||||
internal PdfToUnicodeMap ToUnicodeMap
|
||||
{
|
||||
get { return _toUnicode; }
|
||||
set { _toUnicode = value; }
|
||||
}
|
||||
internal PdfToUnicodeMap _toUnicode;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds a tag of exactly six uppercase letters to the font name
|
||||
/// according to PDF Reference Section 5.5.3 'Font Subsets'
|
||||
/// </summary>
|
||||
internal static string CreateEmbeddedFontSubsetName(string name)
|
||||
{
|
||||
StringBuilder s = new StringBuilder(64);
|
||||
byte[] bytes = Guid.NewGuid().ToByteArray();
|
||||
for (int idx = 0; idx < 6; idx++)
|
||||
s.Append((char)('A' + bytes[idx] % 26));
|
||||
s.Append('+');
|
||||
if (name.StartsWith("/"))
|
||||
s.Append(name.Substring(1));
|
||||
else
|
||||
s.Append(name);
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys common to all font dictionaries.
|
||||
/// </summary>
|
||||
public class Keys : KeysBase
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be Font for a font dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Font")]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string Subtype = "/Subtype";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The PostScript name of the font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string BaseFont = "/BaseFont";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts; must be an indirect reference)
|
||||
/// A font descriptor describing the font<6E>s metrics other than its glyph widths.
|
||||
/// Note: For the standard 14 fonts, the entries FirstChar, LastChar, Widths, and
|
||||
/// FontDescriptor must either all be present or all be absent. Ordinarily, they are
|
||||
/// absent; specifying them enables a standard font to be overridden.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.MustBeIndirect, typeof(PdfFontDescriptor))]
|
||||
public const string FontDescriptor = "/FontDescriptor";
|
||||
}
|
||||
}
|
||||
}
|
351
PrintPDF/PdfSharp/Pdf.Advanced/PdfFontDescriptor.cs
Normal file
351
PrintPDF/PdfSharp/Pdf.Advanced/PdfFontDescriptor.cs
Normal file
@@ -0,0 +1,351 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using PdfSharp.Fonts.OpenType;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// The PDF font descriptor flags.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
enum PdfFontDescriptorFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// All glyphs have the same width (as opposed to proportional or variable-pitch
|
||||
/// fonts, which have different widths).
|
||||
/// </summary>
|
||||
FixedPitch = 1 << 0,
|
||||
|
||||
/// <summary>
|
||||
/// Glyphs have serifs, which are short strokes drawn at an angle on the top and
|
||||
/// bottom of glyph stems. (Sans serif fonts do not have serifs.)
|
||||
/// </summary>
|
||||
Serif = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// Font contains glyphs outside the Adobe standard Latin character set. This
|
||||
/// flag and the Nonsymbolic flag cannot both be set or both be clear.
|
||||
/// </summary>
|
||||
Symbolic = 1 << 2,
|
||||
|
||||
/// <summary>
|
||||
/// Glyphs resemble cursive handwriting.
|
||||
/// </summary>
|
||||
Script = 1 << 3,
|
||||
|
||||
/// <summary>
|
||||
/// Font uses the Adobe standard Latin character set or a subset of it.
|
||||
/// </summary>
|
||||
Nonsymbolic = 1 << 5,
|
||||
|
||||
/// <summary>
|
||||
/// Glyphs have dominant vertical strokes that are slanted.
|
||||
/// </summary>
|
||||
Italic = 1 << 6,
|
||||
|
||||
/// <summary>
|
||||
/// Font contains no lowercase letters; typically used for display purposes,
|
||||
/// such as for titles or headlines.
|
||||
/// </summary>
|
||||
AllCap = 1 << 16,
|
||||
|
||||
/// <summary>
|
||||
/// Font contains both uppercase and lowercase letters. The uppercase letters are
|
||||
/// similar to those in the regular version of the same typeface family. The glyphs
|
||||
/// for the lowercase letters have the same shapes as the corresponding uppercase
|
||||
/// letters, but they are sized and their proportions adjusted so that they have the
|
||||
/// same size and stroke weight as lowercase glyphs in the same typeface family.
|
||||
/// </summary>
|
||||
SmallCap = 1 << 17,
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether bold glyphs are painted with extra pixels even at very small
|
||||
/// text sizes.
|
||||
/// </summary>
|
||||
ForceBold = 1 << 18,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A PDF font descriptor specifies metrics and other attributes of a simple font,
|
||||
/// as distinct from the metrics of individual glyphs.
|
||||
/// </summary>
|
||||
public sealed class PdfFontDescriptor : PdfDictionary
|
||||
{
|
||||
internal PdfFontDescriptor(PdfDocument document, OpenTypeDescriptor descriptor)
|
||||
: base(document)
|
||||
{
|
||||
_descriptor = descriptor;
|
||||
Elements.SetName(Keys.Type, "/FontDescriptor");
|
||||
|
||||
Elements.SetInteger(Keys.Ascent, _descriptor.DesignUnitsToPdf(_descriptor.Ascender));
|
||||
Elements.SetInteger(Keys.CapHeight, _descriptor.DesignUnitsToPdf(_descriptor.CapHeight));
|
||||
Elements.SetInteger(Keys.Descent, _descriptor.DesignUnitsToPdf(_descriptor.Descender));
|
||||
Elements.SetInteger(Keys.Flags, (int)FlagsFromDescriptor(_descriptor));
|
||||
Elements.SetRectangle(Keys.FontBBox, new PdfRectangle(
|
||||
_descriptor.DesignUnitsToPdf(_descriptor.XMin),
|
||||
_descriptor.DesignUnitsToPdf(_descriptor.YMin),
|
||||
_descriptor.DesignUnitsToPdf(_descriptor.XMax),
|
||||
_descriptor.DesignUnitsToPdf(_descriptor.YMax)));
|
||||
// not here, done in PdfFont later...
|
||||
//Elements.SetName(Keys.FontName, "abc"); //descriptor.FontName);
|
||||
Elements.SetReal(Keys.ItalicAngle, _descriptor.ItalicAngle);
|
||||
Elements.SetInteger(Keys.StemV, _descriptor.StemV);
|
||||
Elements.SetInteger(Keys.XHeight, _descriptor.DesignUnitsToPdf(_descriptor.XHeight));
|
||||
}
|
||||
|
||||
//HACK OpenTypeDescriptor descriptor
|
||||
internal OpenTypeDescriptor _descriptor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the font.
|
||||
/// </summary>
|
||||
public string FontName
|
||||
{
|
||||
get { return Elements.GetName(Keys.FontName); }
|
||||
set { Elements.SetName(Keys.FontName, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is symbol font.
|
||||
/// </summary>
|
||||
public bool IsSymbolFont
|
||||
{
|
||||
get { return _isSymbolFont; }
|
||||
}
|
||||
bool _isSymbolFont;
|
||||
|
||||
// HACK FlagsFromDescriptor(OpenTypeDescriptor descriptor)
|
||||
PdfFontDescriptorFlags FlagsFromDescriptor(OpenTypeDescriptor descriptor)
|
||||
{
|
||||
PdfFontDescriptorFlags flags = 0;
|
||||
_isSymbolFont = descriptor.FontFace.cmap.symbol;
|
||||
flags |= descriptor.FontFace.cmap.symbol ? PdfFontDescriptorFlags.Symbolic : PdfFontDescriptorFlags.Nonsymbolic;
|
||||
return flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public sealed class Keys : KeysBase
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes; must be
|
||||
/// FontDescriptor for a font descriptor.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "FontDescriptor")]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The PostScript name of the font. This name should be the same as the
|
||||
/// value of BaseFont in the font or CIDFont dictionary that refers to this font descriptor.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string FontName = "/FontName";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.5; strongly recommended for Type 3 fonts in Tagged PDF documents)
|
||||
/// A string specifying the preferred font family name. For example, for the font
|
||||
/// Times Bold Italic, the FontFamily is Times.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.String | KeyType.Optional)]
|
||||
public const string FontFamily = "/FontFamily";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.5; strongly recommended for Type 3 fonts in Tagged PDF documents)
|
||||
/// The font stretch value. It must be one of the following names (ordered from
|
||||
/// narrowest to widest): UltraCondensed, ExtraCondensed, Condensed, SemiCondensed,
|
||||
/// Normal, SemiExpanded, Expanded, ExtraExpanded or UltraExpanded.
|
||||
/// Note: The specific interpretation of these values varies from font to font.
|
||||
/// For example, Condensed in one font may appear most similar to Normal in another.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string FontStretch = "/FontStretch";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.5; strongly recommended for Type 3 fonts in Tagged PDF documents)
|
||||
/// The weight (thickness) component of the fully-qualified font name or font specifier.
|
||||
/// The possible values are 100, 200, 300, 400, 500, 600, 700, 800, or 900, where each
|
||||
/// number indicates a weight that is at least as dark as its predecessor. A value of
|
||||
/// 400 indicates a normal weight; 700 indicates bold.
|
||||
/// Note: The specific interpretation of these values varies from font to font.
|
||||
/// For example, 300 in one font may appear most similar to 500 in another.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string FontWeight = "/FontWeight";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A collection of flags defining various characteristics of the font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string Flags = "/Flags";
|
||||
|
||||
/// <summary>
|
||||
/// (Required, except for Type 3 fonts) A rectangle (see Section 3.8.4, <20>Rectangles<65>),
|
||||
/// expressed in the glyph coordinate system, specifying the font bounding box. This
|
||||
/// is the smallest rectangle enclosing the shape that would result if all of the
|
||||
/// glyphs of the font were placed with their origins coincident and then filled.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Rectangle | KeyType.Required)]
|
||||
public const string FontBBox = "/FontBBox";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The angle, expressed in degrees counterclockwise from the vertical, of
|
||||
/// the dominant vertical strokes of the font. (For example, the 9-o<>clock position is 90
|
||||
/// degrees, and the 3-o<>clock position is <20>90 degrees.) The value is negative for fonts
|
||||
/// that slope to the right, as almost all italic fonts do.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string ItalicAngle = "/ItalicAngle";
|
||||
|
||||
/// <summary>
|
||||
/// (Required, except for Type 3 fonts) The maximum height above the baseline reached
|
||||
/// by glyphs in this font, excluding the height of glyphs for accented characters.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string Ascent = "/Ascent";
|
||||
|
||||
/// <summary>
|
||||
/// (Required, except for Type 3 fonts) The maximum depth below the baseline reached
|
||||
/// by glyphs in this font. The value is a negative number.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string Descent = "/Descent";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The spacing between baselines of consecutive lines of text.
|
||||
/// Default value: 0.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string Leading = "/Leading";
|
||||
|
||||
/// <summary>
|
||||
/// (Required for fonts that have Latin characters, except for Type 3 fonts) The vertical
|
||||
/// coordinate of the top of flat capital letters, measured from the baseline.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string CapHeight = "/CapHeight";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The font<6E>s x height: the vertical coordinate of the top of flat nonascending
|
||||
/// lowercase letters (like the letter x), measured from the baseline, in fonts that have
|
||||
/// Latin characters. Default value: 0.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string XHeight = "/XHeight";
|
||||
|
||||
/// <summary>
|
||||
/// (Required, except for Type 3 fonts) The thickness, measured horizontally, of the dominant
|
||||
/// vertical stems of glyphs in the font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string StemV = "/StemV";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The thickness, measured vertically, of the dominant horizontal stems
|
||||
/// of glyphs in the font. Default value: 0.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string StemH = "/StemH";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The average width of glyphs in the font. Default value: 0.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string AvgWidth = "/AvgWidth";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The maximum width of glyphs in the font. Default value: 0.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string MaxWidth = "/MaxWidth";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The width to use for character codes whose widths are not specified in a
|
||||
/// font dictionary<72>s Widths array. This has a predictable effect only if all such codes
|
||||
/// map to glyphs whose actual widths are the same as the value of the MissingWidth entry.
|
||||
/// Default value: 0.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Optional)]
|
||||
public const string MissingWidth = "/MissingWidth";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A stream containing a Type 1 font program.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string FontFile = "/FontFile";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.1) A stream containing a TrueType font program.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string FontFile2 = "/FontFile2";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) A stream containing a font program whose format is specified
|
||||
/// by the Subtype entry in the stream dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string FontFile3 = "/FontFile3";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; meaningful only in Type 1 fonts; PDF 1.1) A string listing the character
|
||||
/// names defined in a font subset. The names in this string must be in PDF syntax<61>that is,
|
||||
/// each name preceded by a slash (/). The names can appear in any order. The name .notdef
|
||||
/// should be omitted; it is assumed to exist in the font subset. If this entry is absent,
|
||||
/// the only indication of a font subset is the subset tag in the FontName entry.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.String | KeyType.Optional)]
|
||||
public const string CharSet = "/CharSet";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_meta == null)
|
||||
_meta = CreateMeta(typeof(Keys));
|
||||
return _meta;
|
||||
}
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
143
PrintPDF/PdfSharp/Pdf.Advanced/PdfFontTable.cs
Normal file
143
PrintPDF/PdfSharp/Pdf.Advanced/PdfFontTable.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
internal enum FontType
|
||||
{
|
||||
/// <summary>
|
||||
/// TrueType with WinAnsi encoding.
|
||||
/// </summary>
|
||||
TrueType = 1,
|
||||
|
||||
/// <summary>
|
||||
/// TrueType with Identity-H or Identity-V encoding (unicode).
|
||||
/// </summary>
|
||||
Type0 = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains all used fonts of a document.
|
||||
/// </summary>
|
||||
internal sealed class PdfFontTable : PdfResourceTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of this class, which is a singleton for each document.
|
||||
/// </summary>
|
||||
public PdfFontTable(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PdfFont from an XFont. If no PdfFont already exists, a new one is created.
|
||||
/// </summary>
|
||||
public PdfFont GetFont(XFont font)
|
||||
{
|
||||
string selector = font.Selector;
|
||||
if (selector == null)
|
||||
{
|
||||
selector = ComputeKey(font); //new FontSelector(font);
|
||||
font.Selector = selector;
|
||||
}
|
||||
PdfFont pdfFont;
|
||||
if (!_fonts.TryGetValue(selector, out pdfFont))
|
||||
{
|
||||
if (font.Unicode)
|
||||
pdfFont = new PdfType0Font(Owner, font, font.IsVertical);
|
||||
else
|
||||
pdfFont = new PdfTrueTypeFont(Owner, font);
|
||||
//pdfFont.Document = _document;
|
||||
Debug.Assert(pdfFont.Owner == Owner);
|
||||
_fonts[selector] = pdfFont;
|
||||
}
|
||||
return pdfFont;
|
||||
}
|
||||
|
||||
#if true
|
||||
/// <summary>
|
||||
/// Gets a PdfFont from a font program. If no PdfFont already exists, a new one is created.
|
||||
/// </summary>
|
||||
public PdfFont GetFont(string idName, byte[] fontData)
|
||||
{
|
||||
Debug.Assert(false);
|
||||
//FontSelector selector = new FontSelector(idName);
|
||||
string selector = null; // ComputeKey(font); //new FontSelector(font);
|
||||
PdfFont pdfFont;
|
||||
if (!_fonts.TryGetValue(selector, out pdfFont))
|
||||
{
|
||||
//if (font.Unicode)
|
||||
pdfFont = new PdfType0Font(Owner, idName, fontData, false);
|
||||
//else
|
||||
// pdfFont = new PdfTrueTypeFont(_owner, font);
|
||||
//pdfFont.Document = _document;
|
||||
Debug.Assert(pdfFont.Owner == Owner);
|
||||
_fonts[selector] = pdfFont;
|
||||
}
|
||||
return pdfFont;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Tries to gets a PdfFont from the font dictionary.
|
||||
/// Returns null if no such PdfFont exists.
|
||||
/// </summary>
|
||||
public PdfFont TryGetFont(string idName)
|
||||
{
|
||||
Debug.Assert(false);
|
||||
//FontSelector selector = new FontSelector(idName);
|
||||
string selector = null;
|
||||
PdfFont pdfFont;
|
||||
_fonts.TryGetValue(selector, out pdfFont);
|
||||
return pdfFont;
|
||||
}
|
||||
|
||||
internal static string ComputeKey(XFont font)
|
||||
{
|
||||
XGlyphTypeface glyphTypeface = font.GlyphTypeface;
|
||||
string key = glyphTypeface.Fontface.FullFaceName.ToLowerInvariant() +
|
||||
(glyphTypeface.IsBold ? "/b" : "") + (glyphTypeface.IsItalic ? "/i" : "") + font.Unicode;
|
||||
return key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map from PdfFontSelector to PdfFont.
|
||||
/// </summary>
|
||||
readonly Dictionary<string, PdfFont> _fonts = new Dictionary<string, PdfFont>();
|
||||
|
||||
public void PrepareForSave()
|
||||
{
|
||||
foreach (PdfFont font in _fonts.Values)
|
||||
font.PrepareForSave();
|
||||
}
|
||||
}
|
||||
}
|
509
PrintPDF/PdfSharp/Pdf.Advanced/PdfFormXObject.cs
Normal file
509
PrintPDF/PdfSharp/Pdf.Advanced/PdfFormXObject.cs
Normal file
@@ -0,0 +1,509 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an external form object (e.g. an imported page).
|
||||
/// </summary>
|
||||
public sealed class PdfFormXObject : PdfXObject, IContentStream
|
||||
{
|
||||
internal PdfFormXObject(PdfDocument thisDocument)
|
||||
: base(thisDocument)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/XObject");
|
||||
Elements.SetName(Keys.Subtype, "/Form");
|
||||
}
|
||||
|
||||
internal PdfFormXObject(PdfDocument thisDocument, XForm form)
|
||||
: base(thisDocument)
|
||||
{
|
||||
// BUG: form is not used
|
||||
Elements.SetName(Keys.Type, "/XObject");
|
||||
Elements.SetName(Keys.Subtype, "/Form");
|
||||
|
||||
//if (form.IsTemplate)
|
||||
//{ }
|
||||
}
|
||||
|
||||
internal double DpiX
|
||||
{
|
||||
get { return _dpiX; }
|
||||
set { _dpiX = value; }
|
||||
}
|
||||
double _dpiX = 72;
|
||||
|
||||
internal double DpiY
|
||||
{
|
||||
get { return _dpiY; }
|
||||
set { _dpiY = value; }
|
||||
}
|
||||
double _dpiY = 72;
|
||||
|
||||
internal PdfFormXObject(PdfDocument thisDocument, PdfImportedObjectTable importedObjectTable, XPdfForm form)
|
||||
: base(thisDocument)
|
||||
{
|
||||
Debug.Assert(importedObjectTable != null);
|
||||
Debug.Assert(ReferenceEquals(thisDocument, importedObjectTable.Owner));
|
||||
Elements.SetName(Keys.Type, "/XObject");
|
||||
Elements.SetName(Keys.Subtype, "/Form");
|
||||
|
||||
if (form.IsTemplate)
|
||||
{
|
||||
Debug.Assert(importedObjectTable == null);
|
||||
// TODO more initialization here???
|
||||
return;
|
||||
}
|
||||
|
||||
XPdfForm pdfForm = form;
|
||||
// Get import page
|
||||
PdfPages importPages = importedObjectTable.ExternalDocument.Pages;
|
||||
if (pdfForm.PageNumber < 1 || pdfForm.PageNumber > importPages.Count)
|
||||
PSSR.ImportPageNumberOutOfRange(pdfForm.PageNumber, importPages.Count, form._path);
|
||||
PdfPage importPage = importPages[pdfForm.PageNumber - 1];
|
||||
|
||||
// Import resources
|
||||
PdfItem res = importPage.Elements["/Resources"];
|
||||
if (res != null) // unlikely but possible
|
||||
{
|
||||
#if true
|
||||
// Get root object
|
||||
PdfObject root;
|
||||
if (res is PdfReference)
|
||||
root = ((PdfReference)res).Value;
|
||||
else
|
||||
root = (PdfDictionary)res;
|
||||
|
||||
root = ImportClosure(importedObjectTable, thisDocument, root);
|
||||
// If the root was a direct object, make it indirect.
|
||||
if (root.Reference == null)
|
||||
thisDocument._irefTable.Add(root);
|
||||
|
||||
Debug.Assert(root.Reference != null);
|
||||
Elements["/Resources"] = root.Reference;
|
||||
#else
|
||||
// Get transitive closure
|
||||
PdfObject[] resources = importPage.Owner.Internals.GetClosure(resourcesRoot);
|
||||
int count = resources.Length;
|
||||
#if DEBUG_
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
Debug.Assert(resources[idx].XRef != null);
|
||||
Debug.Assert(resources[idx].XRef.Document != null);
|
||||
Debug.Assert(resources[idx].Document != null);
|
||||
if (resources[idx].ObjectID.ObjectNumber == 12)
|
||||
GetType();
|
||||
}
|
||||
#endif
|
||||
// 1st step. Already imported objects are reused and new ones are cloned.
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
PdfObject obj = resources[idx];
|
||||
if (importedObjectTable.Contains(obj.ObjectID))
|
||||
{
|
||||
// external object was already imported
|
||||
PdfReference iref = importedObjectTable[obj.ObjectID];
|
||||
Debug.Assert(iref != null);
|
||||
Debug.Assert(iref.Value != null);
|
||||
Debug.Assert(iref.Document == Owner);
|
||||
// replace external object by the already clone counterpart
|
||||
resources[idx] = iref.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// External object was not imported earlier and must be cloned
|
||||
PdfObject clone = obj.Clone();
|
||||
Debug.Assert(clone.Reference == null);
|
||||
clone.Document = Owner;
|
||||
if (obj.Reference != null)
|
||||
{
|
||||
// add it to this (the importer) document
|
||||
Owner.irefTable.Add(clone);
|
||||
Debug.Assert(clone.Reference != null);
|
||||
// save old object identifier
|
||||
importedObjectTable.Add(obj.ObjectID, clone.Reference);
|
||||
//Debug.WriteLine("Cloned: " + obj.ObjectID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The root object (the /Resources value) is not an indirect object
|
||||
Debug.Assert(idx == 0);
|
||||
// add it to this (the importer) document
|
||||
Owner.irefTable.Add(clone);
|
||||
Debug.Assert(clone.Reference != null);
|
||||
}
|
||||
// replace external object by its clone
|
||||
resources[idx] = clone;
|
||||
}
|
||||
}
|
||||
#if DEBUG_
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
Debug.Assert(resources[idx].XRef != null);
|
||||
Debug.Assert(resources[idx].XRef.Document != null);
|
||||
Debug.Assert(resources[idx].Document != null);
|
||||
if (resources[idx].ObjectID.ObjectNumber == 12)
|
||||
GetType();
|
||||
}
|
||||
#endif
|
||||
|
||||
// 2nd step. Fix up indirect references that still refers to the import document.
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
PdfObject obj = resources[idx];
|
||||
Debug.Assert(obj.Owner != null);
|
||||
FixUpObject(importedObjectTable, importedObjectTable.Owner, obj);
|
||||
}
|
||||
|
||||
// Set resources key to the root of the clones
|
||||
Elements["/Resources"] = resources[0].Reference;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Take /Rotate into account.
|
||||
PdfRectangle rect = importPage.Elements.GetRectangle(PdfPage.Keys.MediaBox);
|
||||
// Reduce rotation to 0, 90, 180, or 270.
|
||||
int rotate = (importPage.Elements.GetInteger(PdfPage.Keys.Rotate) % 360 + 360) % 360;
|
||||
//rotate = 0;
|
||||
if (rotate == 0)
|
||||
{
|
||||
// Set bounding box to media box.
|
||||
Elements["/BBox"] = rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Have to adjust bounding box? (I think not, but I'm not sure -> wait for problem)
|
||||
Elements["/BBox"] = rect;
|
||||
|
||||
// Rotate the image such that it is upright.
|
||||
XMatrix matrix = new XMatrix();
|
||||
double width = rect.Width;
|
||||
double height = rect.Height;
|
||||
matrix.RotateAtPrepend(-rotate, new XPoint(width / 2, height / 2));
|
||||
|
||||
// Translate the image such that its center lies on the center of the rotated bounding box.
|
||||
double offset = (height - width) / 2;
|
||||
if (rotate == 90)
|
||||
{
|
||||
// TODO It seems we can simplify this as the sign of offset changes too.
|
||||
if (height > width)
|
||||
matrix.TranslatePrepend(offset, offset); // Tested.
|
||||
else
|
||||
matrix.TranslatePrepend(offset, offset); // TODO Test case.
|
||||
}
|
||||
else if (rotate == 270)
|
||||
{
|
||||
// TODO It seems we can simplify this as the sign of offset changes too.
|
||||
if (height > width)
|
||||
matrix.TranslatePrepend(-offset, -offset); // Tested.
|
||||
else
|
||||
matrix.TranslatePrepend(-offset, -offset); // Tested.
|
||||
}
|
||||
|
||||
//string item = "[" + PdfEncoders.ToString(matrix) + "]";
|
||||
//Elements[Keys.Matrix] = new PdfLiteral(item);
|
||||
Elements.SetMatrix(Keys.Matrix, matrix);
|
||||
}
|
||||
|
||||
// Preserve filter because the content keeps unmodified.
|
||||
PdfContent content = importPage.Contents.CreateSingleContent();
|
||||
#if !DEBUG
|
||||
content.Compressed = true;
|
||||
#endif
|
||||
PdfItem filter = content.Elements["/Filter"];
|
||||
if (filter != null)
|
||||
Elements["/Filter"] = filter.Clone();
|
||||
|
||||
// (no cloning needed because the bytes keep untouched)
|
||||
Stream = content.Stream; // new PdfStream(bytes, this);
|
||||
Elements.SetInteger("/Length", content.Stream.Value.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PdfResources object of this form.
|
||||
/// </summary>
|
||||
public PdfResources Resources
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_resources == null)
|
||||
_resources = (PdfResources)Elements.GetValue(Keys.Resources, VCF.Create);
|
||||
return _resources;
|
||||
}
|
||||
}
|
||||
PdfResources _resources;
|
||||
|
||||
PdfResources IContentStream.Resources
|
||||
{
|
||||
get { return Resources; }
|
||||
}
|
||||
|
||||
internal string GetFontName(XFont font, out PdfFont pdfFont)
|
||||
{
|
||||
pdfFont = _document.FontTable.GetFont(font);
|
||||
Debug.Assert(pdfFont != null);
|
||||
string name = Resources.AddFont(pdfFont);
|
||||
return name;
|
||||
}
|
||||
|
||||
string IContentStream.GetFontName(XFont font, out PdfFont pdfFont)
|
||||
{
|
||||
return GetFontName(font, out pdfFont);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the specified font data within this form XObject.
|
||||
/// </summary>
|
||||
internal string GetFontName(string idName, byte[] fontData, out PdfFont pdfFont)
|
||||
{
|
||||
pdfFont = _document.FontTable.GetFont(idName, fontData);
|
||||
Debug.Assert(pdfFont != null);
|
||||
string name = Resources.AddFont(pdfFont);
|
||||
return name;
|
||||
}
|
||||
|
||||
string IContentStream.GetFontName(string idName, byte[] fontData, out PdfFont pdfFont)
|
||||
{
|
||||
return GetFontName(idName, fontData, out pdfFont);
|
||||
}
|
||||
|
||||
string IContentStream.GetImageName(XImage image)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
string IContentStream.GetFormName(XForm form)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if keep_code_some_time_as_reference
|
||||
/// <summary>
|
||||
/// Replace all indirect references to external objects by their cloned counterparts
|
||||
/// owned by the importer document.
|
||||
/// </summary>
|
||||
void FixUpObject_old(PdfImportedObjectTable iot, PdfObject value)
|
||||
{
|
||||
// TODO: merge with PdfXObject.FixUpObject
|
||||
PdfDictionary dict;
|
||||
PdfArray array;
|
||||
if ((dict = value as PdfDictionary) != null)
|
||||
{
|
||||
// Set document for cloned direct objects
|
||||
if (dict.Owner == null)
|
||||
dict.Document = Owner;
|
||||
else
|
||||
Debug.Assert(dict.Owner == Owner);
|
||||
|
||||
// Search for indirect references in all keys
|
||||
PdfName[] names = dict.Elements.KeyNames;
|
||||
foreach (PdfName name in names)
|
||||
{
|
||||
PdfItem item = dict.Elements[name];
|
||||
// Is item an iref?
|
||||
PdfReference iref = item as PdfReference;
|
||||
if (iref != null)
|
||||
{
|
||||
// Does the iref already belong to this document?
|
||||
if (iref.Document == Owner)
|
||||
{
|
||||
// Yes: fine
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(iref.Document == iot.ExternalDocument);
|
||||
// No: replace with iref of cloned object
|
||||
PdfReference newXRef = iot[iref.ObjectID];
|
||||
Debug.Assert(newXRef != null);
|
||||
Debug.Assert(newXRef.Document == Owner);
|
||||
dict.Elements[name] = newXRef;
|
||||
}
|
||||
}
|
||||
else if (item is PdfObject)
|
||||
{
|
||||
// Fix up inner objects
|
||||
FixUpObject_old(iot, (PdfObject)item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((array = value as PdfArray) != null)
|
||||
{
|
||||
// Set document for cloned direct objects
|
||||
if (array.Owner == null)
|
||||
array.Document = Owner;
|
||||
else
|
||||
Debug.Assert(array.Owner == Owner);
|
||||
|
||||
// Search for indirect references in all array elements
|
||||
int count = array.Elements.Count;
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
{
|
||||
PdfItem item = array.Elements[idx];
|
||||
// Is item an iref?
|
||||
PdfReference iref = item as PdfReference;
|
||||
if (iref != null)
|
||||
{
|
||||
// Does the iref belongs to this document?
|
||||
if (iref.Document == Owner)
|
||||
{
|
||||
// Yes: fine
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(iref.Document == iot.ExternalDocument);
|
||||
// No: replace with iref of cloned object
|
||||
PdfReference newXRef = iot[iref.ObjectID];
|
||||
Debug.Assert(newXRef != null);
|
||||
Debug.Assert(newXRef.Document == Owner);
|
||||
array.Elements[idx] = newXRef;
|
||||
}
|
||||
}
|
||||
else if (item is PdfObject)
|
||||
{
|
||||
// Fix up inner objects
|
||||
FixUpObject_old(iot, (PdfObject)item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// /// <summary>
|
||||
// /// Returns ???
|
||||
// /// </summary>
|
||||
// public override string ToString()
|
||||
// {
|
||||
// return "Form";
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public sealed new class Keys : PdfXObject.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Optional) The type of PDF object that this dictionary describes; if present,
|
||||
/// must be XObject for a form XObject.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of XObject that this dictionary describes; must be Form
|
||||
/// for a form XObject.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string Subtype = "/Subtype";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A code identifying the type of form XObject that this dictionary
|
||||
/// describes. The only valid value defined at the time of publication is 1.
|
||||
/// Default value: 1.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public const string FormType = "/FormType";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) An array of four numbers in the form coordinate system, giving the
|
||||
/// coordinates of the left, bottom, right, and top edges, respectively, of the
|
||||
/// form XObject<63>s bounding box. These boundaries are used to clip the form XObject
|
||||
/// and to determine its size for caching.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Rectangle | KeyType.Required)]
|
||||
public const string BBox = "/BBox";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of six numbers specifying the form matrix, which maps
|
||||
/// form space into user space.
|
||||
/// Default value: the identity matrix [1 0 0 1 0 0].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Matrix = "/Matrix";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional but strongly recommended; PDF 1.2) A dictionary specifying any
|
||||
/// resources (such as fonts and images) required by the form XObject.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResources))]
|
||||
public const string Resources = "/Resources";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.4) A group attributes dictionary indicating that the contents
|
||||
/// of the form XObject are to be treated as a group and specifying the attributes
|
||||
/// of that group (see Section 4.9.2, <20>Group XObjects<74>).
|
||||
/// Note: If a Ref entry (see below) is present, the group attributes also apply to the
|
||||
/// external page imported by that entry, which allows such an imported page to be
|
||||
/// treated as a group without further modification.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string Group = "/Group";
|
||||
|
||||
// further keys:
|
||||
//Ref
|
||||
//Metadata
|
||||
//PieceInfo
|
||||
//LastModified
|
||||
//StructParent
|
||||
//StructParents
|
||||
//OPI
|
||||
//OC
|
||||
//Name
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
228
PrintPDF/PdfSharp/Pdf.Advanced/PdfFormXObjectTable.cs
Normal file
228
PrintPDF/PdfSharp/Pdf.Advanced/PdfFormXObjectTable.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains all external PDF files from which PdfFormXObjects are imported into the current document.
|
||||
/// </summary>
|
||||
internal sealed class PdfFormXObjectTable : PdfResourceTable
|
||||
{
|
||||
// The name PdfFormXObjectTable is technically not correct, because in contrast to PdfFontTable
|
||||
// or PdfImageTable this class holds no PdfFormXObject objects. Actually it holds instances of
|
||||
// the class ImportedObjectTable, one for each external document. The PdfFormXObject instances
|
||||
// are not cached, because they hold a transformation matrix that make them unique. If the user
|
||||
// wants to use a particual page of a PdfFormXObject more than once, he must reuse the object
|
||||
// before he changes the PageNumber or the transformation matrix. In other words this class
|
||||
// caches the indirect objects of an external form, not the form itself.
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of this class, which is a singleton for each document.
|
||||
/// </summary>
|
||||
public PdfFormXObjectTable(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PdfFormXObject from an XPdfForm. Because the returned objects must be unique, always
|
||||
/// a new instance of PdfFormXObject is created if none exists for the specified form.
|
||||
/// </summary>
|
||||
public PdfFormXObject GetForm(XForm form)
|
||||
{
|
||||
// If the form already has a PdfFormXObject, return it.
|
||||
if (form._pdfForm != null)
|
||||
{
|
||||
Debug.Assert(form.IsTemplate, "An XPdfForm must not have a PdfFormXObject.");
|
||||
if (ReferenceEquals(form._pdfForm.Owner, Owner))
|
||||
return form._pdfForm;
|
||||
//throw new InvalidOperationException("Because of a current limitation of PDFsharp an XPdfForm object can be used only within one single PdfDocument.");
|
||||
|
||||
// Dispose PdfFromXObject when document has changed
|
||||
form._pdfForm = null;
|
||||
}
|
||||
|
||||
XPdfForm pdfForm = form as XPdfForm;
|
||||
if (pdfForm != null)
|
||||
{
|
||||
// Is the external PDF file from which is imported already known for the current document?
|
||||
Selector selector = new Selector(form);
|
||||
PdfImportedObjectTable importedObjectTable;
|
||||
if (!_forms.TryGetValue(selector, out importedObjectTable))
|
||||
{
|
||||
// No: Get the external document from the form and create ImportedObjectTable.
|
||||
PdfDocument doc = pdfForm.ExternalDocument;
|
||||
importedObjectTable = new PdfImportedObjectTable(Owner, doc);
|
||||
_forms[selector] = importedObjectTable;
|
||||
}
|
||||
|
||||
PdfFormXObject xObject = importedObjectTable.GetXObject(pdfForm.PageNumber);
|
||||
if (xObject == null)
|
||||
{
|
||||
xObject = new PdfFormXObject(Owner, importedObjectTable, pdfForm);
|
||||
importedObjectTable.SetXObject(pdfForm.PageNumber, xObject);
|
||||
}
|
||||
return xObject;
|
||||
}
|
||||
Debug.Assert(form.GetType() == typeof(XForm));
|
||||
form._pdfForm = new PdfFormXObject(Owner, form);
|
||||
return form._pdfForm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the imported object table.
|
||||
/// </summary>
|
||||
public PdfImportedObjectTable GetImportedObjectTable(PdfPage page)
|
||||
{
|
||||
// Is the external PDF file from which is imported already known for the current document?
|
||||
Selector selector = new Selector(page);
|
||||
PdfImportedObjectTable importedObjectTable;
|
||||
if (!_forms.TryGetValue(selector, out importedObjectTable))
|
||||
{
|
||||
importedObjectTable = new PdfImportedObjectTable(Owner, page.Owner);
|
||||
_forms[selector] = importedObjectTable;
|
||||
}
|
||||
return importedObjectTable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the imported object table.
|
||||
/// </summary>
|
||||
public PdfImportedObjectTable GetImportedObjectTable(PdfDocument document)
|
||||
{
|
||||
if (document == null)
|
||||
throw new ArgumentNullException("document");
|
||||
|
||||
// Is the external PDF file from which is imported already known for the current document?
|
||||
Selector selector = new Selector(document);
|
||||
PdfImportedObjectTable importedObjectTable;
|
||||
if (!_forms.TryGetValue(selector, out importedObjectTable))
|
||||
{
|
||||
// Create new table for document.
|
||||
importedObjectTable = new PdfImportedObjectTable(Owner, document);
|
||||
_forms[selector] = importedObjectTable;
|
||||
}
|
||||
return importedObjectTable;
|
||||
}
|
||||
|
||||
public void DetachDocument(PdfDocument.DocumentHandle handle)
|
||||
{
|
||||
if (handle.IsAlive)
|
||||
{
|
||||
foreach (Selector selector in _forms.Keys)
|
||||
{
|
||||
PdfImportedObjectTable table = _forms[selector];
|
||||
if (table.ExternalDocument != null && table.ExternalDocument.Handle == handle)
|
||||
{
|
||||
_forms.Remove(selector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean table
|
||||
bool itemRemoved = true;
|
||||
while (itemRemoved)
|
||||
{
|
||||
itemRemoved = false;
|
||||
foreach (Selector selector in _forms.Keys)
|
||||
{
|
||||
PdfImportedObjectTable table = _forms[selector];
|
||||
if (table.ExternalDocument == null)
|
||||
{
|
||||
_forms.Remove(selector);
|
||||
itemRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map from Selector to PdfImportedObjectTable.
|
||||
/// </summary>
|
||||
readonly Dictionary<Selector, PdfImportedObjectTable> _forms = new Dictionary<Selector, PdfImportedObjectTable>();
|
||||
|
||||
/// <summary>
|
||||
/// A collection of information that uniquely identifies a particular ImportedObjectTable.
|
||||
/// </summary>
|
||||
public class Selector
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of FormSelector from an XPdfForm.
|
||||
/// </summary>
|
||||
public Selector(XForm form)
|
||||
{
|
||||
// HACK: just use full path to identify
|
||||
_path = form._path.ToLowerInvariant();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of FormSelector from a PdfPage.
|
||||
/// </summary>
|
||||
public Selector(PdfPage page)
|
||||
{
|
||||
PdfDocument owner = page.Owner;
|
||||
_path = "*" + owner.Guid.ToString("B");
|
||||
_path = _path.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public Selector(PdfDocument document)
|
||||
{
|
||||
_path = "*" + document.Guid.ToString("B");
|
||||
_path = _path.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get { return _path; }
|
||||
set { _path = value; }
|
||||
}
|
||||
string _path;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Selector selector = obj as Selector;
|
||||
if (selector == null)
|
||||
return false;
|
||||
return _path == selector._path;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _path.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
90
PrintPDF/PdfSharp/Pdf.Advanced/PdfGroupAttributes.cs
Normal file
90
PrintPDF/PdfSharp/Pdf.Advanced/PdfGroupAttributes.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF group XObject.
|
||||
/// </summary>
|
||||
public abstract class PdfGroupAttributes : PdfDictionary
|
||||
{
|
||||
internal PdfGroupAttributes(PdfDocument thisDocument)
|
||||
: base(thisDocument)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Group");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public class Keys : KeysBase
|
||||
{
|
||||
/// <summary>
|
||||
///(Optional) The type of PDF object that this dictionary describes;
|
||||
///if present, must be Group for a group attributes dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The group subtype, which identifies the type of group whose
|
||||
/// attributes this dictionary describes and determines the format and meaning
|
||||
/// of the dictionary<72>s remaining entries. The only group subtype defined in
|
||||
/// PDF 1.4 is Transparency. Other group subtypes may be added in the future.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string S = "/S";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
840
PrintPDF/PdfSharp/Pdf.Advanced/PdfImage.FaxEncode.cs
Normal file
840
PrintPDF/PdfSharp/Pdf.Advanced/PdfImage.FaxEncode.cs
Normal file
@@ -0,0 +1,840 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
// Thomas Hövel
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Some routines were translated from LibTiff.
|
||||
// LibTiff copyright notice:
|
||||
// Copyright (c) 1988-1997 Sam Leffler
|
||||
// Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, distribute, and sell this software and
|
||||
// its documentation for any purpose is hereby granted without fee, provided
|
||||
// that (i) the above copyright notices and this permission notice appear in
|
||||
// all copies of the software and related documentation, and (ii) the names of
|
||||
// Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
// publicity relating to the software without the specific, prior written
|
||||
// permission of Sam Leffler and Silicon Graphics.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
// ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
// LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
// OF THIS SOFTWARE.
|
||||
|
||||
#endregion
|
||||
|
||||
#define USE_GOTO
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
partial class PdfImage
|
||||
{
|
||||
internal readonly static uint[] WhiteTerminatingCodes =
|
||||
{
|
||||
0x35, 8, //00110101 // 0
|
||||
0x07, 6, //000111
|
||||
0x07, 4, //0111
|
||||
0x08, 4, //1000
|
||||
0x0b, 4, //1011
|
||||
0x0c, 4, //1100
|
||||
0x0e, 4, //1110
|
||||
0x0f, 4, //1111
|
||||
0x13, 5, //10011
|
||||
0x14, 5, //10100
|
||||
0x07, 5, //00111 // 10
|
||||
0x08, 5, //01000
|
||||
0x08, 6, //001000
|
||||
0x03, 6, //000011
|
||||
0x34, 6, //110100
|
||||
0x35, 6, //110101
|
||||
0x2a, 6, //101010 // 16
|
||||
0x2b, 6, //101011
|
||||
0x27, 7, //0100111
|
||||
0x0c, 7, //0001100
|
||||
0x08, 7, //0001000 // 20
|
||||
0x17, 7, //0010111
|
||||
0x03, 7, //0000011
|
||||
0x04, 7, //0000100
|
||||
0x28, 7, //0101000
|
||||
0x2b, 7, //0101011
|
||||
0x13, 7, //0010011
|
||||
0x24, 7, //0100100
|
||||
0x18, 7, //0011000
|
||||
0x02, 8, //00000010
|
||||
0x03, 8, //00000011 // 30
|
||||
0x1a, 8, //00011010
|
||||
0x1b, 8, //00011011 // 32
|
||||
0x12, 8, //00010010
|
||||
0x13, 8, //00010011
|
||||
0x14, 8, //00010100
|
||||
0x15, 8, //00010101
|
||||
0x16, 8, //00010110
|
||||
0x17, 8, //00010111
|
||||
0x28, 8, //00101000
|
||||
0x29, 8, //00101001 // 40
|
||||
0x2a, 8, //00101010
|
||||
0x2b, 8, //00101011
|
||||
0x2c, 8, //00101100
|
||||
0x2d, 8, //00101101
|
||||
0x04, 8, //00000100
|
||||
0x05, 8, //00000101
|
||||
0x0a, 8, //00001010
|
||||
0x0b, 8, //00001011 // 48
|
||||
0x52, 8, //01010010
|
||||
0x53, 8, //01010011 // 50
|
||||
0x54, 8, //01010100
|
||||
0x55, 8, //01010101
|
||||
0x24, 8, //00100100
|
||||
0x25, 8, //00100101
|
||||
0x58, 8, //01011000
|
||||
0x59, 8, //01011001
|
||||
0x5a, 8, //01011010
|
||||
0x5b, 8, //01011011
|
||||
0x4a, 8, //01001010
|
||||
0x4b, 8, //01001011 // 60
|
||||
0x32, 8, //00110010
|
||||
0x33, 8, //00110011
|
||||
0x34, 8, //00110100 // 63
|
||||
};
|
||||
|
||||
internal readonly static uint[] BlackTerminatingCodes =
|
||||
{
|
||||
0x37, 10, //0000110111 // 0
|
||||
0x02, 3, //010
|
||||
0x03, 2, //11
|
||||
0x02, 2, //10
|
||||
0x03, 3, //011
|
||||
0x03, 4, //0011
|
||||
0x02, 4, //0010
|
||||
0x03, 5, //00011
|
||||
0x05, 6, //000101
|
||||
0x04, 6, //000100
|
||||
0x04, 7, //0000100
|
||||
0x05, 7, //0000101
|
||||
0x07, 7, //0000111
|
||||
0x04, 8, //00000100
|
||||
0x07, 8, //00000111
|
||||
0x18, 9, //000011000
|
||||
0x17, 10, //0000010111 // 16
|
||||
0x18, 10, //0000011000
|
||||
0x08, 10, //0000001000
|
||||
0x67, 11, //00001100111
|
||||
0x68, 11, //00001101000
|
||||
0x6c, 11, //00001101100
|
||||
0x37, 11, //00000110111
|
||||
0x28, 11, //00000101000
|
||||
0x17, 11, //00000010111
|
||||
0x18, 11, //00000011000
|
||||
0xca, 12, //000011001010
|
||||
0xcb, 12, //000011001011
|
||||
0xcc, 12, //000011001100
|
||||
0xcd, 12, //000011001101
|
||||
0x68, 12, //000001101000 // 30
|
||||
0x69, 12, //000001101001
|
||||
0x6a, 12, //000001101010 // 32
|
||||
0x6b, 12, //000001101011
|
||||
0xd2, 12, //000011010010
|
||||
0xd3, 12, //000011010011
|
||||
0xd4, 12, //000011010100
|
||||
0xd5, 12, //000011010101
|
||||
0xd6, 12, //000011010110
|
||||
0xd7, 12, //000011010111
|
||||
0x6c, 12, //000001101100
|
||||
0x6d, 12, //000001101101
|
||||
0xda, 12, //000011011010
|
||||
0xdb, 12, //000011011011
|
||||
0x54, 12, //000001010100
|
||||
0x55, 12, //000001010101
|
||||
0x56, 12, //000001010110
|
||||
0x57, 12, //000001010111
|
||||
0x64, 12, //000001100100 // 48
|
||||
0x65, 12, //000001100101
|
||||
0x52, 12, //000001010010
|
||||
0x53, 12, //000001010011
|
||||
0x24, 12, //000000100100
|
||||
0x37, 12, //000000110111
|
||||
0x38, 12, //000000111000
|
||||
0x27, 12, //000000100111
|
||||
0x28, 12, //000000101000
|
||||
0x58, 12, //000001011000
|
||||
0x59, 12, //000001011001
|
||||
0x2b, 12, //000000101011
|
||||
0x2c, 12, //000000101100
|
||||
0x5a, 12, //000001011010
|
||||
0x66, 12, //000001100110
|
||||
0x67, 12, //000001100111 // 63
|
||||
};
|
||||
|
||||
internal readonly static uint[] WhiteMakeUpCodes =
|
||||
{
|
||||
0x1b, 5, //11011 64 // 0
|
||||
0x12, 5, //10010 128
|
||||
0x17, 6, //010111 192
|
||||
0x37, 7, //0110111 256
|
||||
0x36, 8, //00110110 320
|
||||
0x37, 8, //00110111 384
|
||||
0x64, 8, //01100100 448
|
||||
0x65, 8, //01100101 512
|
||||
0x68, 8, //01101000 576
|
||||
0x67, 8, //01100111 640
|
||||
0xcc, 9, //011001100 704 // 10
|
||||
0xcd, 9, //011001101 768
|
||||
0xd2, 9, //011010010 832
|
||||
0xd3, 9, //011010011 896
|
||||
0xd4, 9, //011010100 960
|
||||
0xd5, 9, //011010101 1024
|
||||
0xd6, 9, //011010110 1088 // 16
|
||||
0xd7, 9, //011010111 1152
|
||||
0xd8, 9, //011011000 1216
|
||||
0xd9, 9, //011011001 1280
|
||||
0xda, 9, //011011010 1344
|
||||
0xdb, 9, //011011011 1408
|
||||
0x98, 9, //010011000 1472
|
||||
0x99, 9, //010011001 1536
|
||||
0x9a, 9, //010011010 1600
|
||||
0x18, 6, //011000 1664
|
||||
0x9b, 9, //010011011 1728
|
||||
// Common codes for white and black:
|
||||
0x08, 11, //00000001000 1792
|
||||
0x0c, 11, //00000001100 1856
|
||||
0x0d, 11, //00000001101 1920
|
||||
0x12, 12, //000000010010 1984
|
||||
0x13, 12, //000000010011 2048
|
||||
0x14, 12, //000000010100 2112 // 32
|
||||
0x15, 12, //000000010101 2176
|
||||
0x16, 12, //000000010110 2240
|
||||
0x17, 12, //000000010111 2304
|
||||
0x1c, 12, //000000011100 2368
|
||||
0x1d, 12, //000000011101 2432
|
||||
0x1e, 12, //000000011110 2496
|
||||
0x1f, 12, //000000011111 2560
|
||||
0x01, 12, //000000000001 EOL // 40
|
||||
};
|
||||
|
||||
internal readonly static uint[] BlackMakeUpCodes =
|
||||
{
|
||||
0x0f, 10, //0000001111 64 // 0
|
||||
0xc8, 12, //000011001000 128
|
||||
0xc9, 12, //000011001001 192
|
||||
0x5b, 12, //000001011011 256
|
||||
0x33, 12, //000000110011 320
|
||||
0x34, 12, //000000110100 384
|
||||
0x35, 12, //000000110101 448
|
||||
0x6c, 13, //0000001101100 512
|
||||
0x6d, 13, //0000001101101 576
|
||||
0x4a, 13, //0000001001010 640
|
||||
0x4b, 13, //0000001001011 704
|
||||
0x4c, 13, //0000001001100 768
|
||||
0x4d, 13, //0000001001101 832
|
||||
0x72, 13, //0000001110010 896
|
||||
0x73, 13, //0000001110011 960
|
||||
0x74, 13, //0000001110100 1024
|
||||
0x75, 13, //0000001110101 1088 // 16
|
||||
0x76, 13, //0000001110110 1152
|
||||
0x77, 13, //0000001110111 1216
|
||||
0x52, 13, //0000001010010 1280
|
||||
0x53, 13, //0000001010011 1344
|
||||
0x54, 13, //0000001010100 1408
|
||||
0x55, 13, //0000001010101 1472
|
||||
0x5a, 13, //0000001011010 1536
|
||||
0x5b, 13, //0000001011011 1600
|
||||
0x64, 13, //0000001100100 1664
|
||||
0x65, 13, //0000001100101 1728
|
||||
// Common codes for white and black:
|
||||
0x08, 11, //00000001000 1792
|
||||
0x0c, 11, //00000001100 1856
|
||||
0x0d, 11, //00000001101 1920
|
||||
0x12, 12, //000000010010 1984
|
||||
0x13, 12, //000000010011 2048
|
||||
0x14, 12, //000000010100 2112 // 32
|
||||
0x15, 12, //000000010101 2176
|
||||
0x16, 12, //000000010110 2240
|
||||
0x17, 12, //000000010111 2304
|
||||
0x1c, 12, //000000011100 2368
|
||||
0x1d, 12, //000000011101 2432
|
||||
0x1e, 12, //000000011110 2496
|
||||
0x1f, 12, //000000011111 2560
|
||||
0x01, 12, //000000000001 EOL // 40
|
||||
};
|
||||
|
||||
internal readonly static uint[] HorizontalCodes = { 0x1, 3 }; /* 001 */
|
||||
internal readonly static uint[] PassCodes = { 0x1, 4, }; /* 0001 */
|
||||
internal readonly static uint[] VerticalCodes =
|
||||
{
|
||||
0x03, 7, /* 0000 011 */
|
||||
0x03, 6, /* 0000 11 */
|
||||
0x03, 3, /* 011 */
|
||||
0x1, 1, /* 1 */
|
||||
0x2, 3, /* 010 */
|
||||
0x02, 6, /* 0000 10 */
|
||||
0x02, 7, /* 0000 010 */
|
||||
};
|
||||
|
||||
readonly static uint[] _zeroRuns =
|
||||
{
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */
|
||||
};
|
||||
|
||||
readonly static uint[] _oneRuns =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Counts the consecutive one bits in an image line.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="bitsLeft">The bits left.</param>
|
||||
private static uint CountOneBits(BitReader reader, uint bitsLeft)
|
||||
{
|
||||
uint found = 0;
|
||||
for (;;)
|
||||
{
|
||||
uint bits;
|
||||
int @byte = reader.PeekByte(out bits);
|
||||
uint hits = _oneRuns[@byte];
|
||||
if (hits < bits)
|
||||
{
|
||||
if (hits > 0)
|
||||
reader.SkipBits(hits);
|
||||
found += hits;
|
||||
return found >= bitsLeft ? bitsLeft : found;
|
||||
}
|
||||
found += bits;
|
||||
if (found >= bitsLeft)
|
||||
return bitsLeft;
|
||||
reader.NextByte();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the consecutive zero bits in an image line.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="bitsLeft">The bits left.</param>
|
||||
private static uint CountZeroBits(BitReader reader, uint bitsLeft)
|
||||
{
|
||||
uint found = 0;
|
||||
for (;;)
|
||||
{
|
||||
uint bits;
|
||||
int @byte = reader.PeekByte(out bits);
|
||||
uint hits = _zeroRuns[@byte];
|
||||
if (hits < bits)
|
||||
{
|
||||
if (hits > 0)
|
||||
reader.SkipBits(hits);
|
||||
found += hits;
|
||||
return found >= bitsLeft ? bitsLeft : found;
|
||||
}
|
||||
found += bits;
|
||||
if (found >= bitsLeft)
|
||||
return bitsLeft;
|
||||
reader.NextByte();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the offset of the next bit in the range
|
||||
/// [bitStart..bitEnd] that is different from the
|
||||
/// specified color. The end, bitEnd, is returned
|
||||
/// if no such bit exists.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="bitStart">The offset of the start bit.</param>
|
||||
/// <param name="bitEnd">The offset of the end bit.</param>
|
||||
/// <param name="searchOne">If set to <c>true</c> searches "one" (i. e. white), otherwise searches black.</param>
|
||||
/// <returns>The offset of the first non-matching bit.</returns>
|
||||
private static uint FindDifference(BitReader reader, uint bitStart, uint bitEnd, bool searchOne)
|
||||
{
|
||||
// Translated from LibTiff
|
||||
reader.SetPosition(bitStart);
|
||||
return (bitStart + (searchOne ? CountOneBits(reader, bitEnd - bitStart) : CountZeroBits(reader, bitEnd - bitStart)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the offset of the next bit in the range
|
||||
/// [bitStart..bitEnd] that is different from the
|
||||
/// specified color. The end, bitEnd, is returned
|
||||
/// if no such bit exists.
|
||||
/// Like FindDifference, but also check the
|
||||
/// starting bit against the end in case start > end.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="bitStart">The offset of the start bit.</param>
|
||||
/// <param name="bitEnd">The offset of the end bit.</param>
|
||||
/// <param name="searchOne">If set to <c>true</c> searches "one" (i. e. white), otherwise searches black.</param>
|
||||
/// <returns>The offset of the first non-matching bit.</returns>
|
||||
private static uint FindDifferenceWithCheck(BitReader reader, uint bitStart, uint bitEnd, bool searchOne)
|
||||
{
|
||||
// Translated from LibTiff
|
||||
return ((bitStart < bitEnd) ? FindDifference(reader, bitStart, bitEnd, searchOne) : bitEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2d-encode a row of pixels. Consult the CCITT documentation for the algorithm.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
|
||||
/// <param name="imageBits">The bitmap file.</param>
|
||||
/// <param name="currentRow">Index of the current row.</param>
|
||||
/// <param name="referenceRow">Index of the reference row (0xffffffff if there is none).</param>
|
||||
/// <param name="width">The width of the image.</param>
|
||||
/// <param name="height">The height of the image.</param>
|
||||
/// <param name="bytesPerLineBmp">The bytes per line in the bitmap file.</param>
|
||||
static void FaxEncode2DRow(BitWriter writer, uint bytesFileOffset, byte[] imageBits, uint currentRow, uint referenceRow, uint width, uint height, uint bytesPerLineBmp)
|
||||
{
|
||||
// Translated from LibTiff
|
||||
uint bytesOffsetRead = bytesFileOffset + (height - 1 - currentRow) * bytesPerLineBmp;
|
||||
BitReader reader = new BitReader(imageBits, bytesOffsetRead, width);
|
||||
BitReader readerReference;
|
||||
if (referenceRow != 0xffffffff)
|
||||
{
|
||||
uint bytesOffsetReadReference = bytesFileOffset + (height - 1 - referenceRow) * bytesPerLineBmp;
|
||||
readerReference = new BitReader(imageBits, bytesOffsetReadReference, width);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] tmpImageBits = new byte[bytesPerLineBmp];
|
||||
for (int i = 0; i < bytesPerLineBmp; ++i)
|
||||
tmpImageBits[i] = 255;
|
||||
readerReference = new BitReader(tmpImageBits, 0, width);
|
||||
}
|
||||
|
||||
uint a0 = 0;
|
||||
uint a1 = !reader.GetBit(0) ? 0 : FindDifference(reader, 0, width, true);
|
||||
uint b1 = !readerReference.GetBit(0) ? 0 : FindDifference(readerReference, 0, width, true);
|
||||
// ReSharper disable TooWideLocalVariableScope
|
||||
uint a2, b2;
|
||||
// ReSharper restore TooWideLocalVariableScope
|
||||
|
||||
for (;;)
|
||||
{
|
||||
b2 = FindDifferenceWithCheck(readerReference, b1, width, readerReference.GetBit(b1));
|
||||
if (b2 >= a1)
|
||||
{
|
||||
int d = (int)b1 - (int)a1;
|
||||
if (!(-3 <= d && d <= 3))
|
||||
{
|
||||
/* horizontal mode */
|
||||
a2 = FindDifferenceWithCheck(reader, a1, width, reader.GetBit(a1));
|
||||
writer.WriteTableLine(HorizontalCodes, 0);
|
||||
|
||||
if (a0 + a1 == 0 || reader.GetBit(a0))
|
||||
{
|
||||
WriteSample(writer, a1 - a0, true);
|
||||
WriteSample(writer, a2 - a1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteSample(writer, a1 - a0, false);
|
||||
WriteSample(writer, a2 - a1, true);
|
||||
}
|
||||
a0 = a2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* vertical mode */
|
||||
writer.WriteTableLine(VerticalCodes, (uint)(d + 3));
|
||||
a0 = a1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pass mode */
|
||||
writer.WriteTableLine(PassCodes, 0);
|
||||
a0 = b2;
|
||||
}
|
||||
if (a0 >= width)
|
||||
break;
|
||||
bool bitA0 = reader.GetBit(a0);
|
||||
a1 = FindDifference(reader, a0, width, bitA0/*reader.GetBit(a0)*/);
|
||||
b1 = FindDifference(readerReference, a0, width, !bitA0/*reader.GetBit(a0)*/);
|
||||
b1 = FindDifferenceWithCheck(readerReference, b1, width, bitA0/*reader.GetBit(a0)*/);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a bitonal bitmap using 1D CCITT fax encoding.
|
||||
/// </summary>
|
||||
/// <param name="imageData">Space reserved for the fax encoded bitmap. An exception will be thrown if this buffer is too small.</param>
|
||||
/// <param name="imageBits">The bitmap to be encoded.</param>
|
||||
/// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
|
||||
/// <param name="width">The width of the image.</param>
|
||||
/// <param name="height">The height of the image.</param>
|
||||
/// <returns>The size of the fax encoded image (0 on failure).</returns>
|
||||
private static int DoFaxEncoding(ref byte[] imageData, byte[] imageBits, uint bytesFileOffset, uint width, uint height)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint bytesPerLineBmp = ((width + 31) / 32) * 4;
|
||||
BitWriter writer = new BitWriter(ref imageData);
|
||||
for (uint y = 0; y < height; ++y)
|
||||
{
|
||||
uint bytesOffsetRead = bytesFileOffset + (height - 1 - y) * bytesPerLineBmp;
|
||||
BitReader reader = new BitReader(imageBits, bytesOffsetRead, width);
|
||||
for (uint bitsRead = 0; bitsRead < width;)
|
||||
{
|
||||
uint white = CountOneBits(reader, width - bitsRead);
|
||||
WriteSample(writer, white, true);
|
||||
bitsRead += white;
|
||||
if (bitsRead < width)
|
||||
{
|
||||
uint black = CountZeroBits(reader, width - bitsRead);
|
||||
WriteSample(writer, black, false);
|
||||
bitsRead += black;
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.FlushBuffer();
|
||||
return writer.BytesWritten();
|
||||
}
|
||||
catch (Exception /*ex*/)
|
||||
{
|
||||
//ex.GetType();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a bitonal bitmap using 2D group 4 CCITT fax encoding.
|
||||
/// </summary>
|
||||
/// <param name="imageData">Space reserved for the fax encoded bitmap. An exception will be thrown if this buffer is too small.</param>
|
||||
/// <param name="imageBits">The bitmap to be encoded.</param>
|
||||
/// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
|
||||
/// <param name="width">The width of the image.</param>
|
||||
/// <param name="height">The height of the image.</param>
|
||||
/// <returns>The size of the fax encoded image (0 on failure).</returns>
|
||||
internal static int DoFaxEncodingGroup4(ref byte[] imageData, byte[] imageBits, uint bytesFileOffset, uint width, uint height)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint bytesPerLineBmp = ((width + 31) / 32) * 4;
|
||||
BitWriter writer = new BitWriter(ref imageData);
|
||||
for (uint y = 0; y < height; ++y)
|
||||
{
|
||||
FaxEncode2DRow(writer, bytesFileOffset, imageBits, y, (y != 0) ? y - 1 : 0xffffffff, width, height, bytesPerLineBmp);
|
||||
}
|
||||
writer.FlushBuffer();
|
||||
return writer.BytesWritten();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.GetType();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the image data.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="count">The count of bits (pels) to encode.</param>
|
||||
/// <param name="white">The color of the pels.</param>
|
||||
private static void WriteSample(BitWriter writer, uint count, bool white)
|
||||
{
|
||||
uint[] terminatingCodes = white ? WhiteTerminatingCodes : BlackTerminatingCodes;
|
||||
uint[] makeUpCodes = white ? WhiteMakeUpCodes : BlackMakeUpCodes;
|
||||
|
||||
// The make-up code for 2560 will be written as often as required:
|
||||
while (count >= 2624)
|
||||
{
|
||||
writer.WriteTableLine(makeUpCodes, 39); // Magic: 2560
|
||||
count -= 2560;
|
||||
}
|
||||
// A make-up code for a multiple of 64 will be written if required:
|
||||
if (count > 63)
|
||||
{
|
||||
uint line = count / 64 - 1;
|
||||
writer.WriteTableLine(makeUpCodes, line);
|
||||
count -= (line + 1) * 64;
|
||||
}
|
||||
// And finally the terminating code for the remaining value (0 through 63):
|
||||
writer.WriteTableLine(terminatingCodes, count);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The BitReader class is a helper to read bits from an in-memory bitmap file.
|
||||
/// </summary>
|
||||
class BitReader
|
||||
{
|
||||
readonly byte[] _imageBits;
|
||||
uint _bytesOffsetRead;
|
||||
readonly uint _bytesFileOffset;
|
||||
byte _buffer;
|
||||
uint _bitsInBuffer;
|
||||
readonly uint _bitsTotal; // Bits we may read (bits per image line)
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BitReader"/> class.
|
||||
/// </summary>
|
||||
/// <param name="imageBits">The in-memory bitmap file.</param>
|
||||
/// <param name="bytesFileOffset">The offset of the line to read.</param>
|
||||
/// <param name="bits">The count of bits that may be read (i. e. the width of the image for normal usage).</param>
|
||||
internal BitReader(byte[] imageBits, uint bytesFileOffset, uint bits)
|
||||
{
|
||||
_imageBits = imageBits;
|
||||
_bytesFileOffset = bytesFileOffset;
|
||||
_bitsTotal = bits;
|
||||
_bytesOffsetRead = bytesFileOffset;
|
||||
_buffer = imageBits[_bytesOffsetRead];
|
||||
_bitsInBuffer = 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position within the line (needed for 2D encoding).
|
||||
/// </summary>
|
||||
/// <param name="position">The new position.</param>
|
||||
internal void SetPosition(uint position)
|
||||
{
|
||||
_bytesOffsetRead = _bytesFileOffset + (position >> 3);
|
||||
_buffer = _imageBits[_bytesOffsetRead];
|
||||
_bitsInBuffer = 8 - (position & 0x07);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single bit at the specified position.
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <returns>True if bit is set.</returns>
|
||||
internal bool GetBit(uint position)
|
||||
{
|
||||
if (position >= _bitsTotal)
|
||||
return false;
|
||||
SetPosition(position);
|
||||
uint dummy;
|
||||
return (PeekByte(out dummy) & 0x80) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the bits that are in the buffer (without changing the position).
|
||||
/// Data is MSB aligned.
|
||||
/// </summary>
|
||||
/// <param name="bits">The count of bits that were returned (1 through 8).</param>
|
||||
/// <returns>The MSB aligned bits from the buffer.</returns>
|
||||
internal byte PeekByte(out uint bits)
|
||||
{
|
||||
// TODO: try to make this faster!
|
||||
if (_bitsInBuffer == 8)
|
||||
{
|
||||
bits = 8;
|
||||
return _buffer;
|
||||
}
|
||||
bits = _bitsInBuffer;
|
||||
return (byte)(_buffer << (int)(8 - _bitsInBuffer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the buffer to the next byte.
|
||||
/// </summary>
|
||||
internal void NextByte()
|
||||
{
|
||||
_buffer = _imageBits[++_bytesOffsetRead];
|
||||
_bitsInBuffer = 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// "Removes" (eats) bits from the buffer.
|
||||
/// </summary>
|
||||
/// <param name="bits">The count of bits that were processed.</param>
|
||||
internal void SkipBits(uint bits)
|
||||
{
|
||||
Debug.Assert(bits <= _bitsInBuffer, "Buffer underrun");
|
||||
if (bits == _bitsInBuffer)
|
||||
{
|
||||
NextByte();
|
||||
return;
|
||||
}
|
||||
_bitsInBuffer -= bits;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A helper class for writing groups of bits into an array of bytes.
|
||||
/// </summary>
|
||||
class BitWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BitWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="imageData">The byte array to be written to.</param>
|
||||
internal BitWriter(ref byte[] imageData)
|
||||
{
|
||||
_imageData = imageData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the buffered bits into the byte array.
|
||||
/// </summary>
|
||||
internal void FlushBuffer()
|
||||
{
|
||||
if (_bitsInBuffer > 0)
|
||||
{
|
||||
uint bits = 8 - _bitsInBuffer;
|
||||
WriteBits(0, bits);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Masks for n bits in a byte (with n = 0 through 8).
|
||||
/// </summary>
|
||||
static readonly uint[] masks = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
|
||||
|
||||
/// <summary>
|
||||
/// Writes bits to the byte array.
|
||||
/// </summary>
|
||||
/// <param name="value">The bits to be written (LSB aligned).</param>
|
||||
/// <param name="bits">The count of bits.</param>
|
||||
internal void WriteBits(uint value, uint bits)
|
||||
{
|
||||
#if true
|
||||
// TODO: Try to make this faster!
|
||||
|
||||
// If we have to write more bits than fit into the buffer, we fill
|
||||
// the buffer and call the same routine recursively for the rest.
|
||||
#if USE_GOTO
|
||||
// Use GOTO instead of end recursion: (is this faster?)
|
||||
SimulateRecursion:
|
||||
#endif
|
||||
if (bits + _bitsInBuffer > 8)
|
||||
{
|
||||
// We can't add all bits this time.
|
||||
uint bitsNow = 8 - _bitsInBuffer;
|
||||
uint bitsRemainder = bits - bitsNow;
|
||||
WriteBits(value >> (int)(bitsRemainder), bitsNow); // that fits
|
||||
#if USE_GOTO
|
||||
bits = bitsRemainder;
|
||||
goto SimulateRecursion;
|
||||
#else
|
||||
WriteBits(value, bitsRemainder);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
_buffer = (_buffer << (int)bits) + (value & masks[bits]);
|
||||
_bitsInBuffer += bits;
|
||||
|
||||
if (_bitsInBuffer == 8)
|
||||
{
|
||||
// The line below will sometimes throw a System.IndexOutOfRangeException while PDFsharp tries different formats for monochrome bitmaps (exception occurs if CCITT encoding requires more space than an uncompressed bitmap).
|
||||
_imageData[_bytesOffsetWrite] = (byte)_buffer;
|
||||
_bitsInBuffer = 0;
|
||||
++_bytesOffsetWrite;
|
||||
}
|
||||
#else
|
||||
// Simple implementation writing bit by bit:
|
||||
int mask = 1 << (int)(bits - 1);
|
||||
for (int b = 0; b < bits; ++b)
|
||||
{
|
||||
if ((value & mask) != 0)
|
||||
buffer = (buffer << 1) + 1;
|
||||
else
|
||||
buffer = buffer << 1;
|
||||
++bitsInBuffer;
|
||||
mask /= 2;
|
||||
if (bitsInBuffer == 8)
|
||||
{
|
||||
imageData[bytesOffsetWrite] = (byte)buffer;
|
||||
bitsInBuffer = 0;
|
||||
++bytesOffsetWrite;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a line from a look-up table.
|
||||
/// A "line" in the table are two integers, one containing the values, one containing the bit count.
|
||||
/// </summary>
|
||||
internal void WriteTableLine(uint[] table, uint line)
|
||||
{
|
||||
uint value = table[line * 2];
|
||||
uint bits = table[line * 2 + 1];
|
||||
WriteBits(value, bits);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal void WriteEOL()
|
||||
{
|
||||
// Not needed for PDF.
|
||||
WriteTableLine(PdfImage.WhiteMakeUpCodes, 40);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flushes the buffer and returns the count of bytes written to the array.
|
||||
/// </summary>
|
||||
internal int BytesWritten()
|
||||
{
|
||||
FlushBuffer();
|
||||
return _bytesOffsetWrite;
|
||||
}
|
||||
|
||||
int _bytesOffsetWrite;
|
||||
readonly byte[] _imageData;
|
||||
uint _buffer;
|
||||
uint _bitsInBuffer;
|
||||
}
|
||||
}
|
1683
PrintPDF/PdfSharp/Pdf.Advanced/PdfImage.cs
Normal file
1683
PrintPDF/PdfSharp/Pdf.Advanced/PdfImage.cs
Normal file
File diff suppressed because it is too large
Load Diff
117
PrintPDF/PdfSharp/Pdf.Advanced/PdfImageTable.cs
Normal file
117
PrintPDF/PdfSharp/Pdf.Advanced/PdfImageTable.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains all used images of a document.
|
||||
/// </summary>
|
||||
internal sealed class PdfImageTable : PdfResourceTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of this class, which is a singleton for each document.
|
||||
/// </summary>
|
||||
public PdfImageTable(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a PdfImage from an XImage. If no PdfImage already exists, a new one is created.
|
||||
/// </summary>
|
||||
public PdfImage GetImage(XImage image)
|
||||
{
|
||||
ImageSelector selector = image._selector;
|
||||
if (selector == null)
|
||||
{
|
||||
selector = new ImageSelector(image);
|
||||
image._selector = selector;
|
||||
}
|
||||
PdfImage pdfImage;
|
||||
if (!_images.TryGetValue(selector, out pdfImage))
|
||||
{
|
||||
pdfImage = new PdfImage(Owner, image);
|
||||
//pdfImage.Document = _document;
|
||||
Debug.Assert(pdfImage.Owner == Owner);
|
||||
_images[selector] = pdfImage;
|
||||
}
|
||||
return pdfImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map from ImageSelector to PdfImage.
|
||||
/// </summary>
|
||||
readonly Dictionary<ImageSelector, PdfImage> _images = new Dictionary<ImageSelector, PdfImage>();
|
||||
|
||||
/// <summary>
|
||||
/// A collection of information that uniquely identifies a particular PdfImage.
|
||||
/// </summary>
|
||||
public class ImageSelector
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of ImageSelector from an XImage.
|
||||
/// </summary>
|
||||
public ImageSelector(XImage image)
|
||||
{
|
||||
// HACK: implement a way to identify images when they are reused
|
||||
// TODO 4STLA Implementation that calculates MD5 hashes for images generated for the images can be found here: http://forum.pdfsharp.net/viewtopic.php?p=6959#p6959
|
||||
if (image._path == null)
|
||||
image._path = "*" + Guid.NewGuid().ToString("B");
|
||||
|
||||
// HACK: just use full path to identify
|
||||
_path = image._path.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get { return _path; }
|
||||
set { _path = value; }
|
||||
}
|
||||
string _path;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
ImageSelector selector = obj as ImageSelector;
|
||||
if (selector == null)
|
||||
return false;
|
||||
return _path == selector._path;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _path.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
PrintPDF/PdfSharp/Pdf.Advanced/PdfImportedObjectTable.cs
Normal file
117
PrintPDF/PdfSharp/Pdf.Advanced/PdfImportedObjectTable.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the imported objects of an external document. Used to cache objects that are
|
||||
/// already imported when a PdfFormXObject is added to a page.
|
||||
/// </summary>
|
||||
internal sealed class PdfImportedObjectTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of this class with the document the objects are imported from.
|
||||
/// </summary>
|
||||
public PdfImportedObjectTable(PdfDocument owner, PdfDocument externalDocument)
|
||||
{
|
||||
if (owner == null)
|
||||
throw new ArgumentNullException("owner");
|
||||
if (externalDocument == null)
|
||||
throw new ArgumentNullException("externalDocument");
|
||||
_owner = owner;
|
||||
_externalDocumentHandle = externalDocument.Handle;
|
||||
_xObjects = new PdfFormXObject[externalDocument.PageCount];
|
||||
}
|
||||
readonly PdfFormXObject[] _xObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the document this table belongs to.
|
||||
/// </summary>
|
||||
public PdfDocument Owner
|
||||
{
|
||||
get { return _owner; }
|
||||
}
|
||||
readonly PdfDocument _owner;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external document, or null, if the external document is garbage collected.
|
||||
/// </summary>
|
||||
public PdfDocument ExternalDocument
|
||||
{
|
||||
get { return _externalDocumentHandle.IsAlive ? _externalDocumentHandle.Target : null; }
|
||||
}
|
||||
readonly PdfDocument.DocumentHandle _externalDocumentHandle;
|
||||
|
||||
public PdfFormXObject GetXObject(int pageNumber)
|
||||
{
|
||||
return _xObjects[pageNumber - 1];
|
||||
}
|
||||
|
||||
public void SetXObject(int pageNumber, PdfFormXObject xObject)
|
||||
{
|
||||
_xObjects[pageNumber - 1] = xObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the specified object is already imported.
|
||||
/// </summary>
|
||||
public bool Contains(PdfObjectID externalID)
|
||||
{
|
||||
return _externalIDs.ContainsKey(externalID.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a cloned object to this table.
|
||||
/// </summary>
|
||||
/// <param name="externalID">The object identifier in the foreign object.</param>
|
||||
/// <param name="iref">The cross reference to the clone of the foreign object, which belongs to
|
||||
/// this document. In general the clone has a different object identifier.</param>
|
||||
public void Add(PdfObjectID externalID, PdfReference iref)
|
||||
{
|
||||
_externalIDs[externalID.ToString()] = iref;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cloned object that corresponds to the specified external identifier.
|
||||
/// </summary>
|
||||
public PdfReference this[PdfObjectID externalID]
|
||||
{
|
||||
get { return _externalIDs[externalID.ToString()]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps external object identifiers to cross reference entries of the importing document
|
||||
/// {PdfObjectID -> PdfReference}.
|
||||
/// </summary>
|
||||
readonly Dictionary<string, PdfReference> _externalIDs = new Dictionary<string, PdfReference>();
|
||||
}
|
||||
}
|
298
PrintPDF/PdfSharp/Pdf.Advanced/PdfInternals.cs
Normal file
298
PrintPDF/PdfSharp/Pdf.Advanced/PdfInternals.cs
Normal file
@@ -0,0 +1,298 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using PdfSharp.Pdf.IO;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to the internal document data structures. This class prevents the public
|
||||
/// interfaces from pollution with to much internal functions.
|
||||
/// </summary>
|
||||
public class PdfInternals // TODO: PdfDocumentInternals... PdfPageInterals etc.
|
||||
{
|
||||
internal PdfInternals(PdfDocument document)
|
||||
{
|
||||
_document = document;
|
||||
}
|
||||
readonly PdfDocument _document;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the first document identifier.
|
||||
/// </summary>
|
||||
public string FirstDocumentID
|
||||
{
|
||||
get { return _document._trailer.GetDocumentID(0); }
|
||||
set { _document._trailer.SetDocumentID(0, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first document identifier as GUID.
|
||||
/// </summary>
|
||||
public Guid FirstDocumentGuid
|
||||
{
|
||||
get { return GuidFromString(_document._trailer.GetDocumentID(0)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the second document identifier.
|
||||
/// </summary>
|
||||
public string SecondDocumentID
|
||||
{
|
||||
get { return _document._trailer.GetDocumentID(1); }
|
||||
set { _document._trailer.SetDocumentID(1, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first document identifier as GUID.
|
||||
/// </summary>
|
||||
public Guid SecondDocumentGuid
|
||||
{
|
||||
get { return GuidFromString(_document._trailer.GetDocumentID(0)); }
|
||||
}
|
||||
|
||||
Guid GuidFromString(string id)
|
||||
{
|
||||
if (id == null || id.Length != 16)
|
||||
return Guid.Empty;
|
||||
|
||||
StringBuilder guid = new StringBuilder();
|
||||
for (int idx = 0; idx < 16; idx++)
|
||||
guid.AppendFormat("{0:X2}", (byte)id[idx]);
|
||||
|
||||
return new Guid(guid.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the catalog dictionary.
|
||||
/// </summary>
|
||||
public PdfCatalog Catalog
|
||||
{
|
||||
get { return _document.Catalog; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ExtGStateTable object.
|
||||
/// </summary>
|
||||
public PdfExtGStateTable ExtGStateTable
|
||||
{
|
||||
get { return _document.ExtGStateTable; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the object with the specified Identifier, or null, if no such object exists.
|
||||
/// </summary>
|
||||
public PdfObject GetObject(PdfObjectID objectID)
|
||||
{
|
||||
return _document._irefTable[objectID].Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps the specified external object to the substitute object in this document.
|
||||
/// Returns null if no such object exists.
|
||||
/// </summary>
|
||||
public PdfObject MapExternalObject(PdfObject externalObject)
|
||||
{
|
||||
PdfFormXObjectTable table = _document.FormTable;
|
||||
PdfImportedObjectTable iot = table.GetImportedObjectTable(externalObject.Owner);
|
||||
PdfReference reference = iot[externalObject.ObjectID];
|
||||
return reference == null ? null : reference.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the PdfReference of the specified object, or null, if the object is not in the
|
||||
/// document's object table.
|
||||
/// </summary>
|
||||
public static PdfReference GetReference(PdfObject obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException("obj");
|
||||
return obj.Reference;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object identifier of the specified object.
|
||||
/// </summary>
|
||||
public static PdfObjectID GetObjectID(PdfObject obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException("obj");
|
||||
return obj.ObjectID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object number of the specified object.
|
||||
/// </summary>
|
||||
public static int GetObjectNumber(PdfObject obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException("obj");
|
||||
return obj.ObjectNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the generation number of the specified object.
|
||||
/// </summary>
|
||||
public static int GenerationNumber(PdfObject obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException("obj");
|
||||
return obj.GenerationNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all indirect objects ordered by their object identifier.
|
||||
/// </summary>
|
||||
public PdfObject[] GetAllObjects()
|
||||
{
|
||||
PdfReference[] irefs = _document._irefTable.AllReferences;
|
||||
int count = irefs.Length;
|
||||
PdfObject[] objects = new PdfObject[count];
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
objects[idx] = irefs[idx].Value;
|
||||
return objects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all indirect objects ordered by their object identifier.
|
||||
/// </summary>
|
||||
[Obsolete("Use GetAllObjects.")] // Properties should not return arrays
|
||||
public PdfObject[] AllObjects
|
||||
{
|
||||
get { return GetAllObjects(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the indirect object of the specified type, adds it to the document,
|
||||
/// and returns the object.
|
||||
/// </summary>
|
||||
public T CreateIndirectObject<T>() where T : PdfObject
|
||||
{
|
||||
#if true
|
||||
T obj = Activator.CreateInstance<T>();
|
||||
_document._irefTable.Add(obj);
|
||||
#else
|
||||
T result = null;
|
||||
#if !NETFX_CORE && !UWP
|
||||
ConstructorInfo ctorInfo = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.ExactBinding,
|
||||
null, new Type[] { typeof(PdfDocument) }, null);
|
||||
#else
|
||||
ConstructorInfo ctorInfo = null; // TODO
|
||||
#endif
|
||||
if (ctorInfo != null)
|
||||
{
|
||||
result = (T)ctorInfo.Invoke(new object[] { _document });
|
||||
Debug.Assert(result != null);
|
||||
AddObject(result);
|
||||
}
|
||||
Debug.Assert(result != null, "CreateIndirectObject failed with type " + typeof(T).FullName);
|
||||
#endif
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an object to the PDF document. This operation and only this operation makes the object
|
||||
/// an indirect object owned by this document.
|
||||
/// </summary>
|
||||
public void AddObject(PdfObject obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException("obj");
|
||||
if (obj.Owner == null)
|
||||
obj.Document = _document;
|
||||
else if (obj.Owner != _document)
|
||||
throw new InvalidOperationException("Object does not belong to this document.");
|
||||
_document._irefTable.Add(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an object from the PDF document.
|
||||
/// </summary>
|
||||
public void RemoveObject(PdfObject obj)
|
||||
{
|
||||
if (obj == null)
|
||||
throw new ArgumentNullException("obj");
|
||||
if (obj.Reference == null)
|
||||
throw new InvalidOperationException("Only indirect objects can be removed.");
|
||||
if (obj.Owner != _document)
|
||||
throw new InvalidOperationException("Object does not belong to this document.");
|
||||
|
||||
_document._irefTable.Remove(obj.Reference);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array containing the specified object as first element follows by its transitive
|
||||
/// closure. The closure of an object are all objects that can be reached by indirect references.
|
||||
/// The transitive closure is the result of applying the calculation of the closure to a closure
|
||||
/// as long as no new objects came along. This is e.g. useful for getting all objects belonging
|
||||
/// to the resources of a page.
|
||||
/// </summary>
|
||||
public PdfObject[] GetClosure(PdfObject obj)
|
||||
{
|
||||
return GetClosure(obj, Int32.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array containing the specified object as first element follows by its transitive
|
||||
/// closure limited by the specified number of iterations.
|
||||
/// </summary>
|
||||
public PdfObject[] GetClosure(PdfObject obj, int depth)
|
||||
{
|
||||
PdfReference[] references = _document._irefTable.TransitiveClosure(obj, depth);
|
||||
int count = references.Length + 1;
|
||||
PdfObject[] objects = new PdfObject[count];
|
||||
objects[0] = obj;
|
||||
for (int idx = 1; idx < count; idx++)
|
||||
objects[idx] = references[idx - 1].Value;
|
||||
return objects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a PdfItem into the specified stream.
|
||||
/// </summary>
|
||||
// This function exists to keep PdfWriter and PdfItem.WriteObject internal.
|
||||
public void WriteObject(Stream stream, PdfItem item)
|
||||
{
|
||||
// Never write an encrypted object
|
||||
PdfWriter writer = new PdfWriter(stream, null);
|
||||
writer.Options = PdfWriterOptions.OmitStream;
|
||||
item.WriteObject(writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the custom value key.
|
||||
/// </summary>
|
||||
public string CustomValueKey = "/PdfSharp.CustomValue";
|
||||
}
|
||||
}
|
84
PrintPDF/PdfSharp/Pdf.Advanced/PdfObjectInternals.cs
Normal file
84
PrintPDF/PdfSharp/Pdf.Advanced/PdfObjectInternals.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to the internal PDF object data structures. This class prevents the public
|
||||
/// interfaces from pollution with to much internal functions.
|
||||
/// </summary>
|
||||
public class PdfObjectInternals
|
||||
{
|
||||
internal PdfObjectInternals(PdfObject obj)
|
||||
{
|
||||
_obj = obj;
|
||||
}
|
||||
readonly PdfObject _obj;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object identifier. Returns PdfObjectID.Empty for direct objects.
|
||||
/// </summary>
|
||||
public PdfObjectID ObjectID
|
||||
{
|
||||
get { return _obj.ObjectID; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object number.
|
||||
/// </summary>
|
||||
public int ObjectNumber
|
||||
{
|
||||
get { return _obj.ObjectID.ObjectNumber; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the generation number.
|
||||
/// </summary>
|
||||
public int GenerationNumber
|
||||
{
|
||||
get { return _obj.ObjectID.GenerationNumber; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the current type.
|
||||
/// Not a very useful property, but can be used for data binding.
|
||||
/// </summary>
|
||||
public string TypeID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_obj is PdfArray)
|
||||
return "array";
|
||||
if (_obj is PdfDictionary)
|
||||
return "dictionary";
|
||||
return _obj.GetType().Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
173
PrintPDF/PdfSharp/Pdf.Advanced/PdfObjectStream.cs
Normal file
173
PrintPDF/PdfSharp/Pdf.Advanced/PdfObjectStream.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using PdfSharp.Pdf.IO;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an object stream that contains compressed objects.
|
||||
/// PDF 1.5.
|
||||
/// </summary>
|
||||
public class PdfObjectStream : PdfDictionary
|
||||
{
|
||||
// Reference: 3.4.6 Object Streams / Page 100
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfObjectStream"/> class.
|
||||
/// </summary>
|
||||
public PdfObjectStream(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
#if DEBUG && CORE
|
||||
if (Internal.PdfDiagnostics.TraceObjectStreams)
|
||||
{
|
||||
Debug.WriteLine("PdfObjectStream(document) created.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance from an existing dictionary. Used for object type transformation.
|
||||
/// </summary>
|
||||
internal PdfObjectStream(PdfDictionary dict)
|
||||
: base(dict)
|
||||
{
|
||||
int n = Elements.GetInteger(Keys.N);
|
||||
int first = Elements.GetInteger(Keys.First);
|
||||
Stream.TryUnfilter();
|
||||
|
||||
Parser parser = new Parser(null, new MemoryStream(Stream.Value));
|
||||
_header = parser.ReadObjectStreamHeader(n, first);
|
||||
|
||||
#if DEBUG && CORE
|
||||
if (Internal.PdfDiagnostics.TraceObjectStreams)
|
||||
{
|
||||
Debug.WriteLine(String.Format("PdfObjectStream(document) created. Header item count: {0}", _header.GetLength(0)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the compressed object with the specified index.
|
||||
/// </summary>
|
||||
internal void ReadReferences(PdfCrossReferenceTable xrefTable)
|
||||
{
|
||||
////// Create parser for stream.
|
||||
////Parser parser = new Parser(_document, new MemoryStream(Stream.Value));
|
||||
for (int idx = 0; idx < _header.Length; idx++)
|
||||
{
|
||||
int objectNumber = _header[idx][0];
|
||||
int offset = _header[idx][1];
|
||||
|
||||
PdfObjectID objectID = new PdfObjectID(objectNumber);
|
||||
|
||||
// HACK: -1 indicates compressed object.
|
||||
PdfReference iref = new PdfReference(objectID, -1);
|
||||
////iref.ObjectID = objectID;
|
||||
////iref.Value = xrefStream;
|
||||
if (!xrefTable.Contains(iref.ObjectID))
|
||||
{
|
||||
xrefTable.Add(iref);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the compressed object with the specified index.
|
||||
/// </summary>
|
||||
internal PdfReference ReadCompressedObject(int index)
|
||||
{
|
||||
Parser parser = new Parser(_document, new MemoryStream(Stream.Value));
|
||||
int objectNumber = _header[index][0];
|
||||
int offset = _header[index][1];
|
||||
return parser.ReadCompressedObject(objectNumber, offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// N pairs of integers.
|
||||
/// The first integer represents the object number of the compressed object.
|
||||
/// The second integer represents the absolute offset of that object in the decoded stream,
|
||||
/// i.e. the byte offset plus First entry.
|
||||
/// </summary>
|
||||
private readonly int[][] _header; // Reference: Page 102
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys common to all font dictionaries.
|
||||
/// </summary>
|
||||
public class Keys : PdfStream.Keys
|
||||
{
|
||||
// Reference: TABLE 3.14 Additional entries specific to an object stream dictionary / Page 101
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be ObjStmfor an object stream.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "ObjStm")]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The number of compressed objects in the stream.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string N = "/N";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The byte offset (in the decoded stream) of the first
|
||||
/// compressed object.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string First = "/First";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A reference to an object stream, of which the current object
|
||||
/// stream is considered an extension. Both streams are considered part of
|
||||
/// a collection of object streams (see below). A given collection consists
|
||||
/// of a set of streams whose Extendslinks form a directed acyclic graph.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string Extends = "/Extends";
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG && CORE
|
||||
static class ObjectStreamDiagnostics
|
||||
{
|
||||
public static void AddObjectStreamXRef()
|
||||
{ }
|
||||
}
|
||||
#endif
|
||||
}
|
73
PrintPDF/PdfSharp/Pdf.Advanced/PdfPageInheritableObjects.cs
Normal file
73
PrintPDF/PdfSharp/Pdf.Advanced/PdfPageInheritableObjects.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF page object.
|
||||
/// </summary>
|
||||
internal class PdfPageInheritableObjects : PdfDictionary
|
||||
{
|
||||
public PdfPageInheritableObjects()
|
||||
{ }
|
||||
|
||||
// TODO Inheritable Resources not yet supported
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public PdfRectangle MediaBox
|
||||
{
|
||||
get { return _mediaBox; }
|
||||
set { _mediaBox = value; }
|
||||
}
|
||||
PdfRectangle _mediaBox;
|
||||
|
||||
public PdfRectangle CropBox
|
||||
{
|
||||
get { return _cropBox; }
|
||||
set { _cropBox = value; }
|
||||
}
|
||||
PdfRectangle _cropBox;
|
||||
|
||||
public int Rotate
|
||||
{
|
||||
get { return _rotate; }
|
||||
set
|
||||
{
|
||||
if (value % 90 != 0)
|
||||
throw new ArgumentException("The value must be a multiple of 90.", nameof(value));
|
||||
_rotate = value;
|
||||
}
|
||||
}
|
||||
int _rotate;
|
||||
}
|
||||
}
|
41
PrintPDF/PdfSharp/Pdf.Advanced/PdfPageInterals.cs
Normal file
41
PrintPDF/PdfSharp/Pdf.Advanced/PdfPageInterals.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
#if true_ // Not yet used.
|
||||
/// <summary>
|
||||
/// TODO
|
||||
/// </summary>
|
||||
public static class PdfPageInterals
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
}
|
243
PrintPDF/PdfSharp/Pdf.Advanced/PdfReference.cs
Normal file
243
PrintPDF/PdfSharp/Pdf.Advanced/PdfReference.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
// With this define each iref object gets a unique number (uid) to make them distinguishable in the debugger
|
||||
#define UNIQUE_IREF_
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using PdfSharp.Pdf.IO;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an indirect reference to a PdfObject.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("iref({ObjectNumber}, {GenerationNumber})")]
|
||||
public sealed class PdfReference : PdfItem
|
||||
{
|
||||
// About PdfReference
|
||||
//
|
||||
// * A PdfReference holds either the ObjectID or the PdfObject or both.
|
||||
//
|
||||
// * Each PdfObject has a PdfReference if and only if it is an indirect object. Direct objects have
|
||||
// no PdfReference, because they are embedded in a parent objects.
|
||||
//
|
||||
// * PdfReference objects are used to reference PdfObject instances. A value in a PDF dictionary
|
||||
// or array that is a PdfReference represents an indirect reference. A value in a PDF dictionary or
|
||||
// or array that is a PdfObject represents a direct (or embeddded) object.
|
||||
//
|
||||
// * When a PDF file is imported, the PdfXRefTable is filled with PdfReference objects keeping the
|
||||
// ObjectsIDs and file positions (offsets) of all indirect objects.
|
||||
//
|
||||
// * Indirect objects can easily be renumbered because they do not rely on their ObjectsIDs.
|
||||
//
|
||||
// * During modification of a document the ObjectID of an indirect object has no meaning,
|
||||
// except that they must be different in pairs.
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new PdfReference instance for the specified indirect object.
|
||||
/// </summary>
|
||||
public PdfReference(PdfObject pdfObject)
|
||||
{
|
||||
if (pdfObject.Reference != null)
|
||||
throw new InvalidOperationException("Must not create iref for an object that already has one.");
|
||||
_value = pdfObject;
|
||||
pdfObject.Reference = this;
|
||||
#if UNIQUE_IREF && DEBUG
|
||||
_uid = ++s_counter;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new PdfReference instance from the specified object identifier and file position.
|
||||
/// </summary>
|
||||
public PdfReference(PdfObjectID objectID, int position)
|
||||
{
|
||||
_objectID = objectID;
|
||||
_position = position;
|
||||
#if UNIQUE_IREF && DEBUG
|
||||
_uid = ++s_counter;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the object in PDF iref table format.
|
||||
/// </summary>
|
||||
internal void WriteXRefEnty(PdfWriter writer)
|
||||
{
|
||||
// PDFsharp does not yet support PDF 1.5 object streams.
|
||||
|
||||
// Each line must be exactly 20 bytes long, otherwise Acrobat repairs the file.
|
||||
string text = String.Format("{0:0000000000} {1:00000} n\n",
|
||||
_position, _objectID.GenerationNumber); // InUse ? 'n' : 'f');
|
||||
writer.WriteRaw(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an indirect reference.
|
||||
/// </summary>
|
||||
internal override void WriteObject(PdfWriter writer)
|
||||
{
|
||||
writer.Write(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the object identifier.
|
||||
/// </summary>
|
||||
public PdfObjectID ObjectID
|
||||
{
|
||||
get { return _objectID; }
|
||||
set
|
||||
{
|
||||
// Ignore redundant invokations.
|
||||
if (_objectID == value)
|
||||
return;
|
||||
|
||||
_objectID = value;
|
||||
if (Document != null)
|
||||
{
|
||||
//PdfXRefTable table = Document.xrefTable;
|
||||
//table.Remove(this);
|
||||
//objectID = value;
|
||||
//table.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
PdfObjectID _objectID;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object number of the object identifier.
|
||||
/// </summary>
|
||||
public int ObjectNumber
|
||||
{
|
||||
get { return _objectID.ObjectNumber; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the generation number of the object identifier.
|
||||
/// </summary>
|
||||
public int GenerationNumber
|
||||
{
|
||||
get { return _objectID.GenerationNumber; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file position of the related PdfObject.
|
||||
/// </summary>
|
||||
public int Position
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
int _position; // I know it should be long, but I have never seen a 2GB PDF file.
|
||||
|
||||
//public bool InUse
|
||||
//{
|
||||
// get {return inUse;}
|
||||
// set {inUse = value;}
|
||||
//}
|
||||
//bool inUse;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the referenced PdfObject.
|
||||
/// </summary>
|
||||
public PdfObject Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
Debug.Assert(value != null, "The value of a PdfReference must never be null.");
|
||||
Debug.Assert(value.Reference == null || ReferenceEquals(value.Reference, this), "The reference of the value must be null or this.");
|
||||
_value = value;
|
||||
// value must never be null
|
||||
value.Reference = this;
|
||||
}
|
||||
}
|
||||
PdfObject _value;
|
||||
|
||||
/// <summary>
|
||||
/// Hack for dead objects.
|
||||
/// </summary>
|
||||
internal void SetObject(PdfObject value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the document this object belongs to.
|
||||
/// </summary>
|
||||
public PdfDocument Document
|
||||
{
|
||||
get { return _document; }
|
||||
set { _document = value; }
|
||||
}
|
||||
PdfDocument _document;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representing the object identifier.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return _objectID + " R";
|
||||
}
|
||||
|
||||
internal static PdfReferenceComparer Comparer
|
||||
{
|
||||
get { return new PdfReferenceComparer(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements a comparer that compares PdfReference objects by their PdfObjectID.
|
||||
/// </summary>
|
||||
internal class PdfReferenceComparer : IComparer<PdfReference>
|
||||
{
|
||||
public int Compare(PdfReference x, PdfReference y)
|
||||
{
|
||||
PdfReference l = x;
|
||||
PdfReference r = y;
|
||||
if (l != null)
|
||||
{
|
||||
if (r != null)
|
||||
return l._objectID.CompareTo(r._objectID);
|
||||
return -1;
|
||||
}
|
||||
if (r != null)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNIQUE_IREF && DEBUG
|
||||
static int s_counter = 0;
|
||||
int _uid;
|
||||
#endif
|
||||
}
|
||||
}
|
72
PrintPDF/PdfSharp/Pdf.Advanced/PdfResourceMap.cs
Normal file
72
PrintPDF/PdfSharp/Pdf.Advanced/PdfResourceMap.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all dictionaries that map resource names to objects.
|
||||
/// </summary>
|
||||
internal class PdfResourceMap : PdfDictionary //, IEnumerable
|
||||
{
|
||||
public PdfResourceMap()
|
||||
{ }
|
||||
|
||||
public PdfResourceMap(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
protected PdfResourceMap(PdfDictionary dict)
|
||||
: base(dict)
|
||||
{ }
|
||||
|
||||
// public int Count
|
||||
// {
|
||||
// get {return resources.Count;}
|
||||
// }
|
||||
//
|
||||
// public PdfObject this[string key]
|
||||
// {
|
||||
// get {return resources[key] as PdfObject;}
|
||||
// set {resources[key] = value;}
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Adds all imported resource names to the specified hashtable.
|
||||
/// </summary>
|
||||
internal void CollectResourceNames(Dictionary<string, object> usedResourceNames)
|
||||
{
|
||||
// ?TODO: Imported resources (e.g. fonts) can be reused, but I think this is rather difficult. Will be an issue in PDFsharp 2.0.
|
||||
PdfName[] names = Elements.KeyNames;
|
||||
foreach (PdfName name in names)
|
||||
usedResourceNames.Add(name.ToString(), null);
|
||||
}
|
||||
}
|
||||
}
|
58
PrintPDF/PdfSharp/Pdf.Advanced/PdfResourceTable.cs
Normal file
58
PrintPDF/PdfSharp/Pdf.Advanced/PdfResourceTable.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for FontTable, ImageTable, FormXObjectTable etc.
|
||||
/// </summary>
|
||||
public class PdfResourceTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for document wide resource tables.
|
||||
/// </summary>
|
||||
public PdfResourceTable(PdfDocument owner)
|
||||
{
|
||||
if (owner == null)
|
||||
throw new ArgumentNullException("owner");
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the owning document of this resource table.
|
||||
/// </summary>
|
||||
protected PdfDocument Owner
|
||||
{
|
||||
get { return _owner; }
|
||||
}
|
||||
readonly PdfDocument _owner;
|
||||
}
|
||||
}
|
452
PrintPDF/PdfSharp/Pdf.Advanced/PdfResources.cs
Normal file
452
PrintPDF/PdfSharp/Pdf.Advanced/PdfResources.cs
Normal file
@@ -0,0 +1,452 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF resource object.
|
||||
/// </summary>
|
||||
public sealed class PdfResources : PdfDictionary
|
||||
{
|
||||
// Resource management works roughly like this:
|
||||
// When the user creates an XFont and uses it in the XGraphics of a PdfPage, then at the first time
|
||||
// a PdfFont is created and cached in the document global font table. If the user creates a new
|
||||
// XFont object for an exisisting PdfFont, the PdfFont object is reused. When the PdfFont is added
|
||||
// to the resources of a PdfPage for the first time, it is added to the page local PdfResourceMap for
|
||||
// fonts and automatically associated with a local resource name.
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfResources"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">The document.</param>
|
||||
public PdfResources(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements[Keys.ProcSet] = new PdfLiteral("[/PDF/Text/ImageB/ImageC/ImageI]");
|
||||
}
|
||||
|
||||
internal PdfResources(PdfDictionary dict)
|
||||
: base(dict)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified font to this resource dictionary and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddFont(PdfFont font)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(font, out name))
|
||||
{
|
||||
name = NextFontName;
|
||||
_resources[font] = name;
|
||||
if (font.Reference == null)
|
||||
Owner._irefTable.Add(font);
|
||||
Fonts.Elements[name] = font.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified image to this resource dictionary
|
||||
/// and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddImage(PdfImage image)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(image, out name))
|
||||
{
|
||||
name = NextImageName;
|
||||
_resources[image] = name;
|
||||
if (image.Reference == null)
|
||||
Owner._irefTable.Add(image);
|
||||
XObjects.Elements[name] = image.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified form object to this resource dictionary
|
||||
/// and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddForm(PdfFormXObject form)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(form, out name))
|
||||
{
|
||||
name = NextFormName;
|
||||
_resources[form] = name;
|
||||
if (form.Reference == null)
|
||||
Owner._irefTable.Add(form);
|
||||
XObjects.Elements[name] = form.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified graphics state to this resource dictionary
|
||||
/// and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddExtGState(PdfExtGState extGState)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(extGState, out name))
|
||||
{
|
||||
name = NextExtGStateName;
|
||||
_resources[extGState] = name;
|
||||
if (extGState.Reference == null)
|
||||
Owner._irefTable.Add(extGState);
|
||||
ExtGStates.Elements[name] = extGState.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified pattern to this resource dictionary
|
||||
/// and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddPattern(PdfShadingPattern pattern)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(pattern, out name))
|
||||
{
|
||||
name = NextPatternName;
|
||||
_resources[pattern] = name;
|
||||
if (pattern.Reference == null)
|
||||
Owner._irefTable.Add(pattern);
|
||||
Patterns.Elements[name] = pattern.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified pattern to this resource dictionary
|
||||
/// and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddPattern(PdfTilingPattern pattern)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(pattern, out name))
|
||||
{
|
||||
name = NextPatternName;
|
||||
_resources[pattern] = name;
|
||||
if (pattern.Reference == null)
|
||||
Owner._irefTable.Add(pattern);
|
||||
Patterns.Elements[name] = pattern.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified shading to this resource dictionary
|
||||
/// and returns its local resource name.
|
||||
/// </summary>
|
||||
public string AddShading(PdfShading shading)
|
||||
{
|
||||
string name;
|
||||
if (!_resources.TryGetValue(shading, out name))
|
||||
{
|
||||
name = NextShadingName;
|
||||
_resources[shading] = name;
|
||||
if (shading.Reference == null)
|
||||
Owner._irefTable.Add(shading);
|
||||
Shadings.Elements[name] = shading.Reference;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the fonts map.
|
||||
/// </summary>
|
||||
internal PdfResourceMap Fonts
|
||||
{
|
||||
get { return _fonts ?? (_fonts = (PdfResourceMap)Elements.GetValue(Keys.Font, VCF.Create)); }
|
||||
}
|
||||
PdfResourceMap _fonts;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external objects map.
|
||||
/// </summary>
|
||||
internal PdfResourceMap XObjects
|
||||
{
|
||||
get { return _xObjects ?? (_xObjects = (PdfResourceMap)Elements.GetValue(Keys.XObject, VCF.Create)); }
|
||||
}
|
||||
PdfResourceMap _xObjects;
|
||||
|
||||
// TODO: make own class
|
||||
internal PdfResourceMap ExtGStates
|
||||
{
|
||||
get
|
||||
{
|
||||
return _extGStates ?? (_extGStates = (PdfResourceMap)Elements.GetValue(Keys.ExtGState, VCF.Create));
|
||||
}
|
||||
}
|
||||
PdfResourceMap _extGStates;
|
||||
|
||||
// TODO: make own class
|
||||
internal PdfResourceMap ColorSpaces
|
||||
{
|
||||
get { return _colorSpaces ?? (_colorSpaces = (PdfResourceMap)Elements.GetValue(Keys.ColorSpace, VCF.Create)); }
|
||||
}
|
||||
PdfResourceMap _colorSpaces;
|
||||
|
||||
// TODO: make own class
|
||||
internal PdfResourceMap Patterns
|
||||
{
|
||||
get { return _patterns ?? (_patterns = (PdfResourceMap) Elements.GetValue(Keys.Pattern, VCF.Create)); }
|
||||
}
|
||||
PdfResourceMap _patterns;
|
||||
|
||||
// TODO: make own class
|
||||
internal PdfResourceMap Shadings
|
||||
{
|
||||
get { return _shadings ?? (_shadings = (PdfResourceMap) Elements.GetValue(Keys.Shading, VCF.Create)); }
|
||||
}
|
||||
PdfResourceMap _shadings;
|
||||
|
||||
// TODO: make own class
|
||||
internal PdfResourceMap Properties
|
||||
{
|
||||
get {return _properties ?? (_properties = (PdfResourceMap) Elements.GetValue(Keys.Properties, VCF.Create));}
|
||||
}
|
||||
PdfResourceMap _properties;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new local name for this resource.
|
||||
/// </summary>
|
||||
string NextFontName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
while (ExistsResourceNames(name = string.Format("/F{0}", _fontNumber++))) { }
|
||||
return name;
|
||||
}
|
||||
}
|
||||
int _fontNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new local name for this resource.
|
||||
/// </summary>
|
||||
string NextImageName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
while (ExistsResourceNames(name = string.Format("/I{0}", _imageNumber++))) { }
|
||||
return name;
|
||||
}
|
||||
}
|
||||
int _imageNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new local name for this resource.
|
||||
/// </summary>
|
||||
string NextFormName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
while (ExistsResourceNames(name = string.Format("/Fm{0}", _formNumber++))) { }
|
||||
return name;
|
||||
}
|
||||
}
|
||||
int _formNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new local name for this resource.
|
||||
/// </summary>
|
||||
string NextExtGStateName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
while (ExistsResourceNames(name = string.Format("/GS{0}", _extGStateNumber++))) { }
|
||||
return name;
|
||||
}
|
||||
}
|
||||
int _extGStateNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new local name for this resource.
|
||||
/// </summary>
|
||||
string NextPatternName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
while (ExistsResourceNames(name = string.Format("/Pa{0}", _patternNumber++))) ;
|
||||
return name;
|
||||
}
|
||||
}
|
||||
int _patternNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new local name for this resource.
|
||||
/// </summary>
|
||||
string NextShadingName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name;
|
||||
while (ExistsResourceNames(name = string.Format("/Sh{0}", _shadingNumber++))) ;
|
||||
return name;
|
||||
}
|
||||
}
|
||||
int _shadingNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Check whether a resource name is already used in the context of this resource dictionary.
|
||||
/// PDF4NET uses GUIDs as resource names, but I think this weapon is to heavy.
|
||||
/// </summary>
|
||||
internal bool ExistsResourceNames(string name)
|
||||
{
|
||||
// TODO: more precise: is this page imported and is PageOptions != Replace
|
||||
// BUG:
|
||||
//if (!Owner.IsImported)
|
||||
// return false;
|
||||
|
||||
// Collect all resouce names of all imported resources.
|
||||
if (_importedResourceNames == null)
|
||||
{
|
||||
_importedResourceNames = new Dictionary<string, object>();
|
||||
|
||||
if (Elements[Keys.Font] != null)
|
||||
Fonts.CollectResourceNames(_importedResourceNames);
|
||||
|
||||
if (Elements[Keys.XObject] != null)
|
||||
XObjects.CollectResourceNames(_importedResourceNames);
|
||||
|
||||
if (Elements[Keys.ExtGState] != null)
|
||||
ExtGStates.CollectResourceNames(_importedResourceNames);
|
||||
|
||||
if (Elements[Keys.ColorSpace] != null)
|
||||
ColorSpaces.CollectResourceNames(_importedResourceNames);
|
||||
|
||||
if (Elements[Keys.Pattern] != null)
|
||||
Patterns.CollectResourceNames(_importedResourceNames);
|
||||
|
||||
if (Elements[Keys.Shading] != null)
|
||||
Shadings.CollectResourceNames(_importedResourceNames);
|
||||
|
||||
if (Elements[Keys.Properties] != null)
|
||||
Properties.CollectResourceNames(_importedResourceNames);
|
||||
}
|
||||
return _importedResourceNames.ContainsKey(name);
|
||||
// This is superfluous because PDFsharp resource names cannot be double.
|
||||
// importedResourceNames.Add(name, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All the names of imported resources.
|
||||
/// </summary>
|
||||
Dictionary<string, object> _importedResourceNames;
|
||||
|
||||
/// <summary>
|
||||
/// Maps all PDFsharp resources to their local resource names.
|
||||
/// </summary>
|
||||
readonly Dictionary<PdfObject, string> _resources = new Dictionary<PdfObject, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public sealed class Keys : KeysBase
|
||||
{
|
||||
/// <summary>
|
||||
/// (Optional) A dictionary that maps resource names to graphics state
|
||||
/// parameter dictionaries.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string ExtGState = "/ExtGState";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A dictionary that maps each resource name to either the name of a
|
||||
/// device-dependent color space or an array describing a color space.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string ColorSpace = "/ColorSpace";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A dictionary that maps each resource name to either the name of a
|
||||
/// device-dependent color space or an array describing a color space.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string Pattern = "/Pattern";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.3) A dictionary that maps resource names to shading dictionaries.
|
||||
/// </summary>
|
||||
[KeyInfo("1.3", KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string Shading = "/Shading";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A dictionary that maps resource names to external objects.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string XObject = "/XObject";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A dictionary that maps resource names to font dictionaries.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string Font = "/Font";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of predefined procedure set names.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string ProcSet = "/ProcSet";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) A dictionary that maps resource names to property list
|
||||
/// dictionaries for marked content.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfResourceMap))]
|
||||
public const string Properties = "/Properties";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
258
PrintPDF/PdfSharp/Pdf.Advanced/PdfShading.cs
Normal file
258
PrintPDF/PdfSharp/Pdf.Advanced/PdfShading.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
using PdfSharp.Drawing;
|
||||
using PdfSharp.Drawing.Pdf;
|
||||
using PdfSharp.Pdf.Internal;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a shading dictionary.
|
||||
/// </summary>
|
||||
public sealed class PdfShading : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfShading"/> class.
|
||||
/// </summary>
|
||||
public PdfShading(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Setups the shading from the specified brush.
|
||||
/// </summary>
|
||||
internal void SetupFromBrush(XLinearGradientBrush brush, XGraphicsPdfRenderer renderer)
|
||||
{
|
||||
if (brush == null)
|
||||
throw new ArgumentNullException("brush");
|
||||
|
||||
PdfColorMode colorMode = _document.Options.ColorMode;
|
||||
XColor color1 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color1);
|
||||
XColor color2 = ColorSpaceHelper.EnsureColorMode(colorMode, brush._color2);
|
||||
|
||||
PdfDictionary function = new PdfDictionary();
|
||||
|
||||
Elements[Keys.ShadingType] = new PdfInteger(2);
|
||||
if (colorMode != PdfColorMode.Cmyk)
|
||||
Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB");
|
||||
else
|
||||
Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK");
|
||||
|
||||
double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
if (brush._useRect)
|
||||
{
|
||||
XPoint pt1 = renderer.WorldToView(brush._rect.TopLeft);
|
||||
XPoint pt2 = renderer.WorldToView(brush._rect.BottomRight);
|
||||
|
||||
switch (brush._linearGradientMode)
|
||||
{
|
||||
case XLinearGradientMode.Horizontal:
|
||||
x1 = pt1.X;
|
||||
y1 = pt1.Y;
|
||||
x2 = pt2.X;
|
||||
y2 = pt1.Y;
|
||||
break;
|
||||
|
||||
case XLinearGradientMode.Vertical:
|
||||
x1 = pt1.X;
|
||||
y1 = pt1.Y;
|
||||
x2 = pt1.X;
|
||||
y2 = pt2.Y;
|
||||
break;
|
||||
|
||||
case XLinearGradientMode.ForwardDiagonal:
|
||||
x1 = pt1.X;
|
||||
y1 = pt1.Y;
|
||||
x2 = pt2.X;
|
||||
y2 = pt2.Y;
|
||||
break;
|
||||
|
||||
case XLinearGradientMode.BackwardDiagonal:
|
||||
x1 = pt2.X;
|
||||
y1 = pt1.Y;
|
||||
x2 = pt1.X;
|
||||
y2 = pt2.Y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XPoint pt1 = renderer.WorldToView(brush._point1);
|
||||
XPoint pt2 = renderer.WorldToView(brush._point2);
|
||||
|
||||
x1 = pt1.X;
|
||||
y1 = pt1.Y;
|
||||
x2 = pt2.X;
|
||||
y2 = pt2.Y;
|
||||
}
|
||||
|
||||
const string format = Config.SignificantFigures3;
|
||||
Elements[Keys.Coords] = new PdfLiteral("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", x1, y1, x2, y2);
|
||||
|
||||
//Elements[Keys.Background] = new PdfRawItem("[0 1 1]");
|
||||
//Elements[Keys.Domain] =
|
||||
Elements[Keys.Function] = function;
|
||||
//Elements[Keys.Extend] = new PdfRawItem("[true true]");
|
||||
|
||||
string clr1 = "[" + PdfEncoders.ToString(color1, colorMode) + "]";
|
||||
string clr2 = "[" + PdfEncoders.ToString(color2, colorMode) + "]";
|
||||
|
||||
function.Elements["/FunctionType"] = new PdfInteger(2);
|
||||
function.Elements["/C0"] = new PdfLiteral(clr1);
|
||||
function.Elements["/C1"] = new PdfLiteral(clr2);
|
||||
function.Elements["/Domain"] = new PdfLiteral("[0 1]");
|
||||
function.Elements["/N"] = new PdfInteger(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common keys for all streams.
|
||||
/// </summary>
|
||||
internal sealed class Keys : KeysBase
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The shading type:
|
||||
/// 1 Function-based shading
|
||||
/// 2 Axial shading
|
||||
/// 3 Radial shading
|
||||
/// 4 Free-form Gouraud-shaded triangle mesh
|
||||
/// 5 Lattice-form Gouraud-shaded triangle mesh
|
||||
/// 6 Coons patch mesh
|
||||
/// 7 Tensor-product patch mesh
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string ShadingType = "/ShadingType";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The color space in which color values are expressed. This may be any device,
|
||||
/// CIE-based, or special color space except a Pattern space.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.NameOrArray | KeyType.Required)]
|
||||
public const string ColorSpace = "/ColorSpace";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of color components appropriate to the color space, specifying
|
||||
/// a single background color value. If present, this color is used, before any painting
|
||||
/// operation involving the shading, to fill those portions of the area to be painted
|
||||
/// that lie outside the bounds of the shading object. In the opaque imaging model,
|
||||
/// the effect is as if the painting operation were performed twice: first with the
|
||||
/// background color and then with the shading.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Background = "/Background";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of four numbers giving the left, bottom, right, and top coordinates,
|
||||
/// respectively, of the shading<6E>s bounding box. The coordinates are interpreted in the
|
||||
/// shading<6E>s target coordinate space. If present, this bounding box is applied as a temporary
|
||||
/// clipping boundary when the shading is painted, in addition to the current clipping path
|
||||
/// and any other clipping boundaries in effect at that time.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Rectangle | KeyType.Optional)]
|
||||
public const string BBox = "/BBox";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A flag indicating whether to filter the shading function to prevent aliasing
|
||||
/// artifacts. The shading operators sample shading functions at a rate determined by the
|
||||
/// resolution of the output device. Aliasing can occur if the function is not smooth<74>that
|
||||
/// is, if it has a high spatial frequency relative to the sampling rate. Anti-aliasing can
|
||||
/// be computationally expensive and is usually unnecessary, since most shading functions
|
||||
/// are smooth enough or are sampled at a high enough frequency to avoid aliasing effects.
|
||||
/// Anti-aliasing may not be implemented on some output devices, in which case this flag
|
||||
/// is ignored.
|
||||
/// Default value: false.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string AntiAlias = "/AntiAlias";
|
||||
|
||||
// ---- Type 2 ----------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// (Required) An array of four numbers [x0 y0 x1 y1] specifying the starting and
|
||||
/// ending coordinates of the axis, expressed in the shading<6E>s target coordinate space.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Required)]
|
||||
public const string Coords = "/Coords";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of two numbers [t0 t1] specifying the limiting values of a
|
||||
/// parametric variable t. The variable is considered to vary linearly between these
|
||||
/// two values as the color gradient varies between the starting and ending points of
|
||||
/// the axis. The variable t becomes the input argument to the color function(s).
|
||||
/// Default value: [0.0 1.0].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Domain = "/Domain";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A 1-in, n-out function or an array of n 1-in, 1-out functions (where n
|
||||
/// is the number of color components in the shading dictionary<72>s color space). The
|
||||
/// function(s) are called with values of the parametric variable t in the domain defined
|
||||
/// by the Domain entry. Each function<6F>s domain must be a superset of that of the shading
|
||||
/// dictionary. If the value returned by the function for a given color component is out
|
||||
/// of range, it is adjusted to the nearest valid value.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Function | KeyType.Required)]
|
||||
public const string Function = "/Function";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of two boolean values specifying whether to extend the shading
|
||||
/// beyond the starting and ending points of the axis, respectively.
|
||||
/// Default value: [false false].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Extend = "/Extend";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
132
PrintPDF/PdfSharp/Pdf.Advanced/PdfShadingPattern.cs
Normal file
132
PrintPDF/PdfSharp/Pdf.Advanced/PdfShadingPattern.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
using PdfSharp.Drawing;
|
||||
using PdfSharp.Drawing.Pdf;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a shading pattern dictionary.
|
||||
/// </summary>
|
||||
public sealed class PdfShadingPattern : PdfDictionaryWithContentStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfShadingPattern"/> class.
|
||||
/// </summary>
|
||||
public PdfShadingPattern(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Pattern");
|
||||
Elements[Keys.PatternType] = new PdfInteger(2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setups the shading pattern from the specified brush.
|
||||
/// </summary>
|
||||
internal void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix, XGraphicsPdfRenderer renderer)
|
||||
{
|
||||
if (brush == null)
|
||||
throw new ArgumentNullException("brush");
|
||||
|
||||
PdfShading shading = new PdfShading(_document);
|
||||
shading.SetupFromBrush(brush, renderer);
|
||||
Elements[Keys.Shading] = shading;
|
||||
//Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]");
|
||||
Elements.SetMatrix(Keys.Matrix, matrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common keys for all streams.
|
||||
/// </summary>
|
||||
internal sealed new class Keys : PdfDictionaryWithContentStream.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Optional) The type of PDF object that this dictionary describes; if present,
|
||||
/// must be Pattern for a pattern dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A code identifying the type of pattern that this dictionary describes;
|
||||
/// must be 2 for a shading pattern.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string PatternType = "/PatternType";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A shading object (see below) defining the shading pattern<72>s gradient fill.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
|
||||
public const string Shading = "/Shading";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of six numbers specifying the pattern matrix.
|
||||
/// Default value: the identity matrix [1 0 0 1 0 0].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Matrix = "/Matrix";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A graphics state parameter dictionary containing graphics state parameters
|
||||
/// to be put into effect temporarily while the shading pattern is painted. Any parameters
|
||||
/// that are not so specified are inherited from the graphics state that was in effect
|
||||
/// at the beginning of the content stream in which the pattern is defined as a resource.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional)]
|
||||
public const string ExtGState = "/ExtGState";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
110
PrintPDF/PdfSharp/Pdf.Advanced/PdfSoftMask.cs
Normal file
110
PrintPDF/PdfSharp/Pdf.Advanced/PdfSoftMask.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF soft mask.
|
||||
/// </summary>
|
||||
public class PdfSoftMask : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfXObject"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">The document that owns the object.</param>
|
||||
public PdfSoftMask(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Mask");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public class Keys : KeysBase
|
||||
{
|
||||
/// <summary>
|
||||
/// (Optional) The type of PDF object that this dictionary describes;
|
||||
/// if present, must be Mask for a soft-mask dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional, FixedValue = "Mask")]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A subtype specifying the method to be used in deriving the mask values
|
||||
/// from the transparency group specified by the G entry:
|
||||
/// Alpha: Use the group<75>s computed alpha, disregarding its color.
|
||||
/// Luminosity: Convert the group<75>s computed color to a single-component luminosity value.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string S = "/S";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A transparency group XObject to be used as the source of alpha
|
||||
/// or color values for deriving the mask. If the subtype S is Luminosity, the
|
||||
/// group attributes dictionary must contain a CS entry defining the color space
|
||||
/// in which the compositing computation is to be performed.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Required)]
|
||||
public const string G = "/G";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of component values specifying the color to be used
|
||||
/// as the backdrop against which to composite the transparency group XObject G.
|
||||
/// This entry is consulted only if the subtype S is Luminosity. The array consists of
|
||||
/// n numbers, where n is the number of components in the color space specified
|
||||
/// by the CS entry in the group attributes dictionary.
|
||||
/// Default value: the color space<63>s initial value, representing black.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string BC = "/BC";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A function object specifying the transfer function to be used in
|
||||
/// deriving the mask values. The function accepts one input, the computed
|
||||
/// group alpha or luminosity (depending on the value of the subtype S), and
|
||||
/// returns one output, the resulting mask value. Both the input and output
|
||||
/// must be in the range 0.0 to 1.0; if the computed output falls outside this
|
||||
/// range, it is forced to the nearest valid value. The name Identity may be
|
||||
/// specified in place of a function object to designate the identity function.
|
||||
/// Default value: Identity.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.FunctionOrName | KeyType.Optional)]
|
||||
public const string TR = "/TR";
|
||||
}
|
||||
}
|
||||
}
|
177
PrintPDF/PdfSharp/Pdf.Advanced/PdfTilingPattern.cs
Normal file
177
PrintPDF/PdfSharp/Pdf.Advanced/PdfTilingPattern.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if GDI
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
#endif
|
||||
#if WPF
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a tiling pattern dictionary.
|
||||
/// </summary>
|
||||
public sealed class PdfTilingPattern : PdfDictionaryWithContentStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfShadingPattern"/> class.
|
||||
/// </summary>
|
||||
public PdfTilingPattern(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Pattern");
|
||||
Elements[Keys.PatternType] = new PdfInteger(1);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Setups the shading pattern from the specified brush.
|
||||
///// </summary>
|
||||
//public void SetupFromBrush(XLinearGradientBrush brush, XMatrix matrix)
|
||||
//{
|
||||
// if (brush == null)
|
||||
// throw new ArgumentNullException("brush");
|
||||
|
||||
// PdfShading shading = new PdfShading(document);
|
||||
// shading.SetupFromBrush(brush);
|
||||
// Elements[Keys.Shading] = shading;
|
||||
// Elements[Keys.Matrix] = new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]");
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Common keys for all streams.
|
||||
/// </summary>
|
||||
internal sealed new class Keys : PdfDictionaryWithContentStream.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Optional) The type of PDF object that this dictionary describes; if present,
|
||||
/// must be Pattern for a pattern dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A code identifying the type of pattern that this dictionary describes;
|
||||
/// must be 1 for a tiling pattern.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string PatternType = "/PatternType";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A code that determines how the color of the pattern cell is to be specified:
|
||||
/// 1: Colored tiling pattern. The pattern<72>s content stream specifies the colors used to
|
||||
/// paint the pattern cell. When the content stream begins execution, the current color
|
||||
/// is the one that was initially in effect in the pattern<72>s parent content stream.
|
||||
/// 2: Uncolored tiling pattern. The pattern<72>s content stream does not specify any color
|
||||
/// information. Instead, the entire pattern cell is painted with a separately specified color
|
||||
/// each time the pattern is used. Essentially, the content stream describes a stencil
|
||||
/// through which the current color is to be poured. The content stream must not invoke
|
||||
/// operators that specify colors or other color-related parameters in the graphics state;
|
||||
/// otherwise, an error occurs. The content stream may paint an image mask, however,
|
||||
/// since it does not specify any color information.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string PaintType = "/PaintType";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A code that controls adjustments to the spacing of tiles relative to the device
|
||||
/// pixel grid:
|
||||
/// 1: Constant spacing. Pattern cells are spaced consistently<6C>that is, by a multiple of a
|
||||
/// device pixel. To achieve this, the application may need to distort the pattern cell slightly
|
||||
/// by making small adjustments to XStep, YStep, and the transformation matrix. The amount
|
||||
/// of distortion does not exceed 1 device pixel.
|
||||
/// 2: No distortion. The pattern cell is not distorted, but the spacing between pattern cells
|
||||
/// may vary by as much as 1 device pixel, both horizontally and vertically, when the pattern
|
||||
/// is painted. This achieves the spacing requested by XStep and YStep on average but not
|
||||
/// necessarily for each individual pattern cell.
|
||||
/// 3: Constant spacing and faster tiling. Pattern cells are spaced consistently as in tiling
|
||||
/// type 1 but with additional distortion permitted to enable a more efficient implementation.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string TilingType = "/TilingType";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) An array of four numbers in the pattern coordinate system giving the
|
||||
/// coordinates of the left, bottom, right, and top edges, respectively, of the pattern
|
||||
/// cell<6C>s bounding box. These boundaries are used to clip the pattern cell.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Rectangle | KeyType.Optional)]
|
||||
public const string BBox = "/BBox";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The desired horizontal spacing between pattern cells, measured in the
|
||||
/// pattern coordinate system.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string XStep = "/XStep";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The desired vertical spacing between pattern cells, measured in the pattern
|
||||
/// coordinate system. Note that XStep and YStep may differ from the dimensions of the
|
||||
/// pattern cell implied by the BBox entry. This allows tiling with irregularly shaped figures.
|
||||
/// XStep and YStep may be either positive or negative but not zero.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Real | KeyType.Required)]
|
||||
public const string YStep = "/YStep";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A resource dictionary containing all of the named resources required by
|
||||
/// the pattern<72>s content stream (see Section 3.7.2, <20>Resource Dictionaries<65>).
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
|
||||
public new const string Resources = "/Resources";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) An array of six numbers specifying the pattern matrix.
|
||||
/// Default value: the identity matrix [1 0 0 1 0 0].
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string Matrix = "/Matrix";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
148
PrintPDF/PdfSharp/Pdf.Advanced/PdfToUnicodeMap.cs
Normal file
148
PrintPDF/PdfSharp/Pdf.Advanced/PdfToUnicodeMap.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using PdfSharp.Fonts;
|
||||
using PdfSharp.Pdf.Filters;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a ToUnicode map for composite font.
|
||||
/// </summary>
|
||||
internal sealed class PdfToUnicodeMap : PdfDictionary
|
||||
{
|
||||
public PdfToUnicodeMap(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
public PdfToUnicodeMap(PdfDocument document, CMapInfo cmapInfo)
|
||||
: base(document)
|
||||
{
|
||||
_cmapInfo = cmapInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CMap info.
|
||||
/// </summary>
|
||||
public CMapInfo CMapInfo
|
||||
{
|
||||
get { return _cmapInfo; }
|
||||
set { _cmapInfo = value; }
|
||||
}
|
||||
CMapInfo _cmapInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the ToUnicode map from the CMapInfo.
|
||||
/// </summary>
|
||||
internal override void PrepareForSave()
|
||||
{
|
||||
base.PrepareForSave();
|
||||
|
||||
// This code comes literally from PDF Reference
|
||||
string prefix =
|
||||
"/CIDInit /ProcSet findresource begin\n" +
|
||||
"12 dict begin\n" +
|
||||
"begincmap\n" +
|
||||
"/CIDSystemInfo << /Registry (Adobe)/Ordering (UCS)/Supplement 0>> def\n" +
|
||||
"/CMapName /Adobe-Identity-UCS def /CMapType 2 def\n";
|
||||
string suffix = "endcmap CMapName currentdict /CMap defineresource pop end end";
|
||||
|
||||
Dictionary<int, char> glyphIndexToCharacter = new Dictionary<int, char>();
|
||||
int lowIndex = 65536, hiIndex = -1;
|
||||
foreach (KeyValuePair<char, int> entry in _cmapInfo.CharacterToGlyphIndex)
|
||||
{
|
||||
int index = (int)entry.Value;
|
||||
lowIndex = Math.Min(lowIndex, index);
|
||||
hiIndex = Math.Max(hiIndex, index);
|
||||
//glyphIndexToCharacter.Add(index, entry.Key);
|
||||
glyphIndexToCharacter[index] = entry.Key;
|
||||
}
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
#if !SILVERLIGHT && !NETFX_CORE
|
||||
StreamWriter wrt = new StreamWriter(ms, Encoding.ASCII);
|
||||
#else
|
||||
StreamWriter wrt = new StreamWriter(ms, Encoding.UTF8);
|
||||
#endif
|
||||
wrt.Write(prefix);
|
||||
|
||||
wrt.WriteLine("1 begincodespacerange");
|
||||
wrt.WriteLine(String.Format("<{0:X4}><{1:X4}>", lowIndex, hiIndex));
|
||||
wrt.WriteLine("endcodespacerange");
|
||||
|
||||
// Sorting seems not necessary. The limit is 100 entries, we will see.
|
||||
wrt.WriteLine(String.Format("{0} beginbfrange", glyphIndexToCharacter.Count));
|
||||
foreach (KeyValuePair<int, char> entry in glyphIndexToCharacter)
|
||||
wrt.WriteLine(String.Format("<{0:X4}><{0:X4}><{1:X4}>", entry.Key, (int)entry.Value));
|
||||
wrt.WriteLine("endbfrange");
|
||||
|
||||
wrt.Write(suffix);
|
||||
#if !UWP
|
||||
wrt.Close();
|
||||
#else
|
||||
wrt.Dispose();
|
||||
#endif
|
||||
|
||||
// Compress like content streams
|
||||
byte[] bytes = ms.ToArray();
|
||||
#if !UWP
|
||||
ms.Close();
|
||||
#else
|
||||
ms.Dispose();
|
||||
#endif
|
||||
if (Owner.Options.CompressContentStreams)
|
||||
{
|
||||
Elements.SetName("/Filter", "/FlateDecode");
|
||||
bytes = Filtering.FlateDecode.Encode(bytes, _document.Options.FlateEncodeMode);
|
||||
}
|
||||
//PdfStream stream = CreateStream(bytes);
|
||||
else
|
||||
{
|
||||
Elements.Remove("/Filter");
|
||||
}
|
||||
|
||||
if (Stream == null)
|
||||
CreateStream(bytes);
|
||||
else
|
||||
{
|
||||
Stream.Value = bytes;
|
||||
Elements.SetInteger(PdfStream.Keys.Length, Stream.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Keys : PdfStream.Keys
|
||||
{
|
||||
// No new keys.
|
||||
}
|
||||
}
|
||||
}
|
297
PrintPDF/PdfSharp/Pdf.Advanced/PdfTrailer.cs
Normal file
297
PrintPDF/PdfSharp/Pdf.Advanced/PdfTrailer.cs
Normal file
@@ -0,0 +1,297 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using PdfSharp.Pdf.IO;
|
||||
using PdfSharp.Pdf.Security;
|
||||
using PdfSharp.Pdf.Internal;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF trailer dictionary. Even though trailers are dictionaries they never have a cross
|
||||
/// reference entry in PdfReferenceTable.
|
||||
/// </summary>
|
||||
internal class PdfTrailer : PdfDictionary // Reference: 3.4.4 File Trailer / Page 96
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of PdfTrailer.
|
||||
/// </summary>
|
||||
public PdfTrailer(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
_document = document;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfTrailer"/> class from a <see cref="PdfCrossReferenceStream"/>.
|
||||
/// </summary>
|
||||
public PdfTrailer(PdfCrossReferenceStream trailer)
|
||||
: base(trailer._document)
|
||||
{
|
||||
_document = trailer._document;
|
||||
|
||||
// /ID [<09F877EBF282E9408ED1882A9A21D9F2><2A4938E896006F499AC1C2EA7BFB08E4>]
|
||||
// /Info 7 0 R
|
||||
// /Root 1 0 R
|
||||
// /Size 10
|
||||
|
||||
PdfReference iref = trailer.Elements.GetReference(Keys.Info);
|
||||
if (iref != null)
|
||||
Elements.SetReference(Keys.Info, iref);
|
||||
|
||||
Elements.SetReference(Keys.Root, trailer.Elements.GetReference(Keys.Root));
|
||||
|
||||
Elements.SetInteger(Keys.Size, trailer.Elements.GetInteger(Keys.Size));
|
||||
|
||||
PdfArray id = trailer.Elements.GetArray(Keys.ID);
|
||||
if (id != null)
|
||||
Elements.SetValue(Keys.ID, id);
|
||||
}
|
||||
|
||||
public int Size
|
||||
{
|
||||
get { return Elements.GetInteger(Keys.Size); }
|
||||
set { Elements.SetInteger(Keys.Size, value); }
|
||||
}
|
||||
|
||||
// TODO: needed when linearized...
|
||||
//public int Prev
|
||||
//{
|
||||
// get {return Elements.GetInteger(Keys.Prev);}
|
||||
//}
|
||||
|
||||
public PdfDocumentInformation Info
|
||||
{
|
||||
get { return (PdfDocumentInformation)Elements.GetValue(Keys.Info, VCF.CreateIndirect); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (Required; must be an indirect reference)
|
||||
/// The catalog dictionary for the PDF document contained in the file.
|
||||
/// </summary>
|
||||
public PdfCatalog Root
|
||||
{
|
||||
get { return (PdfCatalog)Elements.GetValue(PdfTrailer.Keys.Root, VCF.CreateIndirect); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first or second document identifier.
|
||||
/// </summary>
|
||||
public string GetDocumentID(int index)
|
||||
{
|
||||
if (index < 0 || index > 1)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Index must be 0 or 1.");
|
||||
|
||||
PdfArray array = Elements[Keys.ID] as PdfArray;
|
||||
if (array == null || array.Elements.Count < 2)
|
||||
return "";
|
||||
PdfItem item = array.Elements[index];
|
||||
if (item is PdfString)
|
||||
return ((PdfString)item).Value;
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the first or second document identifier.
|
||||
/// </summary>
|
||||
public void SetDocumentID(int index, string value)
|
||||
{
|
||||
if (index < 0 || index > 1)
|
||||
throw new ArgumentOutOfRangeException("index", index, "Index must be 0 or 1.");
|
||||
|
||||
PdfArray array = Elements[Keys.ID] as PdfArray;
|
||||
if (array == null || array.Elements.Count < 2)
|
||||
array = CreateNewDocumentIDs();
|
||||
array.Elements[index] = new PdfString(value, PdfStringFlags.HexLiteral);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and sets two identical new document IDs.
|
||||
/// </summary>
|
||||
internal PdfArray CreateNewDocumentIDs()
|
||||
{
|
||||
PdfArray array = new PdfArray(_document);
|
||||
byte[] docID = Guid.NewGuid().ToByteArray();
|
||||
string id = PdfEncoders.RawEncoding.GetString(docID, 0, docID.Length);
|
||||
array.Elements.Add(new PdfString(id, PdfStringFlags.HexLiteral));
|
||||
array.Elements.Add(new PdfString(id, PdfStringFlags.HexLiteral));
|
||||
Elements[Keys.ID] = array;
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the standard security handler.
|
||||
/// </summary>
|
||||
public PdfStandardSecurityHandler SecurityHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_securityHandler == null)
|
||||
_securityHandler = (PdfStandardSecurityHandler)Elements.GetValue(Keys.Encrypt, VCF.CreateIndirect);
|
||||
return _securityHandler;
|
||||
}
|
||||
}
|
||||
internal PdfStandardSecurityHandler _securityHandler;
|
||||
|
||||
internal override void WriteObject(PdfWriter writer)
|
||||
{
|
||||
// Delete /XRefStm entry, if any.
|
||||
// HACK:
|
||||
_elements.Remove(Keys.XRefStm);
|
||||
|
||||
// Don't encrypt myself
|
||||
PdfStandardSecurityHandler securityHandler = writer.SecurityHandler;
|
||||
writer.SecurityHandler = null;
|
||||
base.WriteObject(writer);
|
||||
writer.SecurityHandler = securityHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replace temporary irefs by their correct counterparts from the iref table.
|
||||
/// </summary>
|
||||
internal void Finish()
|
||||
{
|
||||
// /Root
|
||||
PdfReference iref = _document._trailer.Elements[Keys.Root] as PdfReference;
|
||||
if (iref != null && iref.Value == null)
|
||||
{
|
||||
iref = _document._irefTable[iref.ObjectID];
|
||||
Debug.Assert(iref.Value != null);
|
||||
_document._trailer.Elements[Keys.Root] = iref;
|
||||
}
|
||||
|
||||
// /Info
|
||||
iref = _document._trailer.Elements[PdfTrailer.Keys.Info] as PdfReference;
|
||||
if (iref != null && iref.Value == null)
|
||||
{
|
||||
iref = _document._irefTable[iref.ObjectID];
|
||||
Debug.Assert(iref.Value != null);
|
||||
_document._trailer.Elements[Keys.Info] = iref;
|
||||
}
|
||||
|
||||
// /Encrypt
|
||||
iref = _document._trailer.Elements[Keys.Encrypt] as PdfReference;
|
||||
if (iref != null)
|
||||
{
|
||||
iref = _document._irefTable[iref.ObjectID];
|
||||
Debug.Assert(iref.Value != null);
|
||||
_document._trailer.Elements[Keys.Encrypt] = iref;
|
||||
|
||||
// The encryption dictionary (security handler) was read in before the XRefTable construction
|
||||
// was completed. The next lines fix that state (it took several hours to find these bugs...).
|
||||
iref.Value = _document._trailer._securityHandler;
|
||||
_document._trailer._securityHandler.Reference = iref;
|
||||
iref.Value.Reference = iref;
|
||||
}
|
||||
|
||||
Elements.Remove(Keys.Prev);
|
||||
|
||||
Debug.Assert(_document._irefTable.IsUnderConstruction == false);
|
||||
_document._irefTable.IsUnderConstruction = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
internal class Keys : KeysBase // Reference: TABLE 3.13 Entries in the file trailer dictionary / Page 97
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required; must not be an indirect reference) The total number of entries in the file<6C>s
|
||||
/// cross-reference table, as defined by the combination of the original section and all
|
||||
/// update sections. Equivalently, this value is 1 greater than the highest object number
|
||||
/// used in the file.
|
||||
/// Note: Any object in a cross-reference section whose number is greater than this value is
|
||||
/// ignored and considered missing.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Required)]
|
||||
public const string Size = "/Size";
|
||||
|
||||
/// <summary>
|
||||
/// (Present only if the file has more than one cross-reference section; must not be an indirect
|
||||
/// reference) The byte offset from the beginning of the file to the beginning of the previous
|
||||
/// cross-reference section.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public const string Prev = "/Prev";
|
||||
|
||||
/// <summary>
|
||||
/// (Required; must be an indirect reference) The catalog dictionary for the PDF document
|
||||
/// contained in the file.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Required, typeof(PdfCatalog))]
|
||||
public const string Root = "/Root";
|
||||
|
||||
/// <summary>
|
||||
/// (Required if document is encrypted; PDF 1.1) The document<6E>s encryption dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfStandardSecurityHandler))]
|
||||
public const string Encrypt = "/Encrypt";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; must be an indirect reference) The document<6E>s information dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.Optional, typeof(PdfDocumentInformation))]
|
||||
public const string Info = "/Info";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional, but strongly recommended; PDF 1.1) An array of two strings constituting
|
||||
/// a file identifier for the file. Although this entry is optional,
|
||||
/// its absence might prevent the file from functioning in some workflows
|
||||
/// that depend on files being uniquely identified.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Optional)]
|
||||
public const string ID = "/ID";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) The byte offset from the beginning of the file of a cross-reference stream.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer | KeyType.Optional)]
|
||||
public const string XRefStm = "/XRefStm";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
public static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
129
PrintPDF/PdfSharp/Pdf.Advanced/PdfTransparencyGroupAttributes.cs
Normal file
129
PrintPDF/PdfSharp/Pdf.Advanced/PdfTransparencyGroupAttributes.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a PDF transparency group XObject.
|
||||
/// </summary>
|
||||
public sealed class PdfTransparencyGroupAttributes : PdfGroupAttributes
|
||||
{
|
||||
internal PdfTransparencyGroupAttributes(PdfDocument thisDocument)
|
||||
: base(thisDocument)
|
||||
{
|
||||
Elements.SetName(Keys.S, "/Transparency");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public sealed new class Keys : PdfGroupAttributes.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Sometimes required, as discussed below)
|
||||
/// The group color space, which is used for the following purposes:
|
||||
/// <20> As the color space into which colors are converted when painted into the group
|
||||
/// <20> As the blending color space in which objects are composited within the group
|
||||
/// <20> As the color space of the group as a whole when it in turn is painted as an object onto its backdrop
|
||||
/// The group color space may be any device or CIE-based color space that
|
||||
/// treats its components as independent additive or subtractive values in the
|
||||
/// range 0.0 to 1.0, subject to the restrictions described in Section 7.2.3, <20>Blending Color Space.<2E>
|
||||
/// These restrictions exclude Lab and lightness-chromaticity ICCBased color spaces,
|
||||
/// as well as the special color spaces Pattern, Indexed, Separation, and DeviceN.
|
||||
/// Device color spaces are subject to remapping according to the DefaultGray,
|
||||
/// DefaultRGB, and DefaultCMYK entries in the ColorSpace subdictionary of the
|
||||
/// current resource dictionary.
|
||||
/// Ordinarily, the CS entry is allowed only for isolated transparency groups
|
||||
/// (those for which I, below, is true), and even then it is optional. However,
|
||||
/// this entry is required in the group attributes dictionary for any transparency
|
||||
/// group XObject that has no parent group or page from which to inherit <20> in
|
||||
/// particular, one that is the value of the G entry in a soft-mask dictionary of
|
||||
/// subtype Luminosity.
|
||||
/// In addition, it is always permissible to specify CS in the group attributes
|
||||
/// dictionary associated with a page object, even if I is false or absent. In the
|
||||
/// normal case in which the page is imposed directly on the output medium,
|
||||
/// the page group is effectively isolated regardless of the I value, and the
|
||||
/// specified CS value is therefore honored. But if the page is in turn used as an
|
||||
/// element of some other page and if the group is non-isolated, CS is ignored
|
||||
/// and the color space is inherited from the actual backdrop with which the
|
||||
/// page is composited.
|
||||
/// Default value: the color space of the parent group or page into which this
|
||||
/// transparency group is painted. (The parent<6E>s color space in turn can be
|
||||
/// either explicitly specified or inherited.)
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.NameOrArray | KeyType.Optional)]
|
||||
public const string CS = "/CS";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A flag specifying whether the transparency group is isolated.
|
||||
/// If this flag is true, objects within the group are composited against a fully
|
||||
/// transparent initial backdrop; if false, they are composited against the
|
||||
/// group<75>s backdrop.
|
||||
/// Default value: false.
|
||||
/// In the group attributes dictionary for a page, the interpretation of this
|
||||
/// entry is slightly altered. In the normal case in which the page is imposed
|
||||
/// directly on the output medium, the page group is effectively isolated and
|
||||
/// the specified I value is ignored. But if the page is in turn used as an
|
||||
/// element of some other page, it is treated as if it were a transparency
|
||||
/// group XObject; the I value is interpreted in the normal way to determine
|
||||
/// whether the page group is isolated.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string I = "/I";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A flag specifying whether the transparency group is a knockout
|
||||
/// group. If this flag is false, later objects within the group are composited
|
||||
/// with earlier ones with which they overlap; if true, they are composited with
|
||||
/// the group<75>s initial backdrop and overwrite (<28>knock out<75>) any earlier
|
||||
/// overlapping objects.
|
||||
/// Default value: false.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
|
||||
public const string K = "/K";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static new DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
254
PrintPDF/PdfSharp/Pdf.Advanced/PdfTrueTypeFont.cs
Normal file
254
PrintPDF/PdfSharp/Pdf.Advanced/PdfTrueTypeFont.cs
Normal file
@@ -0,0 +1,254 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using PdfSharp.Fonts;
|
||||
using PdfSharp.Fonts.OpenType;
|
||||
using PdfSharp.Drawing;
|
||||
using PdfSharp.Pdf.Filters;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a TrueType font.
|
||||
/// </summary>
|
||||
internal class PdfTrueTypeFont : PdfFont
|
||||
{
|
||||
public PdfTrueTypeFont(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of PdfTrueTypeFont from an XFont.
|
||||
/// </summary>
|
||||
public PdfTrueTypeFont(PdfDocument document, XFont font)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Font");
|
||||
Elements.SetName(Keys.Subtype, "/TrueType");
|
||||
|
||||
// TrueType with WinAnsiEncoding only.
|
||||
OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(font);
|
||||
FontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
|
||||
_fontOptions = font.PdfOptions;
|
||||
Debug.Assert(_fontOptions != null);
|
||||
|
||||
//cmapInfo = new CMapInfo(null/*ttDescriptor*/);
|
||||
_cmapInfo = new CMapInfo(ttDescriptor);
|
||||
|
||||
BaseFont = font.GlyphTypeface.GetBaseName();
|
||||
|
||||
if (_fontOptions.FontEmbedding == PdfFontEmbedding.Always)
|
||||
BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);
|
||||
FontDescriptor.FontName = BaseFont;
|
||||
|
||||
Debug.Assert(_fontOptions.FontEncoding == PdfFontEncoding.WinAnsi);
|
||||
if (!IsSymbolFont)
|
||||
Encoding = "/WinAnsiEncoding";
|
||||
|
||||
Owner._irefTable.Add(FontDescriptor);
|
||||
Elements[Keys.FontDescriptor] = FontDescriptor.Reference;
|
||||
|
||||
FontEncoding = font.PdfOptions.FontEncoding;
|
||||
}
|
||||
|
||||
XPdfFontOptions FontOptions
|
||||
{
|
||||
get { return _fontOptions; }
|
||||
}
|
||||
readonly XPdfFontOptions _fontOptions;
|
||||
|
||||
public string BaseFont
|
||||
{
|
||||
get { return Elements.GetName(Keys.BaseFont); }
|
||||
set { Elements.SetName(Keys.BaseFont, value); }
|
||||
}
|
||||
|
||||
public int FirstChar
|
||||
{
|
||||
get { return Elements.GetInteger(Keys.FirstChar); }
|
||||
set { Elements.SetInteger(Keys.FirstChar, value); }
|
||||
}
|
||||
|
||||
public int LastChar
|
||||
{
|
||||
get { return Elements.GetInteger(Keys.LastChar); }
|
||||
set { Elements.SetInteger(Keys.LastChar, value); }
|
||||
}
|
||||
|
||||
public PdfArray Widths
|
||||
{
|
||||
get { return (PdfArray)Elements.GetValue(Keys.Widths, VCF.Create); }
|
||||
}
|
||||
|
||||
public string Encoding
|
||||
{
|
||||
get { return Elements.GetName(Keys.Encoding); }
|
||||
set { Elements.SetName(Keys.Encoding, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the object to get saved.
|
||||
/// </summary>
|
||||
internal override void PrepareForSave()
|
||||
{
|
||||
base.PrepareForSave();
|
||||
|
||||
// Fonts are always embedded.
|
||||
OpenTypeFontface subSet = FontDescriptor._descriptor.FontFace.CreateFontSubSet(_cmapInfo.GlyphIndices, false);
|
||||
byte[] fontData = subSet.FontSource.Bytes;
|
||||
|
||||
PdfDictionary fontStream = new PdfDictionary(Owner);
|
||||
Owner.Internals.AddObject(fontStream);
|
||||
FontDescriptor.Elements[PdfFontDescriptor.Keys.FontFile2] = fontStream.Reference;
|
||||
|
||||
fontStream.Elements["/Length1"] = new PdfInteger(fontData.Length);
|
||||
if (!Owner.Options.NoCompression)
|
||||
{
|
||||
fontData = Filtering.FlateDecode.Encode(fontData, _document.Options.FlateEncodeMode);
|
||||
fontStream.Elements["/Filter"] = new PdfName("/FlateDecode");
|
||||
}
|
||||
fontStream.Elements["/Length"] = new PdfInteger(fontData.Length);
|
||||
fontStream.CreateStream(fontData);
|
||||
|
||||
FirstChar = 0;
|
||||
LastChar = 255;
|
||||
PdfArray width = Widths;
|
||||
//width.Elements.Clear();
|
||||
for (int idx = 0; idx < 256; idx++)
|
||||
width.Elements.Add(new PdfInteger(FontDescriptor._descriptor.Widths[idx]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public new sealed class Keys : PdfFont.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be Font for a font dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Font")]
|
||||
public new const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of font; must be TrueType for a TrueType font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string Subtype = "/Subtype";
|
||||
|
||||
/// <summary>
|
||||
/// (Required in PDF 1.0; optional otherwise) The name by which this font is
|
||||
/// referenced in the Font subdictionary of the current resource dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string Name = "/Name";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The PostScript name of the font. For Type 1 fonts, this is usually
|
||||
/// the value of the FontName entry in the font program; for more information.
|
||||
/// The Post-Script name of the font can be used to find the font<6E>s definition in
|
||||
/// the consumer application or its environment. It is also the name that is used when
|
||||
/// printing to a PostScript output device.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string BaseFont = "/BaseFont";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts) The first character code defined
|
||||
/// in the font<6E>s Widths array.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer)]
|
||||
public const string FirstChar = "/FirstChar";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts) The last character code defined
|
||||
/// in the font<6E>s Widths array.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer)]
|
||||
public const string LastChar = "/LastChar";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts; indirect reference preferred)
|
||||
/// An array of (LastChar - FirstChar + 1) widths, each element being the glyph width
|
||||
/// for the character code that equals FirstChar plus the array index. For character
|
||||
/// codes outside the range FirstChar to LastChar, the value of MissingWidth from the
|
||||
/// FontDescriptor entry for this font is used. The glyph widths are measured in units
|
||||
/// in which 1000 units corresponds to 1 unit in text space. These widths must be
|
||||
/// consistent with the actual widths given in the font program.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array, typeof(PdfArray))]
|
||||
public const string Widths = "/Widths";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts; must be an indirect reference)
|
||||
/// A font descriptor describing the font<6E>s metrics other than its glyph widths.
|
||||
/// Note: For the standard 14 fonts, the entries FirstChar, LastChar, Widths, and
|
||||
/// FontDescriptor must either all be present or all be absent. Ordinarily, they are
|
||||
/// absent; specifying them enables a standard font to be overridden.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.MustBeIndirect, typeof(PdfFontDescriptor))]
|
||||
public new const string FontDescriptor = "/FontDescriptor";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A specification of the font<6E>s character encoding if different from its
|
||||
/// built-in encoding. The value of Encoding is either the name of a predefined
|
||||
/// encoding (MacRomanEncoding, MacExpertEncoding, or WinAnsiEncoding, as described in
|
||||
/// Appendix D) or an encoding dictionary that specifies differences from the font<6E>s
|
||||
/// built-in encoding or from a specified predefined encoding.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Dictionary)]
|
||||
public const string Encoding = "/Encoding";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) A stream containing a CMap file that maps character
|
||||
/// codes to Unicode values.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string ToUnicode = "/ToUnicode";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
241
PrintPDF/PdfSharp/Pdf.Advanced/PdfType0Font.cs
Normal file
241
PrintPDF/PdfSharp/Pdf.Advanced/PdfType0Font.cs
Normal file
@@ -0,0 +1,241 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using PdfSharp.Fonts;
|
||||
using PdfSharp.Fonts.OpenType;
|
||||
using PdfSharp.Drawing;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a composite font. Used for Unicode encoding.
|
||||
/// </summary>
|
||||
internal sealed class PdfType0Font : PdfFont
|
||||
{
|
||||
public PdfType0Font(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
public PdfType0Font(PdfDocument document, XFont font, bool vertical)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Font");
|
||||
Elements.SetName(Keys.Subtype, "/Type0");
|
||||
Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H");
|
||||
|
||||
OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(font);
|
||||
FontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
|
||||
_fontOptions = font.PdfOptions;
|
||||
Debug.Assert(_fontOptions != null);
|
||||
|
||||
_cmapInfo = new CMapInfo(ttDescriptor);
|
||||
_descendantFont = new PdfCIDFont(document, FontDescriptor, font);
|
||||
_descendantFont.CMapInfo = _cmapInfo;
|
||||
|
||||
// Create ToUnicode map
|
||||
_toUnicode = new PdfToUnicodeMap(document, _cmapInfo);
|
||||
document.Internals.AddObject(_toUnicode);
|
||||
Elements.Add(Keys.ToUnicode, _toUnicode);
|
||||
|
||||
BaseFont = font.GlyphTypeface.GetBaseName();
|
||||
// CID fonts are always embedded
|
||||
BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);
|
||||
|
||||
FontDescriptor.FontName = BaseFont;
|
||||
_descendantFont.BaseFont = BaseFont;
|
||||
|
||||
PdfArray descendantFonts = new PdfArray(document);
|
||||
Owner._irefTable.Add(_descendantFont);
|
||||
descendantFonts.Elements.Add(_descendantFont.Reference);
|
||||
Elements[Keys.DescendantFonts] = descendantFonts;
|
||||
}
|
||||
|
||||
public PdfType0Font(PdfDocument document, string idName, byte[] fontData, bool vertical)
|
||||
: base(document)
|
||||
{
|
||||
Elements.SetName(Keys.Type, "/Font");
|
||||
Elements.SetName(Keys.Subtype, "/Type0");
|
||||
Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H");
|
||||
|
||||
OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(idName, fontData);
|
||||
FontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
|
||||
_fontOptions = new XPdfFontOptions(PdfFontEncoding.Unicode);
|
||||
Debug.Assert(_fontOptions != null);
|
||||
|
||||
_cmapInfo = new CMapInfo(ttDescriptor);
|
||||
_descendantFont = new PdfCIDFont(document, FontDescriptor, fontData);
|
||||
_descendantFont.CMapInfo = _cmapInfo;
|
||||
|
||||
// Create ToUnicode map
|
||||
_toUnicode = new PdfToUnicodeMap(document, _cmapInfo);
|
||||
document.Internals.AddObject(_toUnicode);
|
||||
Elements.Add(Keys.ToUnicode, _toUnicode);
|
||||
|
||||
//BaseFont = ttDescriptor.FontName.Replace(" ", "");
|
||||
BaseFont = ttDescriptor.FontName;
|
||||
|
||||
// CID fonts are always embedded
|
||||
if (!BaseFont.Contains("+")) // HACK in PdfType0Font
|
||||
BaseFont = CreateEmbeddedFontSubsetName(BaseFont);
|
||||
|
||||
FontDescriptor.FontName = BaseFont;
|
||||
_descendantFont.BaseFont = BaseFont;
|
||||
|
||||
PdfArray descendantFonts = new PdfArray(document);
|
||||
Owner._irefTable.Add(_descendantFont);
|
||||
descendantFonts.Elements.Add(_descendantFont.Reference);
|
||||
Elements[Keys.DescendantFonts] = descendantFonts;
|
||||
}
|
||||
|
||||
XPdfFontOptions FontOptions
|
||||
{
|
||||
get { return _fontOptions; }
|
||||
}
|
||||
XPdfFontOptions _fontOptions;
|
||||
|
||||
public string BaseFont
|
||||
{
|
||||
get { return Elements.GetName(Keys.BaseFont); }
|
||||
set { Elements.SetName(Keys.BaseFont, value); }
|
||||
}
|
||||
|
||||
internal PdfCIDFont DescendantFont
|
||||
{
|
||||
get { return _descendantFont; }
|
||||
}
|
||||
readonly PdfCIDFont _descendantFont;
|
||||
|
||||
internal override void PrepareForSave()
|
||||
{
|
||||
base.PrepareForSave();
|
||||
|
||||
// Use GetGlyphIndices to create the widths array.
|
||||
OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptor._descriptor;
|
||||
StringBuilder w = new StringBuilder("[");
|
||||
if (_cmapInfo != null)
|
||||
{
|
||||
int[] glyphIndices = _cmapInfo.GetGlyphIndices();
|
||||
int count = glyphIndices.Length;
|
||||
int[] glyphWidths = new int[count];
|
||||
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
glyphWidths[idx] = descriptor.GlyphIndexToPdfWidth(glyphIndices[idx]);
|
||||
|
||||
//TODO: optimize order of indices
|
||||
|
||||
for (int idx = 0; idx < count; idx++)
|
||||
w.AppendFormat("{0}[{1}]", glyphIndices[idx], glyphWidths[idx]);
|
||||
w.Append("]");
|
||||
_descendantFont.Elements.SetValue(PdfCIDFont.Keys.W, new PdfLiteral(w.ToString()));
|
||||
|
||||
}
|
||||
_descendantFont.PrepareForSave();
|
||||
_toUnicode.PrepareForSave();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public new sealed class Keys : PdfFont.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be Font for a font dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Font")]
|
||||
public new const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of font; must be Type0 for a Type 0 font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string Subtype = "/Subtype";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The PostScript name of the font. In principle, this is an arbitrary
|
||||
/// name, since there is no font program associated directly with a Type 0 font
|
||||
/// dictionary. The conventions described here ensure maximum compatibility
|
||||
/// with existing Acrobat products.
|
||||
/// If the descendant is a Type 0 CIDFont, this name should be the concatenation
|
||||
/// of the CIDFont<6E>s BaseFont name, a hyphen, and the CMap name given in the
|
||||
/// Encoding entry (or the CMapName entry in the CMap). If the descendant is a
|
||||
/// Type 2 CIDFont, this name should be the same as the CIDFont<6E>s BaseFont name.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string BaseFont = "/BaseFont";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The name of a predefined CMap, or a stream containing a CMap
|
||||
/// that maps character codes to font numbers and CIDs. If the descendant is a
|
||||
/// Type 2 CIDFont whose associated TrueType font program is not embedded
|
||||
/// in the PDF file, the Encoding entry must be a predefined CMap name.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.StreamOrName | KeyType.Required)]
|
||||
public const string Encoding = "/Encoding";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) A one-element array specifying the CIDFont dictionary that is the
|
||||
/// descendant of this Type 0 font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array | KeyType.Required)]
|
||||
public const string DescendantFonts = "/DescendantFonts";
|
||||
|
||||
/// <summary>
|
||||
/// ((Optional) A stream containing a CMap file that maps character codes to
|
||||
/// Unicode values.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string ToUnicode = "/ToUnicode";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Keys._meta == null)
|
||||
Keys._meta = CreateMeta(typeof(Keys));
|
||||
return Keys._meta;
|
||||
}
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
184
PrintPDF/PdfSharp/Pdf.Advanced/PdfType1Font.cs
Normal file
184
PrintPDF/PdfSharp/Pdf.Advanced/PdfType1Font.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
#if true_ // Not yet implemented-
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using PdfSharp.Internal;
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Not implemented - just for illustration of the class hierarchy.
|
||||
/// </summary>
|
||||
internal sealed class PdfType1Font : PdfFont
|
||||
{
|
||||
public PdfType1Font(PdfDocument document)
|
||||
: base(document)
|
||||
{
|
||||
Elements["\\Type"] = new PdfName("Font");
|
||||
Elements["\\Subtype"] = new PdfName("Type1");
|
||||
}
|
||||
|
||||
//public string BaseFont
|
||||
//{
|
||||
// get {return baseFont;}
|
||||
// set {baseFont = value;}
|
||||
//}
|
||||
//string baseFont;
|
||||
|
||||
|
||||
// internal override void AssignObjectID(ref int objectID)
|
||||
// {
|
||||
// SetObjectID(ref objectID);
|
||||
// }
|
||||
//
|
||||
// internal override void WriteObject(Stream stream)
|
||||
// {
|
||||
// base.WriteObject(stream);
|
||||
// StringBuilder pdf = new StringBuilder();
|
||||
// pdf.AppendFormat("{0} 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n/BaseFont /Helvetica\n/Encoding /WinAnsiEncoding\n>>\nendobj\n", ObjectID);
|
||||
// WriteString(stream, pdf.ToString());
|
||||
// }
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public new sealed class Keys : PdfFont.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// (Required) The type of PDF object that this dictionary describes;
|
||||
/// must be Font for a font dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Font")]
|
||||
public new const string Type = "/Type";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The type of font; must be Type1 for a Type 1 font.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string Subtype = "/Subtype";
|
||||
|
||||
/// <summary>
|
||||
/// (Required in PDF 1.0; optional otherwise) The name by which this font is
|
||||
/// referenced in the Font subdictionary of the current resource dictionary.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Optional)]
|
||||
public const string Name = "/Name";
|
||||
|
||||
/// <summary>
|
||||
/// (Required) The PostScript name of the font. For Type 1 fonts, this is usually
|
||||
/// the value of the FontName entry in the font program; for more information.
|
||||
/// The Post-Script name of the font can be used to find the font<6E>s definition in
|
||||
/// the consumer application or its environment. It is also the name that is used when
|
||||
/// printing to a PostScript output device.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Required)]
|
||||
public new const string BaseFont = "/BaseFont";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts) The first character code defined
|
||||
/// in the font<6E>s Widths array.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer)]
|
||||
public const string FirstChar = "/FirstChar";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts) The last character code defined
|
||||
/// in the font<6E>s Widths array.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Integer)]
|
||||
public const string LastChar = "/LastChar";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts; indirect reference preferred)
|
||||
/// An array of (LastChar - FirstChar + 1) widths, each element being the glyph width
|
||||
/// for the character code that equals FirstChar plus the array index. For character
|
||||
/// codes outside the range FirstChar to LastChar, the value of MissingWidth from the
|
||||
/// FontDescriptor entry for this font is used. The glyph widths are measured in units
|
||||
/// in which 1000 units corresponds to 1 unit in text space. These widths must be
|
||||
/// consistent with the actual widths given in the font program.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Array, typeof(PdfArray))]
|
||||
public const string Widths = "/Widths";
|
||||
|
||||
/// <summary>
|
||||
/// (Required except for the standard 14 fonts; must be an indirect reference)
|
||||
/// A font descriptor describing the font<6E>s metrics other than its glyph widths.
|
||||
/// Note: For the standard 14 fonts, the entries FirstChar, LastChar, Widths, and
|
||||
/// FontDescriptor must either all be present or all be absent. Ordinarily, they are
|
||||
/// absent; specifying them enables a standard font to be overridden.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Dictionary | KeyType.MustBeIndirect, typeof(PdfFontDescriptor))]
|
||||
public new const string FontDescriptor = "/FontDescriptor";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional) A specification of the font<6E>s character encoding if different from its
|
||||
/// built-in encoding. The value of Encoding is either the name of a predefined
|
||||
/// encoding (MacRomanEncoding, MacExpertEncoding, or WinAnsiEncoding, as described in
|
||||
/// Appendix D) or an encoding dictionary that specifies differences from the font<6E>s
|
||||
/// built-in encoding or from a specified predefined encoding.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Name | KeyType.Dictionary)]
|
||||
public const string Encoding = "/Encoding";
|
||||
|
||||
/// <summary>
|
||||
/// (Optional; PDF 1.2) A stream containing a CMap file that maps character
|
||||
/// codes to Unicode values.
|
||||
/// </summary>
|
||||
[KeyInfo(KeyType.Stream | KeyType.Optional)]
|
||||
public const string ToUnicode = "/ToUnicode";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta for these keys.
|
||||
/// </summary>
|
||||
internal static DictionaryMeta Meta
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_meta == null)
|
||||
_meta = CreateMeta(typeof(Keys));
|
||||
return _meta;
|
||||
}
|
||||
}
|
||||
static DictionaryMeta _meta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeysMeta of this dictionary type.
|
||||
/// </summary>
|
||||
internal override DictionaryMeta Meta
|
||||
{
|
||||
get { return Keys.Meta; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
51
PrintPDF/PdfSharp/Pdf.Advanced/PdfXObject.cs
Normal file
51
PrintPDF/PdfSharp/Pdf.Advanced/PdfXObject.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
#region PDFsharp - A .NET library for processing PDF
|
||||
//
|
||||
// Authors:
|
||||
// Stefan Lange
|
||||
//
|
||||
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
|
||||
//
|
||||
// http://www.pdfsharp.com
|
||||
// http://sourceforge.net/projects/pdfsharp
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
namespace PdfSharp.Pdf.Advanced
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all PDF external objects.
|
||||
/// </summary>
|
||||
public abstract class PdfXObject : PdfDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfXObject"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">The document that owns the object.</param>
|
||||
protected PdfXObject(PdfDocument document)
|
||||
: base(document)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Predefined keys of this dictionary.
|
||||
/// </summary>
|
||||
public class Keys : PdfStream.Keys
|
||||
{ }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user