First commit

Send all results
This commit is contained in:
2020-09-04 12:49:15 +05:00
commit 330a2ccfda
2819 changed files with 226201 additions and 0 deletions

View File

@@ -0,0 +1,695 @@
/*
* Copyright 2007-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Not yet used in PDFsharp.
#pragma warning disable 1591
// Currently not used.
#if true_
using System;
using System.ComponentModel;
namespace JetBrains.Annotations
{
/// <summary>
/// Indicates that marked element should be localized or not.
/// </summary>
/// <example>
/// <code>
/// [LocalizationRequiredAttribute(true)]
/// public class Foo
/// {
/// private string str = "my string"; // Warning: Localizable string
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public sealed class LocalizationRequiredAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="LocalizationRequiredAttribute"/> class with
/// <see cref="Required"/> set to <see langword="true"/>.
/// </summary>
public LocalizationRequiredAttribute()
: this(true)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="LocalizationRequiredAttribute"/> class.
/// </summary>
/// <param name="required"><c>true</c> if a element should be localized; otherwise, <c>false</c>.</param>
public LocalizationRequiredAttribute(bool required)
{
Required = required;
}
/// <summary>
/// Gets a value indicating whether a element should be localized.
/// <value><c>true</c> if a element should be localized; otherwise, <c>false</c>.</value>
/// </summary>
[UsedImplicitly]
public bool Required { get; private set; }
/// <summary>
/// Returns whether the value of the given object is equal to the current <see cref="LocalizationRequiredAttribute"/>.
/// </summary>
/// <param name="obj">The object to test the value equality of. </param>
/// <returns>
/// <c>true</c> if the value of the given object is equal to that of the current; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj)
{
var attribute = obj as LocalizationRequiredAttribute;
return attribute != null && attribute.Required == Required;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>A hash code for the current <see cref="LocalizationRequiredAttribute"/>.</returns>
public override int GetHashCode()
{
return base.GetHashCode();
}
}
/// <summary>
/// Indicates that the marked method builds string by format pattern and (optional) arguments.
/// Parameter, which contains format string, should be given in constructor.
/// The format string should be in <see cref="string.Format(IFormatProvider,string,object[])"/> -like form
/// </summary>
/// <example>
/// <code>
/// [StringFormatMethod("message")]
/// public void ShowError(string message, params object[] args)
/// {
/// //Do something
/// }
/// public void Foo()
/// {
/// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class StringFormatMethodAttribute : Attribute
{
/// <summary>
/// Initializes new instance of StringFormatMethodAttribute
/// </summary>
/// <param name="formatParameterName">Specifies which parameter of an annotated method should be treated as format-string</param>
public StringFormatMethodAttribute(string formatParameterName)
{
FormatParameterName = formatParameterName;
}
/// <summary>
/// Gets format parameter name
/// </summary>
[UsedImplicitly]
public string FormatParameterName { get; private set; }
}
/// <summary>
/// Indicates that the function argument should be string literal and match one of the parameters
/// of the caller function.
/// For example, ReSharper annotates the parameter of <see cref="System.ArgumentNullException"/>.
/// </summary>
/// <example>
/// <code>
/// public void Foo(string param)
/// {
/// if (param == null)
/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public sealed class InvokerParameterNameAttribute : Attribute { }
/// <summary>
/// Indicates that the method is contained in a type that implements
/// <see cref="System.ComponentModel.INotifyPropertyChanged"/> interface
/// and this method is used to notify that some property value changed.
/// </summary>
/// <remarks>
/// The method should be non-static and conform to one of the supported signatures:
/// <list>
/// <item><c>NotifyChanged(string)</c></item>
/// <item><c>NotifyChanged(params string[])</c></item>
/// <item><c>NotifyChanged{T}(Expression{Func{T}})</c></item>
/// <item><c>NotifyChanged{T,U}(Expression{Func{T,U}})</c></item>
/// <item><c>SetProperty{T}(ref T, T, string)</c></item>
/// </list>
/// </remarks>
/// <example>
/// <code>
/// public class Foo : INotifyPropertyChanged
/// {
/// public event PropertyChangedEventHandler PropertyChanged;
///
/// [NotifyPropertyChangedInvocator]
/// protected virtual void NotifyChanged(string propertyName)
/// {}
///
/// private string _name;
/// public string Name
/// {
/// get { return _name; }
/// set
/// {
/// _name = value;
/// NotifyChanged("LastName"); // Warning
/// }
/// }
/// }
/// </code>
/// Examples of generated notifications:
/// <list>
/// <item><c>NotifyChanged("Property")</c></item>
/// <item><c>NotifyChanged(() => Property)</c></item>
/// <item><c>NotifyChanged((VM x) => x.Property)</c></item>
/// <item><c>SetProperty(ref myField, value, "Property")</c></item>
/// </list>
/// </example>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute
{
public NotifyPropertyChangedInvocatorAttribute() { }
public NotifyPropertyChangedInvocatorAttribute(string parameterName)
{
ParameterName = parameterName;
}
[UsedImplicitly]
public string ParameterName { get; private set; }
}
/// <summary>
/// Indicates that the value of the marked element could be <c>null</c> sometimes,
/// so the check for <c>null</c> is necessary before its usage.
/// </summary>
/// <example>
/// <code>
/// [CanBeNull]
/// public object Test()
/// {
/// return null;
/// }
///
/// public void UseTest()
/// {
/// var p = Test();
/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class CanBeNullAttribute : Attribute { }
/// <summary>
/// Indicates that the value of the marked element could never be <c>null</c>
/// </summary>
/// <example>
/// <code>
/// [NotNull]
/// public object Foo()
/// {
/// return null; // Warning: Possible 'null' assignment
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class NotNullAttribute : Attribute { }
/// <summary>
/// Describes dependency between method input and output.
/// </summary>
/// <syntax>
/// <p>Function Definition Table syntax:</p>
/// <list>
/// <item>FDT ::= FDTRow [;FDTRow]*</item>
/// <item>FDTRow ::= Input =&gt; Output | Output &lt;= Input</item>
/// <item>Input ::= ParameterName: Value [, Input]*</item>
/// <item>Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value}</item>
/// <item>Value ::= true | false | null | notnull | canbenull</item>
/// </list>
/// If method has single input parameter, its name could be omitted. <br/>
/// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) for method output means that the methos doesn't return normally. <br/>
/// <c>canbenull</c> annotation is only applicable for output parameters. <br/>
/// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, or use single attribute with rows separated by semicolon. <br/>
/// </syntax>
/// <examples>
/// <list>
/// <item><code>
/// [ContractAnnotation("=> halt")]
/// public void TerminationMethod()
/// </code></item>
/// <item><code>
/// [ContractAnnotation("halt &lt;= condition: false")]
/// public void Assert(bool condition, string text) // Regular Assertion method
/// </code></item>
/// <item><code>
/// [ContractAnnotation("s:null => true")]
/// public bool IsNullOrEmpty(string s) // String.IsNullOrEmpty
/// </code></item>
/// <item><code>
/// // A method that returns null if the parameter is null, and not null if the parameter is not null
/// [ContractAnnotation("null => null; notnull => notnull")]
/// public object Transform(object data)
/// </code></item>
/// <item><code>
/// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
/// public bool TryParse(string s, out Person result)
/// </code></item>
/// </list>
/// </examples>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public sealed class ContractAnnotationAttribute : Attribute
{
public ContractAnnotationAttribute([NotNull] string fdt)
: this(fdt, false)
{
}
public ContractAnnotationAttribute([NotNull] string fdt, bool forceFullStates)
{
FDT = fdt;
ForceFullStates = forceFullStates;
}
public string FDT { get; private set; }
public bool ForceFullStates { get; private set; }
}
/// <summary>
/// Indicates that the value of the marked type (or its derivatives)
/// cannot be compared using '==' or '!=' operators and <c>Equals()</c> should be used instead.
/// However, using '==' or '!=' for comparison with <c>null</c> is always permitted.
/// </summary>
/// <example>
/// <code>
/// [CannotApplyEqualityOperator]
/// class NoEquality
/// {
/// }
///
/// class UsesNoEquality
/// {
/// public void Test()
/// {
/// var ca1 = new NoEquality();
/// var ca2 = new NoEquality();
///
/// if (ca1 != null) // OK
/// {
/// bool condition = ca1 == ca2; // Warning
/// }
/// }
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
public sealed class CannotApplyEqualityOperatorAttribute : Attribute { }
/// <summary>
/// When applied to a target attribute, specifies a requirement for any type marked with
/// the target attribute to implement or inherit specific type or types.
/// </summary>
/// <example>
/// <code>
/// [BaseTypeRequired(typeof(IComponent)] // Specify requirement
/// public class ComponentAttribute : Attribute
/// {}
///
/// [Component] // ComponentAttribute requires implementing IComponent interface
/// public class MyComponent : IComponent
/// {}
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
[BaseTypeRequired(typeof(Attribute))]
public sealed class BaseTypeRequiredAttribute : Attribute
{
/// <summary>
/// Initializes new instance of BaseTypeRequiredAttribute
/// </summary>
/// <param name="baseType">Specifies which types are required</param>
public BaseTypeRequiredAttribute(Type baseType)
{
BaseTypes = new[] { baseType };
}
/// <summary>
/// Gets enumerations of specified base types
/// </summary>
public Type[] BaseTypes { get; private set; }
}
/// <summary>
/// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library),
/// so this symbol will not be marked as unused (as well as by other usage inspections)
/// </summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public sealed class UsedImplicitlyAttribute : Attribute
{
[UsedImplicitly]
public UsedImplicitlyAttribute()
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
{ }
[UsedImplicitly]
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
[UsedImplicitly]
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
: this(useKindFlags, ImplicitUseTargetFlags.Default)
{ }
[UsedImplicitly]
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
: this(ImplicitUseKindFlags.Default, targetFlags)
{ }
[UsedImplicitly]
public ImplicitUseKindFlags UseKindFlags { get; private set; }
/// <summary>
/// Gets value indicating what is meant to be used
/// </summary>
[UsedImplicitly]
public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
/// <summary>
/// Should be used on attributes and causes ReSharper
/// to not mark symbols marked with such attributes as unused (as well as by other usage inspections)
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class MeansImplicitUseAttribute : Attribute
{
[UsedImplicitly]
public MeansImplicitUseAttribute()
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
{ }
[UsedImplicitly]
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
[UsedImplicitly]
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
: this(useKindFlags, ImplicitUseTargetFlags.Default)
{
}
[UsedImplicitly]
public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
: this(ImplicitUseKindFlags.Default, targetFlags)
{ }
[UsedImplicitly]
public ImplicitUseKindFlags UseKindFlags { get; private set; }
/// <summary>
/// Gets value indicating what is meant to be used
/// </summary>
[UsedImplicitly]
public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
[Flags]
public enum ImplicitUseKindFlags
{
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
/// <summary>
/// Only entity marked with attribute considered used
/// </summary>
Access = 1,
/// <summary>
/// Indicates implicit assignment to a member
/// </summary>
Assign = 2,
/// <summary>
/// Indicates implicit instantiation of a type with fixed constructor signature.
/// That means any unused constructor parameters won't be reported as such.
/// </summary>
InstantiatedWithFixedConstructorSignature = 4,
/// <summary>
/// Indicates implicit instantiation of a type
/// </summary>
InstantiatedNoFixedConstructorSignature = 8,
}
/// <summary>
/// Specify what is considered used implicitly when marked with <see cref="MeansImplicitUseAttribute"/> or <see cref="UsedImplicitlyAttribute"/>
/// </summary>
[Flags]
public enum ImplicitUseTargetFlags
{
Default = Itself,
Itself = 1,
/// <summary>
/// Members of entity marked with attribute are considered used
/// </summary>
Members = 2,
/// <summary>
/// Entity marked with attribute and all its members considered used
/// </summary>
WithMembers = Itself | Members
}
/// <summary>
/// This attribute is intended to mark publicly available API which should not be removed and so is treated as used.
/// </summary>
[MeansImplicitUse]
public sealed class PublicAPIAttribute : Attribute
{
public PublicAPIAttribute() { }
public PublicAPIAttribute(string comment) { }
}
/// <summary>
/// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack.
/// If the parameter is a delegate, indicates that delegate is executed while the method is executed.
/// If the parameter is an enumerable, indicates that it is enumerated while the method is executed.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = true)]
public sealed class InstantHandleAttribute : Attribute { }
/// <summary>
/// Indicates that a method does not make any observable state changes.
/// The same as <see cref="System.Diagnostics.Contracts.PureAttribute"/>
/// </summary>
/// <example>
/// <code>
/// [Pure]
/// private int Multiply(int x, int y)
/// {
/// return x*y;
/// }
///
/// public void Foo()
/// {
/// const int a=2, b=2;
/// Multiply(a, b); // Waring: Return value of pure method is not used
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public sealed class PureAttribute : Attribute { }
/// <summary>
/// Indicates that a parameter is a path to a file or a folder within a web project.
/// Path can be relative or absolute, starting from web root (~).
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public class PathReferenceAttribute : Attribute
{
public PathReferenceAttribute() { }
[UsedImplicitly]
public PathReferenceAttribute([PathReference] string basePath)
{
BasePath = basePath;
}
[UsedImplicitly]
public string BasePath { get; private set; }
}
// ASP.NET MVC attributes
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC action.
/// If applied to a method, the MVC action name is calculated implicitly from the context.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcActionAttribute : Attribute
{
[UsedImplicitly]
public string AnonymousProperty { get; private set; }
public AspMvcActionAttribute() { }
public AspMvcActionAttribute(string anonymousProperty)
{
AnonymousProperty = anonymousProperty;
}
}
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC araa.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcAreaAttribute : PathReferenceAttribute
{
[UsedImplicitly]
public string AnonymousProperty { get; private set; }
[UsedImplicitly]
public AspMvcAreaAttribute() { }
public AspMvcAreaAttribute(string anonymousProperty)
{
AnonymousProperty = anonymousProperty;
}
}
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC controller.
/// If applied to a method, the MVC controller name is calculated implicitly from the context.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcControllerAttribute : Attribute
{
[UsedImplicitly]
public string AnonymousProperty { get; private set; }
public AspMvcControllerAttribute() { }
public AspMvcControllerAttribute(string anonymousProperty)
{
AnonymousProperty = anonymousProperty;
}
}
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC Master.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Controller.View(String, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcMasterAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC model type.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Controller.View(String, Object)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcModelTypeAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC partial view.
/// If applied to a method, the MVC partial view name is calculated implicitly from the context.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcPartialViewAttribute : PathReferenceAttribute { }
/// <summary>
/// ASP.NET MVC attribute. Allows disabling all inspections for MVC views within a class or a method.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class AspMvcSupressViewErrorAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcDisplayTemplateAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC editor template.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcEditorTemplateAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC view.
/// If applied to a method, the MVC view name is calculated implicitly from the context.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.Mvc.Controller.View(Object)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcViewAttribute : PathReferenceAttribute { }
/// <summary>
/// ASP.NET MVC attribute. When applied to a parameter of an attribute,
/// indicates that this parameter is an MVC action name.
/// </summary>
/// <example>
/// <code>
/// [ActionName("Foo")]
/// public ActionResult Login(string returnUrl)
/// {
/// ViewBag.ReturnUrl = Url.Action("Foo"); // OK
/// return RedirectToAction("Bar"); // Error: Cannot resolve action
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public sealed class AspMvcActionSelectorAttribute : Attribute { }
// Razor attributes
/// <summary>
/// Razor attribute. Indicates that a parameter or a method is a Razor section.
/// Use this attribute for custom wrappers similar to
/// <see cref="System.Web.WebPages.WebPageBase.RenderSection(String)"/>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, Inherited = true)]
public sealed class RazorSectionAttribute : Attribute { }
}
#endif

View File

@@ -0,0 +1,69 @@
#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
{
/// <summary>
/// Floating point formatting.
/// </summary>
static class Config
{
public const string SignificantFigures2 = "0.##";
public const string SignificantFigures3 = "0.###";
public const string SignificantFigures4 = "0.####";
public const string SignificantFigures7 = "0.#######";
public const string SignificantFigures10 = "0.##########";
public const string SignificantFigures1Plus9 = "0.0#########";
}
static class Const
{
/// <summary>
/// Factor to convert from degree to radian measure.
/// </summary>
public const double Deg2Rad = Math.PI / 180; // = 0.017453292519943295
/// <summary>
/// Sinus of the angle to turn a regular font to look oblique. Used for italic simulation.
/// </summary>
public const double ItalicSkewAngleSinus = 0.34202014332566873304409961468226; // = sin(20°)
/// <summary>
/// Factor of the em size of a regular font to look bold. Used for bold simulation.
/// Value of 2% found in original XPS 1.0 documentation.
/// </summary>
public const double BoldEmphasis = 0.02;
// The κ (kappa) for drawing a circle or an ellipse with four Bézier splines, specifying the distance of the influence point from the starting or end point of a spline.
// Petzold: 4/3 * tan(α / 4)
public const double κ = 0.5522847498307933984022516322796; // := 4/3 * (1 - cos(-π/4)) / sin(π/4)) <=> 4/3 * (sqrt(2) - 1) <=> 4/3 * tan(π/8)
}
}

View File

@@ -0,0 +1,113 @@
#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
//
// Documentation of conditional compilation symbols used in PDFsharp.
// Checks correct settings and obsolete conditional compilation symbols.
//
#if NewViewMatrix // obsolete
#error NewViewMatrix must not be defined anmore.
#endif
#if MIGRADOC // obsolete
// empira internal only: Some hacks that make PDFsharp behave like PDFlib when used with Asc.RenderContext.
// Applies to MigraDoc 1.2 only. The Open Source MigraDoc lite does not need this define.
#error MIGRADOC must not be defined anmore.
#endif
#if NET_ZIP // obsolete
// In .NET 2.0 GZipStream is used instead of SharpZipLib
// This does not work as anticipated.
#error Undefine 'NET_ZIP' because it has no effect anymore.
#endif
#if NET_2_0 // obsolete
#error Undefine 'NET_2_0' because earlier versions are not supported anymore.
#endif
#if Gdip // obsolete
#error Conditional compilation symbol 'Gdip' was renamed to 'GDI'.
#endif
#if GdipUseGdiObjects // obsolete
#error Conditional compilation symbol 'GdipUseGdiObjects' was renamed to 'UseGdiObjects'.
#endif
// Fragmentation of large object heap is a serious issue that must be tackled in the future.
// Update: .NET 4.51 can ultimately defragment LOH. So maybe we can wait and see.
#if UseMemoryStreams
// Use MemoryStream instead of byte[] to avoid large heap problems.
#error Undefine 'UseMemoryStreams' because it has no effect anymore.
#else
// Use byte[] (instead of MemoryStream) to analyse the symptoms of large heap issues.
#endif
#if GDI && WPF
// PDFsharp based on both System.Drawing and System.Windows classes
// This is for developing and cross testing only
#elif GDI
// PDFsharp based on System.Drawing classes
#if GdipUseGdiObjects
#error Conditional compilation symbol 'GdipUseGdiObjects' was renamed to 'UseGdiObjects'.
#endif
#if UseGdiObjects
// PDFsharp X graphics classes have implicit cast operators for GDI+ objects.
// Define this to make it easier to use older code with PDFsharp.
// Undefine this to prevent dependencies to GDI+
#endif
#elif WPF
// PDFsharp based on Windows Presentation Foundation.
#elif SILVERLIGHT
// PDFsharp based on 'Silverlight'.
#if !WPF
#error 'SILVERLIGHT' must be defined together with 'WPF'
#endif
#elif WINDOWS_PHONE
// PDFsharp based on 'Windows Phone'.
#if !WPF
#error 'WINDOWS_PHONE' must be defined together with 'WPF'.
#endif
#if !SILVERLIGHT
#error 'WINDOWS_PHONE' must be defined together with 'SILVERLIGHT'.
#endif
#elif CORE
// PDFsharp independent of any particular .NET library.
#elif NETFX_CORE
// PDFsharp based on 'WinRT'.
#elif UWP
// PDFsharp based on 'Windows Universal Platform'.
#else
#error Either 'CORE', 'GDI', 'WPF', 'SILVERLIGHT', 'WINDOWS_PHONE', or 'NETFX_CORE' must be defined. Or UWP.
#endif

View File

@@ -0,0 +1,45 @@
#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.Internal
{
// In PDFsharp hybrid build both GDI and WPF is defined.
// This is for development and testing only.
#if GDI && WPF
/// <summary>
/// Internal switch indicating what context has to be used if both GDI and WPF are defined.
/// </summary>
static class TargetContextHelper
{
public static XGraphicTargetContext TargetContext = XGraphicTargetContext.WPF;
}
#endif
}

View File

@@ -0,0 +1,170 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.ComponentModel;
namespace PdfSharp.Drawing.BarCodes
{
/// <summary>
/// Represents the base class of all bar codes.
/// </summary>
public abstract class BarCode : CodeBase
{
/// <summary>
/// Initializes a new instance of the <see cref="BarCode"/> class.
/// </summary>
/// <param name="text"></param>
/// <param name="size"></param>
/// <param name="direction"></param>
public BarCode(string text, XSize size, CodeDirection direction)
: base(text, size, direction)
{
Text = text;
Size = size;
Direction = direction;
}
/// <summary>
/// Creates a bar code from the specified code type.
/// </summary>
public static BarCode FromType(CodeType type, string text, XSize size, CodeDirection direction)
{
switch (type)
{
case CodeType.Code2of5Interleaved:
return new Code2of5Interleaved(text, size, direction);
case CodeType.Code3of9Standard:
return new Code3of9Standard(text, size, direction);
default:
throw new InvalidEnumArgumentException("type", (int)type, typeof(CodeType));
}
}
/// <summary>
/// Creates a bar code from the specified code type.
/// </summary>
public static BarCode FromType(CodeType type, string text, XSize size)
{
return FromType(type, text, size, CodeDirection.LeftToRight);
}
/// <summary>
/// Creates a bar code from the specified code type.
/// </summary>
public static BarCode FromType(CodeType type, string text)
{
return FromType(type, text, XSize.Empty, CodeDirection.LeftToRight);
}
/// <summary>
/// Creates a bar code from the specified code type.
/// </summary>
public static BarCode FromType(CodeType type)
{
return FromType(type, String.Empty, XSize.Empty, CodeDirection.LeftToRight);
}
/// <summary>
/// When overridden in a derived class gets or sets the wide narrow ratio.
/// </summary>
public virtual double WideNarrowRatio
{
get { return 0; }
set { }
}
/// <summary>
/// Gets or sets the location of the text next to the bar code.
/// </summary>
public TextLocation TextLocation
{
get { return _textLocation; }
set { _textLocation = value; }
}
TextLocation _textLocation;
/// <summary>
/// Gets or sets the length of the data that defines the bar code.
/// </summary>
public int DataLength
{
get { return _dataLength; }
set { _dataLength = value; }
}
int _dataLength;
/// <summary>
/// Gets or sets the optional start character.
/// </summary>
public char StartChar
{
get { return _startChar; }
set { _startChar = value; }
}
char _startChar;
/// <summary>
/// Gets or sets the optional end character.
/// </summary>
public char EndChar
{
get { return _endChar; }
set { _endChar = value; }
}
char _endChar;
/// <summary>
/// Gets or sets a value indicating whether the turbo bit is to be drawn.
/// (A turbo bit is something special to Kern (computer output processing) company (as far as I know))
/// </summary>
public virtual bool TurboBit
{
get { return _turboBit; }
set { _turboBit = value; }
}
bool _turboBit;
internal virtual void InitRendering(BarCodeRenderInfo info)
{
if (Text == null)
throw new InvalidOperationException(BcgSR.BarCodeNotSet);
if (Size.IsEmpty)
throw new InvalidOperationException(BcgSR.EmptyBarCodeSize);
}
/// <summary>
/// When defined in a derived class renders the code.
/// </summary>
protected internal abstract void Render(XGraphics gfx, XBrush brush, XFont font, XPoint position);
}
}

View File

@@ -0,0 +1,54 @@
//
// PDFsharp - A library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
//
// 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.
namespace PdfSharp.Drawing.BarCodes
{
/// <summary>
/// Holds all temporary information needed during rendering.
/// </summary>
class BarCodeRenderInfo
{
public BarCodeRenderInfo(XGraphics gfx, XBrush brush, XFont font, XPoint position)
{
Gfx = gfx;
Brush = brush;
Font = font;
Position = position;
}
public XGraphics Gfx;
public XBrush Brush;
public XFont Font;
public XPoint Position;
public double BarHeight;
public XPoint CurrPos;
public int CurrPosInString;
public double ThinBarWidth;
}
}

View File

@@ -0,0 +1,93 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
// TODO: Mere with PDFsharp strings table
/// <summary>
/// String resources for the empira barcode renderer.
/// </summary>
internal class BcgSR
{
internal static string Invalid2Of5Code(string code)
{
return string.Format("'{0}' is not a valid code for an interleave 2 of 5 bar code. It can only represent an even number of digits.", code);
}
internal static string Invalid3Of9Code(string code)
{
return string.Format("'{0}' is not a valid code for a 3 of 9 standard bar code.", code);
}
internal static string BarCodeNotSet
{
get { return "A text must be set before rendering the bar code."; }
}
internal static string EmptyBarCodeSize
{
get { return "A non-empty size must be set before rendering the bar code."; }
}
internal static string Invalid2of5Relation
{
get { return "Value of relation between thick and thin lines on the interleaved 2 of 5 code must be between 2 and 3."; }
}
internal static string InvalidMarkName(string name)
{
return string.Format("'{0}' is not a valid mark name for this OMR representation.", name);
}
internal static string OmrAlreadyInitialized
{
get { return "Mark descriptions cannot be set when marks have already been set on OMR."; }
}
internal static string DataMatrixTooBig
{
get { return "The given data and encoding combination is too big for the matrix size."; }
}
internal static string DataMatrixNotSupported
{
get { return "Zero sizes, odd sizes and other than ecc200 coded DataMatrix is not supported."; }
}
internal static string DataMatrixNull
{
get { return "No DataMatrix code is produced."; }
}
internal static string DataMatrixInvalid(int columns, int rows)
{
return string.Format("'{1}'x'{0}' is an invalid ecc200 DataMatrix size.", columns, rows);
}
}
}

View File

@@ -0,0 +1,193 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Implementation of the Code 2 of 5 bar code.
/// </summary>
public class Code2of5Interleaved : ThickThinBarCode
{
/// <summary>
/// Initializes a new instance of Interleaved2of5.
/// </summary>
public Code2of5Interleaved()
: base("", XSize.Empty, CodeDirection.LeftToRight)
{}
/// <summary>
/// Initializes a new instance of Interleaved2of5.
/// </summary>
public Code2of5Interleaved(string code)
: base(code, XSize.Empty, CodeDirection.LeftToRight)
{}
/// <summary>
/// Initializes a new instance of Interleaved2of5.
/// </summary>
public Code2of5Interleaved(string code, XSize size)
: base(code, size, CodeDirection.LeftToRight)
{}
/// <summary>
/// Initializes a new instance of Interleaved2of5.
/// </summary>
public Code2of5Interleaved(string code, XSize size, CodeDirection direction)
: base(code, size, direction)
{}
/// <summary>
/// Returns an array of size 5 that represents the thick (true) and thin (false) lines or spaces
/// representing the specified digit.
/// </summary>
/// <param name="digit">The digit to represent.</param>
static bool[] ThickAndThinLines(int digit)
{
return Lines[digit];
}
static bool[][] Lines =
{
new bool[] {false, false, true, true, false},
new bool[] {true, false, false, false, true},
new bool[] {false, true, false, false, true},
new bool[] {true, true, false, false, false},
new bool[] {false, false, true, false, true},
new bool[] {true, false, true, false, false},
new bool[] {false, true, true, false, false},
new bool[] {false, false, false, true, true},
new bool[] {true, false, false, true, false},
new bool[] {false, true, false, true, false},
};
/// <summary>
/// Renders the bar code.
/// </summary>
protected internal override void Render(XGraphics gfx, XBrush brush, XFont font, XPoint position)
{
XGraphicsState state = gfx.Save();
BarCodeRenderInfo info = new BarCodeRenderInfo(gfx, brush, font, position);
InitRendering(info);
info.CurrPosInString = 0;
//info.CurrPos = info.Center - Size / 2;
info.CurrPos = position - CodeBase.CalcDistance(AnchorType.TopLeft, Anchor, Size);
if (TurboBit)
RenderTurboBit(info, true);
RenderStart(info);
while (info.CurrPosInString < Text.Length)
RenderNextPair(info);
RenderStop(info);
if (TurboBit)
RenderTurboBit(info, false);
if (TextLocation != TextLocation.None)
RenderText(info);
gfx.Restore(state);
}
/// <summary>
/// Calculates the thick and thin line widths,
/// taking into account the required rendering size.
/// </summary>
internal override void CalcThinBarWidth(BarCodeRenderInfo info)
{
/*
* The total width is the sum of the following parts:
* Starting lines = 4 * thin
* +
* Code Representation = (2 * thick + 3 * thin) * code.Length
* +
* Stopping lines = 1 * thick + 2 * thin
*
* with r = relation ( = thick / thin), this results in
*
* Total width = (6 + r + (2 * r + 3) * text.Length) * thin
*/
double thinLineAmount = 6 + WideNarrowRatio + (2 * WideNarrowRatio + 3) * Text.Length;
info.ThinBarWidth = Size.Width / thinLineAmount;
}
private void RenderStart(BarCodeRenderInfo info)
{
RenderBar(info, false);
RenderGap(info, false);
RenderBar(info, false);
RenderGap(info, false);
}
private void RenderStop(BarCodeRenderInfo info)
{
RenderBar(info, true);
RenderGap(info, false);
RenderBar(info, false);
}
/// <summary>
/// Renders the next digit pair as bar code element.
/// </summary>
private void RenderNextPair(BarCodeRenderInfo info)
{
int digitForLines = int.Parse(Text[info.CurrPosInString].ToString());
int digitForGaps = int.Parse(Text[info.CurrPosInString + 1].ToString());
bool[] linesArray = Lines[digitForLines];
bool[] gapsArray = Lines[digitForGaps];
for (int idx = 0; idx < 5; ++idx)
{
RenderBar(info, linesArray[idx]);
RenderGap(info, gapsArray[idx]);
}
info.CurrPosInString += 2;
}
/// <summary>
/// Checks the code to be convertible into an interleaved 2 of 5 bar code.
/// </summary>
/// <param name="text">The code to be checked.</param>
protected override void CheckCode(string text)
{
#if true_
if (text == null)
throw new ArgumentNullException("text");
if (text == "")
throw new ArgumentException(BcgSR.Invalid2Of5Code(text));
if (text.Length % 2 != 0)
throw new ArgumentException(BcgSR.Invalid2Of5Code(text));
foreach (char ch in text)
{
if (!Char.IsDigit(ch))
throw new ArgumentException(BcgSR.Invalid2Of5Code(text));
}
#endif
}
}
}

View File

@@ -0,0 +1,271 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Imlpementation of the Code 3 of 9 bar code.
/// </summary>
// ReSharper disable once InconsistentNaming
public class Code3of9Standard : ThickThinBarCode
{
/// <summary>
/// Initializes a new instance of Standard3of9.
/// </summary>
public Code3of9Standard()
: base("", XSize.Empty, CodeDirection.LeftToRight)
{ }
/// <summary>
/// Initializes a new instance of Standard3of9.
/// </summary>
public Code3of9Standard(string code)
: base(code, XSize.Empty, CodeDirection.LeftToRight)
{ }
/// <summary>
/// Initializes a new instance of Standard3of9.
/// </summary>
public Code3of9Standard(string code, XSize size)
: base(code, size, CodeDirection.LeftToRight)
{ }
/// <summary>
/// Initializes a new instance of Standard3of9.
/// </summary>
public Code3of9Standard(string code, XSize size, CodeDirection direction)
: base(code, size, direction)
{ }
/// <summary>
/// Returns an array of size 9 that represents the thick (true) and thin (false) lines and spaces
/// representing the specified digit.
/// </summary>
/// <param name="ch">The character to represent.</param>
private static bool[] ThickThinLines(char ch)
{
return Lines["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*".IndexOf(ch)];
}
static readonly bool[][] Lines =
{
// '0'
new bool[] {false, false, false, true, true, false, true, false, false},
// '1'
new bool[] {true, false, false, true, false, false, false, false, true},
// '2'
new bool[] {false, false, true, true, false, false, false, false, true},
// '3'
new bool[] {true, false, true, true, false, false, false, false, false},
// '4'
new bool[] {false, false, false, true, true, false, false, false, true},
// '5'
new bool[] {true, false, false, true, true, false, false, false, false},
// '6'
new bool[] {false, false, true, true, true, false, false, false, false},
// '7'
new bool[] {false, false, false, true, false, false, true, false, true},
// '8'
new bool[] {true, false, false, true, false, false, true, false, false},
// '9'
new bool[] {false, false, true, true, false, false, true, false, false},
// 'A'
new bool[] {true, false, false, false, false, true, false, false, true},
// 'B'
new bool[] {false, false, true, false, false, true, false, false, true},
// 'C'
new bool[] {true, false, true, false, false, true, false, false, false},
// 'D'
new bool[] {false, false, false, false, true, true, false, false, true},
// 'E'
new bool[] {true, false, false, false, true, true, false, false, false},
// 'F'
new bool[] {false, false, true, false, true, true, false, false, false},
// 'G'
new bool[] {false, false, false, false, false, true, true, false, true},
// 'H'
new bool[] {true, false, false, false, false, true, true, false, false},
// 'I'
new bool[] {false, false, true, false, false, true, true, false, false},
// 'J'
new bool[] {false, false, false, false, true, true, true, false, false},
// 'K'
new bool[] {true, false, false, false, false, false, false, true, true},
// 'L'
new bool[] {false, false, true, false, false, false, false, true, true},
// 'M'
new bool[] {true, false, true, false, false, false, false, true, false},
// 'N'
new bool[] {false, false, false, false, true, false, false, true, true},
// 'O'
new bool[] {true, false, false, false, true, false, false, true, false},
// 'P':
new bool[] {false, false, true, false, true, false, false, true, false},
// 'Q'
new bool[] {false, false, false, false, false, false, true, true, true},
// 'R'
new bool[] {true, false, false, false, false, false, true, true, false},
// 'S'
new bool[] {false, false, true, false, false, false, true, true, false},
// 'T'
new bool[] {false, false, false, false, true, false, true, true, false},
// 'U'
new bool[] {true, true, false, false, false, false, false, false, true},
// 'V'
new bool[] {false, true, true, false, false, false, false, false, true},
// 'W'
new bool[] {true, true, true, false, false, false, false, false, false},
// 'X'
new bool[] {false, true, false, false, true, false, false, false, true},
// 'Y'
new bool[] {true, true, false, false, true, false, false, false, false},
// 'Z'
new bool[] {false, true, true, false, true, false, false, false, false},
// '-'
new bool[] {false, true, false, false, false, false, true, false, true},
// '.'
new bool[] {true, true, false, false, false, false, true, false, false},
// ' '
new bool[] {false, true, true, false, false, false, true, false, false},
// '$'
new bool[] {false, true, false, true, false, true, false, false, false},
// '/'
new bool[] {false, true, false, true, false, false, false, true, false},
// '+'
new bool[] {false, true, false, false, false, true, false, true, false},
// '%'
new bool[] {false, false, false, true, false, true, false, true, false},
// '*'
new bool[] {false, true, false, false, true, false, true, false, false},
};
/// <summary>
/// Calculates the thick and thin line widths,
/// taking into account the required rendering size.
/// </summary>
internal override void CalcThinBarWidth(BarCodeRenderInfo info)
{
/*
* The total width is the sum of the following parts:
* Starting lines = 3 * thick + 7 * thin
* +
* Code Representation = (3 * thick + 7 * thin) * code.Length
* +
* Stopping lines = 3 * thick + 6 * thin
*
* with r = relation ( = thick / thin), this results in
*
* Total width = (13 + 6 * r + (3 * r + 7) * code.Length) * thin
*/
double thinLineAmount = 13 + 6 * WideNarrowRatio + (3 * WideNarrowRatio + 7) * Text.Length;
info.ThinBarWidth = Size.Width / thinLineAmount;
}
/// <summary>
/// Checks the code to be convertible into an standard 3 of 9 bar code.
/// </summary>
/// <param name="text">The code to be checked.</param>
protected override void CheckCode(string text)
{
if (text == null)
throw new ArgumentNullException("text");
if (text.Length == 0)
throw new ArgumentException(BcgSR.Invalid3Of9Code(text));
foreach (char ch in text)
{
if ("0123456789ABCDEFGHIJKLMNOP'QRSTUVWXYZ-. $/+%*".IndexOf(ch) < 0)
throw new ArgumentException(BcgSR.Invalid3Of9Code(text));
}
}
/// <summary>
/// Renders the bar code.
/// </summary>
protected internal override void Render(XGraphics gfx, XBrush brush, XFont font, XPoint position)
{
XGraphicsState state = gfx.Save();
BarCodeRenderInfo info = new BarCodeRenderInfo(gfx, brush, font, position);
InitRendering(info);
info.CurrPosInString = 0;
//info.CurrPos = Center - Size / 2;
info.CurrPos = position - CalcDistance(AnchorType.TopLeft, Anchor, Size);
if (TurboBit)
RenderTurboBit(info, true);
RenderStart(info);
while (info.CurrPosInString < Text.Length)
{
RenderNextChar(info);
RenderGap(info, false);
}
RenderStop(info);
if (TurboBit)
RenderTurboBit(info, false);
if (TextLocation != TextLocation.None)
RenderText(info);
gfx.Restore(state);
}
private void RenderNextChar(BarCodeRenderInfo info)
{
RenderChar(info, Text[info.CurrPosInString]);
++info.CurrPosInString;
}
private void RenderChar(BarCodeRenderInfo info, char ch)
{
bool[] thickThinLines = ThickThinLines(ch);
int idx = 0;
while (idx < 9)
{
RenderBar(info, thickThinLines[idx]);
if (idx < 8)
RenderGap(info, thickThinLines[idx + 1]);
idx += 2;
}
}
private void RenderStart(BarCodeRenderInfo info)
{
RenderChar(info, '*');
RenderGap(info, false);
}
private void RenderStop(BarCodeRenderInfo info)
{
RenderChar(info, '*');
}
}
}

View File

@@ -0,0 +1,169 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Represents the base class of all codes.
/// </summary>
public abstract class CodeBase
{
/// <summary>
/// Initializes a new instance of the <see cref="CodeBase"/> class.
/// </summary>
public CodeBase(string text, XSize size, CodeDirection direction)
{
_text = text;
_size = size;
_direction = direction;
}
//public static CodeBase FromType(CodeType type, string text, XSize size, CodeDirection direction)
//{
// switch (type)
// {
// case CodeType.Code2of5Interleaved:
// return new Code2of5Interleaved(text, size, direction);
// case CodeType.Code3of9Standard:
// return new Code3of9Standard(text, size, direction);
// default:
// throw new InvalidEnumArgumentException("type", (int)type, typeof(CodeType));
// }
//}
//public static CodeBase FromType(CodeType type, string text, XSize size)
//{
// return FromType(type, text, size, CodeDirection.LeftToRight);
//}
//public static CodeBase FromType(CodeType type, string text)
//{
// return FromType(type, text, XSize.Empty, CodeDirection.LeftToRight);
//}
//public static CodeBase FromType(CodeType type)
//{
// return FromType(type, String.Empty, XSize.Empty, CodeDirection.LeftToRight);
//}
/// <summary>
/// Gets or sets the size.
/// </summary>
public XSize Size
{
get { return _size; }
set { _size = value; }
}
XSize _size;
/// <summary>
/// Gets or sets the text the bar code shall represent.
/// </summary>
public string Text
{
get { return _text; }
set
{
CheckCode(value);
_text = value;
}
}
string _text;
/// <summary>
/// Always MiddleCenter.
/// </summary>
public AnchorType Anchor
{
get { return _anchor; }
set { _anchor = value; }
}
AnchorType _anchor;
/// <summary>
/// Gets or sets the drawing direction.
/// </summary>
public CodeDirection Direction
{
get { return _direction; }
set { _direction = value; }
}
CodeDirection _direction;
/// <summary>
/// When implemented in a derived class, determines whether the specified string can be used as Text
/// for this bar code type.
/// </summary>
/// <param name="text">The code string to check.</param>
/// <returns>True if the text can be used for the actual barcode.</returns>
protected abstract void CheckCode(string text);
/// <summary>
/// Calculates the distance between an old anchor point and a new anchor point.
/// </summary>
/// <param name="oldType"></param>
/// <param name="newType"></param>
/// <param name="size"></param>
public static XVector CalcDistance(AnchorType oldType, AnchorType newType, XSize size)
{
if (oldType == newType)
return new XVector();
XVector result;
Delta delta = Deltas[(int)oldType, (int)newType];
result = new XVector(size.Width / 2 * delta.X, size.Height / 2 * delta.Y);
return result;
}
struct Delta
{
public Delta(int x, int y)
{
X = x;
Y = y;
}
public readonly int X;
public readonly int Y;
}
static readonly Delta[,] Deltas = new Delta[9, 9]
{
{ new Delta(0, 0), new Delta(1, 0), new Delta(2, 0), new Delta(0, 1), new Delta(1, 1), new Delta(2, 1), new Delta(0, 2), new Delta(1, 2), new Delta(2, 2) },
{ new Delta(-1, 0), new Delta(0, 0), new Delta(1, 0), new Delta(-1, 1), new Delta(0, 1), new Delta(1, 1), new Delta(-1, 2), new Delta(0, 2), new Delta(1, 2) },
{ new Delta(-2, 0), new Delta(-1, 0), new Delta(0, 0), new Delta(-2, 1), new Delta(-1, 1), new Delta(0, 1), new Delta(-2, 2), new Delta(-1, 2), new Delta(0, 2) },
{ new Delta(0, -1), new Delta(1, -1), new Delta(2, -1), new Delta(0, 0), new Delta(1, 0), new Delta(2, 0), new Delta(0, 1), new Delta(1, 1), new Delta(2, 1) },
{ new Delta(-1, -1), new Delta(0, -1), new Delta(1, -1), new Delta(-1, 0), new Delta(0, 0), new Delta(1, 0), new Delta(-1, 1), new Delta(0, 1), new Delta(1, 1) },
{ new Delta(-2, -1), new Delta(-1, -1), new Delta(0, -1), new Delta(-2, 0), new Delta(-1, 0), new Delta(0, 0), new Delta(-2, 1), new Delta(-1, 1), new Delta(0, 1) },
{ new Delta(0, -2), new Delta(1, -2), new Delta(2, -2), new Delta(0, -1), new Delta(1, -1), new Delta(2, -1), new Delta(0, 0), new Delta(1, 0), new Delta(2, 0) },
{ new Delta(-1, -2), new Delta(0, -2), new Delta(1, -2), new Delta(-1, -1), new Delta(0, -1), new Delta(1, -1), new Delta(-1, 0), new Delta(0, 0), new Delta(1, 0) },
{ new Delta(-2, -2), new Delta(-1, -2), new Delta(0, -2), new Delta(-2, -1), new Delta(-1, -1), new Delta(0, -1), new Delta(-2, 0), new Delta(-1, 0), new Delta(0, 0) },
};
}
}

View File

@@ -0,0 +1,217 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// David Stephensen
// 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;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing.BarCodes
{
/// <summary>
/// Defines the DataMatrix 2D barcode. THIS IS AN EMPIRA INTERNAL IMPLEMENTATION. THE CODE IN
/// THE OPEN SOURCE VERSION IS A FAKE.
/// </summary>
public class CodeDataMatrix : MatrixCode
{
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix()
: this("", "", 26, 26, 0, XSize.Empty)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, int length)
: this(code, "", length, length, 0, XSize.Empty)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, int length, XSize size)
: this(code, "", length, length, 0, size)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, DataMatrixEncoding dmEncoding, int length, XSize size)
: this(code, CreateEncoding(dmEncoding, code.Length), length, length, 0, size)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, int rows, int columns)
: this(code, "", rows, columns, 0, XSize.Empty)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, int rows, int columns, XSize size)
: this(code, "", rows, columns, 0, size)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, DataMatrixEncoding dmEncoding, int rows, int columns, XSize size)
: this(code, CreateEncoding(dmEncoding, code.Length), rows, columns, 0, size)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, int rows, int columns, int quietZone)
: this(code, "", rows, columns, quietZone, XSize.Empty)
{}
/// <summary>
/// Initializes a new instance of CodeDataMatrix.
/// </summary>
public CodeDataMatrix(string code, string encoding, int rows, int columns, int quietZone, XSize size)
: base(code, encoding, rows, columns, size)
{
QuietZone = quietZone;
}
/// <summary>
/// Sets the encoding of the DataMatrix.
/// </summary>
public void SetEncoding(DataMatrixEncoding dmEncoding)
{
Encoding = CreateEncoding(dmEncoding, Text.Length);
}
static string CreateEncoding(DataMatrixEncoding dmEncoding, int length)
{
string tempencoding = "";
switch (dmEncoding)
{
case DataMatrixEncoding.Ascii:
tempencoding = new string('a', length);
break;
case DataMatrixEncoding.C40:
tempencoding = new string('c', length);
break;
case DataMatrixEncoding.Text:
tempencoding = new string('t', length);
break;
case DataMatrixEncoding.X12:
tempencoding = new string('x', length);
break;
case DataMatrixEncoding.EDIFACT:
tempencoding = new string('e', length);
break;
case DataMatrixEncoding.Base256:
tempencoding = new string('b', length);
break;
}
return tempencoding;
}
/// <summary>
/// Gets or sets the size of the Matrix' Quiet Zone.
/// </summary>
public int QuietZone
{
get { return _quietZone; }
set { _quietZone = value; }
}
int _quietZone;
/// <summary>
/// Renders the matrix code.
/// </summary>
protected internal override void Render(XGraphics gfx, XBrush brush, XPoint position)
{
XGraphicsState state = gfx.Save();
switch (Direction)
{
case CodeDirection.RightToLeft:
gfx.RotateAtTransform(180, position);
break;
case CodeDirection.TopToBottom:
gfx.RotateAtTransform(90, position);
break;
case CodeDirection.BottomToTop:
gfx.RotateAtTransform(-90, position);
break;
}
XPoint pos = position + CalcDistance(Anchor, AnchorType.TopLeft, Size);
if (MatrixImage == null)
MatrixImage = DataMatrixImage.GenerateMatrixImage(Text, Encoding, Rows, Columns);
if (QuietZone > 0)
{
XSize sizeWithZone = new XSize(Size.Width, Size.Height);
sizeWithZone.Width = sizeWithZone.Width / (Columns + 2 * QuietZone) * Columns;
sizeWithZone.Height = sizeWithZone.Height / (Rows + 2 * QuietZone) * Rows;
XPoint posWithZone = new XPoint(pos.X, pos.Y);
posWithZone.X += Size.Width / (Columns + 2 * QuietZone) * QuietZone;
posWithZone.Y += Size.Height / (Rows + 2 * QuietZone) * QuietZone;
gfx.DrawRectangle(XBrushes.White, pos.X, pos.Y, Size.Width, Size.Height);
gfx.DrawImage(MatrixImage, posWithZone.X, posWithZone.Y, sizeWithZone.Width, sizeWithZone.Height);
}
else
gfx.DrawImage(MatrixImage, pos.X, pos.Y, Size.Width, Size.Height);
gfx.Restore(state);
}
/// <summary>
/// Determines whether the specified string can be used as data in the DataMatrix.
/// </summary>
/// <param name="text">The code to be checked.</param>
protected override void CheckCode(string text)
{
if (text == null)
throw new ArgumentNullException("text");
DataMatrixImage mImage = new DataMatrixImage(Text, Encoding, Rows, Columns);
mImage.Iec16022Ecc200(Columns, Rows, Encoding, Text.Length, Text, 0, 0, 0);
}
}
}

View File

@@ -0,0 +1,247 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Represents an OMR code.
/// </summary>
public class CodeOmr : BarCode
{
/// <summary>
/// initializes a new OmrCode with the given data.
/// </summary>
public CodeOmr(string text, XSize size, CodeDirection direction)
: base(text, size, direction)
{ }
/// <summary>
/// Renders the OMR code.
/// </summary>
protected internal override void Render(XGraphics gfx, XBrush brush, XFont font, XPoint position)
{
XGraphicsState state = gfx.Save();
switch (Direction)
{
case CodeDirection.RightToLeft:
gfx.RotateAtTransform(180, position);
break;
case CodeDirection.TopToBottom:
gfx.RotateAtTransform(90, position);
break;
case CodeDirection.BottomToTop:
gfx.RotateAtTransform(-90, position);
break;
}
//XPoint pt = center - size / 2;
XPoint pt = position - CodeBase.CalcDistance(AnchorType.TopLeft, Anchor, Size);
uint value;
uint.TryParse(Text, out value);
#if true
// HACK: Project Wallenwein: set LK
value |= 1;
_synchronizeCode = true;
#endif
if (_synchronizeCode)
{
XRect rect = new XRect(pt.X, pt.Y, _makerThickness, Size.Height);
gfx.DrawRectangle(brush, rect);
pt.X += 2 * _makerDistance;
}
for (int idx = 0; idx < 32; idx++)
{
if ((value & 1) == 1)
{
XRect rect = new XRect(pt.X + idx * _makerDistance, pt.Y, _makerThickness, Size.Height);
gfx.DrawRectangle(brush, rect);
}
value = value >> 1;
}
gfx.Restore(state);
}
/// <summary>
/// Gets or sets a value indicating whether a synchronize mark is rendered.
/// </summary>
public bool SynchronizeCode
{
get { return _synchronizeCode; }
set { _synchronizeCode = value; }
}
bool _synchronizeCode;
/// <summary>
/// Gets or sets the distance of the markers.
/// </summary>
public double MakerDistance
{
get { return _makerDistance; }
set { _makerDistance = value; }
}
double _makerDistance = 12; // 1/6"
/// <summary>
/// Gets or sets the thickness of the makers.
/// </summary>
public double MakerThickness
{
get { return _makerThickness; }
set { _makerThickness = value; }
}
double _makerThickness = 1;
///// <summary>
///// Renders the mark at the given position.
///// </summary>
///// <param name="position">The mark position to render.</param>
//private void RenderMark(int position)
//{
// double yPos = TopLeft.Y + UpperDistance + position * ToUnit(markDistance).Centimeter;
// //Center mark
// double xPos = TopLeft.X + Width / 2 - this.MarkWidth / 2;
// Gfx.DrawLine(pen, xPos, yPos, xPos + MarkWidth, yPos);
//}
///// <summary>
///// Distance of the marks. Default is 2/6 inch.
///// </summary>
//public MarkDistance MarkDistance
//{
// get { return markDistance; }
// set { markDistance = value; }
//}
//private MarkDistance markDistance = MarkDistance.Inch2_6;
///// <summary>
///// Converts a mark distance to an XUnit object.
///// </summary>
///// <param name="markDistance">The mark distance to convert.</param>
///// <returns>The converted mark distance.</returns>
//public static XUnit ToUnit(MarkDistance markDistance)
//{
// switch (markDistance)
// {
// case MarkDistance.Inch1_6:
// return XUnit.FromInch(1.0 / 6.0);
// case MarkDistance.Inch2_6:
// return XUnit.FromInch(2.0 / 6.0);
// case MarkDistance.Inch2_8:
// return XUnit.FromInch(2.0 / 8.0);
// default:
// throw new ArgumentOutOfRangeException("markDistance");
// }
//}
///// <summary>
///// The upper left point of the reading zone.
///// </summary>
//public XPoint TopLeft
//{
// get
// {
// XPoint topLeft = center;
// topLeft.X -= Width;
// double height = upperDistance + lowerDistance;
// height += (data.Marks.Length - 1) * ToUnit(MarkDistance).Centimeter;
// topLeft.Y -= height / 2;
// return topLeft;
// }
//}
///// <summary>
///// the upper distance from position to the first mark.
///// The default value is 8 / 6 inch.
///// </summary>
//double UpperDistance
//{
// get { return upperDistance; }
// set { upperDistance = value; }
//}
//private double upperDistance = XUnit.FromInch(8.0 / 6.0).Centimeter;
///// <summary>
///// The lower distance from the last possible mark to the end of the reading zone.
///// The default value is
///// </summary>
//double LowerDistance
//{
// get { return lowerDistance; }
// set { lowerDistance = value; }
//}
//private double lowerDistance = XUnit.FromInch(2.0 / 6.0).Centimeter;
///// <summary>
///// Gets or sets the width of the reading zone.
///// Default and minimum is 3/12 inch.
///// </summary>
//public double Width
//{
// get { return width; }
// set { width = value; }
//}
//double width = XUnit.FromInch(3.0 / 12.0).Centimeter;
///// <summary>
///// Gets or sets the mark width. Default is 1/2 * width.
///// </summary>
//public XUnit MarkWidth
//{
// get
// {
// if (markWidth > 0)
// return markWidth;
// else
// return width / 2;
// }
// set { markWidth = value; }
//}
//XUnit markWidth;
///// <summary>
///// Gets or sets the width of the mark line. Default is 1pt.
///// </summary>
//public XUnit MarkLineWidth
//{
// get { return markLineWidth; }
// set { markLineWidth = value; }
//}
//XUnit markLineWidth = 1;
/// <summary>
/// Determines whether the specified string can be used as Text for the OMR code.
/// </summary>
protected override void CheckCode(string text)
{ }
}
}

View File

@@ -0,0 +1,787 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// David Stephensen
//
// 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;
using System.Windows.Media;
#endif
// WPFHACK
#pragma warning disable 162
namespace PdfSharp.Drawing.BarCodes
{
/// <summary>
/// Creates the XImage object for a DataMatrix.
/// </summary>
internal class DataMatrixImage
{
public static XImage GenerateMatrixImage(string text, string encoding, int rows, int columns)
{
DataMatrixImage dataMatrixImage = new DataMatrixImage(text, encoding, rows, columns);
return dataMatrixImage.DrawMatrix();
}
public DataMatrixImage(string text, string encoding, int rows, int columns)
{
_text = text;
_encoding = encoding;
_rows = rows;
_columns = columns;
}
string _encoding;
readonly string _text;
readonly int _rows;
readonly int _columns;
/// <summary>
/// Possible ECC200 Matrices.
/// </summary>
static Ecc200Block[] ecc200Sizes =
{
new Ecc200Block( 10, 10, 10, 10, 3, 3, 5), //
new Ecc200Block( 12, 12, 12, 12, 5, 5, 7), //
new Ecc200Block( 8, 18, 8, 18, 5, 5, 7), //
new Ecc200Block( 14, 14, 14, 14, 8, 8, 10), //
new Ecc200Block( 8, 32, 8, 16, 10, 10, 11), //
new Ecc200Block( 16, 16, 16, 16, 12, 12, 12), //
new Ecc200Block( 12, 26, 12, 26, 16, 16, 14), //
new Ecc200Block( 18, 18, 18, 18, 18, 18, 14), //
new Ecc200Block( 20, 20, 20, 20, 22, 22, 18), //
new Ecc200Block( 12, 36, 12, 18, 22, 22, 18), //
new Ecc200Block( 22, 22, 22, 22, 30, 30, 20), // Post
new Ecc200Block( 16, 36, 16, 18, 32, 32, 24), //
new Ecc200Block( 24, 24, 24, 24, 36, 36, 24), //
new Ecc200Block( 26, 26, 26, 26, 44, 44, 28), // Post
new Ecc200Block( 16, 48, 16, 24, 49, 49, 28), //
new Ecc200Block( 32, 32, 16, 16, 62, 62, 36), //
new Ecc200Block( 36, 36, 18, 18, 86, 86, 42), //
new Ecc200Block( 40, 40, 20, 20, 114, 114, 48), //
new Ecc200Block( 44, 44, 22, 22, 144, 144, 56), //
new Ecc200Block( 48, 48, 24, 24, 174, 174, 68), //
new Ecc200Block( 52, 52, 26, 26, 204, 102, 42), //
new Ecc200Block( 64, 64, 16, 16, 280, 140, 56), //
new Ecc200Block( 72, 72, 18, 18, 368, 92, 36), //
new Ecc200Block( 80, 80, 20, 20, 456, 114, 48), //
new Ecc200Block( 88, 88, 22, 22, 576, 144, 56), //
new Ecc200Block( 96, 96, 24, 24, 696, 174, 68), //
new Ecc200Block(104, 104, 26, 26, 816, 136, 56), //
new Ecc200Block(120, 120, 20, 20, 1050, 175, 68), //
new Ecc200Block(132, 132, 22, 22, 1304, 163, 62), //
new Ecc200Block(144, 144, 24, 24, 1558, 156, 62), // 156*4+155*2
new Ecc200Block( 0, 0, 0, 0, 0, 0, 0) // terminate
};
public XImage DrawMatrix()
{
return CreateImage(DataMatrix(), _rows, _columns);
}
/// <summary>
/// Creates the DataMatrix code.
/// </summary>
internal char[] DataMatrix()
{
int matrixColumns = _columns;
int matrixRows = _rows;
int ecc = 200;
if (String.IsNullOrEmpty(_encoding))
_encoding = new String('a', _text.Length);
int len = 0;
int maxlen = 0;
int ecclen = 0;
char[] grid = null;
if (matrixColumns != 0 && matrixRows != 0 && (matrixColumns & 1) != 0 && (matrixRows & 1) != 0 && ecc == 200)
throw new ArgumentException(BcgSR.DataMatrixNotSupported);
grid = Iec16022Ecc200(matrixColumns, matrixRows, _encoding, _text.Length, _text, len, maxlen, ecclen);
if (grid == null || matrixColumns == 0)
throw new ArgumentException(BcgSR.DataMatrixNull); //DaSt: ever happen?
return grid;
}
/// <summary>
/// Encodes the DataMatrix.
/// </summary>
internal char[] Iec16022Ecc200(int columns, int rows, string encoding, int barcodeLength, string barcode, int len, int max, int ecc)
{
char[] binary = new char[3000]; // encoded raw data and ecc to place in barcode
Ecc200Block matrix = new Ecc200Block(0, 0, 0, 0, 0, 0, 0);
for (int i = 0; i < 3000; i++)
binary[i] = (char)0;
foreach (Ecc200Block eccmatrix in ecc200Sizes)
{
matrix = eccmatrix;
if (matrix.Width == columns && matrix.Height == rows)
break;
}
if (matrix.Width == 0)
throw new ArgumentException(BcgSR.DataMatrixInvalid(columns, rows));
if (!Ecc200Encode(ref binary, matrix.Bytes, barcode, barcodeLength, encoding, ref len))
throw new ArgumentException(BcgSR.DataMatrixTooBig);
// ecc code
Ecc200(binary, matrix.Bytes, matrix.DataBlock, matrix.RSBlock);
// placement
int x;
int y;
int NR;
int[] places;
int NC = columns - 2 * (columns / matrix.CellWidth);
NR = rows - 2 * (rows / matrix.CellHeight);
places = new int[NC * NR];
Ecc200Placement(ref places, NR, NC);
char[] grid = new char[columns * rows];
for (y = 0; y < rows; y += matrix.CellHeight)
{
for (x = 0; x < columns; x++)
grid[y * columns + x] = (char)1;
for (x = 0; x < columns; x += 2)
grid[(y + matrix.CellHeight - 1) * columns + x] = (char)1;
}
for (x = 0; x < columns; x += matrix.CellWidth)
{
for (y = 0; y < rows; y++)
grid[y * columns + x] = (char)1;
for (y = 0; y < rows; y += 2)
grid[y * columns + x + matrix.CellWidth - 1] = (char)1;
}
for (y = 0; y < NR; y++)
{
for (x = 0; x < NC; x++)
{
int v = places[(NR - y - 1) * NC + x];
if (v == 1 || v > 7 && ((binary[(v >> 3) - 1] & (1 << (v & 7))) != 0))
grid[(1 + y + 2 * (y / (matrix.CellHeight - 2))) * columns + 1 + x + 2 * (x / (matrix.CellWidth - 2))] = (char)1;
}
}
return grid;
}
/// <summary>
/// Encodes the barcode with the DataMatrix ECC200 Encoding.
/// </summary>
internal bool Ecc200Encode(ref char[] t, int targetLength, string s, int sourceLength, string encoding, ref int len)
{
char enc = 'a'; // start in ASCII encoding mode
int targetposition = 0;
int sourceposition = 0;
if (encoding.Length < sourceLength)
return false;
// do the encoding
while (sourceposition < sourceLength && targetposition < targetLength)
{
char newenc = enc; // suggest new encoding
if (targetLength - targetposition <= 1 && (enc == 'c' || enc == 't') || targetLength - targetposition <= 2 && enc == 'x')
enc = 'a'; // auto revert to ASCII
#if !SILVERLIGHT
// StL: Who wrote this nonsense?
//newenc = char.Parse(encoding[sourceposition].ToString(CultureInfo.InvariantCulture).ToLower());
newenc = char.ToLower(encoding[sourceposition]);
#else
throw new NotImplementedException("char.Parse");
#endif
switch (newenc)
{ // encode character
case 'c': // C40
case 't': // Text
case 'x': // X12
{
char[] output = new char[6];
char p = (char)0;
string e = null;
string s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]_";
string s3 = null;
if (newenc == 'c')
{
e = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
s3 = "`abcdefghijklmnopqrstuvwxyz{|}~±";
}
if (newenc == 't')
{
e = " 0123456789abcdefghijklmnopqrstuvwxyz";
s3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~±";
}
if (newenc == 'x')
e = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\r*>";
do
{
char c = s[sourceposition++];
char w;
if ((c & 0x80) != 0)
{
if (newenc == 'x')
{
// fprintf (stderr, "Cannot encode char 0x%02X in X12\n", c);
return false;
}
c &= (char)0x7f;
output[p++] = (char)1;
output[p++] = (char)30;
}
w = e.IndexOf(c) == -1 ? (char)0 : e[e.IndexOf(c)];
if (w != (char)0)
output[p++] = (char)((e.IndexOf(w) + 3) % 40);
else
{
if (newenc == 'x')
{
//fprintf (stderr, "Cannot encode char 0x%02X in X12\n", c);
return false;
}
if (c < 32)
{ // shift 1
output[p++] = (char)0;
output[p++] = c;
}
else
{
w = s2.IndexOf(c) == -1 ? (char)0 : (char)s2.IndexOf(c);
if (w != (char)0)
{ // shift 2
output[p++] = (char)1;
output[p++] = w;
}
else
{
w = s3.IndexOf(c) == -1 ? (char)0 : (char)s3.IndexOf(c);
if (w != (char)0)
{
output[p++] = (char)2;
output[p++] = w;
}
else
//fprintf (stderr, "Could not encode 0x%02X, should not happen\n", c);
return false;
}
}
}
if (p == 2 && targetposition + 2 == targetLength && sourceposition == sourceLength)
output[p++] = (char)0; // shift 1 pad at end
while (p >= 3)
{
int v = output[0] * 1600 + output[1] * 40 + output[2] + 1;
if (enc != newenc)
{
if (enc == 'c' || enc == 't' || enc == 'x')
t[targetposition++] = (char)254; // escape C40/text/X12
else if (enc == 'x')
t[targetposition++] = (char)0x7C; // escape EDIFACT
if (newenc == 'c')
t[targetposition++] = (char)230;
if (newenc == 't')
t[targetposition++] = (char)239;
if (newenc == 'x')
t[targetposition++] = (char)238;
enc = newenc;
}
t[targetposition++] = (char)(v >> 8);
t[targetposition++] = (char)(v & 0xFF);
p -= (char)3;
output[0] = output[3];
output[1] = output[4];
output[2] = output[5];
}
}
while (p != (char)0 && sourceposition < sourceLength);
}
break;
case 'e': // EDIFACT
{
char[] output = new char[4];
char p = (char)0;
if (enc != newenc)
{ // can only be from C40/Text/X12
t[targetposition++] = (char)254;
enc = 'a';
}
while (sourceposition < sourceLength && /*encoding[sourceposition].ToString(CultureInfo.InvariantCulture).ToLower() == "e"*/
char.ToLower(encoding[sourceposition]) == 'e' && p < 4)
output[p++] = s[sourceposition++];
if (p < 4)
{
output[p++] = (char)0x1F;
enc = 'a';
} // termination
t[targetposition] = (char)((s[0] & 0x3F) << 2);
t[targetposition++] |= (char)((s[1] & 0x30) >> 4);
t[targetposition] = (char)((s[1] & 0x0F) << 4);
if (p == 2)
targetposition++;
else
{
t[targetposition++] |= (char)((s[2] & 0x3C) >> 2);
t[targetposition] = (char)((s[2] & 0x03) << 6);
t[targetposition++] |= (char)(s[3] & 0x3F);
}
}
break;
case 'a': // ASCII
if (enc != newenc)
{
if (enc == 'c' || enc == 't' || enc == 'x')
t[targetposition++] = (char)254; // escape C40/text/X12
else
t[targetposition++] = (char)0x7C; // escape EDIFACT
}
enc = 'a';
if (sourceLength - sourceposition >= 2 && char.IsDigit(s[sourceposition]) && char.IsDigit(s[sourceposition + 1]))
{
t[targetposition++] = (char)((s[sourceposition] - '0') * 10 + s[sourceposition + 1] - '0' + 130);
sourceposition += 2;
}
else if (s[sourceposition] > 127)
{
t[targetposition++] = (char)235;
t[targetposition++] = (char)(s[sourceposition++] - 127);
}
else
t[targetposition++] = (char)(s[sourceposition++] + 1);
break;
case 'b': // Binary
{
int l = 0; // how much to encode
if (encoding != null)
{
int p;
for (p = sourceposition; p < sourceLength && /*encoding[p].ToString(CultureInfo.InvariantCulture).ToLower() == "b"*/ char.ToLower(encoding[p]) == 'b'; p++)
l++;
}
t[targetposition++] = (char)231; // base256
if (l < 250)
{
t[targetposition] = (char)State255(l, targetposition);
targetposition++;
}
else
{
t[targetposition] = (char)State255(249 + (l / 250), targetposition);
targetposition++;
t[targetposition] = (char)State255(l % 250, targetposition);
targetposition++;
}
while (l-- != 0 && targetposition < targetLength)
{
t[targetposition] = (char)State255(s[sourceposition++], targetposition);
targetposition++;
}
enc = 'a'; // reverse to ASCII at end
}
break;
// default:
// fprintf (stderr, "Unknown encoding %c\n", newenc);
// return 0; // failed
}
}
if (len != 0)
len = targetposition;
if (targetposition < targetLength && enc != 'a')
{
if (enc == 'c' || enc == 'x' || enc == 't')
t[targetposition++] = (char)254; // escape X12/C40/Text
else
t[targetposition++] = (char)0x7C; // escape EDIFACT
}
if (targetposition < targetLength)
t[targetposition++] = (char)129; // pad
while (targetposition < targetLength)
{ // more padding
int v = 129 + (((targetposition + 1) * 149) % 253) + 1; // see Annex H
if (v > 254)
v -= 254;
t[targetposition++] = (char)v;
}
if (targetposition > targetLength || sourceposition < sourceLength)
return false; // did not fit
return true; // OK
}
int State255(int value, int position)
{
return ((value + (((position + 1) * 149) % 255) + 1) % 256);
}
/// <summary>
/// Places the data in the right positions according to Annex M of the ECC200 specification.
/// </summary>
void Ecc200Placement(ref int[] array, int NR, int NC)
{
int r;
int c;
int p;
// invalidate
for (r = 0; r < NR; r++)
for (c = 0; c < NC; c++)
array[r * NC + c] = 0;
// start
p = 1;
r = 4;
c = 0;
do
{
// check corner
if (r == NR && (c == 0))
Ecc200PlacementCornerA(ref array, NR, NC, p++);
if (r == NR - 2 && c == 0 && ((NC % 4) != 0))
Ecc200PlacementCornerB(ref array, NR, NC, p++);
if (r == NR - 2 && c == 0 && ((NC % 8) == 4))
Ecc200PlacementCornerC(ref array, NR, NC, p++);
if (r == NR + 4 && c == 2 && ((NC % 8) == 0))
Ecc200PlacementCornerD(ref array, NR, NC, p++);
// up/right
do
{
if (r < NR && c >= 0 && array[r * NC + c] == 0)
Ecc200PlacementBlock(ref array, NR, NC, r, c, p++);
r -= 2;
c += 2;
}
while (r >= 0 && c < NC);
r++;
c += 3;
// down/left
do
{
if (r >= 0 && c < NC && array[r * NC + c] == 0)
Ecc200PlacementBlock(ref array, NR, NC, r, c, p++);
r += 2;
c -= 2;
}
while (r < NR && c >= 0);
r += 3;
c++;
}
while (r < NR || c < NC);
// unfilled corner
if (array[NR * NC - 1] == 0)
array[NR * NC - 1] = array[NR * NC - NC - 2] = 1;
}
/// <summary>
/// Places the ECC200 bits in the right positions.
/// </summary>
void Ecc200PlacementBit(ref int[] array, int NR, int NC, int r, int c, int p, int b)
{
if (r < 0)
{
r += NR;
c += 4 - ((NR + 4) % 8);
}
if (c < 0)
{
c += NC;
r += 4 - ((NC + 4) % 8);
}
array[r * NC + c] = (p << 3) + b;
}
void Ecc200PlacementBlock(ref int[] array, int NR, int NC, int r, int c, int p)
{
Ecc200PlacementBit(ref array, NR, NC, r - 2, c - 2, p, 7);
Ecc200PlacementBit(ref array, NR, NC, r - 2, c - 1, p, 6);
Ecc200PlacementBit(ref array, NR, NC, r - 1, c - 2, p, 5);
Ecc200PlacementBit(ref array, NR, NC, r - 1, c - 1, p, 4);
Ecc200PlacementBit(ref array, NR, NC, r - 1, c - 0, p, 3);
Ecc200PlacementBit(ref array, NR, NC, r - 0, c - 2, p, 2);
Ecc200PlacementBit(ref array, NR, NC, r - 0, c - 1, p, 1);
Ecc200PlacementBit(ref array, NR, NC, r - 0, c - 0, p, 0);
}
void Ecc200PlacementCornerA(ref int[] array, int NR, int NC, int p)
{
Ecc200PlacementBit(ref array, NR, NC, NR - 1, 0, p, 7);
Ecc200PlacementBit(ref array, NR, NC, NR - 1, 1, p, 6);
Ecc200PlacementBit(ref array, NR, NC, NR - 1, 2, p, 5);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 2, p, 4);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 1, p, 3);
Ecc200PlacementBit(ref array, NR, NC, 1, NC - 1, p, 2);
Ecc200PlacementBit(ref array, NR, NC, 2, NC - 1, p, 1);
Ecc200PlacementBit(ref array, NR, NC, 3, NC - 1, p, 0);
}
void Ecc200PlacementCornerB(ref int[] array, int NR, int NC, int p)
{
Ecc200PlacementBit(ref array, NR, NC, NR - 3, 0, p, 7);
Ecc200PlacementBit(ref array, NR, NC, NR - 2, 0, p, 6);
Ecc200PlacementBit(ref array, NR, NC, NR - 1, 0, p, 5);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 4, p, 4);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 3, p, 3);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 2, p, 2);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 1, p, 1);
Ecc200PlacementBit(ref array, NR, NC, 1, NC - 1, p, 0);
}
void Ecc200PlacementCornerC(ref int[] array, int NR, int NC, int p)
{
Ecc200PlacementBit(ref array, NR, NC, NR - 3, 0, p, 7);
Ecc200PlacementBit(ref array, NR, NC, NR - 2, 0, p, 6);
Ecc200PlacementBit(ref array, NR, NC, NR - 1, 0, p, 5);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 2, p, 4);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 1, p, 3);
Ecc200PlacementBit(ref array, NR, NC, 1, NC - 1, p, 2);
Ecc200PlacementBit(ref array, NR, NC, 2, NC - 1, p, 1);
Ecc200PlacementBit(ref array, NR, NC, 3, NC - 1, p, 0);
}
void Ecc200PlacementCornerD(ref int[] array, int NR, int NC, int p)
{
Ecc200PlacementBit(ref array, NR, NC, NR - 1, 0, p, 7);
Ecc200PlacementBit(ref array, NR, NC, NR - 1, NC - 1, p, 6);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 3, p, 5);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 2, p, 4);
Ecc200PlacementBit(ref array, NR, NC, 0, NC - 1, p, 3);
Ecc200PlacementBit(ref array, NR, NC, 1, NC - 3, p, 2);
Ecc200PlacementBit(ref array, NR, NC, 1, NC - 2, p, 1);
Ecc200PlacementBit(ref array, NR, NC, 1, NC - 1, p, 0);
}
/// <summary>
/// Calculate and append the Reed Solomon Code.
/// </summary>
void Ecc200(char[] binary, int bytes, int datablock, int rsblock)
{
int blocks = (bytes + 2) / datablock;
int b;
InitGalois(0x12d);
InitReedSolomon(rsblock, 1);
for (b = 0; b < blocks; b++)
{
int[] buf = new int[256];
int[] ecc = new int[256];
int n,
p = 0;
for (n = b; n < bytes; n += blocks)
buf[p++] = binary[n];
EncodeReedSolomon(p, buf, ref ecc);
p = rsblock - 1; // comes back reversed
for (n = b; n < rsblock * blocks; n += blocks)
binary[bytes + n] = (char)ecc[p--];
}
}
static int gfpoly;
static int symsize; // in bits
static int logmod; // 2**symsize - 1
static int rlen;
static int[] log = null;
static int[] alog = null;
static int[] rspoly = null;
/// <summary>
/// Initialize the Galois Field.
/// </summary>
/// <param name="poly"></param>
public static void InitGalois(int poly)
{
int m;
int b;
int p;
int v;
// Return storage from previous setup
if (log != null)
{
log = null;
alog = null;
rspoly = null;
}
// Find the top bit, and hence the symbol size
for (b = 1, m = 0; b <= poly; b <<= 1)
m++;
b >>= 1;
m--;
gfpoly = poly;
symsize = m;
// Calculate the log/alog tables
logmod = (1 << m) - 1;
log = new int[logmod + 1];
alog = new int[logmod];
for (p = 1, v = 0; v < logmod; v++)
{
alog[v] = p;
log[p] = v;
p <<= 1;
if ((p & b) != 0) //DaSt: check!
p ^= poly;
}
}
/// <summary>
/// Initializes the Reed-Solomon Encoder.
/// </summary>
public static void InitReedSolomon(int nsym, int index)
{
int i;
int k;
if (rspoly != null)
rspoly = null;
rspoly = new int[nsym + 1];
rlen = nsym;
rspoly[0] = 1;
for (i = 1; i <= nsym; i++)
{
rspoly[i] = 1;
for (k = i - 1; k > 0; k--)
{
if (rspoly[k] != 0) //DaSt: check!
rspoly[k] = alog[(log[rspoly[k]] + index) % logmod];
rspoly[k] ^= rspoly[k - 1];
}
rspoly[0] = alog[(log[rspoly[0]] + index) % logmod];
index++;
}
}
/// <summary>
/// Encodes the Reed-Solomon encoding
/// </summary>
public void EncodeReedSolomon(int length, int[] data, ref int[] result)
{
int i;
int k;
int m;
for (i = 0; i < rlen; i++)
result[i] = 0;
for (i = 0; i < length; i++)
{
m = result[rlen - 1] ^ data[i];
for (k = rlen - 1; k > 0; k--)
{
if ((m != 0) && (rspoly[k] != 0)) //DaSt: check!
result[k] = result[k - 1] ^ alog[(log[m] + log[rspoly[k]]) % logmod];
else
result[k] = result[k - 1];
}
if ((m != 0) && (rspoly[0] != 0)) //DaSt: check!
result[0] = alog[(log[m] + log[rspoly[0]]) % logmod];
else
result[0] = 0;
}
}
/// <summary>
/// Creates a DataMatrix image object.
/// </summary>
/// <param name="code">A hex string like "AB 08 C3...".</param>
/// <param name="size">I.e. 26 for a 26x26 matrix</param>
public XImage CreateImage(char[] code, int size)//(string code, int size)
{
return CreateImage(code, size, size, 10);
}
/// <summary>
/// Creates a DataMatrix image object.
/// </summary>
public XImage CreateImage(char[] code, int rows, int columns)
{
return CreateImage(code, rows, columns, 10);
}
/// <summary>
/// Creates a DataMatrix image object.
/// </summary>
public XImage CreateImage(char[] code, int rows, int columns, int pixelsize)
{
#if GDI
Bitmap bm = new Bitmap(columns * pixelsize, rows * pixelsize);
using (Graphics gfx = Graphics.FromImage(bm))
{
gfx.FillRectangle(System.Drawing.Brushes.White, new Rectangle(0, 0, columns * pixelsize, rows * pixelsize));
for (int i = rows - 1; i >= 0; i--)
{
for (int j = 0; j < columns; j++)
{
if (code[((rows - 1) - i) * columns + j] == (char)1)
gfx.FillRectangle(System.Drawing.Brushes.Black, j * pixelsize, i * pixelsize, pixelsize, pixelsize);
}
}
}
XImage image = XImage.FromGdiPlusImage(bm);
image.Interpolate = false;
return image;
#endif
#if WPF
// WPFHACK
return null;
#endif
#if CORE || NETFX_CORE || UWP
return null;
#endif
}
struct Ecc200Block
{
public readonly int Height;
public readonly int Width;
public readonly int CellHeight;
public readonly int CellWidth;
public readonly int Bytes;
public readonly int DataBlock;
public readonly int RSBlock;
public Ecc200Block(int h, int w, int ch, int cw, int bytes, int dataBlock, int rsBlock)
{
Height = h;
Width = w;
CellHeight = ch;
CellWidth = cw;
Bytes = bytes;
DataBlock = dataBlock;
RSBlock = rsBlock;
}
}
}
}

View File

@@ -0,0 +1,239 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// David Stephensen
//
// 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
using System;
#if GDI
using System.Drawing;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
#endif
// ========================================================================================
// ========================================================================================
// ===== THIS CLASS IS A FAKE. THE OPEN SOURCE VERSION OF PDFSHARP DOES NOT IMPLEMENT =====
// ===== A DATAMATRIX CODE. THIS IS BECAUSE OF THE ISO COPYRIGHT. =====
// ========================================================================================
// ========================================================================================
// Even if it looks like a datamatrix code it is just random
namespace PdfSharp.Drawing.BarCodes
{
/// <summary>
/// Creates the XImage object for a DataMatrix.
/// Important note for OpenSource version of PDFsharp:
/// The generated image object only contains random data.
/// If you need the correct implementation as defined in the ISO/IEC 16022:2000 specification,
/// please contact empira Software GmbH via www.pdfsharp.com.
/// </summary>
internal class DataMatrixImage
{
public static XImage GenerateMatrixImage(string text, string encoding, int rows, int columns)
{
DataMatrixImage dataMatrixImage = new DataMatrixImage(text, encoding, rows, columns);
return dataMatrixImage.DrawMatrix();
}
public DataMatrixImage(string text, string encoding, int rows, int columns)
{
this.text = text;
this.encoding = encoding;
this.rows = rows;
this.columns = columns;
}
string text;
string encoding;
int rows;
int columns;
/// <summary>
/// Possible ECC200 Matrixes
/// </summary>
static Ecc200Block[] ecc200Sizes =
{
new Ecc200Block( 10, 10, 10, 10, 3, 3, 5), //
new Ecc200Block( 12, 12, 12, 12, 5, 5, 7), //
new Ecc200Block( 8, 18, 8, 18, 5, 5, 7), //
new Ecc200Block( 14, 14, 14, 14, 8, 8, 10), //
new Ecc200Block( 8, 32, 8, 16, 10, 10, 11), //
new Ecc200Block( 16, 16, 16, 16, 12, 12, 12), //
new Ecc200Block( 12, 26, 12, 26, 16, 16, 14), //
new Ecc200Block( 18, 18, 18, 18, 18, 18, 14), //
new Ecc200Block( 20, 20, 20, 20, 22, 22, 18), //
new Ecc200Block( 12, 36, 12, 18, 22, 22, 18), //
new Ecc200Block( 22, 22, 22, 22, 30, 30, 20), //
new Ecc200Block( 16, 36, 16, 18, 32, 32, 24), //
new Ecc200Block( 24, 24, 24, 24, 36, 36, 24), //
new Ecc200Block( 26, 26, 26, 26, 44, 44, 28), //
new Ecc200Block( 16, 48, 16, 24, 49, 49, 28), //
new Ecc200Block( 32, 32, 16, 16, 62, 62, 36), //
new Ecc200Block( 36, 36, 18, 18, 86, 86, 42), //
new Ecc200Block( 40, 40, 20, 20, 114, 114, 48), //
new Ecc200Block( 44, 44, 22, 22, 144, 144, 56), //
new Ecc200Block( 48, 48, 24, 24, 174, 174, 68), //
new Ecc200Block( 52, 52, 26, 26, 204, 102, 42), //
new Ecc200Block( 64, 64, 16, 16, 280, 140, 56), //
new Ecc200Block( 72, 72, 18, 18, 368, 92, 36), //
new Ecc200Block( 80, 80, 20, 20, 456, 114, 48), //
new Ecc200Block( 88, 88, 22, 22, 576, 144, 56), //
new Ecc200Block( 96, 96, 24, 24, 696, 174, 68), //
new Ecc200Block(104, 104, 26, 26, 816, 136, 56), //
new Ecc200Block(120, 120, 20, 20, 1050, 175, 68), //
new Ecc200Block(132, 132, 22, 22, 1304, 163, 62), //
new Ecc200Block(144, 144, 24, 24, 1558, 156, 62), // 156*4+155*2
new Ecc200Block( 0, 0, 0, 0, 0, 0, 0) // terminate
};
public XImage DrawMatrix()
{
return CreateImage(DataMatrix(), this.rows, this.columns);
}
/// <summary>
/// Creates the DataMatrix code.
/// </summary>
internal char[] DataMatrix()
{
int matrixColumns = this.columns;
int matrixRows = this.rows;
Ecc200Block matrix = new Ecc200Block(0, 0, 0, 0, 0, 0, 0);
foreach (Ecc200Block eccmatrix in ecc200Sizes)
{
matrix = eccmatrix;
if (matrix.Width != columns || matrix.Height != rows)
continue;
else
break;
}
char[] grid = new char[matrixColumns * matrixRows];
Random rand = new Random();
for (int ccol = 0; ccol < matrixColumns; ccol++)
grid[ccol] = (char)1;
for (int rrows = 1; rrows < matrixRows; rrows++)
{
grid[rrows * matrixRows] = (char)1;
for (int ccol = 1; ccol < matrixColumns; ccol++)
grid[rrows * matrixRows + ccol] = (char)rand.Next(2);
}
if (grid == null || matrixColumns == 0)
return null; //No barcode produced;
return grid;
}
/// <summary>
/// Encodes the DataMatrix.
/// </summary>
internal char[] Iec16022Ecc200(int columns, int rows, string encoding, int barcodelen, string barcode, int len, int max, int ecc)
{
return null;
}
/// <summary>
/// Creates a DataMatrix image object.
/// </summary>
/// <param name="code">A hex string like "AB 08 C3...".</param>
/// <param name="size">I.e. 26 for a 26x26 matrix</param>
public XImage CreateImage(char[] code, int size)//(string code, int size)
{
return CreateImage(code, size, size, 10);
}
/// <summary>
/// Creates a DataMatrix image object.
/// </summary>
public XImage CreateImage(char[] code, int rows, int columns)
{
return CreateImage(code, rows, columns, 10);
}
/// <summary>
/// Creates a DataMatrix image object.
/// </summary>
public XImage CreateImage(char[] code, int rows, int columns, int pixelsize)
{
#if GDI
Bitmap bm = new Bitmap(columns * pixelsize, rows * pixelsize);
using (Graphics gfx = Graphics.FromImage(bm))
{
gfx.FillRectangle(System.Drawing.Brushes.White, new Rectangle(0, 0, columns * pixelsize, rows * pixelsize));
for (int i = rows - 1; i >= 0; i--)
{
for (int j = 0; j < columns; j++)
{
if (code[((rows - 1) - i) * columns + j] == (char)1)
gfx.FillRectangle(System.Drawing.Brushes.Black, j * pixelsize, i * pixelsize, pixelsize, pixelsize);
}
}
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Firebrick, pixelsize);
gfx.DrawLine(pen, 0, 0, rows * pixelsize, columns * pixelsize);
gfx.DrawLine(pen, columns * pixelsize, 0, 0, rows * pixelsize);
}
XImage image = XImage.FromGdiPlusImage(bm);
image.Interpolate = false;
return image;
#elif WPF
return null;
#endif
}
}
struct Ecc200Block
{
public int Height;
public int Width;
public int CellHeight;
public int CellWidth;
public int Bytes;
public int DataBlock;
public int RSBlock;
public Ecc200Block(int h, int w, int ch, int cw, int bytes, int datablock, int rsblock)
{
Height = h;
Width = w;
CellHeight = ch;
CellWidth = cw;
Bytes = bytes;
DataBlock = datablock;
RSBlock = rsblock;
}
}
}

View File

@@ -0,0 +1,137 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// David Stephensen
// 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.Drawing.BarCodes
{
/// <summary>
/// Represents the base class of all 2D codes.
/// </summary>
public abstract class MatrixCode : CodeBase
{
/// <summary>
/// Initializes a new instance of the <see cref="MatrixCode"/> class.
/// </summary>
public MatrixCode(string text, string encoding, int rows, int columns, XSize size)
: base(text, size, CodeDirection.LeftToRight)
{
_encoding = encoding;
if (String.IsNullOrEmpty(_encoding))
_encoding = new String('a', Text.Length);
if (columns < rows)
{
_rows = columns;
_columns = rows;
}
else
{
_columns = columns;
_rows = rows;
}
Text = text;
}
/// <summary>
/// Gets or sets the encoding. docDaSt
/// </summary>
public string Encoding
{
get { return _encoding; }
set
{
_encoding = value;
_matrixImage = null;
}
}
string _encoding;
/// <summary>
/// docDaSt
/// </summary>
public int Columns
{
get { return _columns; }
set
{
_columns = value;
_matrixImage = null;
}
}
int _columns;
/// <summary>
/// docDaSt
/// </summary>
public int Rows
{
get { return _rows; }
set
{
_rows = value;
_matrixImage = null;
}
}
int _rows;
/// <summary>
/// docDaSt
/// </summary>
public new string Text
{
get { return base.Text; }
set
{
base.Text = value;
_matrixImage = null;
}
}
internal XImage MatrixImage
{
get { return _matrixImage; }
set { _matrixImage = value; }
}
XImage _matrixImage;
/// <summary>
/// When implemented in a derived class renders the 2D code.
/// </summary>
protected internal abstract void Render(XGraphics gfx, XBrush brush, XPoint center);
/// <summary>
/// Determines whether the specified string can be used as Text for this matrix code type.
/// </summary>
protected override void CheckCode(string text)
{ }
}
}

View File

@@ -0,0 +1,130 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
#if true_
/// <summary>
/// Represents the data coded within the OMR code.
/// </summary>
class OmrData
{
private OmrData()
{
}
public static OmrData ForTesting
{
get
{
OmrData data = new OmrData();
data.AddMarkDescription("LK");
data.AddMarkDescription("DGR");
data.AddMarkDescription("GM1");
data.AddMarkDescription("GM2");
data.AddMarkDescription("GM4");
data.AddMarkDescription("GM8");
data.AddMarkDescription("GM16");
data.AddMarkDescription("GM32");
data.AddMarkDescription("ZS1");
data.AddMarkDescription("ZS2");
data.AddMarkDescription("ZS3");
data.AddMarkDescription("ZS4");
data.AddMarkDescription("ZS5");
data.InitMarks();
return data;
}
}
///// <summary>
///// NYI: Get OMR description read from text file.
///// </summary>
///// <returns>An OmrData object.</returns>
//public static OmrData FromDescriptionFile(string filename)
//{
// throw new NotImplementedException();
//}
/// <summary>
/// Adds a mark description by name.
/// </summary>
/// <param name="name">The name to for setting or unsetting the mark.</param>
private void AddMarkDescription(string name)
{
if (_marksInitialized)
throw new InvalidOperationException(BcgSR.OmrAlreadyInitialized);
_nameToIndex[name] = AddedDescriptions;
++AddedDescriptions;
}
private void InitMarks()
{
if (AddedDescriptions == 0)
throw new InvalidOperationException();
_marks = new bool[AddedDescriptions];
_marks.Initialize();
_marksInitialized = true;
}
private int FindIndex(string name)
{
if (!_marksInitialized)
InitMarks();
if (!_nameToIndex.Contains(name))
throw new ArgumentException(BcgSR.InvalidMarkName(name));
return (int)_nameToIndex[name];
}
public void SetMark(string name)
{
int idx = FindIndex(name);
_marks[idx] = true;
}
public void UnsetMark(string name)
{
int idx = FindIndex(name);
_marks[idx] = false;
}
public bool[] Marks
{
get { return _marks; }
}
System.Collections.Hash_table nameToIndex = new Hash_table();
bool[] marks;
int addedDescriptions = 0;
bool marksInitialized = false;
}
#endif
}

View File

@@ -0,0 +1,186 @@
//
// PDFsharp - A library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
//
// 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.
using System;
namespace PdfSharp.Drawing.BarCodes
{
/// <summary>
/// Internal base class for several bar code types.
/// </summary>
public abstract class ThickThinBarCode : BarCode // TODO: The name is not optimal
{
/// <summary>
/// Initializes a new instance of the <see cref="ThickThinBarCode"/> class.
/// </summary>
public ThickThinBarCode(string code, XSize size, CodeDirection direction)
: base(code, size, direction)
{ }
internal override void InitRendering(BarCodeRenderInfo info)
{
base.InitRendering(info);
CalcThinBarWidth(info);
info.BarHeight = Size.Height;
// HACK in ThickThinBarCode
if (TextLocation != TextLocation.None)
info.BarHeight *= 4.0 / 5;
#if DEBUG_
XColor back = XColors.LightSalmon;
back.A = 0.3;
XSolidBrush brush = new XSolidBrush(back);
info.Gfx.DrawRectangle(brush, new XRect(info.Center - size / 2, size));
#endif
switch (Direction)
{
case CodeDirection.RightToLeft:
info.Gfx.RotateAtTransform(180, info.Position);
break;
case CodeDirection.TopToBottom:
info.Gfx.RotateAtTransform(90, info.Position);
break;
case CodeDirection.BottomToTop:
info.Gfx.RotateAtTransform(-90, info.Position);
break;
}
}
/// <summary>
/// Gets or sets the ration between thick an thin lines. Must be between 2 and 3.
/// Optimal and also default value is 2.6.
/// </summary>
public override double WideNarrowRatio
{
get { return _wideNarrowRatio; }
set
{
if (value > 3 || value < 2)
throw new ArgumentOutOfRangeException("value", BcgSR.Invalid2of5Relation);
_wideNarrowRatio = value;
}
}
double _wideNarrowRatio = 2.6;
/// <summary>
/// Renders a thick or thin line for the bar code.
/// </summary>
/// <param name="info"></param>
/// <param name="isThick">Determines whether a thick or a thin line is about to be rendered.</param>
internal void RenderBar(BarCodeRenderInfo info, bool isThick)
{
double barWidth = GetBarWidth(info, isThick);
double height = Size.Height;
double xPos = info.CurrPos.X;
double yPos = info.CurrPos.Y;
switch (TextLocation)
{
case TextLocation.AboveEmbedded:
height -= info.Gfx.MeasureString(Text, info.Font).Height;
yPos += info.Gfx.MeasureString(Text, info.Font).Height;
break;
case TextLocation.BelowEmbedded:
height -= info.Gfx.MeasureString(Text, info.Font).Height;
break;
}
XRect rect = new XRect(xPos, yPos, barWidth, height);
info.Gfx.DrawRectangle(info.Brush, rect);
info.CurrPos.X += barWidth;
}
/// <summary>
/// Renders a thick or thin gap for the bar code.
/// </summary>
/// <param name="info"></param>
/// <param name="isThick">Determines whether a thick or a thin gap is about to be rendered.</param>
internal void RenderGap(BarCodeRenderInfo info, bool isThick)
{
info.CurrPos.X += GetBarWidth(info, isThick);
}
/// <summary>
/// Renders a thick bar before or behind the code.
/// </summary>
internal void RenderTurboBit(BarCodeRenderInfo info, bool startBit)
{
if (startBit)
info.CurrPos.X -= 0.5 + GetBarWidth(info, true);
else
info.CurrPos.X += 0.5; //GetBarWidth(info, true);
RenderBar(info, true);
if (startBit)
info.CurrPos.X += 0.5; //GetBarWidth(info, true);
}
internal void RenderText(BarCodeRenderInfo info)
{
if (info.Font == null)
info.Font = new XFont("Courier New", Size.Height / 6);
XPoint center = info.Position + CalcDistance(Anchor, AnchorType.TopLeft, Size);
switch (TextLocation)
{
case TextLocation.Above:
center = new XPoint(center.X, center.Y - info.Gfx.MeasureString(Text, info.Font).Height);
info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.TopCenter);
break;
case TextLocation.AboveEmbedded:
info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.TopCenter);
break;
case TextLocation.Below:
center = new XPoint(center.X, info.Gfx.MeasureString(Text, info.Font).Height + center.Y);
info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.BottomCenter);
break;
case TextLocation.BelowEmbedded:
info.Gfx.DrawString(Text, info.Font, info.Brush, new XRect(center, Size), XStringFormats.BottomCenter);
break;
}
}
/// <summary>
/// Gets the width of a thick or a thin line (or gap). CalcLineWidth must have been called before.
/// </summary>
/// <param name="info"></param>
/// <param name="isThick">Determines whether a thick line's with shall be returned.</param>
internal double GetBarWidth(BarCodeRenderInfo info, bool isThick)
{
if (isThick)
return info.ThinBarWidth * _wideNarrowRatio;
return info.ThinBarWidth;
}
internal abstract void CalcThinBarWidth(BarCodeRenderInfo info);
}
}

View File

@@ -0,0 +1,82 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Specifies whether and how the text is displayed at the code area.
/// </summary>
public enum AnchorType
{
/// <summary>
/// The anchor is located top left.
/// </summary>
TopLeft,
/// <summary>
/// The anchor is located top center.
/// </summary>
TopCenter,
/// <summary>
/// The anchor is located top right.
/// </summary>
TopRight,
/// <summary>
/// The anchor is located middle left.
/// </summary>
MiddleLeft,
/// <summary>
/// The anchor is located middle center.
/// </summary>
MiddleCenter,
/// <summary>
/// The anchor is located middle right.
/// </summary>
MiddleRight,
/// <summary>
/// The anchor is located bottom left.
/// </summary>
BottomLeft,
/// <summary>
/// The anchor is located bottom center.
/// </summary>
BottomCenter,
/// <summary>
/// The anchor is located bottom right.
/// </summary>
BottomRight,
}
}

View File

@@ -0,0 +1,57 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Specifies the drawing direction of the code.
/// </summary>
public enum CodeDirection
{
/// <summary>
/// Does not rotate the code.
/// </summary>
LeftToRight,
/// <summary>
/// Rotates the code 180<38> at the anchor position.
/// </summary>
BottomToTop,
/// <summary>
/// Rotates the code 180<38> at the anchor position.
/// </summary>
RightToLeft,
/// <summary>
/// Rotates the code 180<38> at the anchor position.
/// </summary>
TopToBottom,
}
}

View File

@@ -0,0 +1,59 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Specifies the type of the bar code.
/// </summary>
public enum CodeType
{
/// <summary>
/// The standard 2 of 5 interleaved bar code.
/// </summary>
// ReSharper disable once InconsistentNaming
Code2of5Interleaved,
/// <summary>
/// The standard 3 of 9 bar code.
/// </summary>
// ReSharper disable once InconsistentNaming
Code3of9Standard,
/// <summary>
/// The OMR code.
/// </summary>
Omr,
/// <summary>
/// The data matrix code.
/// </summary>
DataMatrix,
}
}

View File

@@ -0,0 +1,68 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// docDaSt
/// </summary>
public enum DataMatrixEncoding
{
/// <summary>
/// docDaSt
/// </summary>
Ascii,
/// <summary>
/// docDaSt
/// </summary>
C40,
/// <summary>
/// docDaSt
/// </summary>
Text,
/// <summary>
/// docDaSt
/// </summary>
X12,
/// <summary>
/// docDaSt
/// </summary>
// ReSharper disable once InconsistentNaming
EDIFACT,
/// <summary>
/// docDaSt
/// </summary>
Base256
}
}

View File

@@ -0,0 +1,50 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
///// <summary>
///// Valid mark distances for OMR Codes.
///// </summary>
//public enum MarkDistance
//{
// /// <summary>
// /// 2/6 inch, valid for printing with 6 lpi. (line height = 12 pt).
// /// </summary>
// Inch1_6,
// /// <summary>
// /// 2/6 inch, valid for printing with 6 lpi (line height = 12 pt).
// /// </summary>
// Inch2_6,
// /// <summary>
// /// 2/8 inch, valid for printing with 8 lpi (line height = 9 pt).
// /// </summary>
// Inch2_8
//}
}

View File

@@ -0,0 +1,64 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Klaus Potzesny
//
// 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.Drawing.BarCodes
{
/// <summary>
/// Specifies whether and how the text is displayed at the code.
/// </summary>
public enum TextLocation
{
/// <summary>
/// No text is drawn.
/// </summary>
None,
/// <summary>
/// The text is located above the code.
/// </summary>
Above,
/// <summary>
/// The text is located below the code.
/// </summary>
Below,
/// <summary>
/// The text is located above within the code.
/// </summary>
AboveEmbedded,
/// <summary>
/// The text is located below within the code.
/// </summary>
BelowEmbedded,
}
}

View File

@@ -0,0 +1,328 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// 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.
#endregion
using System;
using System.Diagnostics;
using System.IO;
using PdfSharp.Pdf;
namespace PdfSharp.Drawing
{
/// <summary>
/// This interface will be implemented by specialized classes, one for JPEG, one for BMP, one for PNG, one for GIF. Maybe more.
/// </summary>
internal interface IImageImporter
{
/// <summary>
/// Imports the image. Returns null if the image importer does not support the format.
/// </summary>
ImportedImage ImportImage(StreamReaderHelper stream, PdfDocument document);
/// <summary>
/// Prepares the image data needed for the PDF file.
/// </summary>
ImageData PrepareImage(ImagePrivateData data);
}
// $THHO Add IDispose?.
/// <summary>
/// Helper for dealing with Stream data.
/// </summary>
internal class StreamReaderHelper
{
internal StreamReaderHelper(Stream stream)
{
#if GDI || WPF
_stream = stream;
MemoryStream ms = stream as MemoryStream;
if (ms == null)
{
// THHO4STLA byte[] or MemoryStream?
_ownedMemoryStream = ms = new MemoryStream();
CopyStream(stream, ms);
// For .NET 4: stream.CopyTo(ms);
}
_data = ms.GetBuffer();
_length = (int)ms.Length;
#else
// For WinRT there is no GetBuffer() => alternative implementation for WinRT.
// TODO: Are there advantages of GetBuffer()? It should reduce LOH fragmentation.
_stream = stream;
_stream.Position = 0;
if (_stream.Length > int.MaxValue)
throw new ArgumentException("Stream is too large.", "stream");
_length = (int)_stream.Length;
_data = new byte[_length];
_stream.Read(_data, 0, _length);
#endif
}
internal byte GetByte(int offset)
{
if (_currentOffset + offset >= _length)
{
Debug.Assert(false);
return 0;
}
return _data[_currentOffset + offset];
}
internal ushort GetWord(int offset, bool bigEndian)
{
return (ushort)(bigEndian ?
GetByte(offset) * 256 + GetByte(offset + 1) :
GetByte(offset) + GetByte(offset + 1) * 256);
}
internal uint GetDWord(int offset, bool bigEndian)
{
return (uint)(bigEndian ?
GetWord(offset, true) * 65536 + GetWord(offset + 2, true) :
GetWord(offset, false) + GetWord(offset + 2, false) * 65536);
}
private static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[65536];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
/// <summary>
/// Resets this instance.
/// </summary>
public void Reset()
{
_currentOffset = 0;
}
/// <summary>
/// Gets the original stream.
/// </summary>
public Stream OriginalStream
{
get { return _stream; }
}
private readonly Stream _stream;
internal int CurrentOffset
{
get { return _currentOffset; }
set { _currentOffset = value; }
}
private int _currentOffset;
/// <summary>
/// Gets the data as byte[].
/// </summary>
public byte[] Data
{
get { return _data; }
}
private readonly byte[] _data;
/// <summary>
/// Gets the length of Data.
/// </summary>
public int Length
{
get { return _length; }
}
private readonly int _length;
#if GDI || WPF
/// <summary>
/// Gets the owned memory stream. Can be null if no MemoryStream was created.
/// </summary>
public MemoryStream OwnedMemoryStream
{
get { return _ownedMemoryStream; }
}
private readonly MemoryStream _ownedMemoryStream;
#endif
}
/// <summary>
/// The imported image.
/// </summary>
internal abstract class ImportedImage
{
/// <summary>
/// Initializes a new instance of the <see cref="ImportedImage"/> class.
/// </summary>
protected ImportedImage(IImageImporter importer, ImagePrivateData data, PdfDocument document)
{
Data = data;
_document = document;
data.Image = this;
_importer = importer;
}
/// <summary>
/// Gets information about the image.
/// </summary>
public ImageInformation Information
{
get { return _information; }
private set { _information = value; }
}
private ImageInformation _information = new ImageInformation();
/// <summary>
/// Gets a value indicating whether image data for the PDF file was already prepared.
/// </summary>
public bool HasImageData
{
get { return _imageData != null; }
}
/// <summary>
/// Gets the image data needed for the PDF file.
/// </summary>
public ImageData ImageData
{
get { if(!HasImageData) _imageData = PrepareImageData(); return _imageData; }
private set { _imageData = value; }
}
private ImageData _imageData;
internal virtual ImageData PrepareImageData()
{
throw new NotImplementedException();
}
private IImageImporter _importer;
internal ImagePrivateData Data;
internal readonly PdfDocument _document;
}
/// <summary>
/// Public information about the image, filled immediately.
/// Note: The stream will be read and decoded on the first call to PrepareImageData().
/// ImageInformation can be filled for corrupted images that will throw an expection on PrepareImageData().
/// </summary>
internal class ImageInformation
{
internal enum ImageFormats
{
/// <summary>
/// Standard JPEG format (RGB).
/// </summary>
JPEG,
/// <summary>
/// Grayscale JPEG format.
/// </summary>
JPEGGRAY,
/// <summary>
/// JPEG file with inverted CMYK, thus RGBW.
/// </summary>
JPEGRGBW,
/// <summary>
/// JPEG file with CMYK.
/// </summary>
JPEGCMYK,
Palette1,
Palette4,
Palette8,
RGB24,
ARGB32
}
internal ImageFormats ImageFormat;
internal uint Width;
internal uint Height;
/// <summary>
/// The horizontal DPI (dots per inch). Can be 0 if not supported by the image format.
/// Note: JFIF (JPEG) files may contain either DPI or DPM or just the aspect ratio. Windows BMP files will contain DPM. Other formats may support any combination, including none at all.
/// </summary>
internal decimal HorizontalDPI;
/// <summary>
/// The vertical DPI (dots per inch). Can be 0 if not supported by the image format.
/// </summary>
internal decimal VerticalDPI;
/// <summary>
/// The horizontal DPM (dots per meter). Can be 0 if not supported by the image format.
/// </summary>
internal decimal HorizontalDPM;
/// <summary>
/// The vertical DPM (dots per meter). Can be 0 if not supported by the image format.
/// </summary>
internal decimal VerticalDPM;
/// <summary>
/// The horizontal component of the aspect ratio. Can be 0 if not supported by the image format.
/// Note: Aspect ratio will be set if either DPI or DPM was set, but may also be available in the absence of both DPI and DPM.
/// </summary>
internal decimal HorizontalAspectRatio;
/// <summary>
/// The vertical component of the aspect ratio. Can be 0 if not supported by the image format.
/// </summary>
internal decimal VerticalAspectRatio;
/// <summary>
/// The colors used. Only valid for images with palettes, will be 0 otherwise.
/// </summary>
internal uint ColorsUsed;
}
/// <summary>
/// Contains internal data. This includes a reference to the Stream if data for PDF was not yet prepared.
/// </summary>
internal abstract class ImagePrivateData
{
internal ImagePrivateData()
{
}
/// <summary>
/// Gets the image.
/// </summary>
public ImportedImage Image
{
get { return _image; }
internal set { _image = value; }
}
private ImportedImage _image;
}
/// <summary>
/// Contains data needed for PDF. Will be prepared when needed.
/// </summary>
internal abstract class ImageData
{
}
}

View File

@@ -0,0 +1,92 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// 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.
#endregion
using System.Collections.Generic;
using System.IO;
using PdfSharp.Pdf;
namespace PdfSharp.Drawing.Internal
{
/// <summary>
/// The class that imports images of various formats.
/// </summary>
internal class ImageImporter
{
// TODO Make a singleton!
/// <summary>
/// Gets the image importer.
/// </summary>
public static ImageImporter GetImageImporter()
{
return new ImageImporter();
}
private ImageImporter()
{
_importers.Add(new ImageImporterJpeg());
_importers.Add(new ImageImporterBmp());
// TODO: Special importer for PDF? Or dealt with at a higher level?
}
/// <summary>
/// Imports the image.
/// </summary>
public ImportedImage ImportImage(Stream stream, PdfDocument document)
{
StreamReaderHelper helper = new StreamReaderHelper(stream);
// Try all registered importers to see if any of them can handle the image.
foreach (IImageImporter importer in _importers)
{
helper.Reset();
ImportedImage image = importer.ImportImage(helper, document);
if (image != null)
return image;
}
return null;
}
#if GDI || WPF || CORE
/// <summary>
/// Imports the image.
/// </summary>
public ImportedImage ImportImage(string filename, PdfDocument document)
{
ImportedImage ii;
using (Stream fs = File.OpenRead(filename))
{
ii = ImportImage(fs, document);
}
return ii;
}
#endif
private readonly List<IImageImporter> _importers = new List<IImageImporter>();
}
}

View File

@@ -0,0 +1,681 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// 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.
#endregion
using System;
using PdfSharp.Pdf;
using PdfSharp.Pdf.Advanced;
namespace PdfSharp.Drawing.Internal
{
// $THHO THHO4THHO add support for PdfDocument.Options.
internal class ImageImporterBmp : ImageImporterRoot, IImageImporter
{
public ImportedImage ImportImage(StreamReaderHelper stream, PdfDocument document)
{
try
{
stream.CurrentOffset = 0;
int offsetImageData;
if (TestBitmapFileHeader(stream, out offsetImageData))
{
// Magic: TestBitmapFileHeader updates stream.CurrentOffset on success.
ImagePrivateDataBitmap ipd = new ImagePrivateDataBitmap(stream.Data, stream.Length);
ImportedImage ii = new ImportedImageBitmap(this, ipd, document);
if (TestBitmapInfoHeader(stream, ii, offsetImageData))
{
//stream.CurrentOffset = offsetImageData;
return ii;
}
}
}
// ReSharper disable once EmptyGeneralCatchClause
catch (Exception)
{
}
return null;
}
private bool TestBitmapFileHeader(StreamReaderHelper stream, out int offset)
{
offset = 0;
// File must start with "BM".
if (stream.GetWord(0, true) == 0x424d)
{
int filesize = (int)stream.GetDWord(2, false);
// Integrity check: filesize set in BM header should match size of the stream.
// We test "<" instead of "!=" to allow extra bytes at the end of the stream.
if (filesize < stream.Length)
return false;
offset = (int)stream.GetDWord(10, false);
stream.CurrentOffset += 14;
return true;
}
return false;
}
private bool TestBitmapInfoHeader(StreamReaderHelper stream, ImportedImage ii, int offset)
{
int size = (int)stream.GetDWord(0, false);
if (size == 40 || size == 108 || size == 124) // sizeof BITMAPINFOHEADER == 40, sizeof BITMAPV4HEADER == 108, sizeof BITMAPV5HEADER == 124
{
uint width = stream.GetDWord(4, false);
int height = (int)stream.GetDWord(8, false);
int planes = stream.GetWord(12, false);
int bitcount = stream.GetWord(14, false);
int compression = (int)stream.GetDWord(16, false);
int sizeImage = (int)stream.GetDWord(20, false);
int xPelsPerMeter = (int)stream.GetDWord(24, false);
int yPelsPerMeter = (int)stream.GetDWord(28, false);
uint colorsUsed = stream.GetDWord(32, false);
uint colorsImportant = stream.GetDWord(36, false);
// TODO Integrity and plausibility checks.
if (sizeImage != 0 && sizeImage + offset > stream.Length)
return false;
ImagePrivateDataBitmap privateData = (ImagePrivateDataBitmap)ii.Data;
// Return true only for supported formats.
if (compression == 0 || compression == 3) // BI_RGB == 0, BI_BITFIELDS == 3
{
((ImagePrivateDataBitmap)ii.Data).Offset = offset;
((ImagePrivateDataBitmap)ii.Data).ColorPaletteOffset = stream.CurrentOffset + size;
ii.Information.Width = width;
ii.Information.Height = (uint)Math.Abs(height);
ii.Information.HorizontalDPM = xPelsPerMeter;
ii.Information.VerticalDPM = yPelsPerMeter;
privateData.FlippedImage = height < 0;
if (planes == 1 && bitcount == 24)
{
// RGB24
ii.Information.ImageFormat = ImageInformation.ImageFormats.RGB24;
// TODO: Verify Mask if size >= 108 && compression == 3.
return true;
}
if (planes == 1 && bitcount == 32)
{
// ARGB32
//ii.Information.ImageFormat = ImageInformation.ImageFormats.ARGB32;
ii.Information.ImageFormat = compression == 0 ?
ImageInformation.ImageFormats.RGB24 :
ImageInformation.ImageFormats.ARGB32;
// TODO: tell RGB from ARGB. Idea: assume RGB if alpha is always 0.
// TODO: Verify Mask if size >= 108 && compression == 3.
return true;
}
if (planes == 1 && bitcount == 8)
{
// Palette8
ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette8;
ii.Information.ColorsUsed = colorsUsed;
return true;
}
if (planes == 1 && bitcount == 4)
{
// Palette8
ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette4;
ii.Information.ColorsUsed = colorsUsed;
return true;
}
if (planes == 1 && bitcount == 1)
{
// Palette8
ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette1;
ii.Information.ColorsUsed = colorsUsed;
return true;
}
// TODO Implement more formats!
}
}
return false;
}
public ImageData PrepareImage(ImagePrivateData data)
{
throw new NotImplementedException();
}
}
/// <summary>
/// Bitmap refers to the format used in PDF. Will be used for BMP, PNG, TIFF, GIF and others.
/// </summary>
internal class ImportedImageBitmap : ImportedImage
{
/// <summary>
/// Initializes a new instance of the <see cref="ImportedImageBitmap"/> class.
/// </summary>
public ImportedImageBitmap(IImageImporter importer, ImagePrivateDataBitmap data, PdfDocument document)
: base(importer, data, document)
{ }
internal override ImageData PrepareImageData()
{
ImagePrivateDataBitmap data = (ImagePrivateDataBitmap)Data;
ImageDataBitmap imageData = new ImageDataBitmap(_document);
//imageData.Data = data.Data;
//imageData.Length = data.Length;
data.CopyBitmap(imageData);
return imageData;
}
}
// THHO4THHO Maybe there will be derived classes for direct bitmaps vs. palettized bitmaps or so. Time will tell.
/// <summary>
/// Contains data needed for PDF. Will be prepared when needed.
/// Bitmap refers to the format used in PDF. Will be used for BMP, PNG, TIFF, GIF and others.
/// </summary>
internal class ImageDataBitmap : ImageData
{
private ImageDataBitmap()
{
}
internal ImageDataBitmap(PdfDocument document)
{
_document = document;
}
/// <summary>
/// Gets the data.
/// </summary>
public byte[] Data
{
get { return _data; }
internal set { _data = value; }
}
private byte[] _data;
/// <summary>
/// Gets the length.
/// </summary>
public int Length
{
get { return _length; }
internal set { _length = value; }
}
private int _length;
/// <summary>
/// Gets the data.
/// </summary>
public byte[] DataFax
{
get { return _dataFax; }
internal set { _dataFax = value; }
}
private byte[] _dataFax;
/// <summary>
/// Gets the length.
/// </summary>
public int LengthFax
{
get { return _lengthFax; }
internal set { _lengthFax = value; }
}
private int _lengthFax;
public byte[] AlphaMask
{
get { return _alphaMask; }
internal set { _alphaMask = value; }
}
private byte[] _alphaMask;
public int AlphaMaskLength
{
get { return _alphaMaskLength; }
internal set { _alphaMaskLength = value; }
}
private int _alphaMaskLength;
public byte[] BitmapMask
{
get { return _bitmapMask; }
internal set { _bitmapMask = value; }
}
private byte[] _bitmapMask;
public int BitmapMaskLength
{
get { return _bitmapMaskLength; }
internal set { _bitmapMaskLength = value; }
}
private int _bitmapMaskLength;
public byte[] PaletteData
{
get { return _paletteData; }
set { _paletteData = value; }
}
private byte[] _paletteData;
public int PaletteDataLength
{
get { return _paletteDataLength; }
set { _paletteDataLength = value; }
}
private int _paletteDataLength;
public bool SegmentedColorMask;
public int IsBitonal;
public int K;
public bool IsGray;
internal readonly PdfDocument _document;
}
/// <summary>
/// Image data needed for PDF bitmap images.
/// </summary>
internal class ImagePrivateDataBitmap : ImagePrivateData
{
/// <summary>
/// Initializes a new instance of the <see cref="ImagePrivateDataBitmap"/> class.
/// </summary>
public ImagePrivateDataBitmap(byte[] data, int length)
{
_data = data;
_length = length;
}
/// <summary>
/// Gets the data.
/// </summary>
public byte[] Data
{
get { return _data; }
//internal set { _data = value; }
}
private readonly byte[] _data;
/// <summary>
/// Gets the length.
/// </summary>
public int Length
{
get { return _length; }
//internal set { _length = value; }
}
private readonly int _length;
/// <summary>
/// True if first line is the top line, false if first line is the bottom line of the image. When needed, lines will be reversed while converting data into PDF format.
/// </summary>
internal bool FlippedImage;
/// <summary>
/// The offset of the image data in Data.
/// </summary>
internal int Offset;
/// <summary>
/// The offset of the color palette in Data.
/// </summary>
internal int ColorPaletteOffset;
internal void CopyBitmap(ImageDataBitmap dest)
{
switch (Image.Information.ImageFormat)
{
case ImageInformation.ImageFormats.ARGB32:
CopyTrueColorMemoryBitmap(3, 8, true, dest);
break;
case ImageInformation.ImageFormats.RGB24:
CopyTrueColorMemoryBitmap(4, 8, false, dest);
break;
case ImageInformation.ImageFormats.Palette8:
CopyIndexedMemoryBitmap(8, dest);
break;
case ImageInformation.ImageFormats.Palette4:
CopyIndexedMemoryBitmap(4, dest);
break;
case ImageInformation.ImageFormats.Palette1:
CopyIndexedMemoryBitmap(1, dest);
break;
default:
throw new NotImplementedException();
}
}
/// <summary>
/// Copies images without color palette.
/// </summary>
/// <param name="components">4 (32bpp RGB), 3 (24bpp RGB, 32bpp ARGB)</param>
/// <param name="bits">8</param>
/// <param name="hasAlpha">true (ARGB), false (RGB)</param>
/// <param name="dest">Destination </param>
private void CopyTrueColorMemoryBitmap(int components, int bits, bool hasAlpha, ImageDataBitmap dest)
{
int width = (int)Image.Information.Width;
int height = (int)Image.Information.Height;
int logicalComponents = components;
if (components == 4)
logicalComponents = 3;
byte[] imageData = new byte[components * width * height];
bool hasMask = false;
bool hasAlphaMask = false;
byte[] alphaMask = hasAlpha ? new byte[width * height] : null;
MonochromeMask mask = hasAlpha ?
new MonochromeMask(width, height) : null;
int nFileOffset = Offset;
int nOffsetRead = 0;
if (logicalComponents == 3)
{
for (int y = 0; y < height; ++y)
{
// TODO Handle Flipped.
int nOffsetWrite = 3 * (height - 1 - y) * width;
int nOffsetWriteAlpha = 0;
if (hasAlpha)
{
mask.StartLine(y);
nOffsetWriteAlpha = (height - 1 - y) * width;
}
for (int x = 0; x < width; ++x)
{
imageData[nOffsetWrite] = Data[nFileOffset + nOffsetRead + 2];
imageData[nOffsetWrite + 1] = Data[nFileOffset + nOffsetRead + 1];
imageData[nOffsetWrite + 2] = Data[nFileOffset + nOffsetRead];
if (hasAlpha)
{
mask.AddPel(Data[nFileOffset + nOffsetRead + 3]);
alphaMask[nOffsetWriteAlpha] = Data[nFileOffset + nOffsetRead + 3];
if (!hasMask || !hasAlphaMask)
{
if (Data[nFileOffset + nOffsetRead + 3] != 255)
{
hasMask = true;
if (Data[nFileOffset + nOffsetRead + 3] != 0)
hasAlphaMask = true;
}
}
++nOffsetWriteAlpha;
}
nOffsetRead += hasAlpha ? 4 : components;
nOffsetWrite += 3;
}
nOffsetRead = 4 * ((nOffsetRead + 3) / 4); // Align to 32 bit boundary
}
}
else if (components == 1)
{
// Grayscale
throw new NotImplementedException("Image format not supported (grayscales).");
}
dest.Data = imageData;
dest.Length = imageData.Length;
if (alphaMask != null)
{
dest.AlphaMask = alphaMask;
dest.AlphaMaskLength = alphaMask.Length;
}
if (mask != null)
{
dest.BitmapMask = mask.MaskData;
dest.BitmapMaskLength = mask.MaskData.Length;
}
}
private void CopyIndexedMemoryBitmap(int bits/*, ref bool hasAlpha*/, ImageDataBitmap dest)
{
int firstMaskColor = -1, lastMaskColor = -1;
bool segmentedColorMask = false;
int bytesColorPaletteOffset = ((ImagePrivateDataBitmap)Image.Data).ColorPaletteOffset; // GDI+ always returns Windows bitmaps: sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER
int bytesFileOffset = ((ImagePrivateDataBitmap)Image.Data).Offset;
uint paletteColors = Image.Information.ColorsUsed;
int width = (int)Image.Information.Width;
int height = (int)Image.Information.Height;
MonochromeMask mask = new MonochromeMask(width, height);
bool isGray = bits == 8 && (paletteColors == 256 || paletteColors == 0);
int isBitonal = 0; // 0: false; >0: true; <0: true (inverted)
byte[] paletteData = new byte[3 * paletteColors];
for (int color = 0; color < paletteColors; ++color)
{
paletteData[3 * color] = Data[bytesColorPaletteOffset + 4 * color + 2];
paletteData[3 * color + 1] = Data[bytesColorPaletteOffset + 4 * color + 1];
paletteData[3 * color + 2] = Data[bytesColorPaletteOffset + 4 * color + 0];
if (isGray)
isGray = paletteData[3 * color] == paletteData[3 * color + 1] &&
paletteData[3 * color] == paletteData[3 * color + 2];
if (Data[bytesColorPaletteOffset + 4 * color + 3] < 128)
{
// We treat this as transparency:
if (firstMaskColor == -1)
firstMaskColor = color;
if (lastMaskColor == -1 || lastMaskColor == color - 1)
lastMaskColor = color;
if (lastMaskColor != color)
segmentedColorMask = true;
}
//else
//{
// // We treat this as opacity:
//}
}
if (bits == 1)
{
if (paletteColors == 0)
isBitonal = 1;
if (paletteColors == 2)
{
if (paletteData[0] == 0 &&
paletteData[1] == 0 &&
paletteData[2] == 0 &&
paletteData[3] == 255 &&
paletteData[4] == 255 &&
paletteData[5] == 255)
isBitonal = 1; // Black on white
if (paletteData[5] == 0 &&
paletteData[4] == 0 &&
paletteData[3] == 0 &&
paletteData[2] == 255 &&
paletteData[1] == 255 &&
paletteData[0] == 255)
isBitonal = -1; // White on black
}
}
// NYI: (no sample found where this was required)
// if (segmentedColorMask = true)
// { ... }
bool isFaxEncoding = false;
byte[] imageData = new byte[((width * bits + 7) / 8) * height];
byte[] imageDataFax = null;
int k = 0;
if (bits == 1 && dest._document.Options.EnableCcittCompressionForBilevelImages)
{
// TODO: flag/option?
// We try Group 3 1D and Group 4 (2D) encoding here and keep the smaller byte array.
//byte[] temp = new byte[imageData.Length];
//int ccittSize = DoFaxEncoding(ref temp, imageBits, (uint)bytesFileOffset, (uint)width, (uint)height);
// It seems that Group 3 2D encoding never beats both other encodings, therefore we don't call it here.
//byte[] temp2D = new byte[imageData.Length];
//uint dpiY = (uint)image.VerticalResolution;
//uint kTmp = 0;
//int ccittSize2D = DoFaxEncoding2D((uint)bytesFileOffset, ref temp2D, imageBits, (uint)width, (uint)height, dpiY, out kTmp);
//k = (int) kTmp;
byte[] tempG4 = new byte[imageData.Length];
int ccittSizeG4 = PdfImage.DoFaxEncodingGroup4(ref tempG4, Data, (uint)bytesFileOffset, (uint)width, (uint)height);
isFaxEncoding = /*ccittSize > 0 ||*/ ccittSizeG4 > 0;
if (isFaxEncoding)
{
//if (ccittSize == 0)
// ccittSize = 0x7fffffff;
if (ccittSizeG4 == 0)
ccittSizeG4 = 0x7fffffff;
//if (ccittSize <= ccittSizeG4)
//{
// Array.Resize(ref temp, ccittSize);
// imageDataFax = temp;
// k = 0;
//}
//else
{
Array.Resize(ref tempG4, ccittSizeG4);
imageDataFax = tempG4;
k = -1;
}
}
}
//if (!isFaxEncoding)
{
int bytesOffsetRead = 0;
if (bits == 8 || bits == 4 || bits == 1)
{
int bytesPerLine = (width * bits + 7) / 8;
for (int y = 0; y < height; ++y)
{
mask.StartLine(y);
int bytesOffsetWrite = (height - 1 - y) * ((width * bits + 7) / 8);
for (int x = 0; x < bytesPerLine; ++x)
{
if (isGray)
{
// Lookup the gray value from the palette:
imageData[bytesOffsetWrite] = paletteData[3 * Data[bytesFileOffset + bytesOffsetRead]];
}
else
{
// Store the palette index.
imageData[bytesOffsetWrite] = Data[bytesFileOffset + bytesOffsetRead];
}
if (firstMaskColor != -1)
{
int n = Data[bytesFileOffset + bytesOffsetRead];
if (bits == 8)
{
// TODO???: segmentedColorMask == true => bad mask NYI
mask.AddPel((n >= firstMaskColor) && (n <= lastMaskColor));
}
else if (bits == 4)
{
// TODO???: segmentedColorMask == true => bad mask NYI
int n1 = (n & 0xf0) / 16;
int n2 = (n & 0x0f);
mask.AddPel((n1 >= firstMaskColor) && (n1 <= lastMaskColor));
mask.AddPel((n2 >= firstMaskColor) && (n2 <= lastMaskColor));
}
else if (bits == 1)
{
// TODO???: segmentedColorMask == true => bad mask NYI
for (int bit = 1; bit <= 8; ++bit)
{
int n1 = (n & 0x80) / 128;
mask.AddPel((n1 >= firstMaskColor) && (n1 <= lastMaskColor));
n *= 2;
}
}
}
bytesOffsetRead += 1;
bytesOffsetWrite += 1;
}
bytesOffsetRead = 4 * ((bytesOffsetRead + 3) / 4); // Align to 32 bit boundary
}
}
else
{
throw new NotImplementedException("ReadIndexedMemoryBitmap: unsupported format #3");
}
}
dest.Data = imageData;
dest.Length = imageData.Length;
if (imageDataFax != null)
{
dest.DataFax = imageDataFax;
dest.LengthFax = imageDataFax.Length;
}
dest.IsGray = isGray;
dest.K = k;
dest.IsBitonal = isBitonal;
dest.PaletteData = paletteData;
dest.PaletteDataLength = paletteData.Length;
dest.SegmentedColorMask = segmentedColorMask;
//if (alphaMask != null)
//{
// dest.AlphaMask = alphaMask;
// dest.AlphaMaskLength = alphaMask.Length;
//}
if (mask != null && firstMaskColor != -1)
{
dest.BitmapMask = mask.MaskData;
dest.BitmapMaskLength = mask.MaskData.Length;
}
}
}
}

View File

@@ -0,0 +1,363 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// 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.
#endregion
using System;
using PdfSharp.Pdf;
namespace PdfSharp.Drawing.Internal
{
// ReSharper disable once InconsistentNaming
internal class ImageImporterJpeg : ImageImporterRoot, IImageImporter
{
// TODO Find information about JPEG2000.
// Notes: JFIF is big-endian.
public ImportedImage ImportImage(StreamReaderHelper stream, PdfDocument document)
{
try
{
stream.CurrentOffset = 0;
// Test 2 magic bytes.
if (TestFileHeader(stream))
{
// Skip over 2 magic bytes.
stream.CurrentOffset += 2;
ImagePrivateDataDct ipd = new ImagePrivateDataDct(stream.Data, stream.Length);
ImportedImage ii = new ImportedImageJpeg(this, ipd, document);
if (TestJfifHeader(stream, ii))
{
bool colorHeader = false, infoHeader = false;
while (MoveToNextHeader(stream))
{
if (TestColorFormatHeader(stream, ii))
{
colorHeader = true;
}
else if (TestInfoHeader(stream, ii))
{
infoHeader = true;
}
}
if (colorHeader && infoHeader)
return ii;
}
}
}
// ReSharper disable once EmptyGeneralCatchClause
catch (Exception)
{
}
return null;
}
private bool TestFileHeader(StreamReaderHelper stream)
{
// File must start with 0xffd8.
return stream.GetWord(0, true) == 0xffd8;
}
private bool TestJfifHeader(StreamReaderHelper stream, ImportedImage ii)
{
// The App0 header should be the first header in every JFIF file.
if (stream.GetWord(0, true) == 0xffe0)
{
// Now check for text "JFIF".
if (stream.GetDWord(4, true) == 0x4a464946)
{
int blockLength = stream.GetWord(2, true);
if (blockLength >= 16)
{
int version = stream.GetWord(9, true);
int units = stream.GetByte(11);
int densityX = stream.GetWord(12, true);
int densityY = stream.GetWord(14, true);
switch (units)
{
case 0: // Aspect ratio only.
ii.Information.HorizontalAspectRatio = densityX;
ii.Information.VerticalAspectRatio = densityY;
break;
case 1: // DPI.
ii.Information.HorizontalDPI = densityX;
ii.Information.VerticalDPI = densityY;
break;
case 2: // DPCM.
ii.Information.HorizontalDPM = densityX * 100;
ii.Information.VerticalDPM = densityY * 100;
break;
}
// More information here? More tests?
return true;
}
}
}
return false;
}
private bool TestColorFormatHeader(StreamReaderHelper stream, ImportedImage ii)
{
// The SOS header (start of scan).
if (stream.GetWord(0, true) == 0xffda)
{
int components = stream.GetByte(4);
if (components < 1 || components > 4 || components == 2)
return false;
// 1 for grayscale, 3 for RGB, 4 for CMYK.
int blockLength = stream.GetWord(2, true);
// Integrity check: correct size?
if (blockLength != 6 + 2 * components)
return false;
// Eventually do more tests here.
// Magic: we assume that all JPEG files with 4 components are RGBW (inverted CMYK) and not CMYK.
// We add a test to tell CMYK from RGBW when we encounter a test file in CMYK format.
ii.Information.ImageFormat = components == 3 ? ImageInformation.ImageFormats.JPEG :
(components == 1 ? ImageInformation.ImageFormats.JPEGGRAY : ImageInformation.ImageFormats.JPEGRGBW);
return true;
}
return false;
}
private bool TestInfoHeader(StreamReaderHelper stream, ImportedImage ii)
{
// The SOF header (start of frame).
int header = stream.GetWord(0, true);
if (header >= 0xffc0 && header <= 0xffc3 ||
header >= 0xffc9 && header <= 0xffcb)
{
// Lines in image.
int sizeY = stream.GetWord(5, true);
// Samples per line.
int sizeX = stream.GetWord(7, true);
// $THHO TODO: Check if we always get useful information here.
ii.Information.Width = (uint)sizeX;
ii.Information.Height = (uint)sizeY;
return true;
}
return false;
}
private bool MoveToNextHeader(StreamReaderHelper stream)
{
int blockLength = stream.GetWord(2, true);
int headerMagic = stream.GetByte(0);
int headerType = stream.GetByte(1);
if (headerMagic == 0xff)
{
// EOI: last header.
if (headerType == 0xd9)
return false;
// Check for standalone markers.
if (headerType == 0x01 || headerType >= 0xd0 && headerType <= 0xd7)
{
stream.CurrentOffset += 2;
return true;
}
// Now assume header with block size.
stream.CurrentOffset += 2 + blockLength;
return true;
}
return false;
}
public ImageData PrepareImage(ImagePrivateData data)
{
throw new NotImplementedException();
}
//int GetJpgSizeTestCode(byte[] pData, uint FileSizeLow, out int pWidth, out int pHeight)
//{
// pWidth = -1;
// pHeight = -1;
// int i = 0;
// if ((pData[i] == 0xFF) && (pData[i + 1] == 0xD8) && (pData[i + 2] == 0xFF) && (pData[i + 3] == 0xE0))
// {
// i += 4;
// // Check for valid JPEG header (null terminated JFIF)
// if ((pData[i + 2] == 'J') && (pData[i + 3] == 'F') && (pData[i + 4] == 'I') && (pData[i + 5] == 'F')
// && (pData[i + 6] == 0x00))
// {
// //Retrieve the block length of the first block since the first block will not contain the size of file
// int block_length = pData[i] * 256 + pData[i + 1];
// while (i < FileSizeLow)
// {
// //Increase the file index to get to the next block
// i += block_length;
// if (i >= FileSizeLow)
// {
// //Check to protect against segmentation faults
// return -1;
// }
// if (pData[i] != 0xFF)
// {
// return -2;
// }
// if (pData[i + 1] == 0xC0)
// {
// //0xFFC0 is the "Start of frame" marker which contains the file size
// //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
// pHeight = pData[i + 5] * 256 + pData[i + 6];
// pWidth = pData[i + 7] * 256 + pData[i + 8];
// return 0;
// }
// else
// {
// i += 2; //Skip the block marker
// //Go to the next block
// block_length = pData[i] * 256 + pData[i + 1];
// }
// }
// //If this point is reached then no size was found
// return -3;
// }
// else
// {
// return -4;
// } //Not a valid JFIF string
// }
// else
// {
// return -5;
// } //Not a valid SOI header
// //return -6;
//} // GetJpgSize
}
/// <summary>
/// Imported JPEG image.
/// </summary>
internal class ImportedImageJpeg : ImportedImage
{
/// <summary>
/// Initializes a new instance of the <see cref="ImportedImageJpeg"/> class.
/// </summary>
public ImportedImageJpeg(IImageImporter importer, ImagePrivateDataDct data, PdfDocument document)
: base(importer, data, document)
{ }
internal override ImageData PrepareImageData()
{
ImagePrivateDataDct data = (ImagePrivateDataDct)Data;
ImageDataDct imageData = new ImageDataDct();
imageData.Data = data.Data;
imageData.Length = data.Length;
return imageData;
}
}
/// <summary>
/// Contains data needed for PDF. Will be prepared when needed.
/// </summary>
internal class ImageDataDct : ImageData
{
/// <summary>
/// Gets the data.
/// </summary>
public byte[] Data
{
get { return _data; }
internal set { _data = value; }
}
private byte[] _data;
/// <summary>
/// Gets the length.
/// </summary>
public int Length
{
get { return _length; }
internal set { _length = value; }
}
private int _length;
}
/*internal*/
/// <summary>
/// Private data for JPEG images.
/// </summary>
internal class ImagePrivateDataDct : ImagePrivateData
{
/// <summary>
/// Initializes a new instance of the <see cref="ImagePrivateDataDct"/> class.
/// </summary>
public ImagePrivateDataDct(byte[] data, int length)
{
_data = data;
_length = length;
}
/// <summary>
/// Gets the data.
/// </summary>
public byte[] Data
{
get { return _data; }
//internal set { _data = value; }
}
private readonly byte[] _data;
/// <summary>
/// Gets the length.
/// </summary>
public int Length
{
get { return _length; }
//internal set { _length = value; }
}
private readonly int _length;
}
}

View File

@@ -0,0 +1,35 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// 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.
#endregion
namespace PdfSharp.Drawing.Internal
{
internal abstract class ImageImporterRoot
{
}
}

View File

@@ -0,0 +1,399 @@
#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 PdfSharp.Pdf.IO;
namespace PdfSharp.Drawing.Layout
{
/// <summary>
/// Represents a very simple text formatter.
/// If this class does not satisfy your needs on formatting paragraphs I recommend to take a look
/// at MigraDoc Foundation. Alternatively you should copy this class in your own source code and modify it.
/// </summary>
public class XTextFormatter
{
/// <summary>
/// Initializes a new instance of the <see cref="XTextFormatter"/> class.
/// </summary>
public XTextFormatter(XGraphics gfx)
{
if (gfx == null)
throw new ArgumentNullException("gfx");
_gfx = gfx;
}
readonly XGraphics _gfx;
/// <summary>
/// Gets or sets the text.
/// </summary>
/// <value>The text.</value>
public string Text
{
get { return _text; }
set { _text = value; }
}
string _text;
/// <summary>
/// Gets or sets the font.
/// </summary>
public XFont Font
{
get { return _font; }
set
{
if (value == null)
throw new ArgumentNullException("Font");
_font = value;
_lineSpace = _font.GetHeight(); // old: _font.GetHeight(_gfx);
_cyAscent = _lineSpace * _font.CellAscent / _font.CellSpace;
_cyDescent = _lineSpace * _font.CellDescent / _font.CellSpace;
// HACK in XTextFormatter
_spaceWidth = _gfx.MeasureString("x<>x", value).Width;
_spaceWidth -= _gfx.MeasureString("xx", value).Width;
}
}
XFont _font;
double _lineSpace;
double _cyAscent;
double _cyDescent;
double _spaceWidth;
/// <summary>
/// Gets or sets the bounding box of the layout.
/// </summary>
public XRect LayoutRectangle
{
get { return _layoutRectangle; }
set { _layoutRectangle = value; }
}
XRect _layoutRectangle;
/// <summary>
/// Gets or sets the alignment of the text.
/// </summary>
public XParagraphAlignment Alignment
{
get { return _alignment; }
set { _alignment = value; }
}
XParagraphAlignment _alignment = XParagraphAlignment.Left;
/// <summary>
/// Draws the text.
/// </summary>
/// <param name="text">The text to be drawn.</param>
/// <param name="font">The font.</param>
/// <param name="brush">The text brush.</param>
/// <param name="layoutRectangle">The layout rectangle.</param>
public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectangle)
{
DrawString(text, font, brush, layoutRectangle, XStringFormats.TopLeft);
}
/// <summary>
/// Draws the text.
/// </summary>
/// <param name="text">The text to be drawn.</param>
/// <param name="font">The font.</param>
/// <param name="brush">The text brush.</param>
/// <param name="layoutRectangle">The layout rectangle.</param>
/// <param name="format">The format. Must be <c>XStringFormat.TopLeft</c></param>
public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)
{
if (text == null)
throw new ArgumentNullException("text");
if (font == null)
throw new ArgumentNullException("font");
if (brush == null)
throw new ArgumentNullException("brush");
if (format.Alignment != XStringAlignment.Near || format.LineAlignment != XLineAlignment.Near)
throw new ArgumentException("Only TopLeft alignment is currently implemented.");
Text = text;
Font = font;
LayoutRectangle = layoutRectangle;
if (text.Length == 0)
return;
CreateBlocks();
CreateLayout();
double dx = layoutRectangle.Location.X;
double dy = layoutRectangle.Location.Y + _cyAscent;
int count = _blocks.Count;
for (int idx = 0; idx < count; idx++)
{
Block block = _blocks[idx];
if (block.Stop)
break;
if (block.Type == BlockType.LineBreak)
continue;
_gfx.DrawString(block.Text, font, brush, dx + block.Location.X, dy + block.Location.Y);
}
}
void CreateBlocks()
{
_blocks.Clear();
int length = _text.Length;
bool inNonWhiteSpace = false;
int startIndex = 0, blockLength = 0;
for (int idx = 0; idx < length; idx++)
{
char ch = _text[idx];
// Treat CR and CRLF as LF
if (ch == Chars.CR)
{
if (idx < length - 1 && _text[idx + 1] == Chars.LF)
idx++;
ch = Chars.LF;
}
if (ch == Chars.LF)
{
if (blockLength != 0)
{
string token = _text.Substring(startIndex, blockLength);
_blocks.Add(new Block(token, BlockType.Text,
_gfx.MeasureString(token, _font).Width));
}
startIndex = idx + 1;
blockLength = 0;
_blocks.Add(new Block(BlockType.LineBreak));
}
// The non-breaking space is whitespace, so we treat it like non-whitespace.
else if (ch != Chars.NonBreakableSpace && char.IsWhiteSpace(ch))
{
if (inNonWhiteSpace)
{
string token = _text.Substring(startIndex, blockLength);
_blocks.Add(new Block(token, BlockType.Text,
_gfx.MeasureString(token, _font).Width));
startIndex = idx + 1;
blockLength = 0;
}
else
{
blockLength++;
}
}
else
{
inNonWhiteSpace = true;
blockLength++;
}
}
if (blockLength != 0)
{
string token = _text.Substring(startIndex, blockLength);
_blocks.Add(new Block(token, BlockType.Text,
_gfx.MeasureString(token, _font).Width));
}
}
void CreateLayout()
{
double rectWidth = _layoutRectangle.Width;
double rectHeight = _layoutRectangle.Height - _cyAscent - _cyDescent;
int firstIndex = 0;
double x = 0, y = 0;
int count = _blocks.Count;
for (int idx = 0; idx < count; idx++)
{
Block block = _blocks[idx];
if (block.Type == BlockType.LineBreak)
{
if (Alignment == XParagraphAlignment.Justify)
_blocks[firstIndex].Alignment = XParagraphAlignment.Left;
AlignLine(firstIndex, idx - 1, rectWidth);
firstIndex = idx + 1;
x = 0;
y += _lineSpace;
if (y > rectHeight)
{
block.Stop = true;
break;
}
}
else
{
double width = block.Width;
if ((x + width <= rectWidth || x == 0) && block.Type != BlockType.LineBreak)
{
block.Location = new XPoint(x, y);
x += width + _spaceWidth;
}
else
{
AlignLine(firstIndex, idx - 1, rectWidth);
firstIndex = idx;
y += _lineSpace;
if (y > rectHeight)
{
block.Stop = true;
break;
}
block.Location = new XPoint(0, y);
x = width + _spaceWidth;
}
}
}
if (firstIndex < count && Alignment != XParagraphAlignment.Justify)
AlignLine(firstIndex, count - 1, rectWidth);
}
/// <summary>
/// Align center, right, or justify.
/// </summary>
void AlignLine(int firstIndex, int lastIndex, double layoutWidth)
{
XParagraphAlignment blockAlignment = _blocks[firstIndex].Alignment;
if (_alignment == XParagraphAlignment.Left || blockAlignment == XParagraphAlignment.Left)
return;
int count = lastIndex - firstIndex + 1;
if (count == 0)
return;
double totalWidth = -_spaceWidth;
for (int idx = firstIndex; idx <= lastIndex; idx++)
totalWidth += _blocks[idx].Width + _spaceWidth;
double dx = Math.Max(layoutWidth - totalWidth, 0);
//Debug.Assert(dx >= 0);
if (_alignment != XParagraphAlignment.Justify)
{
if (_alignment == XParagraphAlignment.Center)
dx /= 2;
for (int idx = firstIndex; idx <= lastIndex; idx++)
{
Block block = _blocks[idx];
block.Location += new XSize(dx, 0);
}
}
else if (count > 1) // case: justify
{
dx /= count - 1;
for (int idx = firstIndex + 1, i = 1; idx <= lastIndex; idx++, i++)
{
Block block = _blocks[idx];
block.Location += new XSize(dx * i, 0);
}
}
}
readonly List<Block> _blocks = new List<Block>();
enum BlockType
{
Text, Space, Hyphen, LineBreak,
}
/// <summary>
/// Represents a single word.
/// </summary>
class Block
{
/// <summary>
/// Initializes a new instance of the <see cref="Block"/> class.
/// </summary>
/// <param name="text">The text of the block.</param>
/// <param name="type">The type of the block.</param>
/// <param name="width">The width of the text.</param>
public Block(string text, BlockType type, double width)
{
Text = text;
Type = type;
Width = width;
}
/// <summary>
/// Initializes a new instance of the <see cref="Block"/> class.
/// </summary>
/// <param name="type">The type.</param>
public Block(BlockType type)
{
Type = type;
}
/// <summary>
/// The text represented by this block.
/// </summary>
public readonly string Text;
/// <summary>
/// The type of the block.
/// </summary>
public readonly BlockType Type;
/// <summary>
/// The width of the text.
/// </summary>
public readonly double Width;
/// <summary>
/// The location relative to the upper left corner of the layout rectangle.
/// </summary>
public XPoint Location;
/// <summary>
/// The alignment of this line.
/// </summary>
public XParagraphAlignment Alignment;
/// <summary>
/// A flag indicating that this is the last block that fits in the layout rectangle.
/// </summary>
public bool Stop;
}
// TODO:
// - more XStringFormat variations
// - calculate bounding box
// - left and right indent
// - first line indent
// - margins and paddings
// - background color
// - text background color
// - border style
// - hyphens, soft hyphens, hyphenation
// - kerning
// - change font, size, text color etc.
// - line spacing
// - underline and strike-out variation
// - super- and sub-script
// - ...
}
}

View File

@@ -0,0 +1,62 @@
#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.Drawing.Layout
{
/// <summary>
/// Specifies the alignment of a paragraph.
/// </summary>
public enum XParagraphAlignment
{
/// <summary>
/// Default alignment, typically left alignment.
/// </summary>
Default,
/// <summary>
/// The paragraph is rendered left aligned.
/// </summary>
Left,
/// <summary>
/// The paragraph is rendered centered.
/// </summary>
Center,
/// <summary>
/// The paragraph is rendered right aligned.
/// </summary>
Right,
/// <summary>
/// The paragraph is rendered justified.
/// </summary>
Justify,
}
}

View File

@@ -0,0 +1,543 @@
#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.Globalization;
using System.Text;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
#endif
using PdfSharp.Internal;
using PdfSharp.Pdf;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.Internal;
// ReSharper disable CompareOfFloatsByEqualityOperator
namespace PdfSharp.Drawing.Pdf
{
/// <summary>
/// Represents the current PDF graphics state.
/// </summary>
/// <remarks>
/// Completely revised for PDFsharp 1.4.
/// </remarks>
internal sealed class PdfGraphicsState : ICloneable
{
public PdfGraphicsState(XGraphicsPdfRenderer renderer)
{
_renderer = renderer;
}
readonly XGraphicsPdfRenderer _renderer;
public PdfGraphicsState Clone()
{
PdfGraphicsState state = (PdfGraphicsState)MemberwiseClone();
return state;
}
object ICloneable.Clone()
{
return Clone();
}
internal int Level;
internal InternalGraphicsState InternalState;
public void PushState()
{
// BeginGraphic
_renderer.Append("q/n");
}
public void PopState()
{
//BeginGraphic
_renderer.Append("Q/n");
}
#region Stroke
double _realizedLineWith = -1;
int _realizedLineCap = -1;
int _realizedLineJoin = -1;
double _realizedMiterLimit = -1;
XDashStyle _realizedDashStyle = (XDashStyle)(-1);
string _realizedDashPattern;
XColor _realizedStrokeColor = XColor.Empty;
bool _realizedStrokeOverPrint;
public void RealizePen(XPen pen, PdfColorMode colorMode)
{
const string frmt2 = Config.SignificantFigures2;
const string format = Config.SignificantFigures3;
XColor color = pen.Color;
bool overPrint = pen.Overprint;
color = ColorSpaceHelper.EnsureColorMode(colorMode, color);
if (_realizedLineWith != pen._width)
{
_renderer.AppendFormatArgs("{0:" + format + "} w\n", pen._width);
_realizedLineWith = pen._width;
}
if (_realizedLineCap != (int)pen._lineCap)
{
_renderer.AppendFormatArgs("{0} J\n", (int)pen._lineCap);
_realizedLineCap = (int)pen._lineCap;
}
if (_realizedLineJoin != (int)pen._lineJoin)
{
_renderer.AppendFormatArgs("{0} j\n", (int)pen._lineJoin);
_realizedLineJoin = (int)pen._lineJoin;
}
if (_realizedLineCap == (int)XLineJoin.Miter)
{
if (_realizedMiterLimit != (int)pen._miterLimit && (int)pen._miterLimit != 0)
{
_renderer.AppendFormatInt("{0} M\n", (int)pen._miterLimit);
_realizedMiterLimit = (int)pen._miterLimit;
}
}
if (_realizedDashStyle != pen._dashStyle || pen._dashStyle == XDashStyle.Custom)
{
double dot = pen.Width;
double dash = 3 * dot;
// Line width 0 is not recommended but valid.
XDashStyle dashStyle = pen.DashStyle;
if (dot == 0)
dashStyle = XDashStyle.Solid;
switch (dashStyle)
{
case XDashStyle.Solid:
_renderer.Append("[]0 d\n");
break;
case XDashStyle.Dash:
_renderer.AppendFormatArgs("[{0:" + frmt2 + "} {1:" + frmt2 + "}]0 d\n", dash, dot);
break;
case XDashStyle.Dot:
_renderer.AppendFormatArgs("[{0:" + frmt2 + "}]0 d\n", dot);
break;
case XDashStyle.DashDot:
_renderer.AppendFormatArgs("[{0:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "}]0 d\n", dash, dot);
break;
case XDashStyle.DashDotDot:
_renderer.AppendFormatArgs("[{0:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "} {1:" + frmt2 + "}]0 d\n", dash, dot);
break;
case XDashStyle.Custom:
{
StringBuilder pdf = new StringBuilder("[", 256);
int len = pen._dashPattern == null ? 0 : pen._dashPattern.Length;
for (int idx = 0; idx < len; idx++)
{
if (idx > 0)
pdf.Append(' ');
pdf.Append(PdfEncoders.ToString(pen._dashPattern[idx] * pen._width));
}
// Make an even number of values look like in GDI+
if (len > 0 && len % 2 == 1)
{
pdf.Append(' ');
pdf.Append(PdfEncoders.ToString(0.2 * pen._width));
}
pdf.AppendFormat(CultureInfo.InvariantCulture, "]{0:" + format + "} d\n", pen._dashOffset * pen._width);
string pattern = pdf.ToString();
// BUG: drice2@ageone.de reported a realizing problem
// HACK: I remove the if clause
//if (_realizedDashPattern != pattern)
{
_realizedDashPattern = pattern;
_renderer.Append(pattern);
}
}
break;
}
_realizedDashStyle = dashStyle;
}
if (colorMode != PdfColorMode.Cmyk)
{
if (_realizedStrokeColor.Rgb != color.Rgb)
{
_renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb));
_renderer.Append(" RG\n");
}
}
else
{
if (!ColorSpaceHelper.IsEqualCmyk(_realizedStrokeColor, color))
{
_renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk));
_renderer.Append(" K\n");
}
}
if (_renderer.Owner.Version >= 14 && (_realizedStrokeColor.A != color.A || _realizedStrokeOverPrint != overPrint))
{
PdfExtGState extGState = _renderer.Owner.ExtGStateTable.GetExtGStateStroke(color.A, overPrint);
string gs = _renderer.Resources.AddExtGState(extGState);
_renderer.AppendFormatString("{0} gs\n", gs);
// Must create transparency group.
if (_renderer._page != null && color.A < 1)
_renderer._page.TransparencyUsed = true;
}
_realizedStrokeColor = color;
_realizedStrokeOverPrint = overPrint;
}
#endregion
#region Fill
XColor _realizedFillColor = XColor.Empty;
bool _realizedNonStrokeOverPrint;
public void RealizeBrush(XBrush brush, PdfColorMode colorMode, int renderingMode, double fontEmSize)
{
// Rendering mode 2 is used for bold simulation.
// Reference: TABLE 5.3<EFBFBD><EFBFBD>Text rendering modes / Page 402
XSolidBrush solidBrush = brush as XSolidBrush;
if (solidBrush != null)
{
XColor color = solidBrush.Color;
bool overPrint = solidBrush.Overprint;
if (renderingMode == 0)
{
RealizeFillColor(color, overPrint, colorMode);
}
else if (renderingMode == 2)
{
// Come here in case of bold simulation.
RealizeFillColor(color, false, colorMode);
//color = XColors.Green;
RealizePen(new XPen(color, fontEmSize * Const.BoldEmphasis), colorMode);
}
else
throw new InvalidOperationException("Only rendering modes 0 and 2 are currently supported.");
}
else
{
if (renderingMode != 0)
throw new InvalidOperationException("Rendering modes other than 0 can only be used with solid color brushes.");
XLinearGradientBrush gradientBrush = brush as XLinearGradientBrush;
if (gradientBrush != null)
{
Debug.Assert(UnrealizedCtm.IsIdentity, "Must realize ctm first.");
XMatrix matrix = _renderer.DefaultViewMatrix;
matrix.Prepend(EffectiveCtm);
PdfShadingPattern pattern = new PdfShadingPattern(_renderer.Owner);
pattern.SetupFromBrush(gradientBrush, matrix, _renderer);
string name = _renderer.Resources.AddPattern(pattern);
_renderer.AppendFormatString("/Pattern cs\n", name);
_renderer.AppendFormatString("{0} scn\n", name);
// Invalidate fill color.
_realizedFillColor = XColor.Empty;
}
}
}
private void RealizeFillColor(XColor color, bool overPrint, PdfColorMode colorMode)
{
color = ColorSpaceHelper.EnsureColorMode(colorMode, color);
if (colorMode != PdfColorMode.Cmyk)
{
if (_realizedFillColor.IsEmpty || _realizedFillColor.Rgb != color.Rgb)
{
_renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb));
_renderer.Append(" rg\n");
}
}
else
{
Debug.Assert(colorMode == PdfColorMode.Cmyk);
if (_realizedFillColor.IsEmpty || !ColorSpaceHelper.IsEqualCmyk(_realizedFillColor, color))
{
_renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk));
_renderer.Append(" k\n");
}
}
if (_renderer.Owner.Version >= 14 && (_realizedFillColor.A != color.A || _realizedNonStrokeOverPrint != overPrint))
{
PdfExtGState extGState = _renderer.Owner.ExtGStateTable.GetExtGStateNonStroke(color.A, overPrint);
string gs = _renderer.Resources.AddExtGState(extGState);
_renderer.AppendFormatString("{0} gs\n", gs);
// Must create transparency group.
if (_renderer._page != null && color.A < 1)
_renderer._page.TransparencyUsed = true;
}
_realizedFillColor = color;
_realizedNonStrokeOverPrint = overPrint;
}
internal void RealizeNonStrokeTransparency(double transparency, PdfColorMode colorMode)
{
XColor color = _realizedFillColor;
color.A = transparency;
RealizeFillColor(color, _realizedNonStrokeOverPrint, colorMode);
}
#endregion
#region Text
internal PdfFont _realizedFont;
string _realizedFontName = String.Empty;
double _realizedFontSize;
int _realizedRenderingMode; // Reference: TABLE 5.2 Text state operators / Page 398
double _realizedCharSpace; // Reference: TABLE 5.2 Text state operators / Page 398
public void RealizeFont(XFont font, XBrush brush, int renderingMode)
{
const string format = Config.SignificantFigures3;
// So far rendering mode 0 (fill text) and 2 (fill, then stroke text) only.
RealizeBrush(brush, _renderer._colorMode, renderingMode, font.Size); // _renderer.page.document.Options.ColorMode);
// Realize rendering mode.
if (_realizedRenderingMode != renderingMode)
{
_renderer.AppendFormatInt("{0} Tr\n", renderingMode);
_realizedRenderingMode = renderingMode;
}
// Realize character spacing.
if (_realizedRenderingMode == 0)
{
if (_realizedCharSpace != 0)
{
_renderer.Append("0 Tc\n");
_realizedCharSpace = 0;
}
}
else // _realizedRenderingMode is 2.
{
double charSpace = font.Size * Const.BoldEmphasis;
if (_realizedCharSpace != charSpace)
{
_renderer.AppendFormatDouble("{0:" + format + "} Tc\n", charSpace);
_realizedCharSpace = charSpace;
}
}
_realizedFont = null;
string fontName = _renderer.GetFontName(font, out _realizedFont);
if (fontName != _realizedFontName || _realizedFontSize != font.Size)
{
if (_renderer.Gfx.PageDirection == XPageDirection.Downwards)
_renderer.AppendFormatFont("{0} {1:" + format + "} Tf\n", fontName, font.Size);
else
_renderer.AppendFormatFont("{0} {1:" + format + "} Tf\n", fontName, font.Size);
_realizedFontName = fontName;
_realizedFontSize = font.Size;
}
}
public XPoint RealizedTextPosition;
/// <summary>
/// Indicates that the text transformation matrix currently skews 20<32> to the right.
/// </summary>
public bool ItalicSimulationOn;
#endregion
#region Transformation
/// <summary>
/// The already realized part of the current transformation matrix.
/// </summary>
public XMatrix RealizedCtm;
/// <summary>
/// The not yet realized part of the current transformation matrix.
/// </summary>
public XMatrix UnrealizedCtm;
/// <summary>
/// Product of RealizedCtm and UnrealizedCtm.
/// </summary>
public XMatrix EffectiveCtm;
/// <summary>
/// Inverse of EffectiveCtm used for transformation.
/// </summary>
public XMatrix InverseEffectiveCtm;
public XMatrix WorldTransform;
///// <summary>
///// The world transform in PDF world space.
///// </summary>
//public XMatrix EffectiveCtm
//{
// get
// {
// //if (MustRealizeCtm)
// if (!UnrealizedCtm.IsIdentity)
// {
// XMatrix matrix = RealizedCtm;
// matrix.Prepend(UnrealizedCtm);
// return matrix;
// }
// return RealizedCtm;
// }
// //set
// //{
// // XMatrix matrix = realizedCtm;
// // matrix.Invert();
// // matrix.Prepend(value);
// // unrealizedCtm = matrix;
// // MustRealizeCtm = !unrealizedCtm.IsIdentity;
// //}
//}
public void AddTransform(XMatrix value, XMatrixOrder matrixOrder)
{
// TODO: User matrixOrder
#if DEBUG
if (matrixOrder == XMatrixOrder.Append)
throw new NotImplementedException("XMatrixOrder.Append");
#endif
XMatrix transform = value;
if (_renderer.Gfx.PageDirection == XPageDirection.Downwards)
{
// Take chirality into account and
// invert the direction of rotation.
transform.M12 = -value.M12;
transform.M21 = -value.M21;
}
UnrealizedCtm.Prepend(transform);
WorldTransform.Prepend(value);
}
/// <summary>
/// Realizes the CTM.
/// </summary>
public void RealizeCtm()
{
//if (MustRealizeCtm)
if (!UnrealizedCtm.IsIdentity)
{
Debug.Assert(!UnrealizedCtm.IsIdentity, "mrCtm is unnecessarily set.");
const string format = Config.SignificantFigures7;
double[] matrix = UnrealizedCtm.GetElements();
// Use up to six decimal digits to prevent round up problems.
_renderer.AppendFormatArgs("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} cm\n",
matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
RealizedCtm.Prepend(UnrealizedCtm);
UnrealizedCtm = new XMatrix();
EffectiveCtm = RealizedCtm;
InverseEffectiveCtm = EffectiveCtm;
InverseEffectiveCtm.Invert();
}
}
#endregion
#region Clip Path
public void SetAndRealizeClipRect(XRect clipRect)
{
XGraphicsPath clipPath = new XGraphicsPath();
clipPath.AddRectangle(clipRect);
RealizeClipPath(clipPath);
}
public void SetAndRealizeClipPath(XGraphicsPath clipPath)
{
RealizeClipPath(clipPath);
}
void RealizeClipPath(XGraphicsPath clipPath)
{
#if CORE
DiagnosticsHelper.HandleNotImplemented("RealizeClipPath");
#endif
#if GDI
// Do not render an empty path.
if (clipPath._gdipPath.PointCount < 0)
return;
#endif
#if WPF
// Do not render an empty path.
if (clipPath._pathGeometry.Bounds.IsEmpty)
return;
#endif
_renderer.BeginGraphicMode();
RealizeCtm();
#if CORE
_renderer.AppendPath(clipPath._corePath);
#endif
#if GDI && !WPF
_renderer.AppendPath(clipPath._gdipPath);
#endif
#if WPF && !GDI
_renderer.AppendPath(clipPath._pathGeometry);
#endif
#if WPF && GDI
if (_renderer.Gfx.TargetContext == XGraphicTargetContext.GDI)
_renderer.AppendPath(clipPath._gdipPath);
else
_renderer.AppendPath(clipPath._pathGeometry);
#endif
_renderer.Append(clipPath.FillMode == XFillMode.Winding ? "W n\n" : "W* n\n");
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,44 @@
#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.Drawing.Pdf
{
[Flags]
enum DirtyFlags
{
Ctm = 0x00000001,
ClipPath = 0x00000002,
LineWidth = 0x00000010,
LineJoin = 0x00000020,
MiterLimit = 0x00000040,
StrokeFill = 0x00000070,
}
}

View File

@@ -0,0 +1,47 @@
#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.Drawing.Pdf
{
/// <summary>
/// Indicates whether we are within a BT/ET block.
/// </summary>
enum StreamMode
{
/// <summary>
/// Graphic mode. This is default.
/// </summary>
Graphic,
/// <summary>
/// Text mode.
/// </summary>
Text,
}
}

View File

@@ -0,0 +1,302 @@
#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 PdfSharp.Internal;
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents a graphics path that uses the same notation as GDI+.
/// </summary>
internal class CoreGraphicsPath
{
// Same values as GDI+ uses.
const byte PathPointTypeStart = 0; // move
const byte PathPointTypeLine = 1; // line
const byte PathPointTypeBezier = 3; // default Bezier (= cubic Bezier)
const byte PathPointTypePathTypeMask = 0x07; // type mask (lowest 3 bits).
const byte PathPointTypeCloseSubpath = 0x80; // closed flag
public CoreGraphicsPath()
{ }
public CoreGraphicsPath(CoreGraphicsPath path)
{
_points = new List<XPoint>(path._points);
_types = new List<byte>(path._types);
}
public void MoveOrLineTo(double x, double y)
{
// Make a MoveTo if there is no previous subpath or the previous subpath was closed.
// Otherwise make a LineTo.
if (_types.Count == 0 || (_types[_types.Count - 1] & PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath)
MoveTo(x, y);
else
LineTo(x, y, false);
}
public void MoveTo(double x, double y)
{
_points.Add(new XPoint(x, y));
_types.Add(PathPointTypeStart);
}
public void LineTo(double x, double y, bool closeSubpath)
{
if (_points.Count > 0 && _points[_points.Count - 1].Equals(new XPoint(x, y)))
return;
_points.Add(new XPoint(x, y));
_types.Add((byte)(PathPointTypeLine | (closeSubpath ? PathPointTypeCloseSubpath : 0)));
}
public void BezierTo(double x1, double y1, double x2, double y2, double x3, double y3, bool closeSubpath)
{
_points.Add(new XPoint(x1, y1));
_types.Add(PathPointTypeBezier);
_points.Add(new XPoint(x2, y2));
_types.Add(PathPointTypeBezier);
_points.Add(new XPoint(x3, y3));
_types.Add((byte)(PathPointTypeBezier | (closeSubpath ? PathPointTypeCloseSubpath : 0)));
}
/// <summary>
/// Adds an arc that fills exactly one quadrant (quarter) of an ellipse.
/// Just a quick hack to draw rounded rectangles before AddArc is fully implemented.
/// </summary>
public void QuadrantArcTo(double x, double y, double width, double height, int quadrant, bool clockwise)
{
if (width < 0)
throw new ArgumentOutOfRangeException("width");
if (height < 0)
throw new ArgumentOutOfRangeException("height");
double w = Const.κ * width;
double h = Const.κ * height;
double x1, y1, x2, y2, x3, y3;
switch (quadrant)
{
case 1:
if (clockwise)
{
x1 = x + w;
y1 = y - height;
x2 = x + width;
y2 = y - h;
x3 = x + width;
y3 = y;
}
else
{
x1 = x + width;
y1 = y - h;
x2 = x + w;
y2 = y - height;
x3 = x;
y3 = y - height;
}
break;
case 2:
if (clockwise)
{
x1 = x - width;
y1 = y - h;
x2 = x - w;
y2 = y - height;
x3 = x;
y3 = y - height;
}
else
{
x1 = x - w;
y1 = y - height;
x2 = x - width;
y2 = y - h;
x3 = x - width;
y3 = y;
}
break;
case 3:
if (clockwise)
{
x1 = x - w;
y1 = y + height;
x2 = x - width;
y2 = y + h;
x3 = x - width;
y3 = y;
}
else
{
x1 = x - width;
y1 = y + h;
x2 = x - w;
y2 = y + height;
x3 = x;
y3 = y + height;
}
break;
case 4:
if (clockwise)
{
x1 = x + width;
y1 = y + h;
x2 = x + w;
y2 = y + height;
x3 = x;
y3 = y + height;
}
else
{
x1 = x + w;
y1 = y + height;
x2 = x + width;
y2 = y + h;
x3 = x + width;
y3 = y;
}
break;
default:
throw new ArgumentOutOfRangeException("quadrant");
}
BezierTo(x1, y1, x2, y2, x3, y3, false);
}
/// <summary>
/// Closes the current subpath.
/// </summary>
public void CloseSubpath()
{
int count = _types.Count;
if (count > 0)
_types[count - 1] |= PathPointTypeCloseSubpath;
}
/// <summary>
/// Gets or sets the current fill mode (alternate or winding).
/// </summary>
XFillMode FillMode
{
get { return _fillMode; }
set { _fillMode = value; }
}
XFillMode _fillMode;
public void AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle)
{
XMatrix matrix = XMatrix.Identity;
List<XPoint> points = GeometryHelper.BezierCurveFromArc(x, y, width, height, startAngle, sweepAngle, PathStart.MoveTo1st, ref matrix);
int count = points.Count;
Debug.Assert((count + 2) % 3 == 0);
MoveOrLineTo(points[0].X, points[0].Y);
for (int idx = 1; idx < count; idx += 3)
BezierTo(points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y, false);
}
public void AddArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArg, XSweepDirection sweepDirection)
{
List<XPoint> points = GeometryHelper.BezierCurveFromArc(point1, point2, size, rotationAngle, isLargeArg,
sweepDirection == XSweepDirection.Clockwise, PathStart.MoveTo1st);
int count = points.Count;
Debug.Assert((count + 2) % 3 == 0);
MoveOrLineTo(points[0].X, points[0].Y);
for (int idx = 1; idx < count; idx += 3)
BezierTo(points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y, false);
}
public void AddCurve(XPoint[] points, double tension)
{
int count = points.Length;
if (count < 2)
throw new ArgumentException("AddCurve requires two or more points.", "points");
tension /= 3;
MoveOrLineTo(points[0].X, points[0].Y);
if (count == 2)
{
//figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[1], tension));
ToCurveSegment(points[0], points[0], points[1], points[1], tension);
}
else
{
//figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[2], tension));
ToCurveSegment(points[0], points[0], points[1], points[2], tension);
for (int idx = 1; idx < count - 2; idx++)
{
//figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension));
ToCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension);
}
//figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[count - 1], tension));
ToCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[count - 1], tension);
}
}
///// <summary>
///// Appends a Bézier curve for a cardinal spline through pt1 and pt2.
///// </summary>
//void ToCurveSegment(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, double tension3, bool closeSubpath)
//{
// BezierTo(
// x1 + tension3 * (x2 - x0), y1 + tension3 * (y2 - y0),
// x2 - tension3 * (x3 - x1), y2 - tension3 * (y3 - y1),
// x2, y2, closeSubpath);
//}
void ToCurveSegment(XPoint pt0, XPoint pt1, XPoint pt2, XPoint pt3, double tension3)
{
BezierTo(
pt1.X + tension3 * (pt2.X - pt0.X), pt1.Y + tension3 * (pt2.Y - pt0.Y),
pt2.X - tension3 * (pt3.X - pt1.X), pt2.Y - tension3 * (pt3.Y - pt1.Y),
pt2.X, pt2.Y,
false);
}
/// <summary>
/// Gets the path points in GDI+ style.
/// </summary>
public XPoint[] PathPoints { get { return _points.ToArray(); } }
/// <summary>
/// Gets the path types in GDI+ style.
/// </summary>
public byte[] PathTypes { get { return _types.ToArray(); } }
readonly List<XPoint> _points = new List<XPoint>();
readonly List<byte> _types = new List<byte>();
}
}

View File

@@ -0,0 +1,142 @@
#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.Globalization;
using System.IO;
using System.Text;
#if CORE || GDI
using System.Drawing;
using GdiFontFamily = System.Drawing.FontFamily;
#endif
#if WPF
using System.Windows.Media;
using System.Windows.Markup;
using WpfFontFamily = System.Windows.Media.FontFamily;
#endif
using PdfSharp.Fonts;
using PdfSharp.Fonts.OpenType;
using PdfSharp.Internal;
using PdfSharp.Pdf;
namespace PdfSharp.Drawing
{
/// <summary>
/// Global cache of all internal font family objects.
/// </summary>
internal sealed class FontFamilyCache
{
FontFamilyCache()
{
_familiesByName = new Dictionary<string, FontFamilyInternal>(StringComparer.OrdinalIgnoreCase);
}
public static FontFamilyInternal GetFamilyByName(string familyName)
{
try
{
Lock.EnterFontFactory();
FontFamilyInternal family;
Singleton._familiesByName.TryGetValue(familyName, out family);
return family;
}
finally { Lock.ExitFontFactory(); }
}
/// <summary>
/// Caches the font family or returns a previously cached one.
/// </summary>
public static FontFamilyInternal CacheOrGetFontFamily(FontFamilyInternal fontFamily)
{
try
{
Lock.EnterFontFactory();
// Recall that a font family is uniquely identified by its case insensitive name.
FontFamilyInternal existingFontFamily;
if (Singleton._familiesByName.TryGetValue(fontFamily.Name, out existingFontFamily))
{
#if DEBUG_
if (fontFamily.Name == "xxx")
fontFamily.GetType();
#endif
return existingFontFamily;
}
Singleton._familiesByName.Add(fontFamily.Name, fontFamily);
return fontFamily;
}
finally { Lock.ExitFontFactory(); }
}
/// <summary>
/// Gets the singleton.
/// </summary>
static FontFamilyCache Singleton
{
get
{
// ReSharper disable once InvertIf
if (_singleton == null)
{
try
{
Lock.EnterFontFactory();
if (_singleton == null)
_singleton = new FontFamilyCache();
}
finally { Lock.ExitFontFactory(); }
}
return _singleton;
}
}
static volatile FontFamilyCache _singleton;
internal static string GetCacheState()
{
StringBuilder state = new StringBuilder();
state.Append("====================\n");
state.Append("Font families by name\n");
Dictionary<string, FontFamilyInternal>.KeyCollection familyKeys = Singleton._familiesByName.Keys;
int count = familyKeys.Count;
string[] keys = new string[count];
familyKeys.CopyTo(keys, 0);
Array.Sort(keys, StringComparer.OrdinalIgnoreCase);
foreach (string key in keys)
state.AppendFormat(" {0}: {1}\n", key, Singleton._familiesByName[key].DebuggerDisplay);
state.Append("\n");
return state.ToString();
}
/// <summary>
/// Maps family name to internal font family.
/// </summary>
readonly Dictionary<string, FontFamilyInternal> _familiesByName;
}
}

View File

@@ -0,0 +1,208 @@
#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.Globalization;
using PdfSharp.Internal;
#if CORE || GDI
using System.Drawing;
using GdiFontFamily = System.Drawing.FontFamily;
#endif
#if WPF
using System.Windows.Media;
using System.Windows.Markup;
using WpfFontFamily = System.Windows.Media.FontFamily;
#endif
// ReSharper disable ConvertToAutoProperty
// ReSharper disable ConvertPropertyToExpressionBody
namespace PdfSharp.Drawing
{
/// <summary>
/// Internal implementation class of XFontFamily.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
internal class FontFamilyInternal
{
// Implementation Notes
// FontFamilyInternal implements an XFontFamily.
//
// * Each XFontFamily object is just a handle to its FontFamilyInternal singleton.
//
// * A FontFamilyInternal is uniquely identified by its name. It
// is not possible to use two different fonts that have the same
// family name.
FontFamilyInternal(string familyName, bool createPlatformObjects)
{
_sourceName = _name = familyName;
#if CORE || GDI
if (createPlatformObjects)
{
_gdiFontFamily = new GdiFontFamily(familyName);
_name = _gdiFontFamily.Name;
}
#endif
#if WPF && !SILVERLIGHT
if (createPlatformObjects)
{
_wpfFontFamily = new WpfFontFamily(familyName);
_name = _wpfFontFamily.FamilyNames[FontHelper.XmlLanguageEnUs];
}
#endif
#if SILVERLIGHT
_wpfFontFamily = new WpfFontFamily(_name);
_name = _wpfFontFamily.Source; // Not expected to change _name.
#endif
}
#if CORE || GDI
FontFamilyInternal(GdiFontFamily gdiFontFamily)
{
_sourceName = _name = gdiFontFamily.Name;
_gdiFontFamily = gdiFontFamily;
#if WPF
// Hybrid build only.
_wpfFontFamily = new WpfFontFamily(gdiFontFamily.Name);
#endif
}
#endif
#if WPF
FontFamilyInternal(WpfFontFamily wpfFontFamily)
{
#if !SILVERLIGHT
_sourceName = wpfFontFamily.Source;
_name = wpfFontFamily.FamilyNames[FontHelper.XmlLanguageEnUs];
_wpfFontFamily = wpfFontFamily;
#else
_sourceName = _name = wpfFontFamily.Source;
_wpfFontFamily = wpfFontFamily;
#endif
#if GDI
// Hybrid build only.
_gdiFontFamily = new GdiFontFamily(_sourceName);
#endif
}
#endif
internal static FontFamilyInternal GetOrCreateFromName(string familyName, bool createPlatformObject)
{
try
{
Lock.EnterFontFactory();
FontFamilyInternal family = FontFamilyCache.GetFamilyByName(familyName);
if (family == null)
{
family = new FontFamilyInternal(familyName, createPlatformObject);
family = FontFamilyCache.CacheOrGetFontFamily(family);
}
return family;
}
finally { Lock.ExitFontFactory(); }
}
#if CORE || GDI
internal static FontFamilyInternal GetOrCreateFromGdi(GdiFontFamily gdiFontFamily)
{
try
{
Lock.EnterFontFactory();
FontFamilyInternal fontFamily = new FontFamilyInternal(gdiFontFamily);
fontFamily = FontFamilyCache.CacheOrGetFontFamily(fontFamily);
return fontFamily;
}
finally { Lock.ExitFontFactory(); }
}
#endif
#if WPF
internal static FontFamilyInternal GetOrCreateFromWpf(WpfFontFamily wpfFontFamily)
{
FontFamilyInternal fontFamily = new FontFamilyInternal(wpfFontFamily);
fontFamily = FontFamilyCache.CacheOrGetFontFamily(fontFamily);
return fontFamily;
}
#endif
/// <summary>
/// Gets the family name this family was originally created with.
/// </summary>
public string SourceName
{
get { return _sourceName; }
}
readonly string _sourceName;
/// <summary>
/// Gets the name that uniquely identifies this font family.
/// </summary>
public string Name
{
// In WPF this is the Win32FamilyName, not the WPF family name.
get { return _name; }
}
readonly string _name;
#if CORE || GDI
/// <summary>
/// Gets the underlying GDI+ font family object.
/// Is null if the font was created by a font resolver.
/// </summary>
public GdiFontFamily GdiFamily
{
get { return _gdiFontFamily; }
}
readonly GdiFontFamily _gdiFontFamily;
#endif
#if WPF
/// <summary>
/// Gets the underlying WPF font family object.
/// Is null if the font was created by a font resolver.
/// </summary>
public WpfFontFamily WpfFamily
{
get { return _wpfFontFamily; }
}
readonly WpfFontFamily _wpfFontFamily;
#endif
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSha rper disable UnusedMember.Local
internal string DebuggerDisplay
// ReShar per restore UnusedMember.Local
{
get { return string.Format(CultureInfo.InvariantCulture, "FontFamily: '{0}'", Name); }
}
}
}

View File

@@ -0,0 +1,344 @@
#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.Globalization;
#if CORE || GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using GdiFontFamily = System.Drawing.FontFamily;
using GdiFont = System.Drawing.Font;
using GdiFontStyle = System.Drawing.FontStyle;
#endif
#if WPF
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Markup;
using WpfFontStyle = System.Windows.FontStyle;
using WpfFontWeight = System.Windows.FontWeight;
using WpfBrush = System.Windows.Media.Brush;
using WpfFontFamily = System.Windows.Media.FontFamily;
using WpfTypeface = System.Windows.Media.Typeface;
using WpfGlyphTypeface = System.Windows.Media.GlyphTypeface;
#endif
#if NETFX_CORE
using Windows.UI.Text;
using Windows.UI.Xaml.Media;
#endif
using PdfSharp.Fonts;
using PdfSharp.Fonts.OpenType;
namespace PdfSharp.Drawing
{
/// <summary>
/// A bunch of functions that do not have a better place.
/// </summary>
static class FontHelper
{
/// <summary>
/// Measure string directly from font data.
/// </summary>
public static XSize MeasureString(string text, XFont font, XStringFormat stringFormat_notyetused)
{
XSize size = new XSize();
OpenTypeDescriptor descriptor = FontDescriptorCache.GetOrCreateDescriptorFor(font) as OpenTypeDescriptor;
if (descriptor != null)
{
// Height is the sum of ascender and descender.
size.Height = (descriptor.Ascender + descriptor.Descender) * font.Size / font.UnitsPerEm;
Debug.Assert(descriptor.Ascender > 0);
bool symbol = descriptor.FontFace.cmap.symbol;
int length = text.Length;
int width = 0;
for (int idx = 0; idx < length; idx++)
{
char ch = text[idx];
// HACK: Unclear what to do here.
if (ch < 32)
continue;
if (symbol)
{
// Remap ch for symbol fonts.
ch = (char)(ch | (descriptor.FontFace.os2.usFirstCharIndex & 0xFF00)); // @@@ refactor
// Used | instead of + because of: http://pdfsharp.codeplex.com/workitem/15954
}
int glyphIndex = descriptor.CharCodeToGlyphIndex(ch);
width += descriptor.GlyphIndexToWidth(glyphIndex);
}
// What? size.Width = width * font.Size * (font.Italic ? 1 : 1) / descriptor.UnitsPerEm;
size.Width = width * font.Size / descriptor.UnitsPerEm;
// Adjust bold simulation.
if ((font.GlyphTypeface.StyleSimulations & XStyleSimulations.BoldSimulation) == XStyleSimulations.BoldSimulation)
{
// Add 2% of the em-size for each character.
// Unsure how to deal with white space. Currently count as regular character.
size.Width += length * font.Size * Const.BoldEmphasis;
}
}
Debug.Assert(descriptor != null, "No OpenTypeDescriptor.");
return size;
}
#if CORE || GDI
public static GdiFont CreateFont(string familyName, double emSize, GdiFontStyle style, out XFontSource fontSource)
{
fontSource = null;
// ReSharper disable once JoinDeclarationAndInitializer
GdiFont font;
// Use font resolver in CORE build. XPrivateFontCollection exists only in GDI and WPF build.
#if GDI
// Try private font collection first.
font = XPrivateFontCollection.TryCreateFont(familyName, emSize, style, out fontSource);
if (font != null)
{
// Get font source is different for this font because Win32 does not know it.
return font;
}
#endif
// Create ordinary Win32 font.
font = new GdiFont(familyName, (float)emSize, style, GraphicsUnit.World);
return font;
}
#endif
#if WPF
#if !SILVERLIGHT
public static readonly CultureInfo CultureInfoEnUs = CultureInfo.GetCultureInfo("en-US");
public static readonly XmlLanguage XmlLanguageEnUs = XmlLanguage.GetLanguage("en-US");
#endif
/// <summary>
/// Creates a typeface.
/// </summary>
public static Typeface CreateTypeface(WpfFontFamily family, XFontStyle style)
{
// BUG: does not work with fonts that have others than the four default styles
WpfFontStyle fontStyle = FontStyleFromStyle(style);
WpfFontWeight fontWeight = FontWeightFromStyle(style);
#if !SILVERLIGHT
WpfTypeface typeface = new WpfTypeface(family, fontStyle, fontWeight, FontStretches.Normal);
#else
WpfTypeface typeface = null;
#endif
return typeface;
}
#if !SILVERLIGHT
/// <summary>
/// Creates the formatted text.
/// </summary>
public static FormattedText CreateFormattedText(string text, Typeface typeface, double emSize, WpfBrush brush)
{
//FontFamily fontFamily = new FontFamily(testFontName);
//typeface = new Typeface(fontFamily, FontStyles.Normal, FontWeights.Bold, FontStretches.Condensed);
//List<Typeface> typefaces = new List<Typeface>(fontFamily.GetTypefaces());
//typefaces.GetType();
//typeface = s_typefaces[0];
// BUG: does not work with fonts that have others than the four default styles
FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), FlowDirection.LeftToRight, typeface, emSize, brush);
// .NET 4.0 feature new NumberSubstitution(), TextFormattingMode.Display);
//formattedText.SetFontWeight(FontWeights.Bold);
//formattedText.SetFontStyle(FontStyles.Oblique);
//formattedText.SetFontStretch(FontStretches.Condensed);
return formattedText;
}
#endif
#if SILVERLIGHT_
/// <summary>
/// Creates the TextBlock.
/// </summary>
public static TextBlock CreateTextBlock(string text, XGlyphTypeface glyphTypeface, double emSize, Brush brush)
{
TextBlock textBlock = new TextBlock();
textBlock.FontFamily = glyphTypeface.FontFamily;
textBlock.FontSource = glyphTypeface.FontSource;
textBlock.FontSize = emSize;
textBlock.FontWeight = glyphTypeface.IsBold ? FontWeights.Bold : FontWeights.Normal;
textBlock.FontStyle = glyphTypeface.IsItalic ? FontStyles.Italic : FontStyles.Normal;
textBlock.Foreground = brush;
textBlock.Text = text;
return textBlock;
}
#endif
/// <summary>
/// Simple hack to make it work...
/// Returns Normal or Italic - bold, underline and such get lost here.
/// </summary>
public static WpfFontStyle FontStyleFromStyle(XFontStyle style)
{
switch (style & XFontStyle.BoldItalic) // Mask out Underline, Strikeout, etc.
{
case XFontStyle.Regular:
return FontStyles.Normal;
case XFontStyle.Bold:
return FontStyles.Normal;
case XFontStyle.Italic:
return FontStyles.Italic;
case XFontStyle.BoldItalic:
return FontStyles.Italic;
}
return FontStyles.Normal;
}
/// <summary>
/// Simple hack to make it work...
/// </summary>
public static FontWeight FontWeightFromStyle(XFontStyle style)
{
switch (style & XFontStyle.BoldItalic) // Mask out Underline, Strikeout, etc.
{
case XFontStyle.Regular:
return FontWeights.Normal;
case XFontStyle.Bold:
return FontWeights.Bold;
case XFontStyle.Italic:
return FontWeights.Normal;
case XFontStyle.BoldItalic:
return FontWeights.Bold;
}
return FontWeights.Normal;
}
/// <summary>
/// Determines whether the style is available as a glyph type face in the specified font family, i.e. the specified style is not simulated.
/// </summary>
public static bool IsStyleAvailable(XFontFamily family, XGdiFontStyle style)
{
style &= XGdiFontStyle.BoldItalic;
#if !SILVERLIGHT
// TODOWPF: check for correctness
// FontDescriptor descriptor = FontDescriptorCache.GetOrCreateDescriptor(family.Name, style);
//XFontMetrics metrics = descriptor.FontMetrics;
// style &= XFontStyle.Regular | XFontStyle.Bold | XFontStyle.Italic | XFontStyle.BoldItalic; // same as XFontStyle.BoldItalic
List<WpfTypeface> typefaces = new List<WpfTypeface>(family.WpfFamily.GetTypefaces());
foreach (WpfTypeface typeface in typefaces)
{
bool bold = typeface.Weight == FontWeights.Bold;
bool italic = typeface.Style == FontStyles.Italic;
switch (style)
{
case XGdiFontStyle.Regular:
if (!bold && !italic)
return true;
break;
case XGdiFontStyle.Bold:
if (bold && !italic)
return true;
break;
case XGdiFontStyle.Italic:
if (!bold && italic)
return true;
break;
case XGdiFontStyle.BoldItalic:
if (bold && italic)
return true;
break;
}
////// typeface.sty
////// bool available = false;
////// GlyphTypeface glyphTypeface;
////// if (typeface.TryGetGlyphTypeface(out glyphTypeface))
////// {
//////#if DEBUG_
////// glyphTypeface.GetType();
//////#endif
////// available = true;
////// }
////// if (available)
////// return true;
}
return false;
#else
return true; // AGHACK
#endif
}
#endif
/// <summary>
/// Calculates an Adler32 checksum combined with the buffer length
/// in a 64 bit unsigned integer.
/// </summary>
public static ulong CalcChecksum(byte[] buffer)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
const uint prime = 65521; // largest prime smaller than 65536
uint s1 = 0;
uint s2 = 0;
int length = buffer.Length;
int offset = 0;
while (length > 0)
{
int n = 3800;
if (n > length)
n = length;
length -= n;
while (--n >= 0)
{
s1 += buffer[offset++];
s2 = s2 + s1;
}
s1 %= prime;
s2 %= prime;
}
//return ((ulong)((ulong)(((ulong)s2 << 16) | (ulong)s1)) << 32) | (ulong)buffer.Length;
ulong ul1 = (ulong)s2 << 16;
ul1 = ul1 | s1;
ulong ul2 = (ulong)buffer.Length;
return (ul1 << 32) | ul2;
}
public static XFontStyle CreateStyle(bool isBold, bool isItalic)
{
return (isBold ? XFontStyle.Bold : 0) | (isItalic ? XFontStyle.Italic : 0);
}
}
}

View File

@@ -0,0 +1,874 @@
#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;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows.Media;
using SysPoint = System.Windows.Point;
using SysSize = System.Windows.Size;
#endif
#if NETFX_CORE || UWP
using Windows.UI.Xaml.Media;
using SysPoint = Windows.Foundation.Point;
using SysSize = Windows.Foundation.Size;
#endif
using PdfSharp.Internal;
// ReSharper disable RedundantNameQualifier
// ReSharper disable CompareOfFloatsByEqualityOperator
namespace PdfSharp.Drawing
{
/// <summary>
/// Helper class for Geometry paths.
/// </summary>
static class GeometryHelper
{
#if WPF || NETFX_CORE
/// <summary>
/// Appends a Bézier segment from a curve.
/// </summary>
public static BezierSegment CreateCurveSegment(XPoint pt0, XPoint pt1, XPoint pt2, XPoint pt3, double tension3)
{
#if !SILVERLIGHT && !NETFX_CORE
return new BezierSegment(
new SysPoint(pt1.X + tension3 * (pt2.X - pt0.X), pt1.Y + tension3 * (pt2.Y - pt0.Y)),
new SysPoint(pt2.X - tension3 * (pt3.X - pt1.X), pt2.Y - tension3 * (pt3.Y - pt1.Y)),
new SysPoint(pt2.X, pt2.Y), true);
#else
BezierSegment bezierSegment = new BezierSegment();
bezierSegment.Point1 = new SysPoint(pt1.X + tension3 * (pt2.X - pt0.X), pt1.Y + tension3 * (pt2.Y - pt0.Y));
bezierSegment.Point2 = new SysPoint(pt2.X - tension3 * (pt3.X - pt1.X), pt2.Y - tension3 * (pt3.Y - pt1.Y));
bezierSegment.Point3 = new SysPoint(pt2.X, pt2.Y);
return bezierSegment;
#endif
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Creates a path geometry from a polygon.
/// </summary>
public static PathGeometry CreatePolygonGeometry(SysPoint[] points, XFillMode fillMode, bool closed)
{
PolyLineSegment seg = new PolyLineSegment();
int count = points.Length;
// For correct drawing the start point of the segment must not be the same as the first point.
for (int idx = 1; idx < count; idx++)
seg.Points.Add(new SysPoint(points[idx].X, points[idx].Y));
#if !SILVERLIGHT && !NETFX_CORE
seg.IsStroked = true;
#endif
PathFigure fig = new PathFigure();
fig.StartPoint = new SysPoint(points[0].X, points[0].Y);
fig.Segments.Add(seg);
fig.IsClosed = closed;
PathGeometry geo = new PathGeometry();
geo.FillRule = fillMode == XFillMode.Winding ? FillRule.Nonzero : FillRule.EvenOdd;
geo.Figures.Add(fig);
return geo;
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Creates a path geometry from a polygon.
/// </summary>
public static PolyLineSegment CreatePolyLineSegment(SysPoint[] points, XFillMode fillMode, bool closed)
{
PolyLineSegment seg = new PolyLineSegment();
int count = points.Length;
// For correct drawing the start point of the segment must not be the same as the first point.
for (int idx = 1; idx < count; idx++)
seg.Points.Add(new SysPoint(points[idx].X, points[idx].Y));
#if !SILVERLIGHT && !NETFX_CORE
seg.IsStroked = true;
#endif
return seg;
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Creates the arc segment from parameters of the GDI+ DrawArc function.
/// </summary>
public static ArcSegment CreateArcSegment(double x, double y, double width, double height, double startAngle,
double sweepAngle, out SysPoint startPoint)
{
// Normalize the angles.
double α = startAngle;
if (α < 0)
α = α + (1 + Math.Floor((Math.Abs(α) / 360))) * 360;
else if (α > 360)
α = α - Math.Floor(α / 360) * 360;
Debug.Assert(α >= 0 && α <= 360);
if (Math.Abs(sweepAngle) >= 360)
sweepAngle = Math.Sign(sweepAngle) * 360;
double β = startAngle + sweepAngle;
if (β < 0)
β = β + (1 + Math.Floor((Math.Abs(β) / 360))) * 360;
else if (β > 360)
β = β - Math.Floor(β / 360) * 360;
if (α == 0 && β < 0)
α = 360;
else if (α == 360 && β > 0)
α = 0;
// Scanling factor.
double δx = width / 2;
double δy = height / 2;
// Center of ellipse.
double x0 = x + δx;
double y0 = y + δy;
double cosα, cosβ, sinα, sinβ;
if (width == height)
{
// Circular arc needs no correction.
α = α * Calc.Deg2Rad;
β = β * Calc.Deg2Rad;
}
else
{
// Elliptic arc needs the angles to be adjusted such that the scaling transformation is compensated.
α = α * Calc.Deg2Rad;
sinα = Math.Sin(α);
if (Math.Abs(sinα) > 1E-10)
{
if (α < Math.PI)
α = Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα));
else
α = 3 * Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα));
}
//α = Calc.πHalf - Math.Atan(δy * Math.Cos(α) / (δx * sinα));
β = β * Calc.Deg2Rad;
sinβ = Math.Sin(β);
if (Math.Abs(sinβ) > 1E-10)
{
if (β < Math.PI)
β = Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ));
else
β = 3 * Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ));
}
//β = Calc.πHalf - Math.Atan(δy * Math.Cos(β) / (δx * sinβ));
}
sinα = Math.Sin(α);
cosα = Math.Cos(α);
sinβ = Math.Sin(β);
cosβ = Math.Cos(β);
startPoint = new SysPoint(x0 + δx * cosα, y0 + δy * sinα);
SysPoint destPoint = new SysPoint(x0 + δx * cosβ, y0 + δy * sinβ);
SysSize size = new SysSize(δx, δy);
bool isLargeArc = Math.Abs(sweepAngle) >= 180;
SweepDirection sweepDirection = sweepAngle > 0 ? SweepDirection.Clockwise : SweepDirection.Counterclockwise;
#if !SILVERLIGHT && !NETFX_CORE
bool isStroked = true;
ArcSegment seg = new ArcSegment(destPoint, size, 0, isLargeArc, sweepDirection, isStroked);
#else
ArcSegment seg = new ArcSegment();
seg.Point = destPoint;
seg.Size = size;
seg.RotationAngle = 0;
seg.IsLargeArc = isLargeArc;
seg.SweepDirection = sweepDirection;
// isStroked does not exist in Silverlight 3
#endif
return seg;
}
#endif
/// <summary>
/// Creates between 1 and 5 Béziers curves from parameters specified like in GDI+.
/// </summary>
public static List<XPoint> BezierCurveFromArc(double x, double y, double width, double height, double startAngle, double sweepAngle,
PathStart pathStart, ref XMatrix matrix)
{
List<XPoint> points = new List<XPoint>();
// Normalize the angles.
double α = startAngle;
if (α < 0)
α = α + (1 + Math.Floor((Math.Abs(α) / 360))) * 360;
else if (α > 360)
α = α - Math.Floor(α / 360) * 360;
Debug.Assert(α >= 0 && α <= 360);
double β = sweepAngle;
if (β < -360)
β = -360;
else if (β > 360)
β = 360;
if (α == 0 && β < 0)
α = 360;
else if (α == 360 && β > 0)
α = 0;
// Is it possible that the arc is small starts and ends in same quadrant?
bool smallAngle = Math.Abs(β) <= 90;
β = α + β;
if (β < 0)
β = β + (1 + Math.Floor((Math.Abs(β) / 360))) * 360;
bool clockwise = sweepAngle > 0;
int startQuadrant = Quadrant(α, true, clockwise);
int endQuadrant = Quadrant(β, false, clockwise);
if (startQuadrant == endQuadrant && smallAngle)
AppendPartialArcQuadrant(points, x, y, width, height, α, β, pathStart, matrix);
else
{
int currentQuadrant = startQuadrant;
bool firstLoop = true;
do
{
if (currentQuadrant == startQuadrant && firstLoop)
{
double ξ = currentQuadrant * 90 + (clockwise ? 90 : 0);
AppendPartialArcQuadrant(points, x, y, width, height, α, ξ, pathStart, matrix);
}
else if (currentQuadrant == endQuadrant)
{
double ξ = currentQuadrant * 90 + (clockwise ? 0 : 90);
AppendPartialArcQuadrant(points, x, y, width, height, ξ, β, PathStart.Ignore1st, matrix);
}
else
{
double ξ1 = currentQuadrant * 90 + (clockwise ? 0 : 90);
double ξ2 = currentQuadrant * 90 + (clockwise ? 90 : 0);
AppendPartialArcQuadrant(points, x, y, width, height, ξ1, ξ2, PathStart.Ignore1st, matrix);
}
// Don't stop immediately if arc is greater than 270 degrees.
if (currentQuadrant == endQuadrant && smallAngle)
break;
smallAngle = true;
if (clockwise)
currentQuadrant = currentQuadrant == 3 ? 0 : currentQuadrant + 1;
else
currentQuadrant = currentQuadrant == 0 ? 3 : currentQuadrant - 1;
firstLoop = false;
} while (true);
}
return points;
}
/// <summary>
/// Calculates the quadrant (0 through 3) of the specified angle. If the angle lies on an edge
/// (0, 90, 180, etc.) the result depends on the details how the angle is used.
/// </summary>
static int Quadrant(double φ, bool start, bool clockwise)
{
Debug.Assert(φ >= 0);
if (φ > 360)
φ = φ - Math.Floor(φ / 360) * 360;
int quadrant = (int)(φ / 90);
if (quadrant * 90 == φ)
{
if ((start && !clockwise) || (!start && clockwise))
quadrant = quadrant == 0 ? 3 : quadrant - 1;
}
else
quadrant = clockwise ? ((int)Math.Floor(φ / 90)) % 4 : (int)Math.Floor(φ / 90);
return quadrant;
}
/// <summary>
/// Appends a Bézier curve for an arc within a full quadrant.
/// </summary>
static void AppendPartialArcQuadrant(List<XPoint> points, double x, double y, double width, double height, double α, double β, PathStart pathStart, XMatrix matrix)
{
Debug.Assert(α >= 0 && α <= 360);
Debug.Assert(β >= 0);
if (β > 360)
β = β - Math.Floor(β / 360) * 360;
Debug.Assert(Math.Abs(α - β) <= 90);
// Scanling factor.
double δx = width / 2;
double δy = height / 2;
// Center of ellipse.
double x0 = x + δx;
double y0 = y + δy;
// We have the following quarters:
// |
// 2 | 3
// ----+-----
// 1 | 0
// |
// If the angles lie in quarter 2 or 3, their values are subtracted by 180 and the
// resulting curve is reflected at the center. This algorithm works as expected (simply tried out).
// There may be a mathematically more elegant solution...
bool reflect = false;
if (α >= 180 && β >= 180)
{
α -= 180;
β -= 180;
reflect = true;
}
double cosα, cosβ, sinα, sinβ;
if (width == height)
{
// Circular arc needs no correction.
α = α * Calc.Deg2Rad;
β = β * Calc.Deg2Rad;
}
else
{
// Elliptic arc needs the angles to be adjusted such that the scaling transformation is compensated.
α = α * Calc.Deg2Rad;
sinα = Math.Sin(α);
if (Math.Abs(sinα) > 1E-10)
α = Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα));
β = β * Calc.Deg2Rad;
sinβ = Math.Sin(β);
if (Math.Abs(sinβ) > 1E-10)
β = Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ));
}
double κ = 4 * (1 - Math.Cos((α - β) / 2)) / (3 * Math.Sin((β - α) / 2));
sinα = Math.Sin(α);
cosα = Math.Cos(α);
sinβ = Math.Sin(β);
cosβ = Math.Cos(β);
//XPoint pt1, pt2, pt3;
if (!reflect)
{
// Calculation for quarter 0 and 1.
switch (pathStart)
{
case PathStart.MoveTo1st:
points.Add(matrix.Transform(new XPoint(x0 + δx * cosα, y0 + δy * sinα)));
break;
case PathStart.LineTo1st:
points.Add(matrix.Transform(new XPoint(x0 + δx * cosα, y0 + δy * sinα)));
break;
case PathStart.Ignore1st:
break;
}
points.Add(matrix.Transform(new XPoint(x0 + δx * (cosα - κ * sinα), y0 + δy * (sinα + κ * cosα))));
points.Add(matrix.Transform(new XPoint(x0 + δx * (cosβ + κ * sinβ), y0 + δy * (sinβ - κ * cosβ))));
points.Add(matrix.Transform(new XPoint(x0 + δx * cosβ, y0 + δy * sinβ)));
}
else
{
// Calculation for quarter 2 and 3.
switch (pathStart)
{
case PathStart.MoveTo1st:
points.Add(matrix.Transform(new XPoint(x0 - δx * cosα, y0 - δy * sinα)));
break;
case PathStart.LineTo1st:
points.Add(matrix.Transform(new XPoint(x0 - δx * cosα, y0 - δy * sinα)));
break;
case PathStart.Ignore1st:
break;
}
points.Add(matrix.Transform(new XPoint(x0 - δx * (cosα - κ * sinα), y0 - δy * (sinα + κ * cosα))));
points.Add(matrix.Transform(new XPoint(x0 - δx * (cosβ + κ * sinβ), y0 - δy * (sinβ - κ * cosβ))));
points.Add(matrix.Transform(new XPoint(x0 - δx * cosβ, y0 - δy * sinβ)));
}
}
/// <summary>
/// Creates between 1 and 5 Béziers curves from parameters specified like in WPF.
/// </summary>
public static List<XPoint> BezierCurveFromArc(XPoint point1, XPoint point2, XSize size,
double rotationAngle, bool isLargeArc, bool clockwise, PathStart pathStart)
{
// See also http://www.charlespetzold.com/blog/blog.xml from January 2, 2008:
// http://www.charlespetzold.com/blog/2008/01/Mathematics-of-ArcSegment.html
double δx = size.Width;
double δy = size.Height;
Debug.Assert(δx * δy > 0);
double factor = δy / δx;
bool isCounterclockwise = !clockwise;
// Adjust for different radii and rotation angle.
XMatrix matrix = new XMatrix();
matrix.RotateAppend(-rotationAngle);
matrix.ScaleAppend(δy / δx, 1);
XPoint pt1 = matrix.Transform(point1);
XPoint pt2 = matrix.Transform(point2);
// Get info about chord that connects both points.
XPoint midPoint = new XPoint((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2);
XVector vect = pt2 - pt1;
double halfChord = vect.Length / 2;
// Get vector from chord to center.
XVector vectRotated;
// (comparing two Booleans here!)
if (isLargeArc == isCounterclockwise)
vectRotated = new XVector(-vect.Y, vect.X);
else
vectRotated = new XVector(vect.Y, -vect.X);
vectRotated.Normalize();
// Distance from chord to center.
double centerDistance = Math.Sqrt(δy * δy - halfChord * halfChord);
if (double.IsNaN(centerDistance))
centerDistance = 0;
// Calculate center point.
XPoint center = midPoint + centerDistance * vectRotated;
// Get angles from center to the two points.
double α = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X);
double β = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X);
// (another comparison of two Booleans!)
if (isLargeArc == (Math.Abs(β - α) < Math.PI))
{
if (α < β)
α += 2 * Math.PI;
else
β += 2 * Math.PI;
}
// Invert matrix for final point calculation.
matrix.Invert();
double sweepAngle = β - α;
// Let the algorithm of GDI+ DrawArc to Bézier curves do the rest of the job
return BezierCurveFromArc(center.X - δx * factor, center.Y - δy, 2 * δx * factor, 2 * δy,
α / Calc.Deg2Rad, sweepAngle / Calc.Deg2Rad, pathStart, ref matrix);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The code below comes from WPF source code, because I was not able to convert an arc
// to a series of Bezier curves exactly the way WPF renders the arc. I tested my own code
// with the MinBar Test Suite from QualityLogic and could not find out why it does not match.
// My Bezier curves came very close to the arc, but in some cases they do simply not match.
// So I gave up and use the WPF code.
#if WPF || NETFX_CORE
// ReSharper disable InconsistentNaming
const double FUZZ = 1e-6; // Relative 0
// ReSharper restore InconsistentNaming
//+-------------------------------------------------------------------------------------------------
//
// Function: GetArcAngle
//
// Synopsis: Get the number of Bezier arcs, and sine & cosine of each
//
// Notes: This is a private utility used by ArcToBezier
// We break the arc into pieces so that no piece will span more than 90 degrees.
// The input points are on the unit circle
//
//-------------------------------------------------------------------------------------------------
public static void
GetArcAngle(
XPoint startPoint, // Start point
XPoint endPoint, // End point
bool isLargeArc, // Choose the larger of the 2 possible arcs if TRUE
//SweepDirection sweepDirection, // Direction n which to sweep the arc.
bool isClockwise,
out double cosArcAngle, // Cosine of a the sweep angle of one arc piece
out double sinArcAngle, // Sine of a the sweep angle of one arc piece
out int pieces) // Out: The number of pieces
{
double angle;
// The points are on the unit circle, so:
cosArcAngle = startPoint.X * endPoint.X + startPoint.Y * endPoint.Y;
sinArcAngle = startPoint.X * endPoint.Y - startPoint.Y * endPoint.X;
if (cosArcAngle >= 0)
{
if (isLargeArc)
{
// The angle is between 270 and 360 degrees, so
pieces = 4;
}
else
{
// The angle is between 0 and 90 degrees, so
pieces = 1;
return; // We already have the cosine and sine of the angle
}
}
else
{
if (isLargeArc)
{
// The angle is between 180 and 270 degrees, so
pieces = 3;
}
else
{
// The angle is between 90 and 180 degrees, so
pieces = 2;
}
}
// We have to chop the arc into the computed number of pieces. For cPieces=2 and 4 we could
// have uses the half-angle trig formulas, but for pieces=3 it requires solving a cubic
// equation; the performance difference is not worth the extra code, so we'll get the angle,
// divide it, and get its sine and cosine.
Debug.Assert(pieces > 0);
angle = Math.Atan2(sinArcAngle, cosArcAngle);
if (isClockwise)
{
if (angle < 0)
angle += Math.PI * 2;
}
else
{
if (angle > 0)
angle -= Math.PI * 2;
}
angle /= pieces;
cosArcAngle = Math.Cos(angle);
sinArcAngle = Math.Sin(angle);
}
/******************************************************************************\
*
* Function Description:
*
* Get the distance from a circular arc's endpoints to the control points of the
* Bezier arc that approximates it, as a fraction of the arc's radius.
*
* Since the result is relative to the arc's radius, it depends strictly on the
* arc's angle. The arc is assumed to be of 90 degrees of less, so the angle is
* determined by the cosine of that angle, which is derived from rDot = the dot
* product of two radius vectors. We need the Bezier curve that agrees with
* the arc's points and tangents at the ends and midpoint. Here we compute the
* distance from the curve's endpoints to its control points.
*
* Since we are looking for the relative distance, we can work on the unit
* circle. Place the center of the circle at the origin, and put the X axis as
* the bisector between the 2 vectors. Let a be the angle between the vectors.
* Then the X coordinates of the 1st & last points are cos(a/2). Let x be the X
* coordinate of the 2nd & 3rd points. At t=1/2 we have a point at (1,0).
* But the terms of the polynomial there are all equal:
*
* (1-t)^3 = t*(1-t)^2 = 2^2*(1-t) = t^3 = 1/8,
*
* so from the Bezier formula there we have:
*
* 1 = (1/8) * (cos(a/2) + 3x + 3x + cos(a/2)),
* hence
* x = (1 - cos(a/2)) / 3
*
* The X difference between that and the 1st point is:
*
* DX = x - cos(a/2) = 4(1 - cos(a/2)) / 3.
*
* But DX = distance / sin(a/2), hence the distance is
*
* dist = (4/3)*(1 - cos(a/2)) / sin(a/2).
*
* Created: 5/29/2001 [....]
*
/*****************************************************************************/
public static double
GetBezierDistance( // Return the distance as a fraction of the radius
double dot, // In: The dot product of the two radius vectors
double radius) // In: The radius of the arc's circle (optional=1)
{
double radSquared = radius * radius; // Squared radius
Debug.Assert(dot >= -radSquared * .1); // angle < 90 degrees
Debug.Assert(dot <= radSquared * 1.1); // as dot product of 2 radius vectors
double dist = 0; // Acceptable fallback value
/* Rather than the angle a, we are given rDot = R^2 * cos(a), so we
multiply top and bottom by R:
dist = (4/3)*(R - Rcos(a/2)) / Rsin(a/2)
and use some trig:
__________
cos(a/2) = \/1 + cos(a) / 2
________________ __________
R*cos(a/2) = \/R^2 + R^2 cos(a) / 2 = \/R^2 + rDot / 2 */
double cos = (radSquared + dot) / 2; // =(R*cos(a))^2
if (cos < 0)
return dist;
// __________________
// R*sin(a/2) = \/R^2 - R^2 cos(a/2)
double sin = radSquared - cos; // =(R*sin(a))^2
if (sin <= 0)
return dist;
sin = Math.Sqrt(sin); // = R*cos(a)
cos = Math.Sqrt(cos); // = R*sin(a)
dist = 4 * (radius - cos) / 3;
if (dist <= sin * FUZZ)
dist = 0;
else
dist = 4 * (radius - cos) / sin / 3;
return dist;
}
//+-------------------------------------------------------------------------------------------------
//
// Function: ArcToBezier
//
// Synopsis: Compute the Bezier approximation of an arc
//
// Notes: This utilitycomputes the Bezier approximation for an elliptical arc as it is defined
// in the SVG arc spec. The ellipse from which the arc is carved is axis-aligned in its
// own coordinates, and defined there by its x and y radii. The rotation angle defines
// how the ellipse's axes are rotated relative to our x axis. The start and end points
// define one of 4 possible arcs; the sweep and large-arc flags determine which one of
// these arcs will be chosen. See SVG spec for details.
//
// Returning pieces = 0 indicates a line instead of an arc
// pieces = -1 indicates that the arc degenerates to a point
//
//--------------------------------------------------------------------------------------------------
public static PointCollection ArcToBezier(double xStart, double yStart, double xRadius, double yRadius, double rotationAngle,
bool isLargeArc, bool isClockwise, double xEnd, double yEnd, out int pieces)
{
double cosArcAngle, sinArcAngle, xCenter, yCenter, r, bezDist;
XVector vecToBez1, vecToBez2;
XMatrix matToEllipse;
double fuzz2 = FUZZ * FUZZ;
bool isZeroCenter = false;
pieces = -1;
// In the following, the line segment between between the arc's start and
// end points is referred to as "the chord".
// Transform 1: Shift the origin to the chord's midpoint
double x = (xEnd - xStart) / 2;
double y = (yEnd - yStart) / 2;
double halfChord2 = x * x + y * y; // (half chord length)^2
// Degenerate case: single point
if (halfChord2 < fuzz2)
{
// The chord degeneartes to a point, the arc will be ignored
return null;
}
// Degenerate case: straight line
if (!AcceptRadius(halfChord2, fuzz2, ref xRadius) || !AcceptRadius(halfChord2, fuzz2, ref yRadius))
{
// We have a zero radius, add a straight line segment instead of an arc
pieces = 0;
return null;
}
if (xRadius == 0 || yRadius == 0)
{
// We have a zero radius, add a straight line segment instead of an arc
pieces = 0;
return null;
}
// Transform 2: Rotate to the ellipse's coordinate system
rotationAngle = -rotationAngle * Calc.Deg2Rad;
double cos = Math.Cos(rotationAngle);
double sin = Math.Sin(rotationAngle);
r = x * cos - y * sin;
y = x * sin + y * cos;
x = r;
// Transform 3: Scale so that the ellipse will become a unit circle
x /= xRadius;
y /= yRadius;
// We get to the center of that circle along a verctor perpendicular to the chord
// from the origin, which is the chord's midpoint. By Pythagoras, the length of that
// vector is sqrt(1 - (half chord)^2).
halfChord2 = x * x + y * y; // now in the circle coordinates
if (halfChord2 > 1)
{
// The chord is longer than the circle's diameter; we scale the radii uniformly so
// that the chord will be a diameter. The center will then be the chord's midpoint,
// which is now the origin.
r = Math.Sqrt(halfChord2);
xRadius *= r;
yRadius *= r;
xCenter = yCenter = 0;
isZeroCenter = true;
// Adjust the unit-circle coordinates x and y
x /= r;
y /= r;
}
else
{
// The length of (-y,x) or (x,-y) is sqrt(rHalfChord2), and we want a vector
// of length sqrt(1 - rHalfChord2), so we'll multiply it by:
r = Math.Sqrt((1 - halfChord2) / halfChord2);
//if (isLargeArc != (eSweepDirection == SweepDirection.Clockwise))
if (isLargeArc != isClockwise)
// Going to the center from the origin=chord-midpoint
{
// in the direction of (-y, x)
xCenter = -r * y;
yCenter = r * x;
}
else
{
// in the direction of (y, -x)
xCenter = r * y;
yCenter = -r * x;
}
}
// Transformation 4: shift the origin to the center of the circle, which then becomes
// the unit circle. Since the chord's midpoint is the origin, the start point is (-x, -y)
// and the endpoint is (x, y).
XPoint ptStart = new XPoint(-x - xCenter, -y - yCenter);
XPoint ptEnd = new XPoint(x - xCenter, y - yCenter);
// Set up the matrix that will take us back to our coordinate system. This matrix is
// the inverse of the combination of transformation 1 thru 4.
matToEllipse = new XMatrix(cos * xRadius, -sin * xRadius,
sin * yRadius, cos * yRadius,
(xEnd + xStart) / 2, (yEnd + yStart) / 2);
if (!isZeroCenter)
{
// Prepend the translation that will take the origin to the circle's center
matToEllipse.OffsetX += (matToEllipse.M11 * xCenter + matToEllipse.M21 * yCenter);
matToEllipse.OffsetY += (matToEllipse.M12 * xCenter + matToEllipse.M22 * yCenter);
}
// Get the sine & cosine of the angle that will generate the arc pieces
GetArcAngle(ptStart, ptEnd, isLargeArc, isClockwise, out cosArcAngle, out sinArcAngle, out pieces);
// Get the vector to the first Bezier control point
bezDist = GetBezierDistance(cosArcAngle, 1);
//if (eSweepDirection == SweepDirection.Counterclockwise)
if (!isClockwise)
bezDist = -bezDist;
vecToBez1 = new XVector(-bezDist * ptStart.Y, bezDist * ptStart.X);
PointCollection result = new PointCollection();
// Add the arc pieces, except for the last
for (int idx = 1; idx < pieces; idx++)
{
// Get the arc piece's endpoint
XPoint ptPieceEnd = new XPoint(ptStart.X * cosArcAngle - ptStart.Y * sinArcAngle, ptStart.X * sinArcAngle + ptStart.Y * cosArcAngle);
vecToBez2 = new XVector(-bezDist * ptPieceEnd.Y, bezDist * ptPieceEnd.X);
result.Add(matToEllipse.Transform(ptStart + vecToBez1));
result.Add(matToEllipse.Transform(ptPieceEnd - vecToBez2));
result.Add(matToEllipse.Transform(ptPieceEnd));
// Move on to the next arc
ptStart = ptPieceEnd;
vecToBez1 = vecToBez2;
}
// Last arc - we know the endpoint
vecToBez2 = new XVector(-bezDist * ptEnd.Y, bezDist * ptEnd.X);
result.Add(matToEllipse.Transform(ptStart + vecToBez1));
result.Add(matToEllipse.Transform(ptEnd - vecToBez2));
result.Add(new XPoint(xEnd, yEnd));
return result;
}
/// <summary>
/// Gets a value indicating whether radius large enough compared to the chord length.
/// </summary>
/// <param name="halfChord2">(1/2 chord length)squared </param>
/// <param name="fuzz2">Squared fuzz.</param>
/// <param name="radius">The radius to accept (or not).</param>
static bool AcceptRadius(double halfChord2, double fuzz2, ref double radius)
{
Debug.Assert(halfChord2 >= fuzz2); // Otherewise we have no guarantee that the radius is not 0, and we need to divide by the radius
bool accept = radius * radius > halfChord2 * fuzz2;
if (accept)
{
if (radius < 0)
radius = 0;
}
return accept;
}
#endif
}
}

View File

@@ -0,0 +1,98 @@
#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;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents a stack of XGraphicsState and XGraphicsContainer objects.
/// </summary>
internal class GraphicsStateStack
{
public GraphicsStateStack(XGraphics gfx)
{
_current = new InternalGraphicsState(gfx);
}
public int Count
{
get { return _stack.Count; }
}
public void Push(InternalGraphicsState state)
{
_stack.Push(state);
state.Pushed();
}
public int Restore(InternalGraphicsState state)
{
if (!_stack.Contains(state))
throw new ArgumentException("State not on stack.", "state");
if (state.Invalid)
throw new ArgumentException("State already restored.", "state");
int count = 1;
InternalGraphicsState top = _stack.Pop();
top.Popped();
while (top != state)
{
count++;
state.Invalid = true;
top = _stack.Pop();
top.Popped();
}
state.Invalid = true;
return count;
}
public InternalGraphicsState Current
{
get
{
if (_stack.Count == 0)
return _current;
return _stack.Peek();
}
}
readonly InternalGraphicsState _current;
readonly Stack<InternalGraphicsState> _stack = new Stack<InternalGraphicsState>();
}
}

View File

@@ -0,0 +1,190 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents an abstract drawing surface for PdfPages.
/// </summary>
internal interface IXGraphicsRenderer
{
void Close();
#region Drawing
///// <summary>
///// Fills the entire drawing surface with the specified color.
///// </summary>
//[Obsolete("Will be removed.")]
//void Clear(XColor color);
/// <summary>
/// Draws a straight line.
/// </summary>
void DrawLine(XPen pen, double x1, double y1, double x2, double y2);
/// <summary>
/// Draws a series of straight lines.
/// </summary>
void DrawLines(XPen pen, XPoint[] points);
/// <summary>
/// Draws a B<>zier spline.
/// </summary>
void DrawBezier(XPen pen, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
/// <summary>
/// Draws a series of B<>zier splines.
/// </summary>
void DrawBeziers(XPen pen, XPoint[] points);
/// <summary>
/// Draws a cardinal spline.
/// </summary>
void DrawCurve(XPen pen, XPoint[] points, double tension);
/// <summary>
/// Draws an arc.
/// </summary>
void DrawArc(XPen pen, double x, double y, double width, double height, double startAngle, double sweepAngle);
/// <summary>
/// Draws a rectangle.
/// </summary>
void DrawRectangle(XPen pen, XBrush brush, double x, double y, double width, double height);
/// <summary>
/// Draws a series of rectangles.
/// </summary>
void DrawRectangles(XPen pen, XBrush brush, XRect[] rects);
/// <summary>
/// Draws a rectangle with rounded corners.
/// </summary>
void DrawRoundedRectangle(XPen pen, XBrush brush, double x, double y, double width, double height, double ellipseWidth, double ellipseHeight);
/// <summary>
/// Draws an ellipse.
/// </summary>
void DrawEllipse(XPen pen, XBrush brush, double x, double y, double width, double height);
/// <summary>
/// Draws a polygon.
/// </summary>
void DrawPolygon(XPen pen, XBrush brush, XPoint[] points, XFillMode fillmode);
/// <summary>
/// Draws a pie.
/// </summary>
void DrawPie(XPen pen, XBrush brush, double x, double y, double width, double height, double startAngle, double sweepAngle);
/// <summary>
/// Draws a cardinal spline.
/// </summary>
void DrawClosedCurve(XPen pen, XBrush brush, XPoint[] points, double tension, XFillMode fillmode);
/// <summary>
/// Draws a graphical path.
/// </summary>
void DrawPath(XPen pen, XBrush brush, XGraphicsPath path);
/// <summary>
/// Draws a series of glyphs identified by the specified text and font.
/// </summary>
void DrawString(string s, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format);
/// <summary>
/// Draws an image.
/// </summary>
void DrawImage(XImage image, double x, double y, double width, double height);
void DrawImage(XImage image, XRect destRect, XRect srcRect, XGraphicsUnit srcUnit);
#endregion
#region Save and Restore
/// <summary>
/// Saves the current graphics state without changing it.
/// </summary>
void Save(XGraphicsState state);
/// <summary>
/// Restores the specified graphics state.
/// </summary>
void Restore(XGraphicsState state);
/// <summary>
///
/// </summary>
void BeginContainer(XGraphicsContainer container, XRect dstrect, XRect srcrect, XGraphicsUnit unit);
/// <summary>
///
/// </summary>
void EndContainer(XGraphicsContainer container);
#endregion
#region Transformation
/// <summary>
/// Gets or sets the transformation matrix.
/// </summary>
//XMatrix Transform {get; set;}
void AddTransform(XMatrix transform, XMatrixOrder matrixOrder);
#endregion
#region Clipping
void SetClip(XGraphicsPath path, XCombineMode combineMode);
void ResetClip();
#endregion
#region Miscellaneous
/// <summary>
/// Writes a comment to the output stream. Comments have no effect on the rendering of the output.
/// </summary>
void WriteComment(string comment);
#endregion
}
}

View File

@@ -0,0 +1,136 @@
#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;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Helper class for processing image files.
/// </summary>
static class ImageHelper
{
#if WPF && GDI
/// <summary>
/// Creates a WPF bitmap source from an GDI image.
/// </summary>
public static BitmapSource CreateBitmapSource(Image image)
{
MemoryStream stream = new MemoryStream();
//int width = image.Width;
//int height = image.Height;
//double dpiX = image.HorizontalResolution;
//double dpiY = image.VerticalResolution;
//System.Windows.Media.PixelFormat pixelformat = PixelFormats.Default;
BitmapSource bitmapSource = null;
try
{
string guid = image.RawFormat.Guid.ToString("B").ToUpper();
switch (guid)
{
case "{B96B3CAA-0728-11D3-9D7B-0000F81EF32E}": // memoryBMP
case "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}": // bmp
image.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
BmpBitmapDecoder bmpDecoder = new BmpBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
bitmapSource = bmpDecoder.Frames[0];
break;
case "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}": // png
image.Save(stream, ImageFormat.Png);
stream.Position = 0;
PngBitmapDecoder pngDecoder = new PngBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
bitmapSource = pngDecoder.Frames[0];
break;
case "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}": // jpeg
image.Save(stream, ImageFormat.Jpeg);
JpegBitmapDecoder jpegDecoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
stream.Position = 0;
bitmapSource = jpegDecoder.Frames[0];
break;
case "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}": // gif
image.Save(stream, ImageFormat.Gif);
GifBitmapDecoder gifDecoder = new GifBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
stream.Position = 0;
bitmapSource = gifDecoder.Frames[0];
break;
case "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}": // tiff
image.Save(stream, ImageFormat.Tiff);
TiffBitmapDecoder tiffDecoder = new TiffBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
stream.Position = 0;
bitmapSource = tiffDecoder.Frames[0];
break;
case "{B96B3CB5-0728-11D3-9D7B-0000F81EF32E}": // icon
image.Save(stream, ImageFormat.Icon);
IconBitmapDecoder iconDecoder = new IconBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
stream.Position = 0;
bitmapSource = iconDecoder.Frames[0];
break;
case "{B96B3CAC-0728-11D3-9D7B-0000F81EF32E}": // emf
case "{B96B3CAD-0728-11D3-9D7B-0000F81EF32E}": // wmf
case "{B96B3CB2-0728-11D3-9D7B-0000F81EF32E}": // exif
case "{B96B3CB3-0728-11D3-9D7B-0000F81EF32E}": // photoCD
case "{B96B3CB4-0728-11D3-9D7B-0000F81EF32E}": // flashPIX
default:
throw new InvalidOperationException("Unsupported image format.");
}
}
catch (Exception ex)
{
Debug.WriteLine("ImageHelper.CreateBitmapSource failed:" + ex.Message);
}
finally
{
//if (stream != null)
// stream.Close();
}
return bitmapSource;
}
#endif
}
}

View 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
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
// In GDI+ the functions Save/Restore, BeginContainer/EndContainer, Transform, SetClip and ResetClip
// can be combined in any order. E.g. you can set a clip region, save the graphics state, empty the
// clip region and draw without clipping. Then you can restore to the previous clip region. With PDF
// this behavior is hard to implement. To solve this problem I first an automaton that keeps track
// of all clipping paths and the current transformation when the clip path was set. The automation
// manages a PDF graphics state stack to calculate the desired bahaviour. It also takes into consideration
// not to multiply with inverse matrixes when the user sets a new transformation matrix.
// After the design works on pager I decided not to implement it because it is much to large-scale.
// Instead I lay down some rules how to use the XGraphics class.
//
// * Before you set a transformation matrix save the graphics state (Save) or begin a new container
// (BeginContainer).
//
// * Instead of resetting the transformation matrix, call Restore or EndContainer. If you reset the
// transformation, in PDF must be multiplied with the inverse matrix. That leads to round off errors
// because in PDF file only 3 digits are used and Acrobat internally uses fixed point numbers (until
// versioin 6 or 7 I think).
//
// * When no clip path is defined, you can set or intersect a new path.
//
// * When a clip path is already defined, you can always intersect with a new one (wich leads in general
// to a smaller clip region).
//
// * When a clip path is already defined, you can only reset it to the empty region (ResetClip) when
// the graphics state stack is at the same position as it had when the clip path was defined. Otherwise
// an error occurs.
//
// Keeping these rules leads to easy to read code and best results in PDF output.
/// <summary>
/// Represents the internal state of an XGraphics object.
/// Used when the state is saved and restored.
/// </summary>
internal class InternalGraphicsState
{
public InternalGraphicsState(XGraphics gfx)
{
_gfx = gfx;
}
public InternalGraphicsState(XGraphics gfx, XGraphicsState state)
{
_gfx = gfx;
State = state;
State.InternalState = this;
}
public InternalGraphicsState(XGraphics gfx, XGraphicsContainer container)
{
_gfx = gfx;
container.InternalState = this;
}
/// <summary>
/// Gets or sets the current transformation matrix.
/// </summary>
public XMatrix Transform
{
get { return _transform; }
set { _transform = value; }
}
XMatrix _transform;
/// <summary>
/// Called after this instanced was pushed on the internal graphics stack.
/// </summary>
public void Pushed()
{
#if GDI
// Nothing to do.
#endif
#if WPF && !SILVERLIGHT
// Nothing to do.
#endif
#if SILVERLIGHT
// Save current level of Canvas stack.
_stackLevel = _gfx._dc.Level;
// Create new Canvas for subsequent UIElements.
_gfx._dc.PushCanvas();
#endif
}
/// <summary>
/// Called after this instanced was popped from the internal graphics stack.
/// </summary>
public void Popped()
{
Invalid = true;
#if GDI
// Nothing to do.
#endif
#if WPF && !SILVERLIGHT
// Pop all objects pushed in this state.
if (_gfx.TargetContext == XGraphicTargetContext.WPF)
{
for (int idx = 0; idx < _transformPushLevel; idx++)
_gfx._dc.Pop();
_transformPushLevel = 0;
for (int idx = 0; idx < _geometryPushLevel; idx++)
_gfx._dc.Pop();
_geometryPushLevel = 0;
}
#endif
#if SILVERLIGHT
// Pop all Canvas objects created in this state.
_gfx._dc.Pop(_gfx._dc.Level - _stackLevel);
#endif
}
public bool Invalid;
#if GDI_
/// <summary>
/// The GDI+ GraphicsState if contructed from XGraphicsState.
/// </summary>
public GraphicsState GdiGraphicsState;
#endif
#if WPF && !SILVERLIGHT
public void PushTransform(MatrixTransform transform)
{
_gfx._dc.PushTransform(transform);
_transformPushLevel++;
}
int _transformPushLevel;
public void PushClip(Geometry geometry)
{
_gfx._dc.PushClip(geometry);
_geometryPushLevel++;
}
int _geometryPushLevel;
#endif
#if SILVERLIGHT
public void PushTransform(MatrixTransform transform)
{
_gfx._dc.PushTransform(transform);
}
public void PushClip(Geometry geometry)
{
_gfx._dc.PushClip(geometry);
}
int _stackLevel;
#endif
readonly XGraphics _gfx;
internal XGraphicsState State;
}
}

View File

@@ -0,0 +1,108 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
using PdfSharp.Pdf;
namespace PdfSharp.Drawing
{
/// <summary>
/// Specifies details about how the font is used in PDF creation.
/// </summary>
public class XPdfFontOptions
{
internal XPdfFontOptions() { }
/// <summary>
/// Initializes a new instance of the <see cref="XPdfFontOptions"/> class.
/// </summary>
[Obsolete("Must not specify an embedding option anymore.")]
public XPdfFontOptions(PdfFontEncoding encoding, PdfFontEmbedding embedding)
{
_fontEncoding = encoding;
}
/// <summary>
/// Initializes a new instance of the <see cref="XPdfFontOptions"/> class.
/// </summary>
public XPdfFontOptions(PdfFontEncoding encoding)
{
_fontEncoding = encoding;
}
/// <summary>
/// Initializes a new instance of the <see cref="XPdfFontOptions"/> class.
/// </summary>
[Obsolete("Must not specify an embedding option anymore.")]
public XPdfFontOptions(PdfFontEmbedding embedding)
{
_fontEncoding = PdfFontEncoding.WinAnsi;
}
/// <summary>
/// Gets a value indicating the font embedding.
/// </summary>
public PdfFontEmbedding FontEmbedding
{
get { return PdfFontEmbedding.Always; }
}
/// <summary>
/// Gets a value indicating how the font is encoded.
/// </summary>
public PdfFontEncoding FontEncoding
{
get { return _fontEncoding; }
}
readonly PdfFontEncoding _fontEncoding;
/// <summary>
/// Gets the default options with WinAnsi encoding and always font embedding.
/// </summary>
public static XPdfFontOptions WinAnsiDefault
{
get { return new XPdfFontOptions(PdfFontEncoding.WinAnsi); }
}
/// <summary>
/// Gets the default options with Unicode encoding and always font embedding.
/// </summary>
public static XPdfFontOptions UnicodeDefault
{
get { return new XPdfFontOptions(PdfFontEncoding.Unicode); }
}
}
}

View File

@@ -0,0 +1,70 @@
#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 CORE
#endif
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Provides functionality to load a bitmap image encoded in a specific format.
/// </summary>
public class XBitmapDecoder
{
internal XBitmapDecoder()
{ }
/// <summary>
/// Gets a new instance of the PNG image decoder.
/// </summary>
public static XBitmapDecoder GetPngDecoder()
{
return new XPngBitmapDecoder();
}
}
internal sealed class XPngBitmapDecoder : XBitmapDecoder
{
internal XPngBitmapDecoder()
{ }
}
}

View File

@@ -0,0 +1,122 @@
#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.Internal;
#if CORE
#endif
#if CORE_WITH_GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Provides functionality to save a bitmap image in a specific format.
/// </summary>
public abstract class XBitmapEncoder
{
internal XBitmapEncoder()
{
// Prevent external deriving.
}
/// <summary>
/// Gets a new instance of the PNG image encoder.
/// </summary>
public static XBitmapEncoder GetPngEncoder()
{
return new XPngBitmapEncoder();
}
/// <summary>
/// Gets or sets the bitmap source to be encoded.
/// </summary>
public XBitmapSource Source
{
get { return _source; }
set { _source = value; }
}
XBitmapSource _source;
/// <summary>
/// When overridden in a derived class saves the image on the specified stream
/// in the respective format.
/// </summary>
public abstract void Save(Stream stream);
}
internal sealed class XPngBitmapEncoder : XBitmapEncoder
{
internal XPngBitmapEncoder()
{ }
/// <summary>
/// Saves the image on the specified stream in PNG format.
/// </summary>
public override void Save(Stream stream)
{
if (Source == null)
throw new InvalidOperationException("No image source.");
#if CORE_WITH_GDI || GDI
if (Source.AssociatedGraphics != null)
{
Source.DisassociateWithGraphics();
Debug.Assert(Source.AssociatedGraphics == null);
}
try
{
Lock.EnterGdiPlus();
Source._gdiImage.Save(stream, ImageFormat.Png);
}
finally { Lock.ExitGdiPlus(); }
#endif
#if WPF
DiagnosticsHelper.ThrowNotImplementedException("Save...");
#endif
}
}
}

View File

@@ -0,0 +1,109 @@
#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 CORE
#endif
#if CORE_WITH_GDI
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using PdfSharp.Internal;
#endif
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using PdfSharp.Internal;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#if !GDI
using PdfSharp.Internal;
#endif
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
using PdfSharp.Internal;
#endif
// WPFHACK
#pragma warning disable 0169
#pragma warning disable 0649
namespace PdfSharp.Drawing
{
/// <summary>
/// Defines a pixel based bitmap image.
/// </summary>
public sealed class XBitmapImage : XBitmapSource
{
// TODO: Move code from XImage to this class.
/// <summary>
/// Initializes a new instance of the <see cref="XBitmapImage"/> class.
/// </summary>
internal XBitmapImage(int width, int height)
{
#if GDI || CORE_WITH_GDI
try
{
Lock.EnterGdiPlus();
// Create a default 24 bit ARGB bitmap.
_gdiImage = new Bitmap(width, height);
}
finally { Lock.ExitGdiPlus(); }
#endif
#if WPF
DiagnosticsHelper.ThrowNotImplementedException("CreateBitmap");
#endif
#if NETFX_CORE
DiagnosticsHelper.ThrowNotImplementedException("CreateBitmap");
#endif
#if CORE || GDI && !WPF // Prevent unreachable code error
Initialize();
#endif
}
/// <summary>
/// Creates a default 24 bit ARGB bitmap with the specified pixel size.
/// </summary>
public static XBitmapSource CreateBitmap(int width, int height)
{
// Create a default 24 bit ARGB bitmap.
return new XBitmapImage(width, height);
}
}
}

View File

@@ -0,0 +1,123 @@
#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 CORE
#endif
using System.Diagnostics;
using PdfSharp.Internal;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#endif
// WPFHACK
#pragma warning disable 0169
#pragma warning disable 0649
namespace PdfSharp.Drawing
{
/// <summary>
/// Defines an abstract base class for pixel based images.
/// </summary>
public abstract class XBitmapSource : XImage
{
// TODO: Move code from XImage to this class.
/// <summary>
/// Gets the width of the image in pixels.
/// </summary>
public override int PixelWidth
{
get
{
#if (CORE_WITH_GDI || GDI) && !WPF
try
{
Lock.EnterGdiPlus();
return _gdiImage.Width;
}
finally { Lock.ExitGdiPlus(); }
#endif
#if GDI && WPF
int gdiWidth = _gdiImage.Width;
int wpfWidth = _wpfImage.PixelWidth;
Debug.Assert(gdiWidth == wpfWidth);
return wpfWidth;
#endif
#if WPF && !GDI
return _wpfImage.PixelWidth;
#endif
#if NETFX_CORE || UWP
return _wrtImage.PixelWidth;
#endif
}
}
/// <summary>
/// Gets the height of the image in pixels.
/// </summary>
public override int PixelHeight
{
get
{
#if (CORE_WITH_GDI || GDI) && !WPF
try
{
Lock.EnterGdiPlus();
return _gdiImage.Height;
}
finally { Lock.ExitGdiPlus(); }
#endif
#if GDI && WPF
int gdiHeight = _gdiImage.Height;
int wpfHeight = _wpfImage.PixelHeight;
Debug.Assert(gdiHeight == wpfHeight);
return wpfHeight;
#endif
#if WPF && !GDI
return _wpfImage.PixelHeight;
#endif
#if NETFX_CORE || UWP
return _wrtImage.PixelHeight;
#endif
}
}
}
}

View File

@@ -0,0 +1,87 @@
#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;
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
#if UWP
using Microsoft.Graphics.Canvas.Brushes;
using UwpColor = Windows.UI.Color;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Classes derived from this abstract base class define objects used to fill the
/// interiors of paths.
/// </summary>
public abstract class XBrush
{
#if GDI
internal abstract System.Drawing.Brush RealizeGdiBrush();
#if UseGdiObjects
/// <summary>
/// Converts from a System.Drawing.Brush.
/// </summary>
public static implicit operator XBrush(Brush brush)
{
XBrush xbrush;
SolidBrush solidBrush;
LinearGradientBrush lgBrush;
if ((solidBrush = brush as SolidBrush) != null)
{
xbrush = new XSolidBrush(solidBrush.Color);
}
else if ((lgBrush = brush as LinearGradientBrush) != null)
{
// TODO: xbrush = new LinearGradientBrush(lgBrush.Rectangle, lgBrush.co(solidBrush.Color);
throw new NotImplementedException("Brush type not yet supported by PDFsharp.");
}
else
{
throw new NotImplementedException("Brush type not supported by PDFsharp.");
}
return xbrush;
}
#endif
#endif
#if WPF
internal abstract System.Windows.Media.Brush RealizeWpfBrush();
#endif
#if UWP
internal abstract ICanvasBrush RealizeCanvasBrush();
#endif
}
}

1595
PdfSharp/Drawing/XBrushes.cs Normal file

File diff suppressed because it is too large Load Diff

824
PdfSharp/Drawing/XColor.cs Normal file
View File

@@ -0,0 +1,824 @@
#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.Globalization;
using System.ComponentModel;
#if GDI
using System.Drawing;
#endif
#if WPF
using WpfColor = System.Windows.Media.Color;
#endif
#if UWP
using UwpColor = Windows.UI.Color;
#endif
// ReSharper disable RedundantNameQualifier
namespace PdfSharp.Drawing
{
///<summary>
/// Represents a RGB, CMYK, or gray scale color.
/// </summary>
[DebuggerDisplay("clr=(A={A}, R={R}, G={G}, B={B} C={C}, M={M}, Y={Y}, K={K})")]
public struct XColor
{
XColor(uint argb)
{
_cs = XColorSpace.Rgb;
_a = (byte)((argb >> 24) & 0xff) / 255f;
_r = (byte)((argb >> 16) & 0xff);
_g = (byte)((argb >> 8) & 0xff);
_b = (byte)(argb & 0xff);
_c = 0;
_m = 0;
_y = 0;
_k = 0;
_gs = 0;
RgbChanged();
//_cs.GetType(); // Suppress warning
}
XColor(byte alpha, byte red, byte green, byte blue)
{
_cs = XColorSpace.Rgb;
_a = alpha / 255f;
_r = red;
_g = green;
_b = blue;
_c = 0;
_m = 0;
_y = 0;
_k = 0;
_gs = 0;
RgbChanged();
//_cs.GetType(); // Suppress warning
}
XColor(double alpha, double cyan, double magenta, double yellow, double black)
{
_cs = XColorSpace.Cmyk;
_a = (float)(alpha > 1 ? 1 : (alpha < 0 ? 0 : alpha));
_c = (float)(cyan > 1 ? 1 : (cyan < 0 ? 0 : cyan));
_m = (float)(magenta > 1 ? 1 : (magenta < 0 ? 0 : magenta));
_y = (float)(yellow > 1 ? 1 : (yellow < 0 ? 0 : yellow));
_k = (float)(black > 1 ? 1 : (black < 0 ? 0 : black));
_r = 0;
_g = 0;
_b = 0;
_gs = 0f;
CmykChanged();
}
XColor(double cyan, double magenta, double yellow, double black)
: this(1.0, cyan, magenta, yellow, black)
{ }
XColor(double gray)
{
_cs = XColorSpace.GrayScale;
if (gray < 0)
_gs = 0;
else if (gray > 1)
_gs = 1;
else
_gs = (float)gray;
_a = 1;
_r = 0;
_g = 0;
_b = 0;
_c = 0;
_m = 0;
_y = 0;
_k = 0;
GrayChanged();
}
#if GDI
XColor(System.Drawing.Color color)
: this(color.A, color.R, color.G, color.B)
{ }
#endif
#if WPF
XColor(WpfColor color)
: this(color.A, color.R, color.G, color.B)
{ }
#endif
#if GDI
XColor(KnownColor knownColor)
: this(System.Drawing.Color.FromKnownColor(knownColor))
{ }
#endif
#if UWP
XColor(UwpColor color)
: this(color.A, color.R, color.G, color.B)
{ }
#endif
internal XColor(XKnownColor knownColor)
: this(XKnownColorTable.KnownColorToArgb(knownColor))
{ }
/// <summary>
/// Creates an XColor structure from a 32-bit ARGB value.
/// </summary>
public static XColor FromArgb(int argb)
{
return new XColor((byte)(argb >> 24), (byte)(argb >> 16), (byte)(argb >> 8), (byte)(argb));
}
/// <summary>
/// Creates an XColor structure from a 32-bit ARGB value.
/// </summary>
public static XColor FromArgb(uint argb)
{
return new XColor((byte)(argb >> 24), (byte)(argb >> 16), (byte)(argb >> 8), (byte)(argb));
}
// from System.Drawing.Color
//public static XColor FromArgb(int alpha, Color baseColor);
//public static XColor FromArgb(int red, int green, int blue);
//public static XColor FromArgb(int alpha, int red, int green, int blue);
//public static XColor FromKnownColor(KnownColor color);
//public static XColor FromName(string name);
/// <summary>
/// Creates an XColor structure from the specified 8-bit color values (red, green, and blue).
/// The alpha value is implicitly 255 (fully opaque).
/// </summary>
public static XColor FromArgb(int red, int green, int blue)
{
CheckByte(red, "red");
CheckByte(green, "green");
CheckByte(blue, "blue");
return new XColor(255, (byte)red, (byte)green, (byte)blue);
}
/// <summary>
/// Creates an XColor structure from the four ARGB component (alpha, red, green, and blue) values.
/// </summary>
public static XColor FromArgb(int alpha, int red, int green, int blue)
{
CheckByte(alpha, "alpha");
CheckByte(red, "red");
CheckByte(green, "green");
CheckByte(blue, "blue");
return new XColor((byte)alpha, (byte)red, (byte)green, (byte)blue);
}
#if GDI
/// <summary>
/// Creates an XColor structure from the specified System.Drawing.Color.
/// </summary>
public static XColor FromArgb(System.Drawing.Color color)
{
return new XColor(color);
}
#endif
#if WPF
/// <summary>
/// Creates an XColor structure from the specified System.Drawing.Color.
/// </summary>
public static XColor FromArgb(WpfColor color)
{
return new XColor(color);
}
#endif
#if UWP
/// <summary>
/// Creates an XColor structure from the specified Windows.UI.Color.
/// </summary>
public static XColor FromArgb(UwpColor color)
{
return new XColor(color);
}
#endif
/// <summary>
/// Creates an XColor structure from the specified alpha value and color.
/// </summary>
public static XColor FromArgb(int alpha, XColor color)
{
color.A = ((byte)alpha) / 255.0;
return color;
}
#if GDI
/// <summary>
/// Creates an XColor structure from the specified alpha value and color.
/// </summary>
public static XColor FromArgb(int alpha, System.Drawing.Color color)
{
// Cast required to use correct constructor.
return new XColor((byte)alpha, color.R, color.G, color.B);
}
#endif
#if WPF
/// <summary>
/// Creates an XColor structure from the specified alpha value and color.
/// </summary>
public static XColor FromArgb(int alpha, WpfColor color)
{
// Cast required to use correct constructor.
return new XColor((byte)alpha, color.R, color.G, color.B);
}
#endif
#if UWP
/// <summary>
/// Creates an XColor structure from the specified alpha value and color.
/// </summary>
public static XColor FromArgb(int alpha, UwpColor color)
{
// Cast required to use correct constructor.
return new XColor((byte)alpha, color.R, color.G, color.B);
}
#endif
/// <summary>
/// Creates an XColor structure from the specified CMYK values.
/// </summary>
public static XColor FromCmyk(double cyan, double magenta, double yellow, double black)
{
return new XColor(cyan, magenta, yellow, black);
}
/// <summary>
/// Creates an XColor structure from the specified CMYK values.
/// </summary>
public static XColor FromCmyk(double alpha, double cyan, double magenta, double yellow, double black)
{
return new XColor(alpha, cyan, magenta, yellow, black);
}
/// <summary>
/// Creates an XColor structure from the specified gray value.
/// </summary>
public static XColor FromGrayScale(double grayScale)
{
return new XColor(grayScale);
}
/// <summary>
/// Creates an XColor from the specified pre-defined color.
/// </summary>
public static XColor FromKnownColor(XKnownColor color)
{
return new XColor(color);
}
#if GDI
/// <summary>
/// Creates an XColor from the specified pre-defined color.
/// </summary>
public static XColor FromKnownColor(KnownColor color)
{
return new XColor(color);
}
#endif
/// <summary>
/// Creates an XColor from the specified name of a pre-defined color.
/// </summary>
public static XColor FromName(string name)
{
#if GDI
// The implementation in System.Drawing.dll is interesting. It uses a ColorConverter
// with hash tables, locking mechanisms etc. I'm not sure what problems that solves.
// So I don't use the source, but the reflection.
try
{
return new XColor((KnownColor)Enum.Parse(typeof(KnownColor), name, true));
}
// ReSharper disable EmptyGeneralCatchClause
catch { }
// ReSharper restore EmptyGeneralCatchClause
#endif
return Empty;
}
/// <summary>
/// Gets or sets the color space to be used for PDF generation.
/// </summary>
public XColorSpace ColorSpace
{
get { return _cs; }
set
{
if (!Enum.IsDefined(typeof(XColorSpace), value))
throw new InvalidEnumArgumentException("value", (int)value, typeof(XColorSpace));
_cs = value;
}
}
/// <summary>
/// Indicates whether this XColor structure is uninitialized.
/// </summary>
public bool IsEmpty
{
get { return this == Empty; }
}
#if GDI
#if UseGdiObjects
/// <summary>
/// Implicit conversion from Color to XColor
/// </summary>
public static implicit operator XColor(Color color)
{
return new XColor(color);
}
#endif
///<summary>
/// Creates a System.Drawing.Color object from this color.
/// </summary>
public System.Drawing.Color ToGdiColor()
{
return System.Drawing.Color.FromArgb((int)(_a * 255), _r, _g, _b);
}
#endif
#if WPF
///<summary>
/// Creates a WpfColor object from this color.
/// </summary>
public WpfColor ToWpfColor()
{
return WpfColor.FromArgb((byte)(_a * 255), _r, _g, _b);
}
#endif
#if UWP
///<summary>
/// Creates a Windows.UI.Color object from this color.
/// </summary>
public UwpColor ToUwpColor()
{
return UwpColor.FromArgb((byte)(_a * 255), _r, _g, _b);
}
#endif
/// <summary>
/// Determines whether the specified object is a Color structure and is equivalent to this
/// Color structure.
/// </summary>
public override bool Equals(object obj)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
if (obj is XColor)
{
XColor color = (XColor)obj;
if (_r == color._r && _g == color._g && _b == color._b &&
_c == color._c && _m == color._m && _y == color._y && _k == color._k &&
_gs == color._gs)
{
return _a == color._a;
}
}
return false;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
// ReSharper disable NonReadonlyFieldInGetHashCode
return ((byte)(_a * 255)) ^ _r ^ _g ^ _b;
// ReSharper restore NonReadonlyFieldInGetHashCode
}
/// <summary>
/// Determines whether two colors are equal.
/// </summary>
public static bool operator ==(XColor left, XColor right)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
if (left._r == right._r && left._g == right._g && left._b == right._b &&
left._c == right._c && left._m == right._m && left._y == right._y && left._k == right._k &&
left._gs == right._gs)
{
return left._a == right._a;
}
return false;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Determines whether two colors are not equal.
/// </summary>
public static bool operator !=(XColor left, XColor right)
{
return !(left == right);
}
/// <summary>
/// Gets a value indicating whether this color is a known color.
/// </summary>
public bool IsKnownColor
{
get { return XKnownColorTable.IsKnownColor(Argb); }
}
/// <summary>
/// Gets the hue-saturation-brightness (HSB) hue value, in degrees, for this color.
/// </summary>
/// <returns>The hue, in degrees, of this color. The hue is measured in degrees, ranging from 0 through 360, in HSB color space.</returns>
public double GetHue()
{
// ReSharper disable CompareOfFloatsByEqualityOperator
if ((_r == _g) && (_g == _b))
return 0;
double value1 = _r / 255.0;
double value2 = _g / 255.0;
double value3 = _b / 255.0;
double value7 = 0;
double value4 = value1;
double value5 = value1;
if (value2 > value4)
value4 = value2;
if (value3 > value4)
value4 = value3;
if (value2 < value5)
value5 = value2;
if (value3 < value5)
value5 = value3;
double value6 = value4 - value5;
if (value1 == value4)
value7 = (value2 - value3) / value6;
else if (value2 == value4)
value7 = 2f + ((value3 - value1) / value6);
else if (value3 == value4)
value7 = 4f + ((value1 - value2) / value6);
value7 *= 60;
if (value7 < 0)
value7 += 360;
return value7;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Gets the hue-saturation-brightness (HSB) saturation value for this color.
/// </summary>
/// <returns>The saturation of this color. The saturation ranges from 0 through 1, where 0 is grayscale and 1 is the most saturated.</returns>
public double GetSaturation()
{
// ReSharper disable CompareOfFloatsByEqualityOperator
double value1 = _r / 255.0;
double value2 = _g / 255.0;
double value3 = _b / 255.0;
double value7 = 0;
double value4 = value1;
double value5 = value1;
if (value2 > value4)
value4 = value2;
if (value3 > value4)
value4 = value3;
if (value2 < value5)
value5 = value2;
if (value3 < value5)
value5 = value3;
if (value4 == value5)
return value7;
double value6 = (value4 + value5) / 2;
if (value6 <= 0.5)
return (value4 - value5) / (value4 + value5);
return (value4 - value5) / ((2f - value4) - value5);
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Gets the hue-saturation-brightness (HSB) brightness value for this color.
/// </summary>
/// <returns>The brightness of this color. The brightness ranges from 0 through 1, where 0 represents black and 1 represents white.</returns>
public double GetBrightness()
{
double value1 = _r / 255.0;
double value2 = _g / 255.0;
double value3 = _b / 255.0;
double value4 = value1;
double value5 = value1;
if (value2 > value4)
value4 = value2;
if (value3 > value4)
value4 = value3;
if (value2 < value5)
value5 = value2;
if (value3 < value5)
value5 = value3;
return (value4 + value5) / 2;
}
///<summary>
/// One of the RGB values changed; recalculate other color representations.
/// </summary>
void RgbChanged()
{
// ReSharper disable LocalVariableHidesMember
_cs = XColorSpace.Rgb;
int c = 255 - _r;
int m = 255 - _g;
int y = 255 - _b;
int k = Math.Min(c, Math.Min(m, y));
if (k == 255)
_c = _m = _y = 0;
else
{
float black = 255f - k;
_c = (c - k) / black;
_m = (m - k) / black;
_y = (y - k) / black;
}
_k = _gs = k / 255f;
// ReSharper restore LocalVariableHidesMember
}
///<summary>
/// One of the CMYK values changed; recalculate other color representations.
/// </summary>
void CmykChanged()
{
_cs = XColorSpace.Cmyk;
float black = _k * 255;
float factor = 255f - black;
_r = (byte)(255 - Math.Min(255f, _c * factor + black));
_g = (byte)(255 - Math.Min(255f, _m * factor + black));
_b = (byte)(255 - Math.Min(255f, _y * factor + black));
_gs = (float)(1 - Math.Min(1.0, 0.3f * _c + 0.59f * _m + 0.11 * _y + _k));
}
///<summary>
/// The gray scale value changed; recalculate other color representations.
/// </summary>
void GrayChanged()
{
_cs = XColorSpace.GrayScale;
_r = (byte)(_gs * 255);
_g = (byte)(_gs * 255);
_b = (byte)(_gs * 255);
_c = 0;
_m = 0;
_y = 0;
_k = 1 - _gs;
}
// Properties
/// <summary>
/// Gets or sets the alpha value the specifies the transparency.
/// The value is in the range from 1 (opaque) to 0 (completely transparent).
/// </summary>
public double A
{
get { return _a; }
set
{
if (value < 0)
_a = 0;
else if (value > 1)
_a = 1;
else
_a = (float)value;
}
}
/// <summary>
/// Gets or sets the red value.
/// </summary>
public byte R
{
get { return _r; }
set { _r = value; RgbChanged(); }
}
/// <summary>
/// Gets or sets the green value.
/// </summary>
public byte G
{
get { return _g; }
set { _g = value; RgbChanged(); }
}
/// <summary>
/// Gets or sets the blue value.
/// </summary>
public byte B
{
get { return _b; }
set { _b = value; RgbChanged(); }
}
/// <summary>
/// Gets the RGB part value of the color. Internal helper function.
/// </summary>
internal uint Rgb
{
get { return ((uint)_r << 16) | ((uint)_g << 8) | _b; }
}
/// <summary>
/// Gets the ARGB part value of the color. Internal helper function.
/// </summary>
internal uint Argb
{
get { return ((uint)(_a * 255) << 24) | ((uint)_r << 16) | ((uint)_g << 8) | _b; }
}
/// <summary>
/// Gets or sets the cyan value.
/// </summary>
public double C
{
get { return _c; }
set
{
if (value < 0)
_c = 0;
else if (value > 1)
_c = 1;
else
_c = (float)value;
CmykChanged();
}
}
/// <summary>
/// Gets or sets the magenta value.
/// </summary>
public double M
{
get { return _m; }
set
{
if (value < 0)
_m = 0;
else if (value > 1)
_m = 1;
else
_m = (float)value;
CmykChanged();
}
}
/// <summary>
/// Gets or sets the yellow value.
/// </summary>
public double Y
{
get { return _y; }
set
{
if (value < 0)
_y = 0;
else if (value > 1)
_y = 1;
else
_y = (float)value;
CmykChanged();
}
}
/// <summary>
/// Gets or sets the black (or key) value.
/// </summary>
public double K
{
get { return _k; }
set
{
if (value < 0)
_k = 0;
else if (value > 1)
_k = 1;
else
_k = (float)value;
CmykChanged();
}
}
/// <summary>
/// Gets or sets the gray scale value.
/// </summary>
// ReSharper disable InconsistentNaming
public double GS
// ReSharper restore InconsistentNaming
{
get { return _gs; }
set
{
if (value < 0)
_gs = 0;
else if (value > 1)
_gs = 1;
else
_gs = (float)value;
GrayChanged();
}
}
/// <summary>
/// Represents the null color.
/// </summary>
public static XColor Empty;
///<summary>
/// Special property for XmlSerializer only.
/// </summary>
public string RgbCmykG
{
get
{
return String.Format(CultureInfo.InvariantCulture,
"{0};{1};{2};{3};{4};{5};{6};{7};{8}", _r, _g, _b, _c, _m, _y, _k, _gs, _a);
}
set
{
string[] values = value.Split(';');
_r = byte.Parse(values[0], CultureInfo.InvariantCulture);
_g = byte.Parse(values[1], CultureInfo.InvariantCulture);
_b = byte.Parse(values[2], CultureInfo.InvariantCulture);
_c = float.Parse(values[3], CultureInfo.InvariantCulture);
_m = float.Parse(values[4], CultureInfo.InvariantCulture);
_y = float.Parse(values[5], CultureInfo.InvariantCulture);
_k = float.Parse(values[6], CultureInfo.InvariantCulture);
_gs = float.Parse(values[7], CultureInfo.InvariantCulture);
_a = float.Parse(values[8], CultureInfo.InvariantCulture);
}
}
static void CheckByte(int val, string name)
{
if (val < 0 || val > 0xFF)
throw new ArgumentException(PSSR.InvalidValue(val, name, 0, 255));
}
XColorSpace _cs;
float _a; // alpha
byte _r; // \
byte _g; // |--- RGB
byte _b; // /
float _c; // \
float _m; // |--- CMYK
float _y; // |
float _k; // /
float _gs; // >--- gray scale
}
}

View File

@@ -0,0 +1,361 @@
#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.Globalization;
using System.ComponentModel;
using System.Threading;
#if GDI
using System.Drawing;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Manages the localization of the color class.
/// </summary>
public class XColorResourceManager
{
/// <summary>
/// Initializes a new instance of the <see cref="XColorResourceManager"/> class.
/// </summary>
public XColorResourceManager()
#if !NETFX_CORE && !UWP
: this(Thread.CurrentThread.CurrentUICulture)
#else
: this(CultureInfo.CurrentUICulture)
#endif
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XColorResourceManager"/> class.
/// </summary>
/// <param name="cultureInfo">The culture info.</param>
public XColorResourceManager(CultureInfo cultureInfo)
{
_cultureInfo = cultureInfo;
}
readonly CultureInfo _cultureInfo;
#if DEBUG_
static public void Test()
{
int kcc = XKnownColorTable.colorTable.Length;
for (int idx = 0; idx < kcc; idx++)
{
uint argb = XKnownColorTable.colorTable[idx];
ColorResourceInfo info = GetColorInfo((XKnownColor)idx);
if ((int)info.KnownColor == -1)
{
kcc.GetType();
}
else
{
if (argb != info.Argb)
{
kcc.GetType();
}
}
}
for (int idx = 0; idx < colorInfos.Length; idx++)
{
ColorResourceInfo c2 = colorInfos[idx];
if (c2.Argb != c2.Color.Rgb)
c2.GetType();
}
}
#endif
/// <summary>
/// Gets a known color from an ARGB value. Throws an ArgumentException if the value is not a known color.
/// </summary>
public static XKnownColor GetKnownColor(uint argb)
{
XKnownColor knownColor = XKnownColorTable.GetKnownColor(argb);
if ((int)knownColor == -1)
throw new ArgumentException("The argument is not a known color", "argb");
return knownColor;
}
/// <summary>
/// Gets all known colors.
/// </summary>
/// <param name="includeTransparent">Indicates whether to include the color Transparent.</param>
public static XKnownColor[] GetKnownColors(bool includeTransparent)
{
int count = colorInfos.Length;
XKnownColor[] knownColor = new XKnownColor[count - (includeTransparent ? 0 : 1)];
for (int idxIn = includeTransparent ? 0 : 1, idxOut = 0; idxIn < count; idxIn++, idxOut++)
knownColor[idxOut] = colorInfos[idxIn].KnownColor;
return knownColor;
}
/// <summary>
/// Converts a known color to a localized color name.
/// </summary>
public string ToColorName(XKnownColor knownColor)
{
ColorResourceInfo colorInfo = GetColorInfo(knownColor);
// Currently German only
if (_cultureInfo.TwoLetterISOLanguageName == "de")
return colorInfo.NameDE;
return colorInfo.Name;
}
/// <summary>
/// Converts a color to a localized color name or an ARGB value.
/// </summary>
public string ToColorName(XColor color)
{
string name;
if (color.IsKnownColor)
name = ToColorName(XKnownColorTable.GetKnownColor(color.Argb));
else
name = String.Format("{0}, {1}, {2}, {3}", (int)(255 * color.A), color.R, color.G, color.B);
return name;
}
static ColorResourceInfo GetColorInfo(XKnownColor knownColor)
{
for (int idx = 0; idx < colorInfos.Length; idx++)
{
ColorResourceInfo colorInfo = colorInfos[idx];
if (colorInfo.KnownColor == knownColor)
return colorInfo;
}
throw new InvalidEnumArgumentException("Enum is not an XKnownColor.");
}
// I found no official translation for the 140 pre-defined colors. Some folks made their own translations.
// http://unnecessary.de/wuest/farbtab/farbtabelle-w.html
// http://blog.patrickkempf.de/archives/2004/04/10/html-farben/
// http://www.grafikwunder.de/Grafikecke/Farbtabelle/farbtabelle-006.php
// Silke changed some German translations (women know more colors than men :-)
internal static ColorResourceInfo[] colorInfos = new ColorResourceInfo[]
{
new ColorResourceInfo(XKnownColor.Transparent, XColors.Transparent, 0x00FFFFFF, "Transparent", "Transparent"),
new ColorResourceInfo(XKnownColor.Black, XColors.Black, 0xFF000000, "Black", "Schwarz"),
new ColorResourceInfo(XKnownColor.DarkSlateGray, XColors.DarkSlateGray, 0xFF8FBC8F, "Darkslategray", "Dunkles Schiefergrau"),
new ColorResourceInfo(XKnownColor.SlateGray, XColors.SlateGray, 0xFF708090, "Slategray", "Schiefergrau"),
new ColorResourceInfo(XKnownColor.LightSlateGray, XColors.LightSlateGray, 0xFF778899, "Lightslategray", "Helles Schiefergrau"),
new ColorResourceInfo(XKnownColor.LightSteelBlue, XColors.LightSteelBlue, 0xFFB0C4DE, "Lightsteelblue", "Helles Stahlblau"),
//new ColorResourceInfo(XKnownColor.DimGray, XColors.DimGray, 0xFF696969, "Dimgray", "Mattes Grau"),
new ColorResourceInfo(XKnownColor.DimGray, XColors.DimGray, 0xFF696969, "Dimgray", "Gedecktes Grau"),
new ColorResourceInfo(XKnownColor.Gray, XColors.Gray, 0xFF808080, "Gray", "Grau"),
new ColorResourceInfo(XKnownColor.DarkGray, XColors.DarkGray, 0xFFA9A9A9, "Darkgray", "Dunkelgrau"),
new ColorResourceInfo(XKnownColor.Silver, XColors.Silver, 0xFFC0C0C0, "Silver", "Silber"),
//new ColorResourceInfo(XKnownColor.Gainsboro, XColors.Gainsboro, 0xFFDCDCDC, "Gainsboro", "Gainsboro"),
new ColorResourceInfo(XKnownColor.Gainsboro, XColors.Gainsboro, 0xFFDCDCDC, "Gainsboro", "Helles Blaugrau"),
//new ColorResourceInfo(XKnownColor.WhiteSmoke, XColors.WhiteSmoke, 0xFFF5F5F5, "Whitesmoke", "Rauchiges Weiß"),
new ColorResourceInfo(XKnownColor.WhiteSmoke, XColors.WhiteSmoke, 0xFFF5F5F5, "Whitesmoke", "Rauchweiß"),
//new ColorResourceInfo(XKnownColor.GhostWhite, XColors.GhostWhite, 0xFFF8F8FF, "Ghostwhite", "Geisterweiß"),
new ColorResourceInfo(XKnownColor.GhostWhite, XColors.GhostWhite, 0xFFF8F8FF, "Ghostwhite", "Schattenweiß"),
new ColorResourceInfo(XKnownColor.White, XColors.White, 0xFFFFFFFF, "White", "Weiß"),
new ColorResourceInfo(XKnownColor.Snow, XColors.Snow, 0xFFFFFAFA, "Snow", "Schneeweiß"),
new ColorResourceInfo(XKnownColor.Ivory, XColors.Ivory, 0xFFFFFFF0, "Ivory", "Elfenbein"),
new ColorResourceInfo(XKnownColor.FloralWhite, XColors.FloralWhite, 0xFFFFFAF0, "Floralwhite", "Blütenweiß"),
new ColorResourceInfo(XKnownColor.SeaShell, XColors.SeaShell, 0xFFFFF5EE, "Seashell", "Muschel"),
//new ColorResourceInfo(XKnownColor.OldLace, XColors.OldLace, 0xFFFDF5E6, "Oldlace", "Altgold"),
new ColorResourceInfo(XKnownColor.OldLace, XColors.OldLace, 0xFFFDF5E6, "Oldlace", "Altweiß"),
//new ColorResourceInfo(XKnownColor.Linen, XColors.Linen, 0xFFFAF0E6, "Linen", "Leinenfarbe"),
new ColorResourceInfo(XKnownColor.Linen, XColors.Linen, 0xFFFAF0E6, "Linen", "Leinen"),
new ColorResourceInfo(XKnownColor.AntiqueWhite, XColors.AntiqueWhite, 0xFFFAEBD7, "Antiquewhite", "Antikes Weiß"),
new ColorResourceInfo(XKnownColor.BlanchedAlmond, XColors.BlanchedAlmond, 0xFFFFEBCD, "Blanchedalmond", "Mandelweiß"),
//new ColorResourceInfo(XKnownColor.PapayaWhip, XColors.PapayaWhip, 0xFFFFEFD5, "Papayawhip", "Cremiges Papaya"),
new ColorResourceInfo(XKnownColor.PapayaWhip, XColors.PapayaWhip, 0xFFFFEFD5, "Papayawhip", "Papayacreme"),
new ColorResourceInfo(XKnownColor.Beige, XColors.Beige, 0xFFF5F5DC, "Beige", "Beige"),
new ColorResourceInfo(XKnownColor.Cornsilk, XColors.Cornsilk, 0xFFFFF8DC, "Cornsilk", "Mais"),
//new ColorResourceInfo(XKnownColor.LightGoldenrodYellow, XColors.LightGoldenrodYellow, 0xFFFAFAD2, "Lightgoldenrodyellow", "Helles Goldrutengelb"),
new ColorResourceInfo(XKnownColor.LightGoldenrodYellow, XColors.LightGoldenrodYellow, 0xFFFAFAD2, "Lightgoldenrodyellow", "Helles Goldgelb"),
new ColorResourceInfo(XKnownColor.LightYellow, XColors.LightYellow, 0xFFFFFFE0, "Lightyellow", "Hellgelb"),
new ColorResourceInfo(XKnownColor.LemonChiffon, XColors.LemonChiffon, 0xFFFFFACD, "Lemonchiffon", "Pastellgelb"),
//new ColorResourceInfo(XKnownColor.PaleGoldenrod, XColors.PaleGoldenrod, 0xFFEEE8AA, "Palegoldenrod", "Blasse Goldrutenfarbe"),
new ColorResourceInfo(XKnownColor.PaleGoldenrod, XColors.PaleGoldenrod, 0xFFEEE8AA, "Palegoldenrod", "Blasses Goldgelb"),
new ColorResourceInfo(XKnownColor.Khaki, XColors.Khaki, 0xFFF0E68C, "Khaki", "Khaki"),
new ColorResourceInfo(XKnownColor.Yellow, XColors.Yellow, 0xFFFFFF00, "Yellow", "Gelb"),
new ColorResourceInfo(XKnownColor.Gold, XColors.Gold, 0xFFFFD700, "Gold", "Gold"),
new ColorResourceInfo(XKnownColor.Orange, XColors.Orange, 0xFFFFA500, "Orange", "Orange"),
new ColorResourceInfo(XKnownColor.DarkOrange, XColors.DarkOrange, 0xFFFF8C00, "Darkorange", "Dunkles Orange"),
//new ColorResourceInfo(XKnownColor.Goldenrod, XColors.Goldenrod, 0xFFDAA520, "Goldenrod", "Goldrute"),
new ColorResourceInfo(XKnownColor.Goldenrod, XColors.Goldenrod, 0xFFDAA520, "Goldenrod", "Goldgelb"),
//new ColorResourceInfo(XKnownColor.DarkGoldenrod, XColors.DarkGoldenrod, 0xFFB8860B, "Darkgoldenrod", "Dunkle Goldrutenfarbe"),
new ColorResourceInfo(XKnownColor.DarkGoldenrod, XColors.DarkGoldenrod, 0xFFB8860B, "Darkgoldenrod", "Dunkles Goldgelb"),
new ColorResourceInfo(XKnownColor.Peru, XColors.Peru, 0xFFCD853F, "Peru", "Peru"),
new ColorResourceInfo(XKnownColor.Chocolate, XColors.Chocolate, 0xFFD2691E, "Chocolate", "Schokolade"),
new ColorResourceInfo(XKnownColor.SaddleBrown, XColors.SaddleBrown, 0xFF8B4513, "Saddlebrown", "Sattelbraun"),
new ColorResourceInfo(XKnownColor.Sienna, XColors.Sienna, 0xFFA0522D, "Sienna", "Ocker"),
new ColorResourceInfo(XKnownColor.Brown, XColors.Brown, 0xFFA52A2A, "Brown", "Braun"),
new ColorResourceInfo(XKnownColor.DarkRed, XColors.DarkRed, 0xFF8B0000, "Darkred", "Dunkelrot"),
new ColorResourceInfo(XKnownColor.Maroon, XColors.Maroon, 0xFF800000, "Maroon", "Kastanienbraun"),
new ColorResourceInfo(XKnownColor.PaleTurquoise, XColors.PaleTurquoise, 0xFFAFEEEE, "Paleturquoise", "Blasses Türkis"),
//new ColorResourceInfo(XKnownColor.Firebrick, XColors.Firebrick, 0xFFB22222, "Firebrick", "Ziegelfarbe"),
new ColorResourceInfo(XKnownColor.Firebrick, XColors.Firebrick, 0xFFB22222, "Firebrick", "Ziegel"),
new ColorResourceInfo(XKnownColor.IndianRed, XColors.IndianRed, 0xFFCD5C5C, "Indianred", "Indischrot"),
new ColorResourceInfo(XKnownColor.Crimson, XColors.Crimson, 0xFFDC143C, "Crimson", "Karmesinrot"),
new ColorResourceInfo(XKnownColor.Red, XColors.Red, 0xFFFF0000, "Red", "Rot"),
//new ColorResourceInfo(XKnownColor.OrangeRed, XColors.OrangeRed, 0xFFFF4500, "Orangered", "Orangenrot"),
new ColorResourceInfo(XKnownColor.OrangeRed, XColors.OrangeRed, 0xFFFF4500, "Orangered", "Orangerot"),
//new ColorResourceInfo(XKnownColor.Tomato, XColors.Tomato, 0xFFFF6347, "Tomato", "Tomatenrot"),
new ColorResourceInfo(XKnownColor.Tomato, XColors.Tomato, 0xFFFF6347, "Tomato", "Tomate"),
new ColorResourceInfo(XKnownColor.Coral, XColors.Coral, 0xFFFF7F50, "Coral", "Koralle"),
new ColorResourceInfo(XKnownColor.Salmon, XColors.Salmon, 0xFFFA8072, "Salmon", "Lachs"),
new ColorResourceInfo(XKnownColor.LightCoral, XColors.LightCoral, 0xFFF08080, "Lightcoral", "Helles Korallenrot"),
//new ColorResourceInfo(XKnownColor.DarkSalmon, XColors.DarkSalmon, 0xFFE9967A, "Darksalmon", "Dunkle Lachsfarbe"),
new ColorResourceInfo(XKnownColor.DarkSalmon, XColors.DarkSalmon, 0xFFE9967A, "Darksalmon", "Dunkles Lachs"),
//new ColorResourceInfo(XKnownColor.LightSalmon, XColors.LightSalmon, 0xFFFFA07A, "Lightsalmon", "Helle Lachsfarbe"),
new ColorResourceInfo(XKnownColor.LightSalmon, XColors.LightSalmon, 0xFFFFA07A, "Lightsalmon", "Helles Lachs"),
new ColorResourceInfo(XKnownColor.SandyBrown, XColors.SandyBrown, 0xFFF4A460, "Sandybrown", "Sandbraun"),
//new ColorResourceInfo(XKnownColor.RosyBrown, XColors.RosyBrown, 0xFFBC8F8F, "Rosybrown", "Rosiges Braun"),
new ColorResourceInfo(XKnownColor.RosyBrown, XColors.RosyBrown, 0xFFBC8F8F, "Rosybrown", "Rotbraun"),
new ColorResourceInfo(XKnownColor.Tan, XColors.Tan, 0xFFD2B48C, "Tan", "Gelbbraun"),
//new ColorResourceInfo(XKnownColor.BurlyWood, XColors.BurlyWood, 0xFFDEB887, "Burlywood", "Grobes Braun"),
new ColorResourceInfo(XKnownColor.BurlyWood, XColors.BurlyWood, 0xFFDEB887, "Burlywood", "Kräftiges Sandbraun"),
new ColorResourceInfo(XKnownColor.Wheat, XColors.Wheat, 0xFFF5DEB3, "Wheat", "Weizen"),
new ColorResourceInfo(XKnownColor.PeachPuff, XColors.PeachPuff, 0xFFFFDAB9, "Peachpuff", "Pfirsich"),
//new ColorResourceInfo(XKnownColor.NavajoWhite, XColors.NavajoWhite, 0xFFFFDEAD, "Navajowhite", "Navajoweiß"),
new ColorResourceInfo(XKnownColor.NavajoWhite, XColors.NavajoWhite, 0xFFFFDEAD, "Navajowhite", "Orangeweiß"),
//new ColorResourceInfo(XKnownColor.Bisque, XColors.Bisque, 0xFFFFE4C4, "Bisque", "Tomatencreme"),
new ColorResourceInfo(XKnownColor.Bisque, XColors.Bisque, 0xFFFFE4C4, "Bisque", "Blasses Rotbraun"),
//new ColorResourceInfo(XKnownColor.Moccasin, XColors.Moccasin, 0xFFFFE4B5, "Moccasin", "Moccasin"),
new ColorResourceInfo(XKnownColor.Moccasin, XColors.Moccasin, 0xFFFFE4B5, "Moccasin", "Mokassin"),
//new ColorResourceInfo(XKnownColor.LavenderBlush, XColors.LavenderBlush, 0xFFFFF0F5, "Lavenderblush", "Rosige Lavenderfarbe"),
new ColorResourceInfo(XKnownColor.LavenderBlush, XColors.LavenderBlush, 0xFFFFF0F5, "Lavenderblush", "Roter Lavendel"),
new ColorResourceInfo(XKnownColor.MistyRose, XColors.MistyRose, 0xFFFFE4E1, "Mistyrose", "Altrosa"),
new ColorResourceInfo(XKnownColor.Pink, XColors.Pink, 0xFFFFC0CB, "Pink", "Rosa"),
new ColorResourceInfo(XKnownColor.LightPink, XColors.LightPink, 0xFFFFB6C1, "Lightpink", "Hellrosa"),
new ColorResourceInfo(XKnownColor.HotPink, XColors.HotPink, 0xFFFF69B4, "Hotpink", "Leuchtendes Rosa"),
//// XKnownColor.Fuchsia removed because the same as XKnownColor.Magenta
////new ColorResourceInfo(XKnownColor.Fuchsia, XColors.Fuchsia, 0xFFFF00FF, "Fuchsia", "Fuchsie"),
new ColorResourceInfo(XKnownColor.Magenta, XColors.Magenta, 0xFFFF00FF, "Magenta", "Magentarot"),
new ColorResourceInfo(XKnownColor.DeepPink, XColors.DeepPink, 0xFFFF1493, "Deeppink", "Tiefrosa"),
new ColorResourceInfo(XKnownColor.MediumVioletRed, XColors.MediumVioletRed, 0xFFC71585, "Mediumvioletred", "Mittleres Violettrot"),
new ColorResourceInfo(XKnownColor.PaleVioletRed, XColors.PaleVioletRed, 0xFFDB7093, "Palevioletred", "Blasses Violettrot"),
new ColorResourceInfo(XKnownColor.Plum, XColors.Plum, 0xFFDDA0DD, "Plum", "Pflaume"),
new ColorResourceInfo(XKnownColor.Thistle, XColors.Thistle, 0xFFD8BFD8, "Thistle", "Distel"),
//new ColorResourceInfo(XKnownColor.Lavender, XColors.Lavender, 0xFFE6E6FA, "Lavender", "Lavendelfarbe"),
new ColorResourceInfo(XKnownColor.Lavender, XColors.Lavender, 0xFFE6E6FA, "Lavender", "Lavendel"),
new ColorResourceInfo(XKnownColor.Violet, XColors.Violet, 0xFFEE82EE, "Violet", "Violett"),
new ColorResourceInfo(XKnownColor.Orchid, XColors.Orchid, 0xFFDA70D6, "Orchid", "Orchidee"),
new ColorResourceInfo(XKnownColor.DarkMagenta, XColors.DarkMagenta, 0xFF8B008B, "Darkmagenta", "Dunkles Magentarot"),
new ColorResourceInfo(XKnownColor.Purple, XColors.Purple, 0xFF800080, "Purple", "Violett"),
new ColorResourceInfo(XKnownColor.Indigo, XColors.Indigo, 0xFF4B0082, "Indigo", "Indigo"),
new ColorResourceInfo(XKnownColor.BlueViolet, XColors.BlueViolet, 0xFF8A2BE2, "Blueviolet", "Blauviolett"),
new ColorResourceInfo(XKnownColor.DarkViolet, XColors.DarkViolet, 0xFF9400D3, "Darkviolet", "Dunkles Violett"),
//new ColorResourceInfo(XKnownColor.DarkOrchid, XColors.DarkOrchid, 0xFF9932CC, "Darkorchid", "Dunkle Orchideenfarbe"),
new ColorResourceInfo(XKnownColor.DarkOrchid, XColors.DarkOrchid, 0xFF9932CC, "Darkorchid", "Dunkle Orchidee"),
new ColorResourceInfo(XKnownColor.MediumPurple, XColors.MediumPurple, 0xFF9370DB, "Mediumpurple", "Mittleres Violett"),
//new ColorResourceInfo(XKnownColor.MediumOrchid, XColors.MediumOrchid, 0xFFBA55D3, "Mediumorchid", "Mittlere Orchideenfarbe"),
new ColorResourceInfo(XKnownColor.MediumOrchid, XColors.MediumOrchid, 0xFFBA55D3, "Mediumorchid", "Mittlere Orchidee"),
new ColorResourceInfo(XKnownColor.MediumSlateBlue, XColors.MediumSlateBlue, 0xFF7B68EE, "Mediumslateblue", "Mittleres Schieferblau"),
new ColorResourceInfo(XKnownColor.SlateBlue, XColors.SlateBlue, 0xFF6A5ACD, "Slateblue", "Schieferblau"),
new ColorResourceInfo(XKnownColor.DarkSlateBlue, XColors.DarkSlateBlue, 0xFF483D8B, "Darkslateblue", "Dunkles Schiefergrau"),
new ColorResourceInfo(XKnownColor.MidnightBlue, XColors.MidnightBlue, 0xFF191970, "Midnightblue", "Mitternachtsblau"),
new ColorResourceInfo(XKnownColor.Navy, XColors.Navy, 0xFF000080, "Navy", "Marineblau"),
new ColorResourceInfo(XKnownColor.DarkBlue, XColors.DarkBlue, 0xFF00008B, "Darkblue", "Dunkelblau"),
new ColorResourceInfo(XKnownColor.LightGray, XColors.LightGray, 0xFFD3D3D3, "Lightgray", "Hellgrau"),
new ColorResourceInfo(XKnownColor.MediumBlue, XColors.MediumBlue, 0xFF0000CD, "Mediumblue", "Mittelblau"),
new ColorResourceInfo(XKnownColor.Blue, XColors.Blue, 0xFF0000FF, "Blue", "Blau"),
new ColorResourceInfo(XKnownColor.RoyalBlue, XColors.RoyalBlue, 0xFF4169E1, "Royalblue", "Königsblau"),
new ColorResourceInfo(XKnownColor.SteelBlue, XColors.SteelBlue, 0xFF4682B4, "Steelblue", "Stahlblau"),
new ColorResourceInfo(XKnownColor.CornflowerBlue, XColors.CornflowerBlue, 0xFF6495ED, "Cornflowerblue", "Kornblumenblau"),
new ColorResourceInfo(XKnownColor.DodgerBlue, XColors.DodgerBlue, 0xFF1E90FF, "Dodgerblue", "Dodger-Blau"),
new ColorResourceInfo(XKnownColor.DeepSkyBlue, XColors.DeepSkyBlue, 0xFF00BFFF, "Deepskyblue", "Tiefes Himmelblau"),
new ColorResourceInfo(XKnownColor.LightSkyBlue, XColors.LightSkyBlue, 0xFF87CEFA, "Lightskyblue", "Helles Himmelblau"),
new ColorResourceInfo(XKnownColor.SkyBlue, XColors.SkyBlue, 0xFF87CEEB, "Skyblue", "Himmelblau"),
new ColorResourceInfo(XKnownColor.LightBlue, XColors.LightBlue, 0xFFADD8E6, "Lightblue", "Hellblau"),
//// XKnownColor.Aqua removed because the same as XKnownColor.Cyan
////new ColorResourceInfo(XKnownColor.Aqua, XColors.Aqua, 0xFF00FFFF, "Aqua", "Blaugrün"),
new ColorResourceInfo(XKnownColor.Cyan, XColors.Cyan, 0xFF00FFFF, "Cyan", "Zyan"),
new ColorResourceInfo(XKnownColor.PowderBlue, XColors.PowderBlue, 0xFFB0E0E6, "Powderblue", "Taubenblau"),
new ColorResourceInfo(XKnownColor.LightCyan, XColors.LightCyan, 0xFFE0FFFF, "Lightcyan", "Helles Cyanblau"),
new ColorResourceInfo(XKnownColor.AliceBlue, XColors.AliceBlue, 0xFFA0CE00, "Aliceblue", "Aliceblau"),
new ColorResourceInfo(XKnownColor.Azure, XColors.Azure, 0xFFF0FFFF, "Azure", "Himmelblau"),
//new ColorResourceInfo(XKnownColor.MintCream, XColors.MintCream, 0xFFF5FFFA, "Mintcream", "Cremige Pfefferminzfarbe"),
new ColorResourceInfo(XKnownColor.MintCream, XColors.MintCream, 0xFFF5FFFA, "Mintcream", "Helles Pfefferminzgrün"),
new ColorResourceInfo(XKnownColor.Honeydew, XColors.Honeydew, 0xFFF0FFF0, "Honeydew", "Honigmelone"),
new ColorResourceInfo(XKnownColor.Aquamarine, XColors.Aquamarine, 0xFF7FFFD4, "Aquamarine", "Aquamarinblau"),
new ColorResourceInfo(XKnownColor.Turquoise, XColors.Turquoise, 0xFF40E0D0, "Turquoise", "Türkis"),
new ColorResourceInfo(XKnownColor.MediumTurquoise, XColors.MediumTurquoise, 0xFF48D1CC, "Mediumturqoise", "Mittleres Türkis"),
new ColorResourceInfo(XKnownColor.DarkTurquoise, XColors.DarkTurquoise, 0xFF00CED1, "Darkturquoise", "Dunkles Türkis"),
new ColorResourceInfo(XKnownColor.MediumAquamarine, XColors.MediumAquamarine, 0xFF66CDAA, "Mediumaquamarine", "Mittleres Aquamarinblau"),
new ColorResourceInfo(XKnownColor.LightSeaGreen, XColors.LightSeaGreen, 0xFF20B2AA, "Lightseagreen", "Helles Seegrün"),
new ColorResourceInfo(XKnownColor.DarkCyan, XColors.DarkCyan, 0xFF008B8B, "Darkcyan", "Dunkles Zyanblau"),
//new ColorResourceInfo(XKnownColor.Teal, XColors.Teal, 0xFF008080, "Teal", "Entenbraun"),
new ColorResourceInfo(XKnownColor.Teal, XColors.Teal, 0xFF008080, "Teal", "Entenblau"),
new ColorResourceInfo(XKnownColor.CadetBlue, XColors.CadetBlue, 0xFF5F9EA0, "Cadetblue", "Kadettblau"),
new ColorResourceInfo(XKnownColor.MediumSeaGreen, XColors.MediumSeaGreen, 0xFF3CB371, "Mediumseagreen", "Mittleres Seegrün"),
new ColorResourceInfo(XKnownColor.DarkSeaGreen, XColors.DarkSeaGreen, 0xFF8FBC8F, "Darkseagreen", "Dunkles Seegrün"),
new ColorResourceInfo(XKnownColor.LightGreen, XColors.LightGreen, 0xFF90EE90, "Lightgreen", "Hellgrün"),
new ColorResourceInfo(XKnownColor.PaleGreen, XColors.PaleGreen, 0xFF98FB98, "Palegreen", "Blassgrün"),
new ColorResourceInfo(XKnownColor.MediumSpringGreen, XColors.MediumSpringGreen, 0xFF00FA9A, "Mediumspringgreen", "Mittleres Frühlingsgrün"),
new ColorResourceInfo(XKnownColor.SpringGreen, XColors.SpringGreen, 0xFF00FF7F, "Springgreen", "Frühlingsgrün"),
new ColorResourceInfo(XKnownColor.Lime, XColors.Lime, 0xFF00FF00, "Lime", "Zitronengrün"),
new ColorResourceInfo(XKnownColor.LimeGreen, XColors.LimeGreen, 0xFF32CD32, "Limegreen", "Gelbgrün"),
new ColorResourceInfo(XKnownColor.SeaGreen, XColors.SeaGreen, 0xFF2E8B57, "Seagreen", "Seegrün"),
new ColorResourceInfo(XKnownColor.ForestGreen, XColors.ForestGreen, 0xFF228B22, "Forestgreen", "Waldgrün"),
new ColorResourceInfo(XKnownColor.Green, XColors.Green, 0xFF008000, "Green", "Grün"),
new ColorResourceInfo(XKnownColor.LawnGreen, XColors.LawnGreen, 0xFF008000, "LawnGreen", "Grasgrün"),
new ColorResourceInfo(XKnownColor.DarkGreen, XColors.DarkGreen, 0xFF006400, "Darkgreen", "Dunkelgrün"),
//new ColorResourceInfo(XKnownColor.OliveDrab, XColors.OliveDrab, 0xFF6B8E23, "Olivedrab", "Olivfarbiges Graubraun"),
new ColorResourceInfo(XKnownColor.OliveDrab, XColors.OliveDrab, 0xFF6B8E23, "Olivedrab", "Reife Olive"),
new ColorResourceInfo(XKnownColor.DarkOliveGreen, XColors.DarkOliveGreen, 0xFF556B2F, "Darkolivegreen", "Dunkles Olivgrün"),
new ColorResourceInfo(XKnownColor.Olive, XColors.Olive, 0xFF808000, "Olive", "Olivgrün"),
new ColorResourceInfo(XKnownColor.DarkKhaki, XColors.DarkKhaki, 0xFFBDB76B, "Darkkhaki", "Dunkles Khaki"),
new ColorResourceInfo(XKnownColor.YellowGreen, XColors.YellowGreen, 0xFF9ACD32, "Yellowgreen", "Gelbgrün"),
new ColorResourceInfo(XKnownColor.Chartreuse, XColors.Chartreuse, 0xFF7FFF00, "Chartreuse", "Hellgrün"),
new ColorResourceInfo(XKnownColor.GreenYellow, XColors.GreenYellow, 0xFFADFF2F, "Greenyellow", "Grüngelb"),
};
internal struct ColorResourceInfo
{
public ColorResourceInfo(XKnownColor knownColor, XColor color, uint argb, string name, string nameDE)
{
KnownColor = knownColor;
Color = color;
Argb = argb;
Name = name;
NameDE = nameDE;
}
public XKnownColor KnownColor;
public XColor Color;
public uint Argb;
public string Name;
// ReSharper disable once InconsistentNaming
public string NameDE;
}
}
}

468
PdfSharp/Drawing/XColors.cs Normal file
View File

@@ -0,0 +1,468 @@
#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;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
///<summary>
/// Represents a set of 141 pre-defined RGB colors. Incidentally the values are the same
/// as in System.Drawing.Color.
/// </summary>
public static class XColors
{
///<summary>Gets a predefined color.</summary>
public static XColor AliceBlue { get { return new XColor(XKnownColor.AliceBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor AntiqueWhite { get { return new XColor(XKnownColor.AntiqueWhite); } }
///<summary>Gets a predefined color.</summary>
public static XColor Aqua { get { return new XColor(XKnownColor.Aqua); } }
///<summary>Gets a predefined color.</summary>
public static XColor Aquamarine { get { return new XColor(XKnownColor.Aquamarine); } }
///<summary>Gets a predefined color.</summary>
public static XColor Azure { get { return new XColor(XKnownColor.Azure); } }
///<summary>Gets a predefined color.</summary>
public static XColor Beige { get { return new XColor(XKnownColor.Beige); } }
///<summary>Gets a predefined color.</summary>
public static XColor Bisque { get { return new XColor(XKnownColor.Bisque); } }
///<summary>Gets a predefined color.</summary>
public static XColor Black { get { return new XColor(XKnownColor.Black); } }
///<summary>Gets a predefined color.</summary>
public static XColor BlanchedAlmond { get { return new XColor(XKnownColor.BlanchedAlmond); } }
///<summary>Gets a predefined color.</summary>
public static XColor Blue { get { return new XColor(XKnownColor.Blue); } }
///<summary>Gets a predefined color.</summary>
public static XColor BlueViolet { get { return new XColor(XKnownColor.BlueViolet); } }
///<summary>Gets a predefined color.</summary>
public static XColor Brown { get { return new XColor(XKnownColor.Brown); } }
///<summary>Gets a predefined color.</summary>
public static XColor BurlyWood { get { return new XColor(XKnownColor.BurlyWood); } }
///<summary>Gets a predefined color.</summary>
public static XColor CadetBlue { get { return new XColor(XKnownColor.CadetBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor Chartreuse { get { return new XColor(XKnownColor.Chartreuse); } }
///<summary>Gets a predefined color.</summary>
public static XColor Chocolate { get { return new XColor(XKnownColor.Chocolate); } }
///<summary>Gets a predefined color.</summary>
public static XColor Coral { get { return new XColor(XKnownColor.Coral); } }
///<summary>Gets a predefined color.</summary>
public static XColor CornflowerBlue { get { return new XColor(XKnownColor.CornflowerBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor Cornsilk { get { return new XColor(XKnownColor.Cornsilk); } }
///<summary>Gets a predefined color.</summary>
public static XColor Crimson { get { return new XColor(XKnownColor.Crimson); } }
///<summary>Gets a predefined color.</summary>
public static XColor Cyan { get { return new XColor(XKnownColor.Cyan); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkBlue { get { return new XColor(XKnownColor.DarkBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkCyan { get { return new XColor(XKnownColor.DarkCyan); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkGoldenrod { get { return new XColor(XKnownColor.DarkGoldenrod); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkGray { get { return new XColor(XKnownColor.DarkGray); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkGreen { get { return new XColor(XKnownColor.DarkGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkKhaki { get { return new XColor(XKnownColor.DarkKhaki); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkMagenta { get { return new XColor(XKnownColor.DarkMagenta); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkOliveGreen { get { return new XColor(XKnownColor.DarkOliveGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkOrange { get { return new XColor(XKnownColor.DarkOrange); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkOrchid { get { return new XColor(XKnownColor.DarkOrchid); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkRed { get { return new XColor(XKnownColor.DarkRed); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkSalmon { get { return new XColor(XKnownColor.DarkSalmon); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkSeaGreen { get { return new XColor(XKnownColor.DarkSeaGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkSlateBlue { get { return new XColor(XKnownColor.DarkSlateBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkSlateGray { get { return new XColor(XKnownColor.DarkSlateGray); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkTurquoise { get { return new XColor(XKnownColor.DarkTurquoise); } }
///<summary>Gets a predefined color.</summary>
public static XColor DarkViolet { get { return new XColor(XKnownColor.DarkViolet); } }
///<summary>Gets a predefined color.</summary>
public static XColor DeepPink { get { return new XColor(XKnownColor.DeepPink); } }
///<summary>Gets a predefined color.</summary>
public static XColor DeepSkyBlue { get { return new XColor(XKnownColor.DeepSkyBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor DimGray { get { return new XColor(XKnownColor.DimGray); } }
///<summary>Gets a predefined color.</summary>
public static XColor DodgerBlue { get { return new XColor(XKnownColor.DodgerBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor Firebrick { get { return new XColor(XKnownColor.Firebrick); } }
///<summary>Gets a predefined color.</summary>
public static XColor FloralWhite { get { return new XColor(XKnownColor.FloralWhite); } }
///<summary>Gets a predefined color.</summary>
public static XColor ForestGreen { get { return new XColor(XKnownColor.ForestGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor Fuchsia { get { return new XColor(XKnownColor.Fuchsia); } }
///<summary>Gets a predefined color.</summary>
public static XColor Gainsboro { get { return new XColor(XKnownColor.Gainsboro); } }
///<summary>Gets a predefined color.</summary>
public static XColor GhostWhite { get { return new XColor(XKnownColor.GhostWhite); } }
///<summary>Gets a predefined color.</summary>
public static XColor Gold { get { return new XColor(XKnownColor.Gold); } }
///<summary>Gets a predefined color.</summary>
public static XColor Goldenrod { get { return new XColor(XKnownColor.Goldenrod); } }
///<summary>Gets a predefined color.</summary>
public static XColor Gray { get { return new XColor(XKnownColor.Gray); } }
///<summary>Gets a predefined color.</summary>
public static XColor Green { get { return new XColor(XKnownColor.Green); } }
///<summary>Gets a predefined color.</summary>
public static XColor GreenYellow { get { return new XColor(XKnownColor.GreenYellow); } }
///<summary>Gets a predefined color.</summary>
public static XColor Honeydew { get { return new XColor(XKnownColor.Honeydew); } }
///<summary>Gets a predefined color.</summary>
public static XColor HotPink { get { return new XColor(XKnownColor.HotPink); } }
///<summary>Gets a predefined color.</summary>
public static XColor IndianRed { get { return new XColor(XKnownColor.IndianRed); } }
///<summary>Gets a predefined color.</summary>
public static XColor Indigo { get { return new XColor(XKnownColor.Indigo); } }
///<summary>Gets a predefined color.</summary>
public static XColor Ivory { get { return new XColor(XKnownColor.Ivory); } }
///<summary>Gets a predefined color.</summary>
public static XColor Khaki { get { return new XColor(XKnownColor.Khaki); } }
///<summary>Gets a predefined color.</summary>
public static XColor Lavender { get { return new XColor(XKnownColor.Lavender); } }
///<summary>Gets a predefined color.</summary>
public static XColor LavenderBlush { get { return new XColor(XKnownColor.LavenderBlush); } }
///<summary>Gets a predefined color.</summary>
public static XColor LawnGreen { get { return new XColor(XKnownColor.LawnGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor LemonChiffon { get { return new XColor(XKnownColor.LemonChiffon); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightBlue { get { return new XColor(XKnownColor.LightBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightCoral { get { return new XColor(XKnownColor.LightCoral); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightCyan { get { return new XColor(XKnownColor.LightCyan); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightGoldenrodYellow { get { return new XColor(XKnownColor.LightGoldenrodYellow); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightGray { get { return new XColor(XKnownColor.LightGray); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightGreen { get { return new XColor(XKnownColor.LightGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightPink { get { return new XColor(XKnownColor.LightPink); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightSalmon { get { return new XColor(XKnownColor.LightSalmon); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightSeaGreen { get { return new XColor(XKnownColor.LightSeaGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightSkyBlue { get { return new XColor(XKnownColor.LightSkyBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightSlateGray { get { return new XColor(XKnownColor.LightSlateGray); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightSteelBlue { get { return new XColor(XKnownColor.LightSteelBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor LightYellow { get { return new XColor(XKnownColor.LightYellow); } }
///<summary>Gets a predefined color.</summary>
public static XColor Lime { get { return new XColor(XKnownColor.Lime); } }
///<summary>Gets a predefined color.</summary>
public static XColor LimeGreen { get { return new XColor(XKnownColor.LimeGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor Linen { get { return new XColor(XKnownColor.Linen); } }
///<summary>Gets a predefined color.</summary>
public static XColor Magenta { get { return new XColor(XKnownColor.Magenta); } }
///<summary>Gets a predefined color.</summary>
public static XColor Maroon { get { return new XColor(XKnownColor.Maroon); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumAquamarine { get { return new XColor(XKnownColor.MediumAquamarine); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumBlue { get { return new XColor(XKnownColor.MediumBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumOrchid { get { return new XColor(XKnownColor.MediumOrchid); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumPurple { get { return new XColor(XKnownColor.MediumPurple); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumSeaGreen { get { return new XColor(XKnownColor.MediumSeaGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumSlateBlue { get { return new XColor(XKnownColor.MediumSlateBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumSpringGreen { get { return new XColor(XKnownColor.MediumSpringGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumTurquoise { get { return new XColor(XKnownColor.MediumTurquoise); } }
///<summary>Gets a predefined color.</summary>
public static XColor MediumVioletRed { get { return new XColor(XKnownColor.MediumVioletRed); } }
///<summary>Gets a predefined color.</summary>
public static XColor MidnightBlue { get { return new XColor(XKnownColor.MidnightBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor MintCream { get { return new XColor(XKnownColor.MintCream); } }
///<summary>Gets a predefined color.</summary>
public static XColor MistyRose { get { return new XColor(XKnownColor.MistyRose); } }
///<summary>Gets a predefined color.</summary>
public static XColor Moccasin { get { return new XColor(XKnownColor.Moccasin); } }
///<summary>Gets a predefined color.</summary>
public static XColor NavajoWhite { get { return new XColor(XKnownColor.NavajoWhite); } }
///<summary>Gets a predefined color.</summary>
public static XColor Navy { get { return new XColor(XKnownColor.Navy); } }
///<summary>Gets a predefined color.</summary>
public static XColor OldLace { get { return new XColor(XKnownColor.OldLace); } }
///<summary>Gets a predefined color.</summary>
public static XColor Olive { get { return new XColor(XKnownColor.Olive); } }
///<summary>Gets a predefined color.</summary>
public static XColor OliveDrab { get { return new XColor(XKnownColor.OliveDrab); } }
///<summary>Gets a predefined color.</summary>
public static XColor Orange { get { return new XColor(XKnownColor.Orange); } }
///<summary>Gets a predefined color.</summary>
public static XColor OrangeRed { get { return new XColor(XKnownColor.OrangeRed); } }
///<summary>Gets a predefined color.</summary>
public static XColor Orchid { get { return new XColor(XKnownColor.Orchid); } }
///<summary>Gets a predefined color.</summary>
public static XColor PaleGoldenrod { get { return new XColor(XKnownColor.PaleGoldenrod); } }
///<summary>Gets a predefined color.</summary>
public static XColor PaleGreen { get { return new XColor(XKnownColor.PaleGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor PaleTurquoise { get { return new XColor(XKnownColor.PaleTurquoise); } }
///<summary>Gets a predefined color.</summary>
public static XColor PaleVioletRed { get { return new XColor(XKnownColor.PaleVioletRed); } }
///<summary>Gets a predefined color.</summary>
public static XColor PapayaWhip { get { return new XColor(XKnownColor.PapayaWhip); } }
///<summary>Gets a predefined color.</summary>
public static XColor PeachPuff { get { return new XColor(XKnownColor.PeachPuff); } }
///<summary>Gets a predefined color.</summary>
public static XColor Peru { get { return new XColor(XKnownColor.Peru); } }
///<summary>Gets a predefined color.</summary>
public static XColor Pink { get { return new XColor(XKnownColor.Pink); } }
///<summary>Gets a predefined color.</summary>
public static XColor Plum { get { return new XColor(XKnownColor.Plum); } }
///<summary>Gets a predefined color.</summary>
public static XColor PowderBlue { get { return new XColor(XKnownColor.PowderBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor Purple { get { return new XColor(XKnownColor.Purple); } }
///<summary>Gets a predefined color.</summary>
public static XColor Red { get { return new XColor(XKnownColor.Red); } }
///<summary>Gets a predefined color.</summary>
public static XColor RosyBrown { get { return new XColor(XKnownColor.RosyBrown); } }
///<summary>Gets a predefined color.</summary>
public static XColor RoyalBlue { get { return new XColor(XKnownColor.RoyalBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor SaddleBrown { get { return new XColor(XKnownColor.SaddleBrown); } }
///<summary>Gets a predefined color.</summary>
public static XColor Salmon { get { return new XColor(XKnownColor.Salmon); } }
///<summary>Gets a predefined color.</summary>
public static XColor SandyBrown { get { return new XColor(XKnownColor.SandyBrown); } }
///<summary>Gets a predefined color.</summary>
public static XColor SeaGreen { get { return new XColor(XKnownColor.SeaGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor SeaShell { get { return new XColor(XKnownColor.SeaShell); } }
///<summary>Gets a predefined color.</summary>
public static XColor Sienna { get { return new XColor(XKnownColor.Sienna); } }
///<summary>Gets a predefined color.</summary>
public static XColor Silver { get { return new XColor(XKnownColor.Silver); } }
///<summary>Gets a predefined color.</summary>
public static XColor SkyBlue { get { return new XColor(XKnownColor.SkyBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor SlateBlue { get { return new XColor(XKnownColor.SlateBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor SlateGray { get { return new XColor(XKnownColor.SlateGray); } }
///<summary>Gets a predefined color.</summary>
public static XColor Snow { get { return new XColor(XKnownColor.Snow); } }
///<summary>Gets a predefined color.</summary>
public static XColor SpringGreen { get { return new XColor(XKnownColor.SpringGreen); } }
///<summary>Gets a predefined color.</summary>
public static XColor SteelBlue { get { return new XColor(XKnownColor.SteelBlue); } }
///<summary>Gets a predefined color.</summary>
public static XColor Tan { get { return new XColor(XKnownColor.Tan); } }
///<summary>Gets a predefined color.</summary>
public static XColor Teal { get { return new XColor(XKnownColor.Teal); } }
///<summary>Gets a predefined color.</summary>
public static XColor Thistle { get { return new XColor(XKnownColor.Thistle); } }
///<summary>Gets a predefined color.</summary>
public static XColor Tomato { get { return new XColor(XKnownColor.Tomato); } }
///<summary>Gets a predefined color.</summary>
public static XColor Transparent { get { return new XColor(XKnownColor.Transparent); } }
///<summary>Gets a predefined color.</summary>
public static XColor Turquoise { get { return new XColor(XKnownColor.Turquoise); } }
///<summary>Gets a predefined color.</summary>
public static XColor Violet { get { return new XColor(XKnownColor.Violet); } }
///<summary>Gets a predefined color.</summary>
public static XColor Wheat { get { return new XColor(XKnownColor.Wheat); } }
///<summary>Gets a predefined color.</summary>
public static XColor White { get { return new XColor(XKnownColor.White); } }
///<summary>Gets a predefined color.</summary>
public static XColor WhiteSmoke { get { return new XColor(XKnownColor.WhiteSmoke); } }
///<summary>Gets a predefined color.</summary>
public static XColor Yellow { get { return new XColor(XKnownColor.Yellow); } }
///<summary>Gets a predefined color.</summary>
public static XColor YellowGreen { get { return new XColor(XKnownColor.YellowGreen); } }
}
}

View File

@@ -0,0 +1,97 @@
#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 CORE
#endif
#if CORE
#endif
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Converts XGraphics enums to GDI+ enums.
/// </summary>
internal static class XConvert
{
#if GDI
//#if UseGdiObjects
/// <summary>
/// Converts XLineJoin to LineJoin.
/// </summary>
public static LineJoin ToLineJoin(XLineJoin lineJoin)
{
return GdiLineJoin[(int)lineJoin];
}
static readonly LineJoin[] GdiLineJoin = new LineJoin[] { LineJoin.Miter, LineJoin.Round, LineJoin.Bevel };
//#endif
#endif
#if GDI
//#if UseGdiObjects
/// <summary>
/// Converts XLineCap to LineCap.
/// </summary>
public static LineCap ToLineCap(XLineCap lineCap)
{
return _gdiLineCap[(int)lineCap];
}
static readonly LineCap[] _gdiLineCap = new LineCap[] { LineCap.Flat, LineCap.Round, LineCap.Square };
//#endif
#endif
#if WPF
/// <summary>
/// Converts XLineJoin to PenLineJoin.
/// </summary>
public static PenLineJoin ToPenLineJoin(XLineJoin lineJoin)
{
return WpfLineJoin[(int)lineJoin];
}
static readonly PenLineJoin[] WpfLineJoin = new PenLineJoin[] { PenLineJoin.Miter, PenLineJoin.Round, PenLineJoin.Bevel };
#endif
#if WPF
/// <summary>
/// Converts XLineCap to PenLineCap.
/// </summary>
public static PenLineCap ToPenLineCap(XLineCap lineCap)
{
return WpfLineCap[(int)lineCap];
}
static readonly PenLineCap[] WpfLineCap = new PenLineCap[] { PenLineCap.Flat, PenLineCap.Round, PenLineCap.Square };
#endif
}
}

862
PdfSharp/Drawing/XFont.cs Normal file
View File

@@ -0,0 +1,862 @@
#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
// #??? Clean up
using System;
using System.Diagnostics;
using System.Globalization;
using System.ComponentModel;
#if CORE || GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using GdiFontFamily = System.Drawing.FontFamily;
using GdiFont = System.Drawing.Font;
using GdiFontStyle = System.Drawing.FontStyle;
#endif
#if WPF
using System.Windows.Markup;
using WpfFontFamily = System.Windows.Media.FontFamily;
using WpfTypeface = System.Windows.Media.Typeface;
using WpfGlyphTypeface = System.Windows.Media.GlyphTypeface;
#endif
#if UWP
using UwpFontFamily = Windows.UI.Xaml.Media.FontFamily;
#endif
using PdfSharp.Fonts;
using PdfSharp.Fonts.OpenType;
using PdfSharp.Internal;
using PdfSharp.Pdf;
#if SILVERLIGHT
#pragma warning disable 649
#endif
// ReSharper disable ConvertToAutoProperty
namespace PdfSharp.Drawing
{
/// <summary>
/// Defines an object used to draw text.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
public sealed class XFont
{
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class.
/// </summary>
/// <param name="familyName">Name of the font family.</param>
/// <param name="emSize">The em size.</param>
public XFont(string familyName, double emSize)
: this(familyName, emSize, XFontStyle.Regular, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class.
/// </summary>
/// <param name="familyName">Name of the font family.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
public XFont(string familyName, double emSize, XFontStyle style)
: this(familyName, emSize, style, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class.
/// </summary>
/// <param name="familyName">Name of the font family.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(string familyName, double emSize, XFontStyle style, XPdfFontOptions pdfOptions)
{
_familyName = familyName;
_emSize = emSize;
_style = style;
_pdfOptions = pdfOptions;
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class with enforced style simulation.
/// Only for testing PDFsharp.
/// </summary>
internal XFont(string familyName, double emSize, XFontStyle style, XPdfFontOptions pdfOptions, XStyleSimulations styleSimulations)
{
_familyName = familyName;
_emSize = emSize;
_style = style;
_pdfOptions = pdfOptions;
OverrideStyleSimulations = true;
StyleSimulations = styleSimulations;
Initialize();
}
#if CORE || GDI
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.FontFamily.
/// </summary>
/// <param name="fontFamily">The System.Drawing.FontFamily.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
public XFont(GdiFontFamily fontFamily, double emSize, XFontStyle style)
: this(fontFamily, emSize, style, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.FontFamily.
/// </summary>
/// <param name="fontFamily">The System.Drawing.FontFamily.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(GdiFontFamily fontFamily, double emSize, XFontStyle style, XPdfFontOptions pdfOptions)
{
_familyName = fontFamily.Name;
_gdiFontFamily = fontFamily;
_emSize = emSize;
_style = style;
_pdfOptions = pdfOptions;
InitializeFromGdi();
}
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.Font.
/// </summary>
/// <param name="font">The System.Drawing.Font.</param>
public XFont(GdiFont font)
: this(font, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.Font.
/// </summary>
/// <param name="font">The System.Drawing.Font.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(GdiFont font, XPdfFontOptions pdfOptions)
{
if (font.Unit != GraphicsUnit.World)
throw new ArgumentException("Font must use GraphicsUnit.World.");
_gdiFont = font;
Debug.Assert(font.Name == font.FontFamily.Name);
_familyName = font.Name;
_emSize = font.Size;
_style = FontStyleFrom(font);
_pdfOptions = pdfOptions;
InitializeFromGdi();
}
#endif
#if WPF && !SILVERLIGHT
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Windows.Media.FontFamily.
/// </summary>
/// <param name="fontFamily">The System.Windows.Media.FontFamily.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
public XFont(WpfFontFamily fontFamily, double emSize, XFontStyle style)
: this(fontFamily, emSize, style, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.FontFamily.
/// </summary>
/// <param name="fontFamily">The System.Windows.Media.FontFamily.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(WpfFontFamily fontFamily, double emSize, XFontStyle style, XPdfFontOptions pdfOptions)
{
#if !SILVERLIGHT
_familyName = fontFamily.FamilyNames[XmlLanguage.GetLanguage("en-US")];
#else
// Best we can do in Silverlight.
_familyName = fontFamily.Source;
#endif
_wpfFontFamily = fontFamily;
_emSize = emSize;
_style = style;
_pdfOptions = pdfOptions;
InitializeFromWpf();
}
/// <summary>
/// Initializes a new instance of the <see cref="XFont" /> class from a System.Windows.Media.Typeface.
/// </summary>
/// <param name="typeface">The System.Windows.Media.Typeface.</param>
/// <param name="emSize">The em size.</param>
public XFont(WpfTypeface typeface, double emSize)
: this(typeface, emSize, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Windows.Media.Typeface.
/// </summary>
/// <param name="typeface">The System.Windows.Media.Typeface.</param>
/// <param name="emSize">The em size.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(WpfTypeface typeface, double emSize, XPdfFontOptions pdfOptions)
{
_wpfTypeface = typeface;
//Debug.Assert(font.Name == font.FontFamily.Name);
//_familyName = font.Name;
_emSize = emSize;
_pdfOptions = pdfOptions;
InitializeFromWpf();
}
#endif
#if UWP_
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.FontFamily.
/// </summary>
/// <param name="fontFamily">The System.Drawing.FontFamily.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
public XFont(UwpFontFamily fontFamily, double emSize, XFontStyle style)
: this(fontFamily, emSize, style, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.FontFamily.
/// </summary>
/// <param name="fontFamily">The System.Drawing.FontFamily.</param>
/// <param name="emSize">The em size.</param>
/// <param name="style">The font style.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(UwpFontFamily fontFamily, double emSize, XFontStyle style, XPdfFontOptions pdfOptions)
{
_familyName = fontFamily.Source;
_gdiFontFamily = fontFamily;
_emSize = emSize;
_style = style;
_pdfOptions = pdfOptions;
InitializeFromGdi();
}
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.Font.
/// </summary>
/// <param name="font">The System.Drawing.Font.</param>
public XFont(GdiFont font)
: this(font, new XPdfFontOptions(GlobalFontSettings.DefaultFontEncoding))
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XFont"/> class from a System.Drawing.Font.
/// </summary>
/// <param name="font">The System.Drawing.Font.</param>
/// <param name="pdfOptions">Additional PDF options.</param>
public XFont(GdiFont font, XPdfFontOptions pdfOptions)
{
if (font.Unit != GraphicsUnit.World)
throw new ArgumentException("Font must use GraphicsUnit.World.");
_gdiFont = font;
Debug.Assert(font.Name == font.FontFamily.Name);
_familyName = font.Name;
_emSize = font.Size;
_style = FontStyleFrom(font);
_pdfOptions = pdfOptions;
InitializeFromGdi();
}
#endif
//// Methods
//public Font(Font prototype, FontStyle newStyle);
//public Font(FontFamily family, float emSize);
//public Font(string familyName, float emSize);
//public Font(FontFamily family, float emSize, FontStyle style);
//public Font(FontFamily family, float emSize, GraphicsUnit unit);
//public Font(string familyName, float emSize, FontStyle style);
//public Font(string familyName, float emSize, GraphicsUnit unit);
//public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit);
//public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit);
////public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet);
////public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet);
////public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont);
////public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont);
//public object Clone();
//private static FontFamily CreateFontFamilyWithFallback(string familyName);
//private void Dispose(bool disposing);
//public override bool Equals(object obj);
//protected override void Finalize();
//public static Font FromHdc(IntPtr hdc);
//public static Font FromHfont(IntPtr hfont);
//public static Font FromLogFont(object lf);
//public static Font FromLogFont(object lf, IntPtr hdc);
//public override int GetHashCode();
/// <summary>
/// Initializes this instance by computing the glyph typeface, font family, font source and TrueType fontface.
/// (PDFsharp currently only deals with TrueType fonts.)
/// </summary>
void Initialize()
{
//#if DEBUG
// if (_familyName == "Segoe UI Semilight" && (_style & XFontStyle.BoldItalic) == XFontStyle.Italic)
// GetType();
//#endif
FontResolvingOptions fontResolvingOptions = OverrideStyleSimulations
? new FontResolvingOptions(_style, StyleSimulations)
: new FontResolvingOptions(_style);
// HACK: 'PlatformDefault' is used in unit test code.
if (StringComparer.OrdinalIgnoreCase.Compare(_familyName, GlobalFontSettings.DefaultFontName) == 0)
{
#if CORE || GDI || WPF
_familyName = "Calibri";
#endif
}
// In principle an XFont is an XGlyphTypeface plus an em-size.
_glyphTypeface = XGlyphTypeface.GetOrCreateFrom(_familyName, fontResolvingOptions);
#if GDI // TODO: In CORE build it is not necessary to create a GDI font at all
// Create font by using font family.
XFontSource fontSource; // Not needed here.
_gdiFont = FontHelper.CreateFont(_familyName, (float)_emSize, (GdiFontStyle)(_style & XFontStyle.BoldItalic), out fontSource);
#endif
#if WPF && !SILVERLIGHT // Pure WPF
_wpfFontFamily = _glyphTypeface.FontFamily.WpfFamily;
_wpfTypeface = _glyphTypeface.WpfTypeface;
if (_wpfFontFamily == null)
_wpfFontFamily = new WpfFontFamily(Name);
if (_wpfTypeface == null)
_wpfTypeface = FontHelper.CreateTypeface(WpfFontFamily, _style);
#endif
#if WPF && SILVERLIGHT_ // Pure Silverlight 5
if (GlyphTypeface == null)
{
//Debug.Assert(Typeface == null);
// #P F C
//GlyphTypeface = XPrivateFontCollection.TryGetXGlyphTypeface(Name, _style);
//if (GlyphTypeface == null)
//{
// // HACK: Just make it work...
// GlyphTypeface = GlobalFontSettings.TryGetXGlyphTypeface(Name, _style, out Data);
//}
#if DEBUG
if (GlyphTypeface == null)
throw new Exception("No font: " + Name);
#endif
_wpfFamily = GlyphTypeface.FontFamily;
}
//if (Family == null)
// Family = new System.Windows.Media.FontFamily(Name);
//if (Typeface == null)
// Typeface = FontHelper.CreateTypeface(Family, _style);
#endif
CreateDescriptorAndInitializeFontMetrics();
}
#if CORE || GDI
/// <summary>
/// A GDI+ font object is used to setup the internal font objects.
/// </summary>
void InitializeFromGdi()
{
try
{
Lock.EnterFontFactory();
if (_gdiFontFamily != null)
{
// Create font based on its family.
_gdiFont = new Font(_gdiFontFamily, (float)_emSize, (GdiFontStyle)_style, GraphicsUnit.World);
}
if (_gdiFont != null)
{
#if DEBUG_
string name1 = _gdiFont.Name;
string name2 = _gdiFont.OriginalFontName;
string name3 = _gdiFont.SystemFontName;
#endif
_familyName = _gdiFont.FontFamily.Name;
// TODO: _glyphTypeface = XGlyphTypeface.GetOrCreateFrom(_gdiFont);
}
else
{
Debug.Assert(false);
}
if (_glyphTypeface == null)
_glyphTypeface = XGlyphTypeface.GetOrCreateFromGdi(_gdiFont);
CreateDescriptorAndInitializeFontMetrics();
}
finally { Lock.ExitFontFactory(); }
}
#endif
#if WPF && !SILVERLIGHT
void InitializeFromWpf()
{
if (_wpfFontFamily != null)
{
_wpfTypeface = FontHelper.CreateTypeface(_wpfFontFamily, _style);
}
if (_wpfTypeface != null)
{
_familyName = _wpfTypeface.FontFamily.FamilyNames[XmlLanguage.GetLanguage("en-US")];
_glyphTypeface = XGlyphTypeface.GetOrCreateFromWpf(_wpfTypeface);
}
else
{
Debug.Assert(false);
}
if (_glyphTypeface == null)
_glyphTypeface = XGlyphTypeface.GetOrCreateFrom(_familyName, new FontResolvingOptions(_style));
CreateDescriptorAndInitializeFontMetrics();
}
#endif
/// <summary>
/// Code separated from Metric getter to make code easier to debug.
/// (Setup properties in their getters caused side effects during debugging because Visual Studio calls a getter
/// to early to show its value in a debugger window.)
/// </summary>
void CreateDescriptorAndInitializeFontMetrics() // TODO: refactor
{
Debug.Assert(_fontMetrics == null, "InitializeFontMetrics() was already called.");
_descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptorFor(this); //_familyName, _style, _glyphTypeface.Fontface);
_fontMetrics = new XFontMetrics(_descriptor.FontName, _descriptor.UnitsPerEm, _descriptor.Ascender, _descriptor.Descender,
_descriptor.Leading, _descriptor.LineSpacing, _descriptor.CapHeight, _descriptor.XHeight, _descriptor.StemV, 0, 0, 0,
_descriptor.UnderlinePosition, _descriptor.UnderlineThickness, _descriptor.StrikeoutPosition, _descriptor.StrikeoutSize);
XFontMetrics fm = Metrics;
// Already done in CreateDescriptorAndInitializeFontMetrics.
//if (_descriptor == null)
// _descriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(this); //(Name, (XGdiFontStyle)Font.Style);
UnitsPerEm = _descriptor.UnitsPerEm;
CellAscent = _descriptor.Ascender;
CellDescent = _descriptor.Descender;
CellSpace = _descriptor.LineSpacing;
#if DEBUG_ && GDI
int gdiValueUnitsPerEm = Font.FontFamily.GetEmHeight(Font.Style);
Debug.Assert(gdiValueUnitsPerEm == UnitsPerEm);
int gdiValueAscent = Font.FontFamily.GetCellAscent(Font.Style);
Debug.Assert(gdiValueAscent == CellAscent);
int gdiValueDescent = Font.FontFamily.GetCellDescent(Font.Style);
Debug.Assert(gdiValueDescent == CellDescent);
int gdiValueLineSpacing = Font.FontFamily.GetLineSpacing(Font.Style);
Debug.Assert(gdiValueLineSpacing == CellSpace);
#endif
#if DEBUG_ && WPF && !SILVERLIGHT
int wpfValueLineSpacing = (int)Math.Round(Family.LineSpacing * _descriptor.UnitsPerEm);
Debug.Assert(wpfValueLineSpacing == CellSpace);
#endif
Debug.Assert(fm.UnitsPerEm == _descriptor.UnitsPerEm);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Gets the XFontFamily object associated with this XFont object.
/// </summary>
[Browsable(false)]
public XFontFamily FontFamily
{
get { return _glyphTypeface.FontFamily; }
}
/// <summary>
/// WRONG: Gets the face name of this Font object.
/// Indeed it returns the font family name.
/// </summary>
// [Obsolete("This function returns the font family name, not the face name. Use xxx.FontFamily.Name or xxx.FaceName")]
public string Name
{
get { return _glyphTypeface.FontFamily.Name; }
}
internal string FaceName
{
get { return _glyphTypeface.FaceName; }
}
/// <summary>
/// Gets the em-size of this font measured in the unit of this font object.
/// </summary>
public double Size
{
get { return _emSize; }
}
readonly double _emSize;
/// <summary>
/// Gets style information for this Font object.
/// </summary>
[Browsable(false)]
public XFontStyle Style
{
get { return _style; }
}
readonly XFontStyle _style;
/// <summary>
/// Indicates whether this XFont object is bold.
/// </summary>
public bool Bold
{
get { return (_style & XFontStyle.Bold) == XFontStyle.Bold; }
}
/// <summary>
/// Indicates whether this XFont object is italic.
/// </summary>
public bool Italic
{
get { return (_style & XFontStyle.Italic) == XFontStyle.Italic; }
}
/// <summary>
/// Indicates whether this XFont object is stroke out.
/// </summary>
public bool Strikeout
{
get { return (_style & XFontStyle.Strikeout) == XFontStyle.Strikeout; }
}
/// <summary>
/// Indicates whether this XFont object is underlined.
/// </summary>
public bool Underline
{
get { return (_style & XFontStyle.Underline) == XFontStyle.Underline; }
}
/// <summary>
/// Temporary HACK for XPS to PDF converter.
/// </summary>
internal bool IsVertical
{
get { return _isVertical; }
set { _isVertical = value; }
}
bool _isVertical;
/// <summary>
/// Gets the PDF options of the font.
/// </summary>
public XPdfFontOptions PdfOptions
{
get { return _pdfOptions ?? (_pdfOptions = new XPdfFontOptions()); }
}
XPdfFontOptions _pdfOptions;
/// <summary>
/// Indicates whether this XFont is encoded as Unicode.
/// </summary>
internal bool Unicode
{
get { return _pdfOptions != null && _pdfOptions.FontEncoding == PdfFontEncoding.Unicode; }
}
/// <summary>
/// Gets the cell space for the font. The CellSpace is the line spacing, the sum of CellAscent and CellDescent and optionally some extra space.
/// </summary>
public int CellSpace
{
get { return _cellSpace; }
internal set { _cellSpace = value; }
}
int _cellSpace;
/// <summary>
/// Gets the cell ascent, the area above the base line that is used by the font.
/// </summary>
public int CellAscent
{
get { return _cellAscent; }
internal set { _cellAscent = value; }
}
int _cellAscent;
/// <summary>
/// Gets the cell descent, the area below the base line that is used by the font.
/// </summary>
public int CellDescent
{
get { return _cellDescent; }
internal set { _cellDescent = value; }
}
int _cellDescent;
/// <summary>
/// Gets the font metrics.
/// </summary>
/// <value>The metrics.</value>
public XFontMetrics Metrics
{
get
{
// Code moved to InitializeFontMetrics().
//if (_fontMetrics == null)
//{
// FontDescriptor descriptor = FontDescriptorStock.Global.CreateDescriptor(this);
// _fontMetrics = new XFontMetrics(descriptor.FontName, descriptor.UnitsPerEm, descriptor.Ascender, descriptor.Descender,
// descriptor.Leading, descriptor.LineSpacing, descriptor.CapHeight, descriptor.XHeight, descriptor.StemV, 0, 0, 0);
//}
Debug.Assert(_fontMetrics != null, "InitializeFontMetrics() not yet called.");
return _fontMetrics;
}
}
XFontMetrics _fontMetrics;
/// <summary>
/// Returns the line spacing, in pixels, of this font. The line spacing is the vertical distance
/// between the base lines of two consecutive lines of text. Thus, the line spacing includes the
/// blank space between lines along with the height of the character itself.
/// </summary>
public double GetHeight()
{
double value = CellSpace * _emSize / UnitsPerEm;
#if CORE || NETFX_CORE || UWP
return value;
#endif
#if GDI && !WPF
#if DEBUG_
double gdiValue = Font.GetHeight();
Debug.Assert(DoubleUtil.AreRoughlyEqual(gdiValue, value, 5));
#endif
return value;
#endif
#if WPF && !GDI
return value;
#endif
#if WPF && GDI // Testing only
return value;
#endif
}
/// <summary>
/// Returns the line spacing, in the current unit of a specified Graphics object, of this font.
/// The line spacing is the vertical distance between the base lines of two consecutive lines of
/// text. Thus, the line spacing includes the blank space between lines along with the height of
/// </summary>
[Obsolete("Use GetHeight() without parameter.")]
public double GetHeight(XGraphics graphics)
{
#if true
throw new InvalidOperationException("Honestly: Use GetHeight() without parameter!");
#else
#if CORE || NETFX_CORE
double value = CellSpace * _emSize / UnitsPerEm;
return value;
#endif
#if GDI && !WPF
if (graphics._gfx != null) // #MediumTrust
{
double value = Font.GetHeight(graphics._gfx);
Debug.Assert(value == Font.GetHeight(graphics._gfx.DpiY));
double value2 = CellSpace * _emSize / UnitsPerEm;
Debug.Assert(value - value2 < 1e-3, "??");
return Font.GetHeight(graphics._gfx);
}
return CellSpace * _emSize / UnitsPerEm;
#endif
#if WPF && !GDI
double value = CellSpace * _emSize / UnitsPerEm;
return value;
#endif
#if GDI && WPF // Testing only
if (graphics.TargetContext == XGraphicTargetContext.GDI)
{
#if DEBUG
double value = Font.GetHeight(graphics._gfx);
// 2355*(0.3/2048)*96 = 33.11719
double myValue = CellSpace * (_emSize / (96 * UnitsPerEm)) * 96;
myValue = CellSpace * _emSize / UnitsPerEm;
//Debug.Assert(value == myValue, "??");
//Debug.Assert(value - myValue < 1e-3, "??");
#endif
return Font.GetHeight(graphics._gfx);
}
if (graphics.TargetContext == XGraphicTargetContext.WPF)
{
double value = CellSpace * _emSize / UnitsPerEm;
return value;
}
// ReSharper disable HeuristicUnreachableCode
Debug.Fail("Either GDI or WPF.");
return 0;
// ReSharper restore HeuristicUnreachableCode
#endif
#endif
}
/// <summary>
/// Gets the line spacing of this font.
/// </summary>
[Browsable(false)]
public int Height
{
// Implementation from System.Drawing.Font.cs
get { return (int)Math.Ceiling(GetHeight()); }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
internal XGlyphTypeface GlyphTypeface
{
get { return _glyphTypeface; }
}
XGlyphTypeface _glyphTypeface;
internal OpenTypeDescriptor Descriptor
{
get { return _descriptor; }
private set { _descriptor = value; }
}
OpenTypeDescriptor _descriptor;
internal string FamilyName
{
get { return _familyName; }
}
string _familyName;
internal int UnitsPerEm
{
get { return _unitsPerEm; }
private set { _unitsPerEm = value; }
}
internal int _unitsPerEm;
/// <summary>
/// Override style simulations by using the value of StyleSimulations.
/// </summary>
internal bool OverrideStyleSimulations;
/// <summary>
/// Used to enforce style simulations by renderer. For development purposes only.
/// </summary>
internal XStyleSimulations StyleSimulations;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if CORE || GDI
/// <summary>
/// Gets the GDI family.
/// </summary>
/// <value>The GDI family.</value>
public GdiFontFamily GdiFontFamily
{
get { return _gdiFontFamily; }
}
readonly GdiFontFamily _gdiFontFamily;
internal GdiFont GdiFont
{
get { return _gdiFont; }
}
Font _gdiFont;
internal static XFontStyle FontStyleFrom(GdiFont font)
{
return
(font.Bold ? XFontStyle.Bold : 0) |
(font.Italic ? XFontStyle.Italic : 0) |
(font.Strikeout ? XFontStyle.Strikeout : 0) |
(font.Underline ? XFontStyle.Underline : 0);
}
#if true || UseGdiObjects
/// <summary>
/// Implicit conversion form Font to XFont
/// </summary>
public static implicit operator XFont(GdiFont font)
{
return new XFont(font);
}
#endif
#endif
#if WPF
/// <summary>
/// Gets the WPF font family.
/// Can be null.
/// </summary>
internal WpfFontFamily WpfFontFamily
{
get { return _wpfFontFamily; }
}
WpfFontFamily _wpfFontFamily;
internal WpfTypeface WpfTypeface
{
get { return _wpfTypeface; }
}
WpfTypeface _wpfTypeface;
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Cache PdfFontTable.FontSelector to speed up finding the right PdfFont
/// if this font is used more than once.
/// </summary>
internal string Selector
{
get { return _selector; }
set { _selector = value; }
}
string _selector;
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get { return String.Format(CultureInfo.InvariantCulture, "font=('{0}' {1:0.##})", Name, Size); }
}
}
}

View File

@@ -0,0 +1,319 @@
#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 CORE || GDI
using System.Drawing;
using GdiFont = System.Drawing.Font;
using GdiFontFamily = System.Drawing.FontFamily;
using GdiFontStyle = System.Drawing.FontStyle;
#endif
#if WPF
using System.Windows.Media;
using System.Windows.Markup;
using WpfFontFamily = System.Windows.Media.FontFamily;
using WpfFontStyle = System.Windows.FontStyle;
#endif
using PdfSharp.Fonts;
using PdfSharp.Fonts.OpenType;
namespace PdfSharp.Drawing
{
/// <summary>
/// Defines a group of typefaces having a similar basic design and certain variations in styles.
/// </summary>
public sealed class XFontFamily
{
/// <summary>
/// Initializes a new instance of the <see cref="XFontFamily"/> class.
/// </summary>
/// <param name="familyName">The family name of a font.</param>
public XFontFamily(string familyName)
{
FamilyInternal = FontFamilyInternal.GetOrCreateFromName(familyName, true);
}
internal XFontFamily(string familyName, bool createPlatformObjects)
{
FamilyInternal = FontFamilyInternal.GetOrCreateFromName(familyName, createPlatformObjects);
}
/// <summary>
/// Initializes a new instance of the <see cref="XFontFamily"/> class from FontFamilyInternal.
/// </summary>
XFontFamily(FontFamilyInternal fontFamilyInternal)
{
FamilyInternal = fontFamilyInternal;
}
#if CORE || GDI
//public XFontFamily(GdiFontFamily gdiFontFamily)
//{
// FamilyInternal = FontFamilyInternal.GetOrCreateFromGdi(gdiFontFamily);
//}
#endif
#if WPF
//public XFontFamily(WpfFontFamily wpfFontFamily)
//{
// FamilyInternal = FontFamilyInternal.GetOrCreateFromWpf(wpfFontFamily);
// //// HACK
// //int idxHash = _name.LastIndexOf('#');
// //if (idxHash > 0)
// // _name = _name.Substring(idxHash + 1);
// //_wpfFamily = family;
//}
#endif
internal static XFontFamily CreateFromName_not_used(string name, bool createPlatformFamily)
{
XFontFamily fontFamily = new XFontFamily(name);
if (createPlatformFamily)
{
#if GDI
//fontFamily._gdiFamily = new System.Drawing.FontFamily(name);
#endif
#if WPF
//fontFamily._wpfFamily = new System.Windows.Media.FontFamily(name);
#endif
}
return fontFamily;
}
/// <summary>
/// An XGlyphTypeface for a font source that comes from a custom font resolver
/// creates a solitary font family exclusively for it.
/// </summary>
internal static XFontFamily GetOrCreateFontFamily(string name)
{
// Custom font resolver face names must not clash with platform family names.
FontFamilyInternal fontFamilyInternal = FontFamilyCache.GetFamilyByName(name);
if (fontFamilyInternal == null)
{
fontFamilyInternal = FontFamilyInternal.GetOrCreateFromName(name, false);
fontFamilyInternal = FontFamilyCache.CacheOrGetFontFamily(fontFamilyInternal);
}
// Create font family and save it in cache. Do not try to create platform objects.
return new XFontFamily(fontFamilyInternal);
}
#if CORE || GDI
internal static XFontFamily GetOrCreateFromGdi(GdiFont font)
{
FontFamilyInternal fontFamilyInternal = FontFamilyInternal.GetOrCreateFromGdi(font.FontFamily);
return new XFontFamily(fontFamilyInternal);
}
#endif
#if WPF
internal static XFontFamily GetOrCreateFromWpf(WpfFontFamily wpfFontFamily)
{
FontFamilyInternal fontFamilyInternal = FontFamilyInternal.GetOrCreateFromWpf(wpfFontFamily);
return new XFontFamily(fontFamilyInternal);
}
#endif
#if SILVERLIGHT
//internal static XFontFamily CreateFromWpf(System.Windows.Media.FontFamily wpfFontFamily)
//{
// XFontFamily fontFamily = new XFontFamily(wpfFontFamily.FamilyNames[XmlLanguage.GetLanguage("en")]);
// fontFamily._wpfFamily = wpfFontFamily;
// return fontFamily;
//}
#endif
/// <summary>
/// Gets the name of the font family.
/// </summary>
public string Name
{
get { return FamilyInternal.Name; }
}
#if true__
public double LineSpacing
{
get
{
WpfFamily.FamilyTypefaces[0].UnderlineThickness
}
}
#endif
/// <summary>
/// Returns the cell ascent, in design units, of the XFontFamily object of the specified style.
/// </summary>
public int GetCellAscent(XFontStyle style)
{
OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style);
int result = descriptor.Ascender;
#if DEBUG_ && GDI
int gdiValue = _gdiFamily.GetCellAscent((FontStyle)style);
Debug.Assert(gdiValue == result);
#endif
return result;
}
/// <summary>
/// Returns the cell descent, in design units, of the XFontFamily object of the specified style.
/// </summary>
public int GetCellDescent(XFontStyle style)
{
OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style);
int result = descriptor.Descender;
#if DEBUG_ && GDI
int gdiValue = _gdiFamily.GetCellDescent((FontStyle)style);
Debug.Assert(gdiValue == result);
#endif
return result;
}
/// <summary>
/// Gets the height, in font design units, of the em square for the specified style.
/// </summary>
public int GetEmHeight(XFontStyle style)
{
OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style);
int result = descriptor.UnitsPerEm;
#if DEBUG_ && GDI
int gdiValue = _gdiFamily.GetEmHeight((FontStyle)style);
Debug.Assert(gdiValue == result);
#endif
#if DEBUG_
int headValue = descriptor.FontFace.head.unitsPerEm;
Debug.Assert(headValue == result);
#endif
return result;
}
/// <summary>
/// Returns the line spacing, in design units, of the FontFamily object of the specified style.
/// The line spacing is the vertical distance between the base lines of two consecutive lines of text.
/// </summary>
public int GetLineSpacing(XFontStyle style)
{
OpenTypeDescriptor descriptor = (OpenTypeDescriptor)FontDescriptorCache.GetOrCreateDescriptor(Name, style);
int result = descriptor.LineSpacing;
#if DEBUG_ && GDI
int gdiValue = _gdiFamily.GetLineSpacing((FontStyle)style);
Debug.Assert(gdiValue == result);
#endif
#if DEBUG_ && WPF && !SILVERLIGHT
int wpfValue = (int)Math.Round(_wpfFamily.LineSpacing * GetEmHeight(style));
Debug.Assert(wpfValue == result);
#endif
return result;
}
//public string GetName(int language);
/// <summary>
/// Indicates whether the specified FontStyle enumeration is available.
/// </summary>
public bool IsStyleAvailable(XFontStyle style)
{
XGdiFontStyle xStyle = ((XGdiFontStyle)style) & XGdiFontStyle.BoldItalic;
#if CORE
throw new InvalidOperationException("In CORE build it is the responsibility of the developer to provide all required font faces.");
#endif
#if GDI && !WPF
if (GdiFamily != null)
return GdiFamily.IsStyleAvailable((GdiFontStyle)xStyle);
return false;
#endif
#if WPF && !GDI
if (WpfFamily != null)
return FontHelper.IsStyleAvailable(this, xStyle);
return false;
#endif
#if WPF && GDI
#if DEBUG
//bool gdiResult = _gdiFamily.IsStyle Available((FontStyle)style);
//bool wpfResult = FontHelper.IsStyle Available(this, style);
//// TODOWPF: check when fails
//Debug.Assert(gdiResult == wpfResult, "GDI+ and WPF provide different values.");
#endif
return FontHelper.IsStyleAvailable(this, xStyle);
#endif
#if NETFX_CORE || UWP
throw new InvalidOperationException("In NETFX_CORE build it is the responsibility of the developer to provide all required font faces.");
#endif
}
/// <summary>
/// Returns an array that contains all the FontFamily objects associated with the current graphics context.
/// </summary>
[Obsolete("Use platform API directly.")]
public static XFontFamily[] Families
{
get
{
throw new InvalidOperationException("Obsolete and not implemted any more.");
}
}
/// <summary>
/// Returns an array that contains all the FontFamily objects available for the specified
/// graphics context.
/// </summary>
[Obsolete("Use platform API directly.")]
public static XFontFamily[] GetFamilies(XGraphics graphics)
{
throw new InvalidOperationException("Obsolete and not implemted any more.");
}
#if GDI
/// <summary>
/// Gets the underlying GDI+ font family object.
/// Is null if the font was created by a font resolver.
/// </summary>
internal GdiFontFamily GdiFamily
{
get { return FamilyInternal.GdiFamily; }
}
#endif
#if WPF
/// <summary>
/// Gets the underlying WPF font family object.
/// Is null if the font was created by a font resolver.
/// </summary>
internal WpfFontFamily WpfFamily
{
get { return FamilyInternal.WpfFamily; }
}
#endif
/// <summary>
/// The implementation sigleton of font family;
/// </summary>
internal FontFamilyInternal FamilyInternal;
}
}

View File

@@ -0,0 +1,203 @@
#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.Drawing
{
/// <summary>
/// Collects information of a font.
/// </summary>
public sealed class XFontMetrics
{
internal XFontMetrics(string name, int unitsPerEm, int ascent, int descent, int leading, int lineSpacing,
int capHeight, int xHeight, int stemV, int stemH, int averageWidth, int maxWidth ,
int underlinePosition, int underlineThickness, int strikethroughPosition, int strikethroughThickness)
{
_name = name;
_unitsPerEm = unitsPerEm;
_ascent = ascent;
_descent = descent;
_leading = leading;
_lineSpacing = lineSpacing;
_capHeight = capHeight;
_xHeight = xHeight;
_stemV = stemV;
_stemH = stemH;
_averageWidth = averageWidth;
_maxWidth = maxWidth;
_underlinePosition = underlinePosition;
_underlineThickness = underlineThickness;
_strikethroughPosition = strikethroughPosition;
_strikethroughThickness = strikethroughThickness;
}
/// <summary>
/// Gets the font name.
/// </summary>
public string Name
{
get { return _name; }
}
readonly string _name;
/// <summary>
/// Gets the ascent value.
/// </summary>
public int UnitsPerEm
{
get { return _unitsPerEm; }
}
readonly int _unitsPerEm;
/// <summary>
/// Gets the ascent value.
/// </summary>
public int Ascent
{
get { return _ascent; }
}
readonly int _ascent;
/// <summary>
/// Gets the descent value.
/// </summary>
public int Descent
{
get { return _descent; }
}
readonly int _descent;
/// <summary>
/// Gets the average width.
/// </summary>
public int AverageWidth
{
get { return _averageWidth; }
}
readonly int _averageWidth;
/// <summary>
/// Gets the height of capital letters.
/// </summary>
public int CapHeight
{
get { return _capHeight; }
}
readonly int _capHeight;
/// <summary>
/// Gets the leading value.
/// </summary>
public int Leading
{
get { return _leading; }
}
readonly int _leading;
/// <summary>
/// Gets the line spacing value.
/// </summary>
public int LineSpacing
{
get { return _lineSpacing; }
}
readonly int _lineSpacing;
/// <summary>
/// Gets the maximum width of a character.
/// </summary>
public int MaxWidth
{
get { return _maxWidth; }
}
readonly int _maxWidth;
/// <summary>
/// Gets an internal value.
/// </summary>
public int StemH
{
get { return _stemH; }
}
readonly int _stemH;
/// <summary>
/// Gets an internal value.
/// </summary>
public int StemV
{
get { return _stemV; }
}
readonly int _stemV;
/// <summary>
/// Gets the height of a lower-case character.
/// </summary>
public int XHeight
{
get { return _xHeight; }
}
readonly int _xHeight;
/// <summary>
/// Gets the underline position.
/// </summary>
public int UnderlinePosition
{
get { return _underlinePosition; }
}
readonly int _underlinePosition;
/// <summary>
/// Gets the underline thicksness.
/// </summary>
public int UnderlineThickness
{
get { return _underlineThickness; }
}
readonly int _underlineThickness;
/// <summary>
/// Gets the strikethrough position.
/// </summary>
public int StrikethroughPosition
{
get { return _strikethroughPosition; }
}
readonly int _strikethroughPosition;
/// <summary>
/// Gets the strikethrough thicksness.
/// </summary>
public int StrikethroughThickness
{
get { return _strikethroughThickness; }
}
readonly int _strikethroughThickness;
}
}

View File

@@ -0,0 +1,299 @@
#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.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using PdfSharp.Fonts;
#if CORE || GDI
using GdiFont = System.Drawing.Font;
using GdiFontStyle = System.Drawing.FontStyle;
#endif
#if WPF
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using WpfFontFamily = System.Windows.Media.FontFamily;
using WpfTypeface = System.Windows.Media.Typeface;
using WpfGlyphTypeface = System.Windows.Media.GlyphTypeface;
#endif
using PdfSharp.Internal;
using PdfSharp.Fonts.OpenType;
namespace PdfSharp.Drawing
{
/// <summary>
/// The bytes of a font file.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
internal class XFontSource
{
// Implementation Notes
//
// * XFontSource represents a single font (file) in memory.
// * An XFontSource hold a reference to it OpenTypeFontface.
// * To prevent large heap fragmentation this class must exists only once.
// * TODO: ttcf
// Signature of a true type collection font.
const uint ttcf = 0x66637474;
XFontSource(byte[] bytes, ulong key)
{
_fontName = null;
_bytes = bytes;
_key = key;
}
/// <summary>
/// Gets an existing font source or creates a new one.
/// A new font source is cached in font factory.
/// </summary>
public static XFontSource GetOrCreateFrom(byte[] bytes)
{
ulong key = FontHelper.CalcChecksum(bytes);
XFontSource fontSource;
if (!FontFactory.TryGetFontSourceByKey(key, out fontSource))
{
fontSource = new XFontSource(bytes, key);
// Theoretically the font source could be created by a differend thread in the meantime.
fontSource = FontFactory.CacheFontSource(fontSource);
}
return fontSource;
}
#if CORE || GDI
internal static XFontSource GetOrCreateFromGdi(string typefaceKey, GdiFont gdiFont)
{
byte[] bytes = ReadFontBytesFromGdi(gdiFont);
XFontSource fontSource = GetOrCreateFrom(typefaceKey, bytes);
return fontSource;
}
static byte[] ReadFontBytesFromGdi(GdiFont gdiFont)
{
// Weird: LastError is always 123 or 127. Comment out Debug.Assert.
int error = Marshal.GetLastWin32Error();
//Debug.Assert(error == 0);
error = Marshal.GetLastWin32Error();
//Debug.Assert(error == 0);
IntPtr hfont = gdiFont.ToHfont();
#if true
IntPtr hdc = NativeMethods.GetDC(IntPtr.Zero);
#else
NativeMethods.LOGFONT logFont = new NativeMethods.LOGFONT();
logFont.lfHeight = 30;
logFont.lfWidth = 0;
logFont.lfEscapement = 0;
logFont.lfOrientation = 0;
logFont.lfWeight = 400;
logFont.lfItalic = 0;
logFont.lfUnderline = 0;
logFont.lfStrikeOut = 0;
logFont.lfCharSet = 0;
logFont.lfOutPrecision = 0;
logFont.lfClipPrecision = 0;
logFont.lfQuality = 0;
logFont.lfPitchAndFamily = 0;
logFont.lfFaceName = "Arial";
gdiFont.ToLogFont(logFont);
hfont = NativeMethods.CreateFontIndirect(logFont);
// IntPtr hdc = NativeMethods.CreateDC("DISPLAY", null, null, IntPtr.Zero);
IntPtr hdc = NativeMethods.CreateCompatibleDC(IntPtr.Zero);
#endif
error = Marshal.GetLastWin32Error();
//Debug.Assert(error == 0);
IntPtr oldFont = NativeMethods.SelectObject(hdc, hfont);
error = Marshal.GetLastWin32Error();
//Debug.Assert(error == 0);
// Get size of the font file.
bool isTtcf = false;
// In Azure I get 0xc0000022
int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
// Check for ntstatus.h: #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
if ((uint)size == 0xc0000022)
throw new InvalidOperationException("Microsoft Azure returns STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) from GetFontData. This is a bug in Azure. You must implement a FontResolver to circumvent this issue.");
if (size == NativeMethods.GDI_ERROR)
{
// Assume that the font file is a true type collection.
size = NativeMethods.GetFontData(hdc, ttcf, 0, null, 0);
isTtcf = true;
}
error = Marshal.GetLastWin32Error();
//Debug.Assert(error == 0);
if (size == 0)
throw new InvalidOperationException("Cannot retrieve font data.");
byte[] bytes = new byte[size];
int effectiveSize = NativeMethods.GetFontData(hdc, isTtcf ? ttcf : 0, 0, bytes, size);
Debug.Assert(size == effectiveSize);
// Clean up.
NativeMethods.SelectObject(hdc, oldFont);
NativeMethods.ReleaseDC(IntPtr.Zero, hdc);
return bytes;
}
#endif
#if WPF && !SILVERLIGHT
internal static XFontSource GetOrCreateFromWpf(string typefaceKey, WpfGlyphTypeface wpfGlyphTypeface)
{
byte[] bytes = ReadFontBytesFromWpf(wpfGlyphTypeface);
XFontSource fontSource = GetOrCreateFrom(typefaceKey, bytes);
return fontSource;
}
internal static byte[] ReadFontBytesFromWpf(WpfGlyphTypeface wpfGlyphTypeface)
{
using (Stream fontStream = wpfGlyphTypeface.GetFontStream())
{
if (fontStream == null)
throw new InvalidOperationException("Cannot retrieve font data.");
int size = (int)fontStream.Length;
byte[] bytes = new byte[size];
fontStream.Read(bytes, 0, size);
return bytes;
}
}
#endif
static XFontSource GetOrCreateFrom(string typefaceKey, byte[] fontBytes)
{
XFontSource fontSource;
ulong key = FontHelper.CalcChecksum(fontBytes);
if (FontFactory.TryGetFontSourceByKey(key, out fontSource))
{
// The font source already exists, but is not yet cached under the specified typeface key.
FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
}
else
{
// No font source exists. Create new one and cache it.
fontSource = new XFontSource(fontBytes, key);
FontFactory.CacheNewFontSource(typefaceKey, fontSource);
}
return fontSource;
}
public static XFontSource CreateCompiledFont(byte[] bytes)
{
XFontSource fontSource = new XFontSource(bytes, 0);
return fontSource;
}
/// <summary>
/// Gets or sets the fontface.
/// </summary>
internal OpenTypeFontface Fontface
{
get { return _fontface; }
set
{
_fontface = value;
_fontName = value.name.FullFontName;
}
}
OpenTypeFontface _fontface;
/// <summary>
/// Gets the key that uniquely identifies this font source.
/// </summary>
internal ulong Key
{
get
{
if (_key == 0)
_key = FontHelper.CalcChecksum(Bytes);
return _key;
}
}
ulong _key;
public void IncrementKey()
{
// HACK: Depends on implementation of CalcChecksum.
// Increment check sum and keep length untouched.
_key += 1ul << 32;
}
/// <summary>
/// Gets the name of the font's name table.
/// </summary>
public string FontName
{
get { return _fontName; }
}
string _fontName;
/// <summary>
/// Gets the bytes of the font.
/// </summary>
public byte[] Bytes
{
get { return _bytes; }
}
readonly byte[] _bytes;
public override int GetHashCode()
{
return (int)((Key >> 32) ^ Key);
}
public override bool Equals(object obj)
{
XFontSource fontSource = obj as XFontSource;
if (fontSource == null)
return false;
return Key == fontSource.Key;
}
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSha rper disable UnusedMember.Local
internal string DebuggerDisplay
// ReShar per restore UnusedMember.Local
{
// The key is converted to a value a human can remember during debugging.
get { return String.Format(CultureInfo.InvariantCulture, "XFontSource: '{0}', keyhash={1}", FontName, Key % 99991 /* largest prime number less than 100000 */); }
}
}
}

View File

@@ -0,0 +1,53 @@
#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.Drawing
{
#if PDFSHARP20
enum FontStretchValues
{
UltraCondensed = 1,
ExtraCondensed = 2,
Condensed = 3,
SemiCondensed = 4,
Normal = 5,
SemiExpanded = 6,
Expanded = 7,
ExtraExpanded = 8,
UltraExpanded = 9,
}
/// <summary>
/// NYI. Reserved for future extensions of PDFsharp.
/// </summary>
// [DebuggerDisplay("'{Name}', {Size}")]
public class XFontStretch
{ }
#endif
}

View File

@@ -0,0 +1,174 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
#endif
// Not used in PDFsharp 1.x.
namespace PdfSharp.Drawing
{
#if true_ // PDFSHARP20
/// <summary>
/// Defines the density of a typeface, in terms of the lightness or heaviness of the strokes.
/// </summary>
[DebuggerDisplay("'{Weight}'")]
public class XFontWeight : IFormattable
{
internal XFontWeight(int weight)
{
_weight = weight;
}
/// <summary>
/// Gets the weight of the font, a value between 1 and 999.
/// </summary>
public int Weight
{
get { return (_weight); }
}
private readonly int _weight;
//public static XFontWeight FromOpenTypeWeight(int weightValue)
//{
// if (weightValue < 1 || weightValue > 999)
// throw new ArgumentOutOfRangeException("weightValue", "Parameter must be between 1 and 999.");
// return new XFontWeight(weightValue);
//}
/// <summary>
/// Compares the specified font weights.
/// </summary>
public static int Compare(XFontWeight left, XFontWeight right)
{
return left._weight - right._weight;
}
/// <summary>
/// Implements the operator &lt;.
/// </summary>
public static bool operator <(XFontWeight left, XFontWeight right)
{
return Compare(left, right) < 0;
}
/// <summary>
/// Implements the operator &lt;=.
/// </summary>
public static bool operator <=(XFontWeight left, XFontWeight right)
{
return Compare(left, right) <= 0;
}
/// <summary>
/// Implements the operator &gt;.
/// </summary>
public static bool operator >(XFontWeight left, XFontWeight right)
{
return Compare(left, right) > 0;
}
/// <summary>
/// Implements the operator &gt;=.
/// </summary>
public static bool operator >=(XFontWeight left, XFontWeight right)
{
return Compare(left, right) >= 0;
}
/// <summary>
/// Implements the operator ==.
/// </summary>
public static bool operator ==(XFontWeight left, XFontWeight right)
{
return Compare(left, right) == 0;
}
/// <summary>
/// Implements the operator !=.
/// </summary>
public static bool operator !=(XFontWeight left, XFontWeight right)
{
return !(left == right);
}
/// <summary>
/// Determines whether the specified <see cref="XFontWeight"/> is equal to the current <see cref="XFontWeight"/>.
/// </summary>
public bool Equals(XFontWeight obj)
{
return this == obj;
}
/// <summary>
/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
/// </summary>
public override bool Equals(object obj)
{
return (obj is XFontWeight) && this == ((XFontWeight)obj);
}
/// <summary>
/// Serves as a hash function for this type.
/// </summary>
public override int GetHashCode()
{
return Weight;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </summary>
public override string ToString()
{
return ConvertToString(null, null);
}
string IFormattable.ToString(string format, IFormatProvider provider)
{
return ConvertToString(format, provider);
}
internal string ConvertToString(string format, IFormatProvider provider)
{
provider = provider ?? CultureInfo.InvariantCulture;
string str;
if (!XFontWeights.FontWeightToString(Weight, out str))
return Weight.ToString(format, provider);
return str;
}
}
#endif
}

View File

@@ -0,0 +1,309 @@
#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
// Not used in PDFsharp 1.x.
namespace PdfSharp.Drawing
{
enum FontWeightValues
{
Thin = 100,
ExtraLight = 200,
Light = 300,
Normal = 400,
Medium = 500,
SemiBold = 600,
Bold = 700,
ExtraBold = 800,
Black = 900,
ExtraBlack = 950,
}
#if true_ // PDFSHARP20
/// <summary>
/// Defines a set of static predefined XFontWeight values.
/// </summary>
public static class XFontWeights
{
internal static bool FontWeightStringToKnownWeight(string s, IFormatProvider provider, ref XFontWeight fontWeight)
{
int num;
switch (s.ToLower())
{
case "thin":
fontWeight = Thin;
return true;
case "extralight":
fontWeight = ExtraLight;
return true;
case "ultralight":
fontWeight = UltraLight;
return true;
case "light":
fontWeight = Light;
return true;
case "normal":
fontWeight = Normal;
return true;
case "regular":
fontWeight = Regular;
return true;
case "medium":
fontWeight = Medium;
return true;
case "semibold":
fontWeight = SemiBold;
return true;
case "demibold":
fontWeight = DemiBold;
return true;
case "bold":
fontWeight = Bold;
return true;
case "extrabold":
fontWeight = ExtraBold;
return true;
case "ultrabold":
fontWeight = UltraBold;
return true;
case "heavy":
fontWeight = Heavy;
return true;
case "black":
fontWeight = Black;
return true;
case "extrablack":
fontWeight = ExtraBlack;
return true;
case "ultrablack":
fontWeight = UltraBlack;
return true;
}
if (Int32.TryParse(s, NumberStyles.Integer, provider, out num))
{
fontWeight = new XFontWeight(num);
return true;
}
return false;
}
internal static bool FontWeightToString(int weight, out string convertedValue)
{
switch (weight)
{
case 100:
convertedValue = "Thin";
return true;
case 200:
convertedValue = "ExtraLight";
return true;
case 300:
convertedValue = "Light";
return true;
case 400:
convertedValue = "Normal";
return true;
case 500:
convertedValue = "Medium";
return true;
case 600:
convertedValue = "SemiBold";
return true;
case 700:
convertedValue = "Bold";
return true;
case 800:
convertedValue = "ExtraBold";
return true;
case 900:
convertedValue = "Black";
return true;
case 950:
convertedValue = "ExtraBlack";
return true;
}
convertedValue = null;
return false;
}
/// <summary>
/// Specifies a "Thin" font weight.
/// </summary>
public static XFontWeight Thin
{
get { return new XFontWeight(100); }
}
/// <summary>
/// Specifies a "ExtraLight" font weight.
/// </summary>
public static XFontWeight ExtraLight
{
get { return new XFontWeight(200); }
}
/// <summary>
/// Specifies a "UltraLight" font weight.
/// </summary>
public static XFontWeight UltraLight
{
get { return new XFontWeight(200); }
}
/// <summary>
/// Specifies a "Light" font weight.
/// </summary>
public static XFontWeight Light
{
get { return new XFontWeight(300); }
}
/// <summary>
/// Specifies a "Normal" font weight.
/// </summary>
public static XFontWeight Normal
{
get { return new XFontWeight(400); }
}
/// <summary>
/// Specifies a "Regular" font weight.
/// </summary>
public static XFontWeight Regular
{
get { return new XFontWeight(400); }
}
/// <summary>
/// Specifies a "Medium" font weight.
/// </summary>
public static XFontWeight Medium
{
get { return new XFontWeight(500); }
}
/// <summary>
/// Specifies a "SemiBold" font weight.
/// </summary>
public static XFontWeight SemiBold
{
get { return new XFontWeight(600); }
}
/// <summary>
/// Specifies a "DemiBold" font weight.
/// </summary>
public static XFontWeight DemiBold
{
get { return new XFontWeight(600); }
}
/// <summary>
/// Specifies a "Bold" font weight.
/// </summary>
public static XFontWeight Bold
{
get { return new XFontWeight(700); }
}
/// <summary>
/// Specifies a "ExtraBold" font weight.
/// </summary>
public static XFontWeight ExtraBold
{
get { return new XFontWeight(800); }
}
/// <summary>
/// Specifies a "UltraBold" font weight.
/// </summary>
public static XFontWeight UltraBold
{
get { return new XFontWeight(800); }
}
/// <summary>
/// Specifies a "Heavy" font weight.
/// </summary>
public static XFontWeight Heavy
{
get { return new XFontWeight(900); }
}
/// <summary>
/// Specifies a "Black" font weight.
/// </summary>
public static XFontWeight Black
{
get { return new XFontWeight(900); }
}
/// <summary>
/// Specifies a "ExtraBlack" font weight.
/// </summary>
public static XFontWeight ExtraBlack
{
get { return new XFontWeight(950); }
}
/// <summary>
/// Specifies a "UltraBlack" font weight.
/// </summary>
public static XFontWeight UltraBlack
{
get { return new XFontWeight(950); }
}
}
#endif
}

570
PdfSharp/Drawing/XForm.cs Normal file
View File

@@ -0,0 +1,570 @@
#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;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows.Media;
#endif
using PdfSharp.Drawing.Pdf;
using PdfSharp.Pdf;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.Filters;
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents a graphical object that can be used to render retained graphics on it.
/// In GDI+ it is represented by a Metafile, in WPF by a DrawingVisual, and in PDF by a Form XObjects.
/// </summary>
public class XForm : XImage, IContentStream
{
internal enum FormState
{
/// <summary>
/// The form is an imported PDF page.
/// </summary>
NotATemplate,
/// <summary>
/// The template is just created.
/// </summary>
Created,
/// <summary>
/// XGraphics.FromForm() was called.
/// </summary>
UnderConstruction,
/// <summary>
/// The form was drawn at least once and is 'frozen' now.
/// </summary>
Finished,
}
/// <summary>
/// Initializes a new instance of the <see cref="XForm"/> class.
/// </summary>
protected XForm()
{ }
#if GDI
/// <summary>
/// Initializes a new instance of the XForm class such that it can be drawn on the specified graphics
/// object.
/// </summary>
/// <param name="gfx">The graphics object that later is used to draw this form.</param>
/// <param name="size">The size in points of the form.</param>
public XForm(XGraphics gfx, XSize size)
{
if (gfx == null)
throw new ArgumentNullException("gfx");
if (size.Width < 1 || size.Height < 1)
throw new ArgumentNullException("size", "The size of the XPdfForm is to small.");
_formState = FormState.Created;
//templateSize = size;
_viewBox.Width = size.Width;
_viewBox.Height = size.Height;
// If gfx belongs to a PdfPage also create the PdfFormXObject
if (gfx.PdfPage != null)
{
_document = gfx.PdfPage.Owner;
_pdfForm = new PdfFormXObject(_document, this);
PdfRectangle rect = new PdfRectangle(new XPoint(), size);
_pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, rect);
}
}
#endif
#if GDI
/// <summary>
/// Initializes a new instance of the XForm class such that it can be drawn on the specified graphics
/// object.
/// </summary>
/// <param name="gfx">The graphics object that later is used to draw this form.</param>
/// <param name="width">The width of the form.</param>
/// <param name="height">The height of the form.</param>
public XForm(XGraphics gfx, XUnit width, XUnit height)
: this(gfx, new XSize(width, height))
{ }
#endif
/// <summary>
/// Initializes a new instance of the <see cref="XForm"/> class that represents a page of a PDF document.
/// </summary>
/// <param name="document">The PDF document.</param>
/// <param name="viewBox">The view box of the page.</param>
public XForm(PdfDocument document, XRect viewBox)
{
if (viewBox.Width < 1 || viewBox.Height < 1)
throw new ArgumentNullException("viewBox", "The size of the XPdfForm is to small.");
// I must tie the XPdfForm to a document immediately, because otherwise I would have no place where
// to store the resources.
if (document == null)
throw new ArgumentNullException("document", "An XPdfForm template must be associated with a document at creation time.");
_formState = FormState.Created;
_document = document;
_pdfForm = new PdfFormXObject(document, this);
//_templateSize = size;
_viewBox = viewBox;
PdfRectangle rect = new PdfRectangle(viewBox);
_pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, rect);
}
/// <summary>
/// Initializes a new instance of the <see cref="XForm"/> class that represents a page of a PDF document.
/// </summary>
/// <param name="document">The PDF document.</param>
/// <param name="size">The size of the page.</param>
public XForm(PdfDocument document, XSize size)
: this(document, new XRect(0, 0, size.Width, size.Height))
{
////if (size.width < 1 || size.height < 1)
//// throw new ArgumentNullException("size", "The size of the XPdfForm is to small.");
////// I must tie the XPdfForm to a document immediately, because otherwise I would have no place where
////// to store the resources.
////if (document == null)
//// throw new ArgumentNullException("document", "An XPdfForm template must be associated with a document.");
////_formState = FormState.Created;
////_document = document;
////pdfForm = new PdfFormXObject(document, this);
////templateSize = size;
////PdfRectangle rect = new PdfRectangle(new XPoint(), size);
////pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, rect);
}
/// <summary>
/// Initializes a new instance of the <see cref="XForm"/> class that represents a page of a PDF document.
/// </summary>
/// <param name="document">The PDF document.</param>
/// <param name="width">The width of the page.</param>
/// <param name="height">The height of the page</param>
public XForm(PdfDocument document, XUnit width, XUnit height)
: this(document, new XRect(0, 0, width, height))
{ }
/// <summary>
/// This function should be called when drawing the content of this form is finished.
/// The XGraphics object used for drawing the content is disposed by this function and
/// cannot be used for any further drawing operations.
/// PDFsharp automatically calls this function when this form was used the first time
/// in a DrawImage function.
/// </summary>
public void DrawingFinished()
{
if (_formState == FormState.Finished)
return;
if (_formState == FormState.NotATemplate)
throw new InvalidOperationException("This object is an imported PDF page and you cannot finish drawing on it because you must not draw on it at all.");
Finish();
}
/// <summary>
/// Called from XGraphics constructor that creates an instance that work on this form.
/// </summary>
internal void AssociateGraphics(XGraphics gfx)
{
if (_formState == FormState.NotATemplate)
throw new NotImplementedException("The current version of PDFsharp cannot draw on an imported page.");
if (_formState == FormState.UnderConstruction)
throw new InvalidOperationException("An XGraphics object already exists for this form.");
if (_formState == FormState.Finished)
throw new InvalidOperationException("After drawing a form it cannot be modified anymore.");
Debug.Assert(_formState == FormState.Created);
_formState = FormState.UnderConstruction;
Gfx = gfx;
}
internal XGraphics Gfx;
/// <summary>
/// Disposes this instance.
/// </summary>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
/// <summary>
/// Sets the form in the state FormState.Finished.
/// </summary>
internal virtual void Finish()
{
#if GDI
if (_formState == FormState.NotATemplate || _formState == FormState.Finished)
return;
if (Gfx.Metafile != null)
_gdiImage = Gfx.Metafile;
Debug.Assert(_formState == FormState.Created || _formState == FormState.UnderConstruction);
_formState = FormState.Finished;
Gfx.Dispose();
Gfx = null;
if (PdfRenderer != null)
{
//pdfForm.CreateStream(PdfEncoders.RawEncoding.GetBytes(PdfRenderer.GetContent()));
PdfRenderer.Close();
Debug.Assert(PdfRenderer == null);
if (_document.Options.CompressContentStreams)
{
_pdfForm.Stream.Value = Filtering.FlateDecode.Encode(_pdfForm.Stream.Value, _document.Options.FlateEncodeMode);
_pdfForm.Elements["/Filter"] = new PdfName("/FlateDecode");
}
int length = _pdfForm.Stream.Length;
_pdfForm.Elements.SetInteger("/Length", length);
}
#endif
#if WPF
#endif
}
/// <summary>
/// Gets the owning document.
/// </summary>
internal PdfDocument Owner
{
get { return _document; }
}
PdfDocument _document;
/// <summary>
/// Gets the color model used in the underlying PDF document.
/// </summary>
internal PdfColorMode ColorMode
{
get
{
if (_document == null)
return PdfColorMode.Undefined;
return _document.Options.ColorMode;
}
}
/// <summary>
/// Gets a value indicating whether this instance is a template.
/// </summary>
internal bool IsTemplate
{
get { return _formState != FormState.NotATemplate; }
}
internal FormState _formState;
/// <summary>
/// Get the width of the page identified by the property PageNumber.
/// </summary>
[Obsolete("Use either PixelWidth or PointWidth. Temporarily obsolete because of rearrangements for WPF. Currently same as PixelWidth, but will become PointWidth in future releases of PDFsharp.")]
public override double Width
{
//get { return templateSize.width; }
get { return _viewBox.Width; }
}
/// <summary>
/// Get the width of the page identified by the property PageNumber.
/// </summary>
[Obsolete("Use either PixelHeight or PointHeight. Temporarily obsolete because of rearrangements for WPF. Currently same as PixelHeight, but will become PointHeight in future releases of PDFsharp.")]
public override double Height
{
//get { return templateSize.height; }
get { return _viewBox.Height; }
}
/// <summary>
/// Get the width in point of this image.
/// </summary>
public override double PointWidth
{
//get { return templateSize.width; }
get { return _viewBox.Width; }
}
/// <summary>
/// Get the height in point of this image.
/// </summary>
public override double PointHeight
{
//get { return templateSize.height; }
get { return _viewBox.Height; }
}
/// <summary>
/// Get the width of the page identified by the property PageNumber.
/// </summary>
public override int PixelWidth
{
//get { return (int)templateSize.width; }
get { return (int)_viewBox.Width; }
}
/// <summary>
/// Get the height of the page identified by the property PageNumber.
/// </summary>
public override int PixelHeight
{
//get { return (int)templateSize.height; }
get { return (int)_viewBox.Height; }
}
/// <summary>
/// Get the size of the page identified by the property PageNumber.
/// </summary>
public override XSize Size
{
//get { return templateSize; }
get { return _viewBox.Size; }
}
//XSize templateSize;
/// <summary>
/// Gets the view box of the form.
/// </summary>
public XRect ViewBox
{
get { return _viewBox; }
}
XRect _viewBox;
/// <summary>
/// Gets 72, the horizontal resolution by design of a form object.
/// </summary>
public override double HorizontalResolution
{
get { return 72; }
}
/// <summary>
/// Gets 72 always, the vertical resolution by design of a form object.
/// </summary>
public override double VerticalResolution
{
get { return 72; }
}
/// <summary>
/// Gets or sets the bounding box.
/// </summary>
public XRect BoundingBox
{
get { return _boundingBox; }
set { _boundingBox = value; } // TODO: pdfForm = null
}
XRect _boundingBox;
/// <summary>
/// Gets or sets the transformation matrix.
/// </summary>
public virtual XMatrix Transform
{
get { return _transform; }
set
{
if (_formState == FormState.Finished)
throw new InvalidOperationException("After a XPdfForm was once drawn it must not be modified.");
_transform = value;
}
}
internal XMatrix _transform;
internal PdfResources Resources
{
get
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
return PdfForm.Resources;
//if (resources == null)
// resources = (PdfResources)pdfForm.Elements.GetValue(PdfFormXObject.Keys.Resources, VCF.Create); // VCF.CreateIndirect
//return resources;
}
}
//PdfResources resources;
/// <summary>
/// Implements the interface because the primary function is internal.
/// </summary>
PdfResources IContentStream.Resources
{
get { return Resources; }
}
/// <summary>
/// Gets the resource name of the specified font within this form.
/// </summary>
internal string GetFontName(XFont font, out PdfFont pdfFont)
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
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>
/// Tries to get the resource name of the specified font data within this form.
/// Returns null if no such font exists.
/// </summary>
internal string TryGetFontName(string idName, out PdfFont pdfFont)
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
pdfFont = _document.FontTable.TryGetFont(idName);
string name = null;
if (pdfFont != null)
name = Resources.AddFont(pdfFont);
return name;
}
/// <summary>
/// Gets the resource name of the specified font data within this form.
/// </summary>
internal string GetFontName(string idName, byte[] fontData, out PdfFont pdfFont)
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
pdfFont = _document.FontTable.GetFont(idName, fontData);
//pdfFont = new PdfType0Font(Owner, idName, fontData);
//pdfFont.Document = _document;
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 form.
/// </summary>
internal string GetImageName(XImage image)
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
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)
{
return GetImageName(image);
}
internal PdfFormXObject PdfForm
{
get
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
if (_pdfForm.Reference == null)
_document._irefTable.Add(_pdfForm);
return _pdfForm;
}
}
/// <summary>
/// Gets the resource name of the specified form within this form.
/// </summary>
internal string GetFormName(XForm form)
{
Debug.Assert(IsTemplate, "This function is for form templates only.");
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)
{
return GetFormName(form);
}
/// <summary>
/// The PdfFormXObject gets invalid when PageNumber or transform changed. This is because a modification
/// of an XPdfForm must not change objects that are already been drawn.
/// </summary>
internal PdfFormXObject _pdfForm; // TODO: make private
internal XGraphicsPdfRenderer PdfRenderer;
#if WPF && !SILVERLIGHT
/// <summary>
/// Gets a value indicating whether this image is cmyk.
/// </summary>
/// <value><c>true</c> if this image is cmyk; otherwise, <c>false</c>.</value>
internal override bool IsCmyk
{
get { return false; } // not supported and not relevant
}
/// <summary>
/// Gets a value indicating whether this image is JPEG.
/// </summary>
/// <value><c>true</c> if this image is JPEG; otherwise, <c>false</c>.</value>
internal override bool IsJpeg
{
get { return base.IsJpeg; }// not supported and not relevant
}
/// <summary>
/// Gets the JPEG memory stream (if IsJpeg returns true).
/// </summary>
/// <value>The memory.</value>
public override MemoryStream Memory
{
get { throw new NotImplementedException(); }
}
#endif
}
}

View File

@@ -0,0 +1,602 @@
#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.Globalization;
#if CORE || GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using GdiFontFamily = System.Drawing.FontFamily;
using GdiFont = System.Drawing.Font;
using GdiFontStyle = System.Drawing.FontStyle;
#endif
#if WPF
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using WpfFontFamily = System.Windows.Media.FontFamily;
using WpfTypeface = System.Windows.Media.Typeface;
using WpfGlyphTypeface = System.Windows.Media.GlyphTypeface;
using WpfStyleSimulations = System.Windows.Media.StyleSimulations;
#endif
#if UWP
using Windows.UI.Xaml.Media;
#endif
using PdfSharp.Fonts;
using PdfSharp.Fonts.OpenType;
using PdfSharp.Internal;
#pragma warning disable 649
#if SILVERLIGHT
#pragma warning disable 219
#endif
#if NETFX_CORE
#pragma warning disable 649
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Specifies a physical font face that corresponds to a font file on the disk or in memory.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
internal sealed class XGlyphTypeface
{
// Implementation Notes
// XGlyphTypeface is the centerpiece for font management. There is a one to one relationship
// between XFont an XGlyphTypeface.
//
// * Each XGlyphTypeface can belong to one or more XFont objects.
// * An XGlyphTypeface hold an XFontFamily.
// * XGlyphTypeface hold a reference to an OpenTypeFontface.
// *
//
const string KeyPrefix = "tk:"; // "typeface key"
#if CORE || GDI
XGlyphTypeface(string key, XFontFamily fontFamily, XFontSource fontSource, XStyleSimulations styleSimulations, GdiFont gdiFont)
{
_key = key;
_fontFamily = fontFamily;
_fontSource = fontSource;
_fontface = OpenTypeFontface.CetOrCreateFrom(fontSource);
Debug.Assert(ReferenceEquals(_fontSource.Fontface, _fontface));
_gdiFont = gdiFont;
_styleSimulations = styleSimulations;
Initialize();
}
#endif
#if GDI
/// <summary>
/// Initializes a new instance of the <see cref="XGlyphTypeface"/> class by a font source.
/// </summary>
public XGlyphTypeface(XFontSource fontSource)
{
string familyName = fontSource.Fontface.name.Name;
_fontFamily = new XFontFamily(familyName, false);
_fontface = fontSource.Fontface;
_isBold = _fontface.os2.IsBold;
_isItalic = _fontface.os2.IsItalic;
_key = ComputeKey(familyName, _isBold, _isItalic);
//_fontFamily =xfont FontFamilyCache.GetFamilyByName(familyName);
_fontSource = fontSource;
Initialize();
}
#endif
#if WPF
XGlyphTypeface(string key, XFontFamily fontFamily, XFontSource fontSource, XStyleSimulations styleSimulations, WpfTypeface wpfTypeface, WpfGlyphTypeface wpfGlyphTypeface)
{
_key = key;
_fontFamily = fontFamily;
_fontSource = fontSource;
_styleSimulations = styleSimulations;
_fontface = OpenTypeFontface.CetOrCreateFrom(fontSource);
Debug.Assert(ReferenceEquals(_fontSource.Fontface, _fontface));
_wpfTypeface = wpfTypeface;
_wpfGlyphTypeface = wpfGlyphTypeface;
Initialize();
}
#endif
#if NETFX_CORE || UWP
XGlyphTypeface(string key, XFontFamily fontFamily, XFontSource fontSource, XStyleSimulations styleSimulations)
{
_key = key;
_fontFamily = fontFamily;
_fontSource = fontSource;
_styleSimulations = styleSimulations;
_fontface = OpenTypeFontface.CetOrCreateFrom(fontSource);
Debug.Assert(ReferenceEquals(_fontSource.Fontface, _fontface));
//_wpfTypeface = wpfTypeface;
//_wpfGlyphTypeface = wpfGlyphTypeface;
Initialize();
}
#endif
public static XGlyphTypeface GetOrCreateFrom(string familyName, FontResolvingOptions fontResolvingOptions)
{
// Check cache for requested type face.
string typefaceKey = ComputeKey(familyName, fontResolvingOptions);
XGlyphTypeface glyphTypeface;
try
{
// Lock around TryGetGlyphTypeface and AddGlyphTypeface.
Lock.EnterFontFactory();
if (GlyphTypefaceCache.TryGetGlyphTypeface(typefaceKey, out glyphTypeface))
{
// Just return existing one.
return glyphTypeface;
}
// Resolve typeface by FontFactory.
FontResolverInfo fontResolverInfo = FontFactory.ResolveTypeface(familyName, fontResolvingOptions, typefaceKey);
if (fontResolverInfo == null)
{
// No fallback - just stop.
throw new InvalidOperationException("No appropriate font found.");
}
#if CORE || GDI
GdiFont gdiFont = null;
#endif
#if WPF
WpfFontFamily wpfFontFamily = null;
WpfTypeface wpfTypeface = null;
WpfGlyphTypeface wpfGlyphTypeface = null;
#endif
#if UWP
// Nothing to do.
#endif
// Now create the font family at the first.
XFontFamily fontFamily;
PlatformFontResolverInfo platformFontResolverInfo = fontResolverInfo as PlatformFontResolverInfo;
if (platformFontResolverInfo != null)
{
// Case: fontResolverInfo was created by platform font resolver
// and contains platform specific objects that are reused.
#if CORE || GDI
// Reuse GDI+ font from platform font resolver.
gdiFont = platformFontResolverInfo.GdiFont;
fontFamily = XFontFamily.GetOrCreateFromGdi(gdiFont);
#endif
#if WPF
#if !SILVERLIGHT
// Reuse WPF font family created from platform font resolver.
wpfFontFamily = platformFontResolverInfo.WpfFontFamily;
wpfTypeface = platformFontResolverInfo.WpfTypeface;
wpfGlyphTypeface = platformFontResolverInfo.WpfGlyphTypeface;
fontFamily = XFontFamily.GetOrCreateFromWpf(wpfFontFamily);
#else
fontFamily = XFontFamily.GetOrCreateFromWpf(new WpfFontFamily(familyName));
#endif
#endif
#if NETFX_CORE || UWP
fontFamily = null;
#endif
}
else
{
// Case: fontResolverInfo was created by custom font resolver.
// Get or create font family for custom font resolver retrieved font source.
fontFamily = XFontFamily.GetOrCreateFontFamily(familyName);
}
// We have a valid font resolver info. That means we also have an XFontSource object loaded in the cache.
XFontSource fontSource = FontFactory.GetFontSourceByFontName(fontResolverInfo.FaceName);
Debug.Assert(fontSource != null);
// Each font source already contains its OpenTypeFontface.
#if CORE || GDI
glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, fontResolverInfo.StyleSimulations, gdiFont);
#endif
#if WPF
glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, fontResolverInfo.StyleSimulations, wpfTypeface, wpfGlyphTypeface);
#endif
#if NETFX_CORE || UWP
glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, fontResolverInfo.StyleSimulations);
#endif
GlyphTypefaceCache.AddGlyphTypeface(glyphTypeface);
}
finally { Lock.ExitFontFactory(); }
return glyphTypeface;
}
#if CORE || GDI
public static XGlyphTypeface GetOrCreateFromGdi(GdiFont gdiFont)
{
// $TODO THHO Lock???
string typefaceKey = ComputeKey(gdiFont);
XGlyphTypeface glyphTypeface;
if (GlyphTypefaceCache.TryGetGlyphTypeface(typefaceKey, out glyphTypeface))
{
// We have the glyph typeface already in cache.
return glyphTypeface;
}
XFontFamily fontFamily = XFontFamily.GetOrCreateFromGdi(gdiFont);
XFontSource fontSource = XFontSource.GetOrCreateFromGdi(typefaceKey, gdiFont);
// Check if styles must be simulated.
XStyleSimulations styleSimulations = XStyleSimulations.None;
if (gdiFont.Bold && !fontSource.Fontface.os2.IsBold)
styleSimulations |= XStyleSimulations.BoldSimulation;
if (gdiFont.Italic && !fontSource.Fontface.os2.IsItalic)
styleSimulations |= XStyleSimulations.ItalicSimulation;
glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource, styleSimulations, gdiFont);
GlyphTypefaceCache.AddGlyphTypeface(glyphTypeface);
return glyphTypeface;
}
#endif
#if WPF && !SILVERLIGHT
public static XGlyphTypeface GetOrCreateFromWpf(WpfTypeface wpfTypeface)
{
#if DEBUG
if (wpfTypeface.FontFamily.Source == "Segoe UI Semilight")
wpfTypeface.GetType();
#endif
//string typefaceKey = ComputeKey(wpfTypeface);
//XGlyphTypeface glyphTypeface;
//if (GlyphTypefaceCache.TryGetGlyphTypeface(typefaceKey, out glyphTypeface))
//{
// // We have the glyph typeface already in cache.
// return glyphTypeface;
//}
// Lock around TryGetGlyphTypeface and AddGlyphTypeface.
try
{
Lock.EnterFontFactory();
// Create WPF glyph typeface.
WpfGlyphTypeface wpfGlyphTypeface;
if (!wpfTypeface.TryGetGlyphTypeface(out wpfGlyphTypeface))
return null;
string typefaceKey = ComputeKey(wpfGlyphTypeface);
string name1 = wpfGlyphTypeface.DesignerNames[FontHelper.CultureInfoEnUs];
string name2 = wpfGlyphTypeface.FaceNames[FontHelper.CultureInfoEnUs];
string name3 = wpfGlyphTypeface.FamilyNames[FontHelper.CultureInfoEnUs];
string name4 = wpfGlyphTypeface.ManufacturerNames[FontHelper.CultureInfoEnUs];
string name5 = wpfGlyphTypeface.Win32FaceNames[FontHelper.CultureInfoEnUs];
string name6 = wpfGlyphTypeface.Win32FamilyNames[FontHelper.CultureInfoEnUs];
XGlyphTypeface glyphTypeface;
if (GlyphTypefaceCache.TryGetGlyphTypeface(typefaceKey, out glyphTypeface))
{
// We have the glyph typeface already in cache.
return glyphTypeface;
}
XFontFamily fontFamily = XFontFamily.GetOrCreateFromWpf(wpfTypeface.FontFamily);
XFontSource fontSource = XFontSource.GetOrCreateFromWpf(typefaceKey, wpfGlyphTypeface);
glyphTypeface = new XGlyphTypeface(typefaceKey, fontFamily, fontSource,
(XStyleSimulations)wpfGlyphTypeface.StyleSimulations,
wpfTypeface, wpfGlyphTypeface);
GlyphTypefaceCache.AddGlyphTypeface(glyphTypeface);
return glyphTypeface;
}
finally { Lock.ExitFontFactory(); }
}
#endif
public XFontFamily FontFamily
{
get { return _fontFamily; }
}
readonly XFontFamily _fontFamily;
internal OpenTypeFontface Fontface
{
get { return _fontface; }
}
readonly OpenTypeFontface _fontface;
public XFontSource FontSource
{
get { return _fontSource; }
}
readonly XFontSource _fontSource;
void Initialize()
{
_familyName = _fontface.name.Name;
if (string.IsNullOrEmpty(_faceName) || _faceName.StartsWith("?"))
_faceName = _familyName;
_styleName = _fontface.name.Style;
_displayName = _fontface.name.FullFontName;
if (string.IsNullOrEmpty(_displayName))
{
_displayName = _familyName;
if (string.IsNullOrEmpty(_styleName))
_displayName += " (" + _styleName + ")";
}
// Bold, as defined in OS/2 table.
_isBold = _fontface.os2.IsBold;
// Debug.Assert(_isBold == (_fontface.os2.usWeightClass > 400), "Check font weight.");
// Italic, as defined in OS/2 table.
_isItalic = _fontface.os2.IsItalic;
}
/// <summary>
/// Gets the name of the font face. This can be a file name, an uri, or a GUID.
/// </summary>
internal string FaceName
{
get { return _faceName; }
}
string _faceName;
/// <summary>
/// Gets the English family name of the font, for example "Arial".
/// </summary>
public string FamilyName
{
get { return _familyName; }
}
string _familyName;
/// <summary>
/// Gets the English subfamily name of the font,
/// for example "Bold".
/// </summary>
public string StyleName
{
get { return _styleName; }
}
string _styleName;
/// <summary>
/// Gets the English display name of the font,
/// for example "Arial italic".
/// </summary>
public string DisplayName
{
get { return _displayName; }
}
string _displayName;
/// <summary>
/// Gets a value indicating whether the font weight is bold.
/// </summary>
public bool IsBold
{
get { return _isBold; }
}
bool _isBold;
/// <summary>
/// Gets a value indicating whether the font style is italic.
/// </summary>
public bool IsItalic
{
get { return _isItalic; }
}
bool _isItalic;
public XStyleSimulations StyleSimulations
{
get { return _styleSimulations; }
}
XStyleSimulations _styleSimulations;
/// <summary>
/// Gets the suffix of the face name in a PDF font and font descriptor.
/// The name based on the effective value of bold and italic from the OS/2 table.
/// </summary>
string GetFaceNameSuffix()
{
// Use naming of Microsoft Word.
if (IsBold)
return IsItalic ? ",BoldItalic" : ",Bold";
return IsItalic ? ",Italic" : "";
}
internal string GetBaseName()
{
string name = DisplayName;
int ich = name.IndexOf("bold", StringComparison.OrdinalIgnoreCase);
if (ich > 0)
name = name.Substring(0, ich) + name.Substring(ich + 4, name.Length - ich - 4);
ich = name.IndexOf("italic", StringComparison.OrdinalIgnoreCase);
if (ich > 0)
name = name.Substring(0, ich) + name.Substring(ich + 6, name.Length - ich - 6);
//name = name.Replace(" ", "");
name = name.Trim();
name += GetFaceNameSuffix();
return name;
}
/// <summary>
/// Computes the bijective key for a typeface.
/// </summary>
internal static string ComputeKey(string familyName, FontResolvingOptions fontResolvingOptions)
{
// Compute a human readable key.
string simulationSuffix = "";
if (fontResolvingOptions.OverrideStyleSimulations)
{
switch (fontResolvingOptions.StyleSimulations)
{
case XStyleSimulations.BoldSimulation: simulationSuffix = "|b+/i-"; break;
case XStyleSimulations.ItalicSimulation: simulationSuffix = "|b-/i+"; break;
case XStyleSimulations.BoldItalicSimulation: simulationSuffix = "|b+/i+"; break;
case XStyleSimulations.None: break;
default: throw new ArgumentOutOfRangeException("fontResolvingOptions");
}
}
string key = KeyPrefix + familyName.ToLowerInvariant()
+ (fontResolvingOptions.IsItalic ? "/i" : "/n") // normal / oblique / italic
+ (fontResolvingOptions.IsBold ? "/700" : "/400") + "/5" // Stretch.Normal
+ simulationSuffix;
return key;
}
/// <summary>
/// Computes the bijective key for a typeface.
/// </summary>
internal static string ComputeKey(string familyName, bool isBold, bool isItalic)
{
return ComputeKey(familyName, new FontResolvingOptions(FontHelper.CreateStyle(isBold, isItalic)));
}
#if CORE || GDI
internal static string ComputeKey(GdiFont gdiFont)
{
string name1 = gdiFont.Name;
string name2 = gdiFont.OriginalFontName;
string name3 = gdiFont.SystemFontName;
string name = name1;
GdiFontStyle style = gdiFont.Style;
string key = KeyPrefix + name.ToLowerInvariant() + ((style & GdiFontStyle.Italic) == GdiFontStyle.Italic ? "/i" : "/n") + ((style & GdiFontStyle.Bold) == GdiFontStyle.Bold ? "/700" : "/400") + "/5"; // Stretch.Normal
return key;
}
#endif
#if WPF && !SILVERLIGHT
internal static string ComputeKey(WpfGlyphTypeface wpfGlyphTypeface)
{
string name1 = wpfGlyphTypeface.DesignerNames[FontHelper.CultureInfoEnUs];
string faceName = wpfGlyphTypeface.FaceNames[FontHelper.CultureInfoEnUs];
string familyName = wpfGlyphTypeface.FamilyNames[FontHelper.CultureInfoEnUs];
string name4 = wpfGlyphTypeface.ManufacturerNames[FontHelper.CultureInfoEnUs];
string name5 = wpfGlyphTypeface.Win32FaceNames[FontHelper.CultureInfoEnUs];
string name6 = wpfGlyphTypeface.Win32FamilyNames[FontHelper.CultureInfoEnUs];
string name = familyName.ToLower() + '/' + faceName.ToLowerInvariant();
string style = wpfGlyphTypeface.Style.ToString();
string weight = wpfGlyphTypeface.Weight.ToString();
string stretch = wpfGlyphTypeface.Stretch.ToString();
string simulations = wpfGlyphTypeface.StyleSimulations.ToString();
//string key = name + '/' + style + '/' + weight + '/' + stretch + '/' + simulations;
string key = KeyPrefix + name + '/' + style.Substring(0, 1) + '/' + wpfGlyphTypeface.Weight.ToOpenTypeWeight().ToString(CultureInfo.InvariantCulture) + '/' + wpfGlyphTypeface.Stretch.ToOpenTypeStretch().ToString(CultureInfo.InvariantCulture);
switch (wpfGlyphTypeface.StyleSimulations)
{
case WpfStyleSimulations.BoldSimulation: key += "|b+/i-"; break;
case WpfStyleSimulations.ItalicSimulation: key += "|b-/i+"; break;
case WpfStyleSimulations.BoldItalicSimulation: key += "|b+/i+"; break;
case WpfStyleSimulations.None: break;
}
return key.ToLowerInvariant();
}
#endif
public string Key
{
get { return _key; }
}
readonly string _key;
#if CORE || GDI
internal GdiFont GdiFont
{
get { return _gdiFont; }
}
private readonly GdiFont _gdiFont;
#endif
#if WPF
internal WpfTypeface WpfTypeface
{
get { return _wpfTypeface; }
}
readonly WpfTypeface _wpfTypeface;
internal WpfGlyphTypeface WpfGlyphTypeface
{
get { return _wpfGlyphTypeface; }
}
readonly WpfGlyphTypeface _wpfGlyphTypeface;
#endif
#if SILVERLIGHT_
/// <summary>
/// Gets the FontSource object used in Silverlight 4.
/// </summary>
public FontSource FontSource
{
get
{
if (_fontSource == null)
{
#if true
MemoryStream stream = new MemoryStream(_fontface.FontData.Bytes);
_fontSource = new FontSource(stream);
#else
using (MemoryStream stream = new MemoryStream(_fontface.Data))
{
_fontSource = new FontSource(stream);
}
#endif
}
return _fontSource;
}
}
FontSource _fontSource;
#endif
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSharper disable UnusedMember.Local
internal string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get { return string.Format(CultureInfo.InvariantCulture, "{0} - {1} ({2})", FamilyName, StyleName, FaceName); }
}
}
}

File diff suppressed because it is too large Load Diff

View 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
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents the internal state of an XGraphics object.
/// </summary>
public sealed class XGraphicsContainer
{
#if GDI
internal XGraphicsContainer(GraphicsState state)
{
GdiState = state;
}
internal GraphicsState GdiState;
#endif
#if WPF
internal XGraphicsContainer()
{ }
#endif
internal InternalGraphicsState InternalState;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Provides access to the internal data structures of XGraphicsPath.
/// This class prevents the public interface from pollution with internal functions.
/// </summary>
public sealed class XGraphicsPathInternals
{
internal XGraphicsPathInternals(XGraphicsPath path)
{
_path = path;
}
XGraphicsPath _path;
#if GDI
/// <summary>
/// Gets the underlying GDI+ path object.
/// </summary>
public GraphicsPath GdiPath
{
get { return _path._gdipPath; }
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Gets the underlying WPF path geometry object.
/// </summary>
public PathGeometry WpfPath
{
get { return _path._pathGeometry; }
}
#endif
}
}

View File

@@ -0,0 +1,77 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
#if true_ // unused
/// <summary>
/// Represents a segment of a path defined by a type and a set of points.
/// </summary>
internal sealed class XGraphicsPathItem
{
public XGraphicsPathItem(XGraphicsPathItemType type)
{
Type = type;
Points = null;
}
#if GDI
public XGraphicsPathItem(XGraphicsPathItemType type, params PointF[] points)
{
Type = type;
Points = XGraphics.MakeXPointArray(points, 0, points.Length);
}
#endif
public XGraphicsPathItem(XGraphicsPathItemType type, params XPoint[] points)
{
Type = type;
Points = (XPoint[])points.Clone();
}
public XGraphicsPathItem Clone()
{
XGraphicsPathItem item = (XGraphicsPathItem)MemberwiseClone();
item.Points = (XPoint[])Points.Clone();
return item;
}
public XGraphicsPathItemType Type;
public XPoint[] Points;
}
#endif
}

View File

@@ -0,0 +1,65 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents the internal state of an XGraphics object.
/// This class is used as a handle for restoring the context.
/// </summary>
public sealed class XGraphicsState
{
// This class is simply a wrapper of InternalGraphicsState.
#if CORE
internal XGraphicsState()
{ }
#endif
#if GDI
internal XGraphicsState(GraphicsState state)
{
GdiState = state;
}
internal GraphicsState GdiState;
#endif
#if WPF
internal XGraphicsState()
{ }
#endif
internal InternalGraphicsState InternalState;
}
}

1560
PdfSharp/Drawing/XImage.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,141 @@
#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.Drawing
{
/// <summary>
/// Specifies the format of the image.
/// </summary>
public sealed class XImageFormat
{
XImageFormat(Guid guid)
{
_guid = guid;
}
internal Guid Guid
{
get { return _guid; }
}
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
public override bool Equals(object obj)
{
XImageFormat format = obj as XImageFormat;
if (format == null)
return false;
return _guid == format._guid;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
return _guid.GetHashCode();
}
/// <summary>
/// Gets the Portable Network Graphics (PNG) image format.
/// </summary>
public static XImageFormat Png
{
get { return _png; }
}
/// <summary>
/// Gets the Graphics Interchange Format (GIF) image format.
/// </summary>
public static XImageFormat Gif
{
get { return _gif; }
}
/// <summary>
/// Gets the Joint Photographic Experts Group (JPEG) image format.
/// </summary>
public static XImageFormat Jpeg
{
get { return _jpeg; }
}
/// <summary>
/// Gets the Tag Image File Format (TIFF) image format.
/// </summary>
public static XImageFormat Tiff
{
get { return _tiff; }
}
/// <summary>
/// Gets the Portable Document Format (PDF) image format
/// </summary>
public static XImageFormat Pdf
{
get { return _pdf; }
}
/// <summary>
/// Gets the Windows icon image format.
/// </summary>
public static XImageFormat Icon
{
get { return _icon; }
}
readonly Guid _guid;
// Guids used in GDI+
//ImageFormat.memoryBMP = new ImageFormat(new Guid("{b96b3caa-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.bmp = new ImageFormat(new Guid("{b96b3cab-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.emf = new ImageFormat(new Guid("{b96b3cac-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.wmf = new ImageFormat(new Guid("{b96b3cad-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.jpeg = new ImageFormat(new Guid("{b96b3cae-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.png = new ImageFormat(new Guid("{b96b3caf-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.gif = new ImageFormat(new Guid("{b96b3cb0-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.tiff = new ImageFormat(new Guid("{b96b3cb1-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.exif = new ImageFormat(new Guid("{b96b3cb2-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.photoCD = new ImageFormat(new Guid("{b96b3cb3-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.flashPIX = new ImageFormat(new Guid("{b96b3cb4-0728-11d3-9d7b-0000f81ef32e}"));
//ImageFormat.icon = new ImageFormat(new Guid("{b96b3cb5-0728-11d3-9d7b-0000f81ef32e}"));
// #??? Why Guids?
private static readonly XImageFormat _png = new XImageFormat(new Guid("{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"));
private static readonly XImageFormat _gif = new XImageFormat(new Guid("{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"));
private static readonly XImageFormat _jpeg = new XImageFormat(new Guid("{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"));
private static readonly XImageFormat _tiff = new XImageFormat(new Guid("{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"));
private static readonly XImageFormat _icon = new XImageFormat(new Guid("{B96B3CB5-0728-11D3-9D7B-0000F81EF32E}"));
// not GDI+ conform
private static readonly XImageFormat _pdf = new XImageFormat(new Guid("{84570158-DBF0-4C6B-8368-62D6A3CA76E0}"));
}
}

View File

@@ -0,0 +1,222 @@
#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;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
internal class XKnownColorTable
{
internal static uint[] ColorTable;
public static uint KnownColorToArgb(XKnownColor color)
{
if (ColorTable == null)
InitColorTable();
if (color <= XKnownColor.YellowGreen)
return ColorTable[(int)color];
return 0;
}
public static bool IsKnownColor(uint argb)
{
for (int idx = 0; idx < ColorTable.Length; idx++)
{
if (ColorTable[idx] == argb)
return true;
}
return false;
}
public static XKnownColor GetKnownColor(uint argb)
{
for (int idx = 0; idx < ColorTable.Length; idx++)
{
if (ColorTable[idx] == argb)
return (XKnownColor)idx;
}
return (XKnownColor)(-1);
}
private static void InitColorTable()
{
// Same values as in GDI+ and System.Windows.Media.XColors
// Note that Magenta is the same as Fuchsia and Zyan is the same as Aqua.
uint[] colors = new uint[141];
colors[0] = 0xFFF0F8FF; // AliceBlue
colors[1] = 0xFFFAEBD7; // AntiqueWhite
colors[2] = 0xFF00FFFF; // Aqua
colors[3] = 0xFF7FFFD4; // Aquamarine
colors[4] = 0xFFF0FFFF; // Azure
colors[5] = 0xFFF5F5DC; // Beige
colors[6] = 0xFFFFE4C4; // Bisque
colors[7] = 0xFF000000; // Black
colors[8] = 0xFFFFEBCD; // BlanchedAlmond
colors[9] = 0xFF0000FF; // Blue
colors[10] = 0xFF8A2BE2; // BlueViolet
colors[11] = 0xFFA52A2A; // Brown
colors[12] = 0xFFDEB887; // BurlyWood
colors[13] = 0xFF5F9EA0; // CadetBlue
colors[14] = 0xFF7FFF00; // Chartreuse
colors[15] = 0xFFD2691E; // Chocolate
colors[16] = 0xFFFF7F50; // Coral
colors[17] = 0xFF6495ED; // CornflowerBlue
colors[18] = 0xFFFFF8DC; // Cornsilk
colors[19] = 0xFFDC143C; // Crimson
colors[20] = 0xFF00FFFF; // Cyan
colors[21] = 0xFF00008B; // DarkBlue
colors[22] = 0xFF008B8B; // DarkCyan
colors[23] = 0xFFB8860B; // DarkGoldenrod
colors[24] = 0xFFA9A9A9; // DarkGray
colors[25] = 0xFF006400; // DarkGreen
colors[26] = 0xFFBDB76B; // DarkKhaki
colors[27] = 0xFF8B008B; // DarkMagenta
colors[28] = 0xFF556B2F; // DarkOliveGreen
colors[29] = 0xFFFF8C00; // DarkOrange
colors[30] = 0xFF9932CC; // DarkOrchid
colors[31] = 0xFF8B0000; // DarkRed
colors[32] = 0xFFE9967A; // DarkSalmon
colors[33] = 0xFF8FBC8B; // DarkSeaGreen
colors[34] = 0xFF483D8B; // DarkSlateBlue
colors[35] = 0xFF2F4F4F; // DarkSlateGray
colors[36] = 0xFF00CED1; // DarkTurquoise
colors[37] = 0xFF9400D3; // DarkViolet
colors[38] = 0xFFFF1493; // DeepPink
colors[39] = 0xFF00BFFF; // DeepSkyBlue
colors[40] = 0xFF696969; // DimGray
colors[41] = 0xFF1E90FF; // DodgerBlue
colors[42] = 0xFFB22222; // Firebrick
colors[43] = 0xFFFFFAF0; // FloralWhite
colors[44] = 0xFF228B22; // ForestGreen
colors[45] = 0xFFFF00FF; // Fuchsia
colors[46] = 0xFFDCDCDC; // Gainsboro
colors[47] = 0xFFF8F8FF; // GhostWhite
colors[48] = 0xFFFFD700; // Gold
colors[49] = 0xFFDAA520; // Goldenrod
colors[50] = 0xFF808080; // Gray
colors[51] = 0xFF008000; // Green
colors[52] = 0xFFADFF2F; // GreenYellow
colors[53] = 0xFFF0FFF0; // Honeydew
colors[54] = 0xFFFF69B4; // HotPink
colors[55] = 0xFFCD5C5C; // IndianRed
colors[56] = 0xFF4B0082; // Indigo
colors[57] = 0xFFFFFFF0; // Ivory
colors[58] = 0xFFF0E68C; // Khaki
colors[59] = 0xFFE6E6FA; // Lavender
colors[60] = 0xFFFFF0F5; // LavenderBlush
colors[61] = 0xFF7CFC00; // LawnGreen
colors[62] = 0xFFFFFACD; // LemonChiffon
colors[63] = 0xFFADD8E6; // LightBlue
colors[64] = 0xFFF08080; // LightCoral
colors[65] = 0xFFE0FFFF; // LightCyan
colors[66] = 0xFFFAFAD2; // LightGoldenrodYellow
colors[67] = 0xFFD3D3D3; // LightGray
colors[68] = 0xFF90EE90; // LightGreen
colors[69] = 0xFFFFB6C1; // LightPink
colors[70] = 0xFFFFA07A; // LightSalmon
colors[71] = 0xFF20B2AA; // LightSeaGreen
colors[72] = 0xFF87CEFA; // LightSkyBlue
colors[73] = 0xFF778899; // LightSlateGray
colors[74] = 0xFFB0C4DE; // LightSteelBlue
colors[75] = 0xFFFFFFE0; // LightYellow
colors[76] = 0xFF00FF00; // Lime
colors[77] = 0xFF32CD32; // LimeGreen
colors[78] = 0xFFFAF0E6; // Linen
colors[79] = 0xFFFF00FF; // Magenta
colors[80] = 0xFF800000; // Maroon
colors[81] = 0xFF66CDAA; // MediumAquamarine
colors[82] = 0xFF0000CD; // MediumBlue
colors[83] = 0xFFBA55D3; // MediumOrchid
colors[84] = 0xFF9370DB; // MediumPurple
colors[85] = 0xFF3CB371; // MediumSeaGreen
colors[86] = 0xFF7B68EE; // MediumSlateBlue
colors[87] = 0xFF00FA9A; // MediumSpringGreen
colors[88] = 0xFF48D1CC; // MediumTurquoise
colors[89] = 0xFFC71585; // MediumVioletRed
colors[90] = 0xFF191970; // MidnightBlue
colors[91] = 0xFFF5FFFA; // MintCream
colors[92] = 0xFFFFE4E1; // MistyRose
colors[93] = 0xFFFFE4B5; // Moccasin
colors[94] = 0xFFFFDEAD; // NavajoWhite
colors[95] = 0xFF000080; // Navy
colors[96] = 0xFFFDF5E6; // OldLace
colors[97] = 0xFF808000; // Olive
colors[98] = 0xFF6B8E23; // OliveDrab
colors[99] = 0xFFFFA500; // Orange
colors[100] = 0xFFFF4500; // OrangeRed
colors[101] = 0xFFDA70D6; // Orchid
colors[102] = 0xFFEEE8AA; // PaleGoldenrod
colors[103] = 0xFF98FB98; // PaleGreen
colors[104] = 0xFFAFEEEE; // PaleTurquoise
colors[105] = 0xFFDB7093; // PaleVioletRed
colors[106] = 0xFFFFEFD5; // PapayaWhip
colors[107] = 0xFFFFDAB9; // PeachPuff
colors[108] = 0xFFCD853F; // Peru
colors[109] = 0xFFFFC0CB; // Pink
colors[110] = 0xFFDDA0DD; // Plum
colors[111] = 0xFFB0E0E6; // PowderBlue
colors[112] = 0xFF800080; // Purple
colors[113] = 0xFFFF0000; // Red
colors[114] = 0xFFBC8F8F; // RosyBrown
colors[115] = 0xFF4169E1; // RoyalBlue
colors[116] = 0xFF8B4513; // SaddleBrown
colors[117] = 0xFFFA8072; // Salmon
colors[118] = 0xFFF4A460; // SandyBrown
colors[119] = 0xFF2E8B57; // SeaGreen
colors[120] = 0xFFFFF5EE; // SeaShell
colors[121] = 0xFFA0522D; // Sienna
colors[122] = 0xFFC0C0C0; // Silver
colors[123] = 0xFF87CEEB; // SkyBlue
colors[124] = 0xFF6A5ACD; // SlateBlue
colors[125] = 0xFF708090; // SlateGray
colors[126] = 0xFFFFFAFA; // Snow
colors[127] = 0xFF00FF7F; // SpringGreen
colors[128] = 0xFF4682B4; // SteelBlue
colors[129] = 0xFFD2B48C; // Tan
colors[130] = 0xFF008080; // Teal
colors[131] = 0xFFD8BFD8; // Thistle
colors[132] = 0xFFFF6347; // Tomato
colors[133] = 0x00FFFFFF; // Transparent
colors[134] = 0xFF40E0D0; // Turquoise
colors[135] = 0xFFEE82EE; // Violet
colors[136] = 0xFFF5DEB3; // Wheat
colors[137] = 0xFFFFFFFF; // White
colors[138] = 0xFFF5F5F5; // WhiteSmoke
colors[139] = 0xFFFFFF00; // Yellow
colors[140] = 0xFF9ACD32; // YellowGreen
ColorTable = colors;
}
}
}

View File

@@ -0,0 +1,393 @@
#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.ComponentModel;
using PdfSharp.Internal;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using GdiLinearGradientBrush = System.Drawing.Drawing2D.LinearGradientBrush;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using SysPoint = System.Windows.Point;
using SysSize = System.Windows.Size;
using SysRect = System.Windows.Rect;
using WpfBrush = System.Windows.Media.Brush;
using WpfLinearGradientBrush = System.Windows.Media.LinearGradientBrush;
#endif
#if UWP
using Windows.UI;
using Windows.UI.Xaml.Media;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Brushes;
#endif
// ReSharper disable RedundantNameQualifier because it is required for hybrid build
namespace PdfSharp.Drawing
{
/// <summary>
/// Defines a Brush with a linear gradient.
/// </summary>
public sealed class XLinearGradientBrush : XBrush
{
#if GDI
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(System.Drawing.Point point1, System.Drawing.Point point2, XColor color1, XColor color2)
: this(new XPoint(point1), new XPoint(point2), color1, color2)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(PointF point1, PointF point2, XColor color1, XColor color2)
: this(new XPoint(point1), new XPoint(point2), color1, color2)
{ }
#endif
#if WPF
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(SysPoint point1, SysPoint point2, XColor color1, XColor color2)
: this(new XPoint(point1), new XPoint(point2), color1, color2)
{ }
#endif
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(XPoint point1, XPoint point2, XColor color1, XColor color2)
{
_point1 = point1;
_point2 = point2;
_color1 = color1;
_color2 = color2;
}
#if GDI
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(Rectangle rect, XColor color1, XColor color2, XLinearGradientMode linearGradientMode)
: this(new XRect(rect), color1, color2, linearGradientMode)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(RectangleF rect, XColor color1, XColor color2, XLinearGradientMode linearGradientMode)
: this(new XRect(rect), color1, color2, linearGradientMode)
{ }
#endif
#if WPF
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(Rect rect, XColor color1, XColor color2, XLinearGradientMode linearGradientMode)
: this(new XRect(rect), color1, color2, linearGradientMode)
{ }
#endif
/// <summary>
/// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
/// </summary>
public XLinearGradientBrush(XRect rect, XColor color1, XColor color2, XLinearGradientMode linearGradientMode)
{
if (!Enum.IsDefined(typeof(XLinearGradientMode), linearGradientMode))
throw new InvalidEnumArgumentException("linearGradientMode", (int)linearGradientMode, typeof(XLinearGradientMode));
if (rect.Width == 0 || rect.Height == 0)
throw new ArgumentException("Invalid rectangle.", "rect");
_useRect = true;
_color1 = color1;
_color2 = color2;
_rect = rect;
_linearGradientMode = linearGradientMode;
}
// TODO:
//public XLinearGradientBrush(Rectangle rect, XColor color1, XColor color2, double angle);
//public XLinearGradientBrush(RectangleF rect, XColor color1, XColor color2, double angle);
//public XLinearGradientBrush(Rectangle rect, XColor color1, XColor color2, double angle, bool isAngleScaleable);
//public XLinearGradientBrush(RectangleF rect, XColor color1, XColor color2, double angle, bool isAngleScaleable);
//public XLinearGradientBrush(RectangleF rect, XColor color1, XColor color2, double angle, bool isAngleScaleable);
//private Blend _GetBlend();
//private ColorBlend _GetInterpolationColors();
//private XColor[] _GetLinearColors();
//private RectangleF _GetRectangle();
//private Matrix _GetTransform();
//private WrapMode _GetWrapMode();
//private void _SetBlend(Blend blend);
//private void _SetInterpolationColors(ColorBlend blend);
//private void _SetLinearColors(XColor color1, XColor color2);
//private void _SetTransform(Matrix matrix);
//private void _SetWrapMode(WrapMode wrapMode);
//public override object Clone();
/// <summary>
/// Gets or sets an XMatrix that defines a local geometric transform for this LinearGradientBrush.
/// </summary>
public XMatrix Transform
{
get { return _matrix; }
set { _matrix = value; }
}
/// <summary>
/// Translates the brush with the specified offset.
/// </summary>
public void TranslateTransform(double dx, double dy)
{
_matrix.TranslatePrepend(dx, dy);
}
/// <summary>
/// Translates the brush with the specified offset.
/// </summary>
public void TranslateTransform(double dx, double dy, XMatrixOrder order)
{
_matrix.Translate(dx, dy, order);
}
/// <summary>
/// Scales the brush with the specified scalars.
/// </summary>
public void ScaleTransform(double sx, double sy)
{
_matrix.ScalePrepend(sx, sy);
}
/// <summary>
/// Scales the brush with the specified scalars.
/// </summary>
public void ScaleTransform(double sx, double sy, XMatrixOrder order)
{
_matrix.Scale(sx, sy, order);
}
/// <summary>
/// Rotates the brush with the specified angle.
/// </summary>
public void RotateTransform(double angle)
{
_matrix.RotatePrepend(angle);
}
/// <summary>
/// Rotates the brush with the specified angle.
/// </summary>
public void RotateTransform(double angle, XMatrixOrder order)
{
_matrix.Rotate(angle, order);
}
/// <summary>
/// Multiply the brush transformation matrix with the specified matrix.
/// </summary>
public void MultiplyTransform(XMatrix matrix)
{
_matrix.Prepend(matrix);
}
/// <summary>
/// Multiply the brush transformation matrix with the specified matrix.
/// </summary>
public void MultiplyTransform(XMatrix matrix, XMatrixOrder order)
{
_matrix.Multiply(matrix, order);
}
/// <summary>
/// Resets the brush transformation matrix with identity matrix.
/// </summary>
public void ResetTransform()
{
_matrix = new XMatrix();
}
//public void SetBlendTriangularShape(double focus);
//public void SetBlendTriangularShape(double focus, double scale);
//public void SetSigmaBellShape(double focus);
//public void SetSigmaBellShape(double focus, double scale);
#if GDI
internal override System.Drawing.Brush RealizeGdiBrush()
{
//if (dirty)
//{
// if (brush == null)
// brush = new SolidBrush(color.ToGdiColor());
// else
// {
// brush.Color = color.ToGdiColor();
// }
// dirty = false;
//}
// TODO: use dirty to optimize code
GdiLinearGradientBrush brush;
try
{
Lock.EnterGdiPlus();
if (_useRect)
{
brush = new GdiLinearGradientBrush(_rect.ToRectangleF(),
_color1.ToGdiColor(), _color2.ToGdiColor(), (LinearGradientMode)_linearGradientMode);
}
else
{
brush = new GdiLinearGradientBrush(
_point1.ToPointF(), _point2.ToPointF(),
_color1.ToGdiColor(), _color2.ToGdiColor());
}
if (!_matrix.IsIdentity)
brush.Transform = _matrix.ToGdiMatrix();
//brush.WrapMode = WrapMode.Clamp;
}
finally { Lock.ExitGdiPlus(); }
return brush;
}
#endif
#if WPF
internal override WpfBrush RealizeWpfBrush()
{
//if (dirty)
//{
// if (brush == null)
// brush = new SolidBrush(color.ToGdiColor());
// else
// {
// brush.Color = color.ToGdiColor();
// }
// dirty = false;
//}
WpfLinearGradientBrush brush;
if (_useRect)
{
#if !SILVERLIGHT
brush = new WpfLinearGradientBrush(_color1.ToWpfColor(), _color2.ToWpfColor(), new SysPoint(0, 0), new SysPoint(1, 1));// rect.TopLeft, this.rect.BottomRight);
//brush = new System.Drawing.Drawing2D.LinearGradientBrush(rect.ToRectangleF(),
// color1.ToGdiColor(), color2.ToGdiColor(), (LinearGradientMode)linearGradientMode);
#else
GradientStop gs1 = new GradientStop();
gs1.Color = _color1.ToWpfColor();
gs1.Offset = 0;
GradientStop gs2 = new GradientStop();
gs2.Color = _color2.ToWpfColor();
gs2.Offset = 1;
GradientStopCollection gsc = new GradientStopCollection();
gsc.Add(gs1);
gsc.Add(gs2);
brush = new LinearGradientBrush(gsc, 0);
brush.StartPoint = new Point(0, 0);
brush.EndPoint = new Point(1, 1);
#endif
}
else
{
#if !SILVERLIGHT
brush = new System.Windows.Media.LinearGradientBrush(_color1.ToWpfColor(), _color2.ToWpfColor(), _point1, _point2);
//brush = new System.Drawing.Drawing2D.LinearGradientBrush(
// point1.ToPointF(), point2.ToPointF(),
// color1.ToGdiColor(), color2.ToGdiColor());
#else
GradientStop gs1 = new GradientStop();
gs1.Color = _color1.ToWpfColor();
gs1.Offset = 0;
GradientStop gs2 = new GradientStop();
gs2.Color = _color2.ToWpfColor();
gs2.Offset = 1;
GradientStopCollection gsc = new GradientStopCollection();
gsc.Add(gs1);
gsc.Add(gs2);
brush = new LinearGradientBrush(gsc, 0);
brush.StartPoint = _point1;
brush.EndPoint = _point2;
#endif
}
if (!_matrix.IsIdentity)
{
#if !SILVERLIGHT
brush.Transform = new MatrixTransform(_matrix.ToWpfMatrix());
#else
MatrixTransform transform = new MatrixTransform();
transform.Matrix = _matrix.ToWpfMatrix();
brush.Transform = transform;
#endif
}
return brush;
}
#endif
#if UWP
internal override ICanvasBrush RealizeCanvasBrush()
{
ICanvasBrush brush;
brush = new CanvasSolidColorBrush(CanvasDevice.GetSharedDevice(), Colors.RoyalBlue);
return brush;
}
#endif
//public Blend Blend { get; set; }
//public bool GammaCorrection { get; set; }
//public ColorBlend InterpolationColors { get; set; }
//public XColor[] LinearColors { get; set; }
//public RectangleF Rectangle { get; }
//public WrapMode WrapMode { get; set; }
//private bool interpolationColorsWasSet;
internal bool _useRect;
internal XPoint _point1, _point2;
internal XColor _color1, _color2;
internal XRect _rect;
internal XLinearGradientMode _linearGradientMode;
internal XMatrix _matrix;
}
}

1557
PdfSharp/Drawing/XMatrix.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,415 @@
#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.IO;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
#endif
#if WPF
using System.Windows.Media;
#endif
using PdfSharp.Internal;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents a so called 'PDF form external object', which is typically an imported page of an external
/// PDF document. XPdfForm objects are used like images to draw an existing PDF page of an external
/// document in the current document. XPdfForm objects can only be placed in PDF documents. If you try
/// to draw them using a XGraphics based on an GDI+ context no action is taken if no placeholder image
/// is specified. Otherwise the place holder is drawn.
/// </summary>
public class XPdfForm : XForm
{
/// <summary>
/// Initializes a new instance of the XPdfForm class from the specified path to an external PDF document.
/// Although PDFsharp internally caches XPdfForm objects it is recommended to reuse XPdfForm objects
/// in your code and change the PageNumber property if more than one page is needed form the external
/// document. Furthermore, because XPdfForm can occupy very much memory, it is recommended to
/// dispose XPdfForm objects if not needed anymore.
/// </summary>
internal XPdfForm(string path)
{
int pageNumber;
path = ExtractPageNumber(path, out pageNumber);
#if !NETFX_CORE
path = Path.GetFullPath(path);
if (!File.Exists(path))
throw new FileNotFoundException(PSSR.FileNotFound(path));
#endif
if (PdfReader.TestPdfFile(path) == 0)
throw new ArgumentException("The specified file has no valid PDF file header.", "path");
_path = path;
if (pageNumber != 0)
PageNumber = pageNumber;
}
/// <summary>
/// Initializes a new instance of the <see cref="XPdfForm"/> class from a stream.
/// </summary>
/// <param name="stream">The stream.</param>
internal XPdfForm(Stream stream)
{
// Create a dummy unique path
_path = "*" + Guid.NewGuid().ToString("B");
if (PdfReader.TestPdfFile(stream) == 0)
throw new ArgumentException("The specified stream has no valid PDF file header.", "stream");
_externalDocument = PdfReader.Open(stream);
}
/// <summary>
/// Creates an XPdfForm from a file.
/// </summary>
public static new XPdfForm FromFile(string path)
{
// TODO: Same file should return same object (that's why the function is static).
return new XPdfForm(path);
}
/// <summary>
/// Creates an XPdfForm from a stream.
/// </summary>
public static new XPdfForm FromStream(Stream stream)
{
return new XPdfForm(stream);
}
/*
void Initialize()
{
// ImageFormat has no overridden Equals...
}
*/
/// <summary>
/// Sets the form in the state FormState.Finished.
/// </summary>
internal override void Finish()
{
if (_formState == FormState.NotATemplate || _formState == FormState.Finished)
return;
base.Finish();
//if (Gfx.metafile != null)
// image = Gfx.metafile;
//Debug.Assert(_fromState == FormState.Created || _fromState == FormState.UnderConstruction);
//_fromState = FormState.Finished;
//Gfx.Dispose();
//Gfx = null;
//if (_pdfRenderer != null)
//{
// _pdfForm.Stream = new PdfDictionary.PdfStream(PdfEncoders.RawEncoding.GetBytes(pdfRenderer.GetContent()), this.pdfForm);
// if (_document.Options.CompressContentStreams)
// {
// _pdfForm.Stream.Value = Filtering.FlateDecode.Encode(pdfForm.Stream.Value);
// _pdfForm.Elements["/Filter"] = new PdfName("/FlateDecode");
// }
// int length = _pdfForm.Stream.Length;
// _pdfForm.Elements.SetInteger("/Length", length);
//}
}
/// <summary>
/// Frees the memory occupied by the underlying imported PDF document, even if other XPdfForm objects
/// refer to this document. A reuse of this object doesn't fail, because the underlying PDF document
/// is re-imported if necessary.
/// </summary>
// TODO: NYI: Dispose
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
_disposed = true;
try
{
if (disposing)
{
//...
}
if (_externalDocument != null)
PdfDocument.Tls.DetachDocument(_externalDocument.Handle);
//...
}
finally
{
base.Dispose(disposing);
}
}
}
bool _disposed;
/// <summary>
/// Gets or sets an image that is used for drawing if the current XGraphics object cannot handle
/// PDF forms. A place holder is useful for showing a preview of a page on the display, because
/// PDFsharp cannot render native PDF objects.
/// </summary>
public XImage PlaceHolder
{
get { return _placeHolder; }
set { _placeHolder = value; }
}
XImage _placeHolder;
/// <summary>
/// Gets the underlying PdfPage (if one exists).
/// </summary>
public PdfPage Page
{
get
{
if (IsTemplate)
return null;
PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
return page;
}
}
/// <summary>
/// Gets the number of pages in the PDF form.
/// </summary>
public int PageCount
{
get
{
if (IsTemplate)
return 1;
if (_pageCount == -1)
_pageCount = ExternalDocument.Pages.Count;
return _pageCount;
}
}
int _pageCount = -1;
/// <summary>
/// Gets the width in point of the page identified by the property PageNumber.
/// </summary>
[Obsolete("Use either PixelWidth or PointWidth. Temporarily obsolete because of rearrangements for WPF.")]
public override double Width
{
get
{
PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
return page.Width;
}
}
/// <summary>
/// Gets the height in point of the page identified by the property PageNumber.
/// </summary>
[Obsolete("Use either PixelHeight or PointHeight. Temporarily obsolete because of rearrangements for WPF.")]
public override double Height
{
get
{
PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
return page.Height;
}
}
/// <summary>
/// Gets the width in point of the page identified by the property PageNumber.
/// </summary>
public override double PointWidth
{
get
{
PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
return page.Width;
}
}
/// <summary>
/// Gets the height in point of the page identified by the property PageNumber.
/// </summary>
public override double PointHeight
{
get
{
PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
return page.Height;
}
}
/// <summary>
/// Gets the width in point of the page identified by the property PageNumber.
/// </summary>
public override int PixelWidth
{
get
{
//PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
//return (int)page.Width;
return DoubleUtil.DoubleToInt(PointWidth);
}
}
/// <summary>
/// Gets the height in point of the page identified by the property PageNumber.
/// </summary>
public override int PixelHeight
{
get
{
//PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
//return (int)page.Height;
return DoubleUtil.DoubleToInt(PointHeight);
}
}
/// <summary>
/// Get the size of the page identified by the property PageNumber.
/// </summary>
public override XSize Size
{
get
{
PdfPage page = ExternalDocument.Pages[_pageNumber - 1];
return new XSize(page.Width, page.Height);
}
}
/// <summary>
/// Gets or sets the transformation matrix.
/// </summary>
public override XMatrix Transform
{
get { return _transform; }
set
{
if (_transform != value)
{
// discard PdfFromXObject when Transform changed
_pdfForm = null;
_transform = value;
}
}
}
/// <summary>
/// Gets or sets the page number in the external PDF document this object refers to. The page number
/// is one-based, i.e. it is in the range from 1 to PageCount. The default value is 1.
/// </summary>
public int PageNumber
{
get { return _pageNumber; }
set
{
if (IsTemplate)
throw new InvalidOperationException("The page number of an XPdfForm template cannot be modified.");
if (_pageNumber != value)
{
_pageNumber = value;
// dispose PdfFromXObject when number has changed
_pdfForm = null;
}
}
}
int _pageNumber = 1;
/// <summary>
/// Gets or sets the page index in the external PDF document this object refers to. The page index
/// is zero-based, i.e. it is in the range from 0 to PageCount - 1. The default value is 0.
/// </summary>
public int PageIndex
{
get { return PageNumber - 1; }
set { PageNumber = value + 1; }
}
/// <summary>
/// Gets the underlying document from which pages are imported.
/// </summary>
internal PdfDocument ExternalDocument
{
// The problem is that you can ask an XPdfForm about the number of its pages before it was
// drawn the first time. At this moment the XPdfForm doesn't know the document where it will
// be later draw on one of its pages. To prevent the import of the same document more than
// once, all imported documents of a thread are cached. The cache is local to the current
// thread and not to the appdomain, because I won't get problems in a multi-thread environment
// that I don't understand.
get
{
if (IsTemplate)
throw new InvalidOperationException("This XPdfForm is a template and not an imported PDF page; therefore it has no external document.");
if (_externalDocument == null)
_externalDocument = PdfDocument.Tls.GetDocument(_path);
return _externalDocument;
}
}
internal PdfDocument _externalDocument;
/// <summary>
/// Extracts the page number if the path has the form 'MyFile.pdf#123' and returns
/// the actual path without the number sign and the following digits.
/// </summary>
public static string ExtractPageNumber(string path, out int pageNumber)
{
if (path == null)
throw new ArgumentNullException("path");
pageNumber = 0;
int length = path.Length;
if (length != 0)
{
length--;
if (char.IsDigit(path, length))
{
while (char.IsDigit(path, length) && length >= 0)
length--;
if (length > 0 && path[length] == '#')
{
// Must have at least one dot left of colon to distinguish from e.g. '#123'
if (path.IndexOf('.') != -1)
{
pageNumber = int.Parse(path.Substring(length + 1));
path = path.Substring(0, length);
}
}
}
}
return path;
}
}
}

404
PdfSharp/Drawing/XPen.cs Normal file
View File

@@ -0,0 +1,404 @@
#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.Internal;
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using GdiPen = System.Drawing.Pen;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using WpfPen =System.Windows.Media.Pen;
using WpfBrush =System.Windows.Media.Brush;
#endif
#if UWP
#endif
namespace PdfSharp.Drawing
{
// TODO Free GDI objects (pens, brushes, ...) automatically without IDisposable.
/// <summary>
/// Defines an object used to draw lines and curves.
/// </summary>
public sealed class XPen
{
/// <summary>
/// Initializes a new instance of the <see cref="XPen"/> class.
/// </summary>
public XPen(XColor color)
: this(color, 1, false)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XPen"/> class.
/// </summary>
public XPen(XColor color, double width)
: this(color, width, false)
{ }
internal XPen(XColor color, double width, bool immutable)
{
_color = color;
_width = width;
_lineJoin = XLineJoin.Miter;
_lineCap = XLineCap.Flat;
_dashStyle = XDashStyle.Solid;
_dashOffset = 0f;
_immutable = immutable;
}
/// <summary>
/// Initializes a new instance of the <see cref="XPen"/> class.
/// </summary>
public XPen(XPen pen)
{
_color = pen._color;
_width = pen._width;
_lineJoin = pen._lineJoin;
_lineCap = pen._lineCap;
_dashStyle = pen._dashStyle;
_dashOffset = pen._dashOffset;
_dashPattern = pen._dashPattern;
if (_dashPattern != null)
_dashPattern = (double[])_dashPattern.Clone();
}
/// <summary>
/// Clones this instance.
/// </summary>
public XPen Clone()
{
return new XPen(this);
}
/// <summary>
/// Gets or sets the color.
/// </summary>
public XColor Color
{
get { return _color; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _color != value;
_color = value;
}
}
internal XColor _color;
/// <summary>
/// Gets or sets the width.
/// </summary>
public double Width
{
get { return _width; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _width != value;
_width = value;
}
}
internal double _width;
/// <summary>
/// Gets or sets the line join.
/// </summary>
public XLineJoin LineJoin
{
get { return _lineJoin; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _lineJoin != value;
_lineJoin = value;
}
}
internal XLineJoin _lineJoin;
/// <summary>
/// Gets or sets the line cap.
/// </summary>
public XLineCap LineCap
{
get { return _lineCap; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _lineCap != value;
_lineCap = value;
}
}
internal XLineCap _lineCap;
/// <summary>
/// Gets or sets the miter limit.
/// </summary>
public double MiterLimit
{
get { return _miterLimit; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _miterLimit != value;
_miterLimit = value;
}
}
internal double _miterLimit;
/// <summary>
/// Gets or sets the dash style.
/// </summary>
public XDashStyle DashStyle
{
get { return _dashStyle; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _dashStyle != value;
_dashStyle = value;
}
}
internal XDashStyle _dashStyle;
/// <summary>
/// Gets or sets the dash offset.
/// </summary>
public double DashOffset
{
get { return _dashOffset; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_dirty = _dirty || _dashOffset != value;
_dashOffset = value;
}
}
internal double _dashOffset;
/// <summary>
/// Gets or sets the dash pattern.
/// </summary>
public double[] DashPattern
{
get
{
if (_dashPattern == null)
_dashPattern = new double[0];
return _dashPattern;
}
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
int length = value.Length;
//if (length == 0)
// throw new ArgumentException("Dash pattern array must not be empty.");
for (int idx = 0; idx < length; idx++)
{
if (value[idx] <= 0)
throw new ArgumentException("Dash pattern value must greater than zero.");
}
_dirty = true;
_dashStyle = XDashStyle.Custom;
_dashPattern = (double[])value.Clone();
}
}
internal double[] _dashPattern;
/// <summary>
/// Gets or sets a value indicating whether the pen enables overprint when used in a PDF document.
/// Experimental, takes effect only on CMYK color mode.
/// </summary>
public bool Overprint
{
get { return _overprint; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XPen"));
_overprint = value;
}
}
internal bool _overprint;
#if GDI
#if UseGdiObjects
/// <summary>
/// Implicit conversion from Pen to XPen
/// </summary>
public static implicit operator XPen(Pen pen)
{
XPen xpen;
try
{
Lock.EnterGdiPlus();
switch (pen.PenType)
{
case PenType.SolidColor:
xpen = new XPen(pen.Color, pen.Width);
xpen.LineJoin = (XLineJoin)pen.LineJoin;
xpen.DashStyle = (XDashStyle)pen.DashStyle;
xpen._miterLimit = pen.MiterLimit;
break;
default:
throw new NotImplementedException("Pen type not supported by PDFsharp.");
}
// Bug fixed by drice2@ageone.de
if (pen.DashStyle == System.Drawing.Drawing2D.DashStyle.Custom)
{
int length = pen.DashPattern.Length;
double[] pattern = new double[length];
for (int idx = 0; idx < length; idx++)
pattern[idx] = pen.DashPattern[idx];
xpen.DashPattern = pattern;
xpen._dashOffset = pen.DashOffset;
}
}
finally { Lock.ExitGdiPlus(); }
return xpen;
}
#endif
internal System.Drawing.Pen RealizeGdiPen()
{
if (_dirty)
{
if (_gdiPen == null)
_gdiPen = new System.Drawing.Pen(_color.ToGdiColor(), (float)_width);
else
{
_gdiPen.Color = _color.ToGdiColor();
_gdiPen.Width = (float)_width;
}
LineCap lineCap = XConvert.ToLineCap(_lineCap);
_gdiPen.StartCap = lineCap;
_gdiPen.EndCap = lineCap;
_gdiPen.LineJoin = XConvert.ToLineJoin(_lineJoin);
_gdiPen.DashOffset = (float)_dashOffset;
if (_dashStyle == XDashStyle.Custom)
{
int len = _dashPattern == null ? 0 : _dashPattern.Length;
float[] pattern = new float[len];
for (int idx = 0; idx < len; idx++)
pattern[idx] = (float)_dashPattern[idx];
_gdiPen.DashPattern = pattern;
}
else
_gdiPen.DashStyle = (System.Drawing.Drawing2D.DashStyle)_dashStyle;
}
return _gdiPen;
}
#endif
#if WPF
internal WpfPen RealizeWpfPen()
{
#if !SILVERLIGHT
if (_dirty || !_dirty) // TODOWPF: XPen is frozen by design, WPF Pen can change
{
//if (_wpfPen == null)
_wpfPen = new WpfPen(new SolidColorBrush(_color.ToWpfColor()), _width);
//else
//{
// _wpfPen.Brush = new SolidColorBrush(_color.ToWpfColor());
// _wpfPen.Thickness = _width;
//}
PenLineCap lineCap = XConvert.ToPenLineCap(_lineCap);
_wpfPen.StartLineCap = lineCap;
_wpfPen.EndLineCap = lineCap;
_wpfPen.LineJoin = XConvert.ToPenLineJoin(_lineJoin);
if (_dashStyle == XDashStyle.Custom)
{
// TODOWPF: does not work in all cases
_wpfPen.DashStyle = new System.Windows.Media.DashStyle(_dashPattern, _dashOffset);
}
else
{
switch (_dashStyle)
{
case XDashStyle.Solid:
_wpfPen.DashStyle = DashStyles.Solid;
break;
case XDashStyle.Dash:
//_wpfPen.DashStyle = DashStyles.Dash;
_wpfPen.DashStyle = new System.Windows.Media.DashStyle(new double[] { 2, 2 }, 0);
break;
case XDashStyle.Dot:
//_wpfPen.DashStyle = DashStyles.Dot;
_wpfPen.DashStyle = new System.Windows.Media.DashStyle(new double[] { 0, 2 }, 1.5);
break;
case XDashStyle.DashDot:
//_wpfPen.DashStyle = DashStyles.DashDot;
_wpfPen.DashStyle = new System.Windows.Media.DashStyle(new double[] { 2, 2, 0, 2 }, 0);
break;
case XDashStyle.DashDotDot:
//_wpfPen.DashStyle = DashStyles.DashDotDot;
_wpfPen.DashStyle = new System.Windows.Media.DashStyle(new double[] { 2, 2, 0, 2, 0, 2 }, 0);
break;
}
}
}
#else
_wpfPen = new System.Windows.Media.Pen();
_wpfPen.Brush = new SolidColorBrush(_color.ToWpfColor());
_wpfPen.Thickness = _width;
#endif
return _wpfPen;
}
#endif
bool _dirty = true;
readonly bool _immutable;
#if GDI
GdiPen _gdiPen;
#endif
#if WPF
WpfPen _wpfPen;
#endif
}
}

1595
PdfSharp/Drawing/XPens.cs Normal file

File diff suppressed because it is too large Load Diff

434
PdfSharp/Drawing/XPoint.cs Normal file
View File

@@ -0,0 +1,434 @@
#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.Globalization;
using System.Runtime.InteropServices;
#if CORE
#endif
#if GDI
using System.Drawing;
#endif
#if WPF
using System.Windows;
using SysPoint = System.Windows.Point;
using SysSize = System.Windows.Size;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media;
using SysPoint = Windows.Foundation.Point;
using SysSize = Windows.Foundation.Size;
#endif
#if !EDF_CORE
using PdfSharp.Internal;
#else
using PdfSharp.Internal;
#endif
#if !EDF_CORE
namespace PdfSharp.Drawing
#else
namespace Edf.Drawing
#endif
{
/// <summary>
/// Represents a pair of floating point x- and y-coordinates that defines a point
/// in a two-dimensional plane.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
[Serializable]
[StructLayout(LayoutKind.Sequential)] // TypeConverter(typeof(PointConverter)), ValueSerializer(typeof(PointValueSerializer))]
public struct XPoint : IFormattable
{
/// <summary>
/// Initializes a new instance of the XPoint class with the specified coordinates.
/// </summary>
public XPoint(double x, double y)
{
_x = x;
_y = y;
}
#if GDI
/// <summary>
/// Initializes a new instance of the XPoint class with the specified point.
/// </summary>
public XPoint(System.Drawing.Point point)
{
_x = point.X;
_y = point.Y;
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Initializes a new instance of the XPoint class with the specified point.
/// </summary>
public XPoint(SysPoint point)
{
_x = point.X;
_y = point.Y;
}
#endif
#if GDI
/// <summary>
/// Initializes a new instance of the XPoint class with the specified point.
/// </summary>
public XPoint(PointF point)
{
_x = point.X;
_y = point.Y;
}
#endif
/// <summary>
/// Determines whether two points are equal.
/// </summary>
public static bool operator ==(XPoint point1, XPoint point2)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return point1._x == point2._x && point1._y == point2._y;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Determines whether two points are not equal.
/// </summary>
public static bool operator !=(XPoint point1, XPoint point2)
{
return !(point1 == point2);
}
/// <summary>
/// Indicates whether the specified points are equal.
/// </summary>
public static bool Equals(XPoint point1, XPoint point2)
{
return point1.X.Equals(point2.X) && point1.Y.Equals(point2.Y);
}
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
public override bool Equals(object o)
{
if (!(o is XPoint))
return false;
return Equals(this, (XPoint)o);
}
/// <summary>
/// Indicates whether this instance and a specified point are equal.
/// </summary>
public bool Equals(XPoint value)
{
return Equals(this, value);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
/// <summary>
/// Parses the point from a string.
/// </summary>
public static XPoint Parse(string source)
{
CultureInfo cultureInfo = CultureInfo.InvariantCulture;
TokenizerHelper helper = new TokenizerHelper(source, cultureInfo);
string str = helper.NextTokenRequired();
XPoint point = new XPoint(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
helper.LastTokenRequired();
return point;
}
/// <summary>
/// Parses an array of points from a string.
/// </summary>
public static XPoint[] ParsePoints(string value)
{
if (value == null)
throw new ArgumentNullException("value");
// TODO: Reflect reliabel implementation from Avalon
// TODOWPF
string[] values = value.Split(' ');
int count = values.Length;
XPoint[] points = new XPoint[count];
for (int idx = 0; idx < count; idx++)
points[idx] = Parse(values[idx]);
return points;
}
/// <summary>
/// Gets the x-coordinate of this XPoint.
/// </summary>
public double X
{
get { return _x; }
set { _x = value; }
}
double _x;
/// <summary>
/// Gets the x-coordinate of this XPoint.
/// </summary>
public double Y
{
get { return _y; }
set { _y = value; }
}
double _y;
#if CORE
#if UseGdiObjects
/// <summary>
/// Converts this XPoint to a System.Drawing.Point.
/// </summary>
public PointF ToPointF()
{
return new PointF((float)_x, (float)_y);
}
#endif
#endif
#if GDI
/// <summary>
/// Converts this XPoint to a System.Drawing.Point.
/// </summary>
public PointF ToPointF()
{
return new PointF((float)_x, (float)_y);
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Converts this XPoint to a System.Windows.Point.
/// </summary>
public SysPoint ToPoint()
{
return new SysPoint(_x, _y);
}
#endif
/// <summary>
/// Converts this XPoint to a human readable string.
/// </summary>
public override string ToString()
{
return ConvertToString(null, null);
}
/// <summary>
/// Converts this XPoint to a human readable string.
/// </summary>
public string ToString(IFormatProvider provider)
{
return ConvertToString(null, provider);
}
/// <summary>
/// Converts this XPoint to a human readable string.
/// </summary>
string IFormattable.ToString(string format, IFormatProvider provider)
{
return ConvertToString(format, provider);
}
/// <summary>
/// Implements ToString.
/// </summary>
internal string ConvertToString(string format, IFormatProvider provider)
{
char numericListSeparator = TokenizerHelper.GetNumericListSeparator(provider);
provider = provider ?? CultureInfo.InvariantCulture;
return string.Format(provider, "{1:" + format + "}{0}{2:" + format + "}", new object[] { numericListSeparator, _x, _y });
}
/// <summary>
/// Offsets the x and y value of this point.
/// </summary>
public void Offset(double offsetX, double offsetY)
{
_x += offsetX;
_y += offsetY;
}
/// <summary>
/// Adds a point and a vector.
/// </summary>
public static XPoint operator +(XPoint point, XVector vector)
{
return new XPoint(point._x + vector.X, point._y + vector.Y);
}
/// <summary>
/// Adds a point and a size.
/// </summary>
public static XPoint operator +(XPoint point, XSize size) // TODO: make obsolete
{
return new XPoint(point._x + size.Width, point._y + size.Height);
}
/// <summary>
/// Adds a point and a vector.
/// </summary>
public static XPoint Add(XPoint point, XVector vector)
{
return new XPoint(point._x + vector.X, point._y + vector.Y);
}
/// <summary>
/// Subtracts a vector from a point.
/// </summary>
public static XPoint operator -(XPoint point, XVector vector)
{
return new XPoint(point._x - vector.X, point._y - vector.Y);
}
/// <summary>
/// Subtracts a vector from a point.
/// </summary>
public static XPoint Subtract(XPoint point, XVector vector)
{
return new XPoint(point._x - vector.X, point._y - vector.Y);
}
/// <summary>
/// Subtracts a point from a point.
/// </summary>
public static XVector operator -(XPoint point1, XPoint point2)
{
return new XVector(point1._x - point2._x, point1._y - point2._y);
}
/// <summary>
/// Subtracts a size from a point.
/// </summary>
[Obsolete("Use XVector instead of XSize as second parameter.")]
public static XPoint operator -(XPoint point, XSize size) // TODO: make obsolete
{
return new XPoint(point._x - size.Width, point._y - size.Height);
}
/// <summary>
/// Subtracts a point from a point.
/// </summary>
public static XVector Subtract(XPoint point1, XPoint point2)
{
return new XVector(point1._x - point2._x, point1._y - point2._y);
}
/// <summary>
/// Multiplies a point with a matrix.
/// </summary>
public static XPoint operator *(XPoint point, XMatrix matrix)
{
return matrix.Transform(point);
}
/// <summary>
/// Multiplies a point with a matrix.
/// </summary>
public static XPoint Multiply(XPoint point, XMatrix matrix)
{
return matrix.Transform(point);
}
/// <summary>
/// Multiplies a point with a scalar value.
/// </summary>
public static XPoint operator *(XPoint point, double value)
{
return new XPoint(point._x * value, point._y * value);
}
/// <summary>
/// Multiplies a point with a scalar value.
/// </summary>
public static XPoint operator *(double value, XPoint point)
{
return new XPoint(value * point._x, value * point._y);
}
/// <summary>
/// Performs an explicit conversion from XPoint to XSize.
/// </summary>
public static explicit operator XSize(XPoint point)
{
return new XSize(Math.Abs(point._x), Math.Abs(point._y));
}
/// <summary>
/// Performs an explicit conversion from XPoint to XVector.
/// </summary>
public static explicit operator XVector(XPoint point)
{
return new XVector(point._x, point._y);
}
#if WPF || NETFX_CORE
/// <summary>
/// Performs an implicit conversion from XPoint to Point.
/// </summary>
public static implicit operator SysPoint(XPoint point)
{
return new SysPoint(point.X, point.Y);
}
/// <summary>
/// Performs an implicit conversion from Point to XPoint.
/// </summary>
public static implicit operator XPoint(SysPoint point)
{
return new XPoint(point.X, point.Y);
}
#endif
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
const string format = Config.SignificantFigures10;
return String.Format(CultureInfo.InvariantCulture, "point=({0:" + format + "}, {1:" + format + "})", _x, _y);
}
}
}
}

View File

@@ -0,0 +1,441 @@
#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.IO;
using System.Runtime.InteropServices;
using PdfSharp.Fonts;
#if CORE || GDI
using System.Drawing;
using System.Drawing.Drawing2D;
using GdiFontFamily = System.Drawing.FontFamily;
using GdiFont = System.Drawing.Font;
using GdiFontStyle = System.Drawing.FontStyle;
using GdiPrivateFontCollection = System.Drawing.Text.PrivateFontCollection;
#endif
#if WPF
using System.Windows.Markup;
using WpfFonts = System.Windows.Media.Fonts;
using WpfFontFamily = System.Windows.Media.FontFamily;
using WpfTypeface = System.Windows.Media.Typeface;
using WpfGlyphTypeface = System.Windows.Media.GlyphTypeface;
#endif
namespace PdfSharp.Drawing
{
#if true
///<summary>
/// Makes fonts that are not installed on the system available within the current application domain.<br/>
/// In Silverlight required for all fonts used in PDF documents.
/// </summary>
public sealed class XPrivateFontCollection
{
// This one is global and can only grow. It is not possible to remove fonts that have been added.
/// <summary>
/// Initializes a new instance of the <see cref="XPrivateFontCollection"/> class.
/// </summary>
XPrivateFontCollection()
{
// HACK: Use one global PrivateFontCollection in GDI+
}
#if GDI
//internal PrivateFontCollection PrivateFontCollection
//{
// get { return privateFontCollection; }
// set { privateFontCollection = value; }
//}
GdiPrivateFontCollection GetPrivateFontCollection()
{
// Create only if really needed.
if (_privateFontCollection == null)
_privateFontCollection = new GdiPrivateFontCollection();
return _privateFontCollection;
}
// PrivateFontCollection of GDI+
private GdiPrivateFontCollection _privateFontCollection;
#endif
/// <summary>
/// Gets the global font collection.
/// </summary>
internal static XPrivateFontCollection Singleton
{
get { return _singleton; }
}
internal static XPrivateFontCollection _singleton = new XPrivateFontCollection();
#if GDI
/// <summary>
/// Adds the font data to the font collections.
/// </summary>
[Obsolete("Use Add(Stream stream)")]
public void AddFont(byte[] data, string familyName)
{
if (String.IsNullOrEmpty(familyName))
throw new ArgumentNullException("familyName");
//if (glyphTypeface == null)
// throw new ArgumentNullException("glyphTypeface");
// Add to GDI+ PrivateFontCollection
int length = data.Length;
// Copy data without unsafe code
IntPtr ip = Marshal.AllocCoTaskMem(length);
Marshal.Copy(data, 0, ip, length);
GetPrivateFontCollection().AddMemoryFont(ip, length);
// Do not free the memory here, AddMemoryFont stores a pointer, not a copy!
//Marshal.FreeCoTaskMem(ip);
//privateFonts.Add(glyphTypeface);
}
#endif
/// <summary>
/// Adds the specified font data to the global PrivateFontCollection.
/// Family name and style are automatically retrieved from the font.
/// </summary>
#if GDI
[Obsolete("Use Add(Stream stream)")]
#else
[Obsolete("Use the GDI build of PDFsharp and use Add(Stream stream)")]
#endif
public static void AddFont(string filename)
{
throw new NotImplementedException();
//XGlyphTypeface glyphTypeface = new XGlyphTypeface(filename);
//Global.AddGlyphTypeface(glyphTypeface);
}
#if GDI
/// <summary>
/// Adds the specified font data to the global PrivateFontCollection.
/// Family name and style are automatically retrieved from the font.
/// </summary>
[Obsolete("Use Add(stream).")]
public static void AddFont(Stream stream)
{
Add(stream);
}
/// <summary>
/// Adds the specified font data to the global PrivateFontCollection.
/// Family name and style are automatically retrieved from the font.
/// </summary>
public static void Add(Stream stream)
{
int length = (int)stream.Length;
byte[] bytes = new byte[length];
stream.Read(bytes, 0, length);
Add(bytes);
}
/// <summary>
/// Adds the specified font data to the global PrivateFontCollection.
/// Family name and style are automatically retrieved from the font.
/// </summary>
public static void Add(byte[] font)
{
IntPtr unmanagedPointer = Marshal.AllocCoTaskMem(font.Length);
Marshal.Copy(font, 0, unmanagedPointer, font.Length);
Singleton.GetPrivateFontCollection().AddMemoryFont(unmanagedPointer, font.Length);
// Do not free the memory here, AddMemoryFont stores a pointer, not a copy!
//Marshal.FreeCoTaskMem(ip);
XFontSource fontSource = XFontSource.GetOrCreateFrom(font);
string familyName = fontSource.FontName;
if (familyName.EndsWith(" Regular", StringComparison.OrdinalIgnoreCase))
familyName = familyName.Substring(0, familyName.Length - 8);
bool bold = fontSource.Fontface.os2.IsBold;
bool italic = fontSource.Fontface.os2.IsItalic;
IncompetentlyMakeAHackToFixAProblemYouWoldNeverHaveIfYouUseAFontResolver(fontSource, ref familyName, ref bold, ref italic);
string key = MakeKey(familyName, bold, italic);
Singleton._fontSources.Add(key, fontSource);
string typefaceKey = XGlyphTypeface.ComputeKey(familyName, bold, italic);
FontFactory.CacheExistingFontSourceWithNewTypefaceKey(typefaceKey, fontSource);
}
static void IncompetentlyMakeAHackToFixAProblemYouWoldNeverHaveIfYouUseAFontResolver(XFontSource fontSource,
ref string familyName, ref bool bold, ref bool italic)
{
const string regularSuffix = " Regular";
const string boldSuffix = " Bold";
const string italicSuffix = " Italic";
const string boldItalicSuffix = " Bold Italic";
const string italicBoldSuffix = " Italic Bold";
if (familyName.EndsWith(regularSuffix, StringComparison.OrdinalIgnoreCase))
{
familyName = familyName.Substring(0, familyName.Length - regularSuffix.Length);
Debug.Assert(!bold && !italic);
bold = italic = false;
}
else if (familyName.EndsWith(boldItalicSuffix, StringComparison.OrdinalIgnoreCase) || familyName.EndsWith(italicBoldSuffix, StringComparison.OrdinalIgnoreCase))
{
familyName = familyName.Substring(0, familyName.Length - boldItalicSuffix.Length);
Debug.Assert(bold && italic);
bold = italic = true;
}
else if (familyName.EndsWith(boldSuffix, StringComparison.OrdinalIgnoreCase))
{
familyName = familyName.Substring(0, familyName.Length - boldSuffix.Length);
Debug.Assert(bold && !italic);
bold = true;
italic = false;
}
else if (familyName.EndsWith(italicSuffix, StringComparison.OrdinalIgnoreCase))
{
familyName = familyName.Substring(0, familyName.Length - italicSuffix.Length);
Debug.Assert(!bold && italic);
bold = false;
italic = true;
}
else
{
Debug.Assert(!bold && !italic);
bold = false;
italic = false;
}
}
#endif
/// <summary>
/// Adds the specified font data to the global PrivateFontCollection.
/// Family name and style are automatically retrieved from the font.
/// </summary>
#if GDI
[Obsolete("Use Add(Stream stream)")]
#else
[Obsolete("Use the GDI build of PDFsharp and use Add(Stream stream)")]
#endif
public static void AddFont(Stream stream, string facename)
{
throw new NotImplementedException();
//XGlyphTypeface glyphTypeface = new XGlyphTypeface(stream, facename);
//Global.AddGlyphTypeface(glyphTypeface);
}
// /// <summary>
// /// Adds XGlyphTypeface to internal collection.
// /// Family name and style are automatically retrieved from the font.
// /// </summary>
// void AddGlyphTypeface(XGlyphTypeface glyphTypeface)
// {
// string name = MakeName(glyphTypeface);
// if (_typefaces.ContainsKey(name))
// throw new InvalidOperationException(PSSR.FontAlreadyAdded(glyphTypeface.DisplayName));
// _typefaces.Add(name, glyphTypeface);
// //Debug.WriteLine("Font added: " + name);
//#if GDI
// // Add to GDI+ PrivateFontCollection singleton.
// byte[] data = glyphTypeface.Fontface.FontSource.Bytes;
// int length = data.Length;
// IntPtr ip = Marshal.AllocCoTaskMem(length);
// Marshal.Copy(data, 0, ip, length);
// _privateFontCollection.AddMemoryFont(ip, length);
// // Do not free the memory here, AddMemoryFont stores a pointer, not a copy!
// // Marshal.FreeCoTaskMem(ip);
//#endif
//#if WPF
//#endif
// }
#if WPF
/// <summary>
/// Initializes a new instance of the FontFamily class from the specified font family name and an optional base uniform resource identifier (URI) value.
/// Sample: Add(new Uri("pack://application:,,,/"), "./myFonts/#FontFamilyName");)
/// </summary>
/// <param name="baseUri">Specifies the base URI that is used to resolve familyName.</param>
/// <param name="familyName">The family name or names that comprise the new FontFamily. Multiple family names should be separated by commas.</param>
public static void Add(Uri baseUri, string familyName)
{
Uri uri = new Uri("pack://application:,,,/");
// TODO: What means 'Multiple family names should be separated by commas.'?
// does not work
if (String.IsNullOrEmpty(familyName))
throw new ArgumentNullException("familyName");
if (familyName.Contains(","))
throw new NotImplementedException("Only one family name is supported.");
// Family name starts right of '#'.
int idxHash = familyName.IndexOf('#');
if (idxHash < 0)
throw new ArgumentException("Family name must contain a '#'. Example './#MyFontFamilyName'", "familyName");
string key = familyName.Substring(idxHash + 1);
if (String.IsNullOrEmpty(key))
throw new ArgumentException("familyName has invalid format.");
if (Singleton._fontFamilies.ContainsKey(key))
throw new ArgumentException("An entry with the specified family name already exists.");
#if !SILVERLIGHT
#if DEBUG_
foreach (WpfFontFamily fontFamily1 in WpfFonts.GetFontFamilies(baseUri, familyName))
{
ICollection<WpfTypeface> wpfTypefaces = fontFamily1.GetTypefaces();
wpfTypefaces.GetType();
}
#endif
// Create WPF font family.
WpfFontFamily fontFamily = new WpfFontFamily(baseUri, familyName);
//System.Windows.Media.FontFamily x;
// Required for new Uri("pack://application:,,,/")
// ReSharper disable once ObjectCreationAsStatement
// new System.Windows.Application();
#else
System.Windows.Media.FontFamily fontFamily = new System.Windows.Media.FontFamily(familyName);
#endif
// Check whether font data really exists
#if DEBUG && !SILVERLIGHT
ICollection<WpfTypeface> list = fontFamily.GetTypefaces();
foreach (WpfTypeface typeFace in list)
{
Debug.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}", familyName, typeFace.FaceNames[FontHelper.XmlLanguageEnUs], typeFace.Style, typeFace.Weight, typeFace.Stretch));
WpfGlyphTypeface glyphTypeface;
if (!typeFace.TryGetGlyphTypeface(out glyphTypeface))
{
Debug.WriteLine(" Glyph typeface does not exists.");
//throw new ArgumentException("Font with the specified family name does not exist.");
}
}
#endif
Singleton._fontFamilies.Add(key, fontFamily);
}
#endif
//internal static XGlyphTypeface TryGetXGlyphTypeface(string familyName, XFontStyle style)
//{
// string name = MakeName(familyName, style);
// XGlyphTypeface typeface;
// _global._typefaces.TryGetValue(name, out typeface);
// return typeface;
//}
#if GDI
internal static GdiFont TryCreateFont(string name, double size, GdiFontStyle style, out XFontSource fontSource)
{
fontSource = null;
try
{
GdiPrivateFontCollection pfc = Singleton._privateFontCollection;
if (pfc == null)
return null;
#if true
string key = MakeKey(name, (XFontStyle)style);
if (Singleton._fontSources.TryGetValue(key, out fontSource))
{
GdiFont font = new GdiFont(name, (float)size, style, GraphicsUnit.World);
#if DEBUG_
Debug.Assert(StringComparer.OrdinalIgnoreCase.Compare(name, font.Name) == 0);
Debug.Assert(font.Bold == ((style & GdiFontStyle.Bold) != 0));
Debug.Assert(font.Italic == ((style & GdiFontStyle.Italic) != 0));
#endif
return font;
}
return null;
#else
foreach (GdiFontFamily family in pfc.Families)
{
if (string.Compare(family.Name, name, StringComparison.OrdinalIgnoreCase) == 0)
{
GdiFont font = new GdiFont(family, (float)size, style, GraphicsUnit.World);
if (string.Compare(font.Name, name, StringComparison.OrdinalIgnoreCase) != 0)
{
// Style simulation is not implemented in GDI+.
// Use WPF build.
}
return font;
}
}
#endif
}
catch (Exception ex)
{
// Ignore exception and return null.
Debug.WriteLine(ex.ToString());
}
return null;
}
#endif
#if WPF && !SILVERLIGHT
internal static WpfTypeface TryCreateTypeface(string name, XFontStyle style, out WpfFontFamily fontFamily)
{
if (Singleton._fontFamilies.TryGetValue(name, out fontFamily))
{
WpfTypeface typeface = FontHelper.CreateTypeface(fontFamily, style);
return typeface;
}
return null;
}
#endif
static string MakeKey(string familyName, XFontStyle style)
{
return MakeKey(familyName, (style & XFontStyle.Bold) != 0, (style & XFontStyle.Italic) != 0);
}
static string MakeKey(string familyName, bool bold, bool italic)
{
return familyName + "#" + (bold ? "b" : "") + (italic ? "i" : "");
}
readonly Dictionary<string, XGlyphTypeface> _typefaces = new Dictionary<string, XGlyphTypeface>();
#if GDI
//List<XGlyphTypeface> privateFonts = new List<XGlyphTypeface>();
readonly Dictionary<string, XFontSource> _fontSources = new Dictionary<string, XFontSource>(StringComparer.OrdinalIgnoreCase);
#endif
#if WPF
readonly Dictionary<string, WpfFontFamily> _fontFamilies = new Dictionary<string, WpfFontFamily>(StringComparer.OrdinalIgnoreCase);
#endif
}
#endif
}

847
PdfSharp/Drawing/XRect.cs Normal file
View File

@@ -0,0 +1,847 @@
#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.Globalization;
using System.Runtime.InteropServices;
#if CORE
#endif
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
using SysPoint = System.Windows.Point;
using SysSize = System.Windows.Size;
using SysRect = System.Windows.Rect;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media;
using SysPoint = Windows.Foundation.Point;
using SysSize = Windows.Foundation.Size;
using SysRect = Windows.Foundation.Rect;
#endif
#if !EDF_CORE
using PdfSharp.Internal;
#else
using PdfSharp.Internal;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Stores a set of four floating-point numbers that represent the location and size of a rectangle.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
[Serializable, StructLayout(LayoutKind.Sequential)] // , ValueSerializer(typeof(RectValueSerializer)), TypeConverter(typeof(RectConverter))]
public struct XRect : IFormattable
{
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(double x, double y, double width, double height)
{
if (width < 0 || height < 0)
throw new ArgumentException("WidthAndHeightCannotBeNegative"); //SR.Get(SRID.Size_WidthAndHeightCannotBeNegative, new object[0]));
_x = x;
_y = y;
_width = width;
_height = height;
}
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(XPoint point1, XPoint point2)
{
_x = Math.Min(point1.X, point2.X);
_y = Math.Min(point1.Y, point2.Y);
_width = Math.Max(Math.Max(point1.X, point2.X) - _x, 0);
_height = Math.Max(Math.Max(point1.Y, point2.Y) - _y, 0);
}
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(XPoint point, XVector vector)
: this(point, point + vector)
{ }
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(XPoint location, XSize size)
{
if (size.IsEmpty)
this = s_empty;
else
{
_x = location.X;
_y = location.Y;
_width = size.Width;
_height = size.Height;
}
}
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(XSize size)
{
if (size.IsEmpty)
this = s_empty;
else
{
_x = _y = 0;
_width = size.Width;
_height = size.Height;
}
}
#if GDI
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(PointF location, SizeF size)
{
_x = location.X;
_y = location.Y;
_width = size.Width;
_height = size.Height;
}
#endif
#if GDI
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(RectangleF rect)
{
_x = rect.X;
_y = rect.Y;
_width = rect.Width;
_height = rect.Height;
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Initializes a new instance of the XRect class.
/// </summary>
public XRect(SysRect rect)
{
_x = rect.X;
_y = rect.Y;
_width = rect.Width;
_height = rect.Height;
}
#endif
/// <summary>
/// Creates a rectangle from for straight lines.
/// </summary>
// ReSharper disable InconsistentNaming
public static XRect FromLTRB(double left, double top, double right, double bottom)
// ReSharper restore InconsistentNaming
{
return new XRect(left, top, right - left, bottom - top);
}
/// <summary>
/// Determines whether the two rectangles are equal.
/// </summary>
public static bool operator ==(XRect rect1, XRect rect2)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return rect1.X == rect2.X && rect1.Y == rect2.Y && rect1.Width == rect2.Width && rect1.Height == rect2.Height;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Determines whether the two rectangles are not equal.
/// </summary>
public static bool operator !=(XRect rect1, XRect rect2)
{
return !(rect1 == rect2);
}
/// <summary>
/// Determines whether the two rectangles are equal.
/// </summary>
public static bool Equals(XRect rect1, XRect rect2)
{
if (rect1.IsEmpty)
return rect2.IsEmpty;
return rect1.X.Equals(rect2.X) && rect1.Y.Equals(rect2.Y) && rect1.Width.Equals(rect2.Width) && rect1.Height.Equals(rect2.Height);
}
/// <summary>
/// Determines whether this instance and the specified object are equal.
/// </summary>
public override bool Equals(object o)
{
if (!(o is XRect))
return false;
return Equals(this, (XRect)o);
}
/// <summary>
/// Determines whether this instance and the specified rect are equal.
/// </summary>
public bool Equals(XRect value)
{
return Equals(this, value);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
if (IsEmpty)
return 0;
return X.GetHashCode() ^ Y.GetHashCode() ^ Width.GetHashCode() ^ Height.GetHashCode();
}
/// <summary>
/// Parses the rectangle from a string.
/// </summary>
public static XRect Parse(string source)
{
XRect empty;
CultureInfo cultureInfo = CultureInfo.InvariantCulture;
TokenizerHelper helper = new TokenizerHelper(source, cultureInfo);
string str = helper.NextTokenRequired();
if (str == "Empty")
empty = Empty;
else
empty = new XRect(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
helper.LastTokenRequired();
return empty;
}
/// <summary>
/// Converts this XRect to a human readable string.
/// </summary>
public override string ToString()
{
return ConvertToString(null, null);
}
/// <summary>
/// Converts this XRect to a human readable string.
/// </summary>
public string ToString(IFormatProvider provider)
{
return ConvertToString(null, provider);
}
/// <summary>
/// Converts this XRect to a human readable string.
/// </summary>
string IFormattable.ToString(string format, IFormatProvider provider)
{
return ConvertToString(format, provider);
}
internal string ConvertToString(string format, IFormatProvider provider)
{
if (IsEmpty)
return "Empty";
char numericListSeparator = TokenizerHelper.GetNumericListSeparator(provider);
provider = provider ?? CultureInfo.InvariantCulture;
// ReSharper disable FormatStringProblem
return string.Format(provider, "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}", new object[] { numericListSeparator, _x, _y, _width, _height });
// ReSharper restore FormatStringProblem
}
/// <summary>
/// Gets the empty rectangle.
/// </summary>
public static XRect Empty
{
get { return s_empty; }
}
/// <summary>
/// Gets a value indicating whether this instance is empty.
/// </summary>
public bool IsEmpty
{
get { return _width < 0; }
}
/// <summary>
/// Gets or sets the location of the rectangle.
/// </summary>
public XPoint Location
{
get { return new XPoint(_x, _y); }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptyRect"); //SR.Get(SRID.Rect_CannotModifyEmptyRect, new object[0]));
_x = value.X;
_y = value.Y;
}
}
/// <summary>
/// Gets or sets the size of the rectangle.
/// </summary>
//[Browsable(false)]
public XSize Size
{
get
{
if (IsEmpty)
return XSize.Empty;
return new XSize(_width, _height);
}
set
{
if (value.IsEmpty)
this = s_empty;
else
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptyRect"); //SR.Get(SRID.Rect_CannotModifyEmptyRect, new object[0]));
_width = value.Width;
_height = value.Height;
}
}
}
/// <summary>
/// Gets or sets the X value of the rectangle.
/// </summary>
public double X
{
get { return _x; }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptyRect"); //SR.Get(SRID.Rect_CannotModifyEmptyRect, new object[0]));
_x = value;
}
}
double _x;
/// <summary>
/// Gets or sets the Y value of the rectangle.
/// </summary>
public double Y
{
get { return _y; }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptyRect"); //SR.Get(SRID.Rect_CannotModifyEmptyRect, new object[0]));
_y = value;
}
}
double _y;
/// <summary>
/// Gets or sets the width of the rectangle.
/// </summary>
public double Width
{
get { return _width; }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptyRect"); //SR.Get(SRID.Rect_CannotModifyEmptyRect, new object[0]));
if (value < 0)
throw new ArgumentException("WidthCannotBeNegative"); //SR.Get(SRID.Size_WidthCannotBeNegative, new object[0]));
_width = value;
}
}
double _width;
/// <summary>
/// Gets or sets the height of the rectangle.
/// </summary>
public double Height
{
get { return _height; }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptyRect"); //SR.Get(SRID.Rect_CannotModifyEmptyRect, new object[0]));
if (value < 0)
throw new ArgumentException("HeightCannotBeNegative"); //SR.Get(SRID.Size_HeightCannotBeNegative, new object[0]));
_height = value;
}
}
double _height;
/// <summary>
/// Gets the x-axis value of the left side of the rectangle.
/// </summary>
public double Left
{
get { return _x; }
}
/// <summary>
/// Gets the y-axis value of the top side of the rectangle.
/// </summary>
public double Top
{
get { return _y; }
}
/// <summary>
/// Gets the x-axis value of the right side of the rectangle.
/// </summary>
public double Right
{
get
{
if (IsEmpty)
return double.NegativeInfinity;
return _x + _width;
}
}
/// <summary>
/// Gets the y-axis value of the bottom side of the rectangle.
/// </summary>
public double Bottom
{
get
{
if (IsEmpty)
return double.NegativeInfinity;
return _y + _height;
}
}
/// <summary>
/// Gets the position of the top-left corner of the rectangle.
/// </summary>
public XPoint TopLeft
{
get { return new XPoint(Left, Top); }
}
/// <summary>
/// Gets the position of the top-right corner of the rectangle.
/// </summary>
public XPoint TopRight
{
get { return new XPoint(Right, Top); }
}
/// <summary>
/// Gets the position of the bottom-left corner of the rectangle.
/// </summary>
public XPoint BottomLeft
{
get { return new XPoint(Left, Bottom); }
}
/// <summary>
/// Gets the position of the bottom-right corner of the rectangle.
/// </summary>
public XPoint BottomRight
{
get { return new XPoint(Right, Bottom); }
}
/// <summary>
/// Gets the center of the rectangle.
/// </summary>
//[Browsable(false)]
public XPoint Center
{
get { return new XPoint(_x + _width / 2, _y + _height / 2); }
}
/// <summary>
/// Indicates whether the rectangle contains the specified point.
/// </summary>
public bool Contains(XPoint point)
{
return Contains(point.X, point.Y);
}
/// <summary>
/// Indicates whether the rectangle contains the specified point.
/// </summary>
public bool Contains(double x, double y)
{
if (IsEmpty)
return false;
return ContainsInternal(x, y);
}
/// <summary>
/// Indicates whether the rectangle contains the specified rectangle.
/// </summary>
public bool Contains(XRect rect)
{
return !IsEmpty && !rect.IsEmpty &&
_x <= rect._x && _y <= rect._y &&
_x + _width >= rect._x + rect._width && _y + _height >= rect._y + rect._height;
}
/// <summary>
/// Indicates whether the specified rectangle intersects with the current rectangle.
/// </summary>
public bool IntersectsWith(XRect rect)
{
return !IsEmpty && !rect.IsEmpty &&
rect.Left <= Right && rect.Right >= Left &&
rect.Top <= Bottom && rect.Bottom >= Top;
}
/// <summary>
/// Sets current rectangle to the intersection of the current rectangle and the specified rectangle.
/// </summary>
public void Intersect(XRect rect)
{
if (!IntersectsWith(rect))
this = Empty;
else
{
double left = Math.Max(Left, rect.Left);
double top = Math.Max(Top, rect.Top);
_width = Math.Max(Math.Min(Right, rect.Right) - left, 0.0);
_height = Math.Max(Math.Min(Bottom, rect.Bottom) - top, 0.0);
_x = left;
_y = top;
}
}
/// <summary>
/// Returns the intersection of two rectangles.
/// </summary>
public static XRect Intersect(XRect rect1, XRect rect2)
{
rect1.Intersect(rect2);
return rect1;
}
/// <summary>
/// Sets current rectangle to the union of the current rectangle and the specified rectangle.
/// </summary>
public void Union(XRect rect)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
if (IsEmpty)
this = rect;
else if (!rect.IsEmpty)
{
double left = Math.Min(Left, rect.Left);
double top = Math.Min(Top, rect.Top);
if (rect.Width == Double.PositiveInfinity || Width == Double.PositiveInfinity)
_width = Double.PositiveInfinity;
else
{
double right = Math.Max(Right, rect.Right);
_width = Math.Max(right - left, 0.0);
}
if (rect.Height == Double.PositiveInfinity || _height == Double.PositiveInfinity)
_height = Double.PositiveInfinity;
else
{
double bottom = Math.Max(Bottom, rect.Bottom);
_height = Math.Max(bottom - top, 0.0);
}
_x = left;
_y = top;
}
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Returns the union of two rectangles.
/// </summary>
public static XRect Union(XRect rect1, XRect rect2)
{
rect1.Union(rect2);
return rect1;
}
/// <summary>
/// Sets current rectangle to the union of the current rectangle and the specified point.
/// </summary>
public void Union(XPoint point)
{
Union(new XRect(point, point));
}
/// <summary>
/// Returns the intersection of a rectangle and a point.
/// </summary>
public static XRect Union(XRect rect, XPoint point)
{
rect.Union(new XRect(point, point));
return rect;
}
/// <summary>
/// Moves a rectangle by the specified amount.
/// </summary>
public void Offset(XVector offsetVector)
{
if (IsEmpty)
throw new InvalidOperationException("CannotCallMethod"); //SR.Get(SRID.Rect_CannotCallMethod, new object[0]));
_x += offsetVector.X;
_y += offsetVector.Y;
}
/// <summary>
/// Moves a rectangle by the specified amount.
/// </summary>
public void Offset(double offsetX, double offsetY)
{
if (IsEmpty)
throw new InvalidOperationException("CannotCallMethod"); //SR.Get(SRID.Rect_CannotCallMethod, new object[0]));
_x += offsetX;
_y += offsetY;
}
/// <summary>
/// Returns a rectangle that is offset from the specified rectangle by using the specified vector.
/// </summary>
public static XRect Offset(XRect rect, XVector offsetVector)
{
rect.Offset(offsetVector.X, offsetVector.Y);
return rect;
}
/// <summary>
/// Returns a rectangle that is offset from the specified rectangle by using specified horizontal and vertical amounts.
/// </summary>
public static XRect Offset(XRect rect, double offsetX, double offsetY)
{
rect.Offset(offsetX, offsetY);
return rect;
}
/// <summary>
/// Translates the rectangle by adding the specified point.
/// </summary>
//[Obsolete("Use Offset.")]
public static XRect operator +(XRect rect, XPoint point)
{
return new XRect(rect._x + point.X, rect.Y + point.Y, rect._width, rect._height);
}
/// <summary>
/// Translates the rectangle by subtracting the specified point.
/// </summary>
//[Obsolete("Use Offset.")]
public static XRect operator -(XRect rect, XPoint point)
{
return new XRect(rect._x - point.X, rect.Y - point.Y, rect._width, rect._height);
}
/// <summary>
/// Expands the rectangle by using the specified Size, in all directions.
/// </summary>
public void Inflate(XSize size)
{
Inflate(size.Width, size.Height);
}
/// <summary>
/// Expands or shrinks the rectangle by using the specified width and height amounts, in all directions.
/// </summary>
public void Inflate(double width, double height)
{
if (IsEmpty)
throw new InvalidOperationException("CannotCallMethod"); //SR.Get(SRID.Rect_CannotCallMethod, new object[0]));
_x -= width;
_y -= height;
_width += width;
_width += width;
_height += height;
_height += height;
if (_width < 0 || _height < 0)
this = s_empty;
}
/// <summary>
/// Returns the rectangle that results from expanding the specified rectangle by the specified Size, in all directions.
/// </summary>
public static XRect Inflate(XRect rect, XSize size)
{
rect.Inflate(size.Width, size.Height);
return rect;
}
/// <summary>
/// Creates a rectangle that results from expanding or shrinking the specified rectangle by the specified width and height amounts, in all directions.
/// </summary>
public static XRect Inflate(XRect rect, double width, double height)
{
rect.Inflate(width, height);
return rect;
}
/// <summary>
/// Returns the rectangle that results from applying the specified matrix to the specified rectangle.
/// </summary>
public static XRect Transform(XRect rect, XMatrix matrix)
{
XMatrix.MatrixHelper.TransformRect(ref rect, ref matrix);
return rect;
}
/// <summary>
/// Transforms the rectangle by applying the specified matrix.
/// </summary>
public void Transform(XMatrix matrix)
{
XMatrix.MatrixHelper.TransformRect(ref this, ref matrix);
}
/// <summary>
/// Multiplies the size of the current rectangle by the specified x and y values.
/// </summary>
public void Scale(double scaleX, double scaleY)
{
if (!IsEmpty)
{
_x *= scaleX;
_y *= scaleY;
_width *= scaleX;
_height *= scaleY;
if (scaleX < 0)
{
_x += _width;
_width *= -1.0;
}
if (scaleY < 0)
{
_y += _height;
_height *= -1.0;
}
}
}
#if CORE // Internal version in CORE build.
#if UseGdiObjects
/// <summary>
/// Converts this instance to a System.Drawing.RectangleF.
/// </summary>
internal RectangleF ToRectangleF()
{
return new RectangleF((float)_x, (float)_y, (float)_width, (float)_height);
}
#endif
#endif
#if GDI
/// <summary>
/// Converts this instance to a System.Drawing.RectangleF.
/// </summary>
public RectangleF ToRectangleF()
{
return new RectangleF((float)_x, (float)_y, (float)_width, (float)_height);
}
#endif
#if GDI
/// <summary>
/// Performs an implicit conversion from a System.Drawing.Rectangle to an XRect.
/// </summary>
public static implicit operator XRect(Rectangle rect)
{
return new XRect(rect.X, rect.Y, rect.Width, rect.Height);
}
/// <summary>
/// Performs an implicit conversion from a System.Drawing.RectangleF to an XRect.
/// </summary>
public static implicit operator XRect(RectangleF rect)
{
return new XRect(rect.X, rect.Y, rect.Width, rect.Height);
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Performs an implicit conversion from System.Windows.Rect to XRect.
/// </summary>
public static implicit operator XRect(SysRect rect)
{
return new XRect(rect.X, rect.Y, rect.Width, rect.Height);
}
#endif
bool ContainsInternal(double x, double y)
{
return x >= _x && x - _width <= _x && y >= _y && y - _height <= _y;
}
static XRect CreateEmptyRect()
{
XRect rect = new XRect();
rect._x = double.PositiveInfinity;
rect._y = double.PositiveInfinity;
rect._width = double.NegativeInfinity;
rect._height = double.NegativeInfinity;
return rect;
}
static XRect()
{
s_empty = CreateEmptyRect();
}
static readonly XRect s_empty;
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
/// <value>The debugger display.</value>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
const string format = Config.SignificantFigures10;
return String.Format(CultureInfo.InvariantCulture,
"rect=({0:" + format + "}, {1:" + format + "}, {2:" + format + "}, {3:" + format + "})",
_x, _y, _width, _height);
}
}
}
}

376
PdfSharp/Drawing/XSize.cs Normal file
View File

@@ -0,0 +1,376 @@
#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.Globalization;
using System.Runtime.InteropServices;
#if GDI
using System.Drawing;
#endif
#if WPF
using System.Windows;
using SysPoint = System.Windows.Point;
using SysSize = System.Windows.Size;
#endif
#if NETFX_CORE
using Windows.UI.Xaml.Media;
using SysPoint = Windows.Foundation.Point;
using SysSize = Windows.Foundation.Size;
#endif
#if !EDF_CORE
using PdfSharp.Internal;
#else
using PdfSharp.Internal;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents a pair of floating-point numbers, typically the width and height of a
/// graphical object.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
[Serializable, StructLayout(LayoutKind.Sequential)] //, ValueSerializer(typeof(SizeValueSerializer)), TypeConverter(typeof(SizeConverter))]
public struct XSize : IFormattable
{
/// <summary>
/// Initializes a new instance of the XPoint class with the specified values.
/// </summary>
public XSize(double width, double height)
{
if (width < 0 || height < 0)
throw new ArgumentException("WidthAndHeightCannotBeNegative"); //SR.Get(SRID.Size_WidthAndHeightCannotBeNegative, new object[0]));
_width = width;
_height = height;
}
/// <summary>
/// Determines whether two size objects are equal.
/// </summary>
public static bool operator ==(XSize size1, XSize size2)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return size1.Width == size2.Width && size1.Height == size2.Height;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Determines whether two size objects are not equal.
/// </summary>
public static bool operator !=(XSize size1, XSize size2)
{
return !(size1 == size2);
}
/// <summary>
/// Indicates whether this two instance are equal.
/// </summary>
public static bool Equals(XSize size1, XSize size2)
{
if (size1.IsEmpty)
return size2.IsEmpty;
return size1.Width.Equals(size2.Width) && size1.Height.Equals(size2.Height);
}
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
public override bool Equals(object o)
{
if (!(o is XSize))
return false;
return Equals(this, (XSize)o);
}
/// <summary>
/// Indicates whether this instance and a specified size are equal.
/// </summary>
public bool Equals(XSize value)
{
return Equals(this, value);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
if (IsEmpty)
return 0;
return Width.GetHashCode() ^ Height.GetHashCode();
}
/// <summary>
/// Parses the size from a string.
/// </summary>
public static XSize Parse(string source)
{
XSize empty;
CultureInfo cultureInfo = CultureInfo.InvariantCulture;
TokenizerHelper helper = new TokenizerHelper(source, cultureInfo);
string str = helper.NextTokenRequired();
if (str == "Empty")
empty = Empty;
else
empty = new XSize(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
helper.LastTokenRequired();
return empty;
}
#if GDI
/// <summary>
/// Converts this XSize to a PointF.
/// </summary>
public PointF ToPointF()
{
return new PointF((float)_width, (float)_height);
}
#endif
/// <summary>
/// Converts this XSize to an XPoint.
/// </summary>
public XPoint ToXPoint()
{
return new XPoint(_width, _height);
}
/// <summary>
/// Converts this XSize to an XVector.
/// </summary>
public XVector ToXVector()
{
return new XVector(_width, _height);
}
#if GDI
/// <summary>
/// Converts this XSize to a SizeF.
/// </summary>
public SizeF ToSizeF()
{
return new SizeF((float)_width, (float)_height);
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Converts this XSize to a System.Windows.Size.
/// </summary>
public SysSize ToSize()
{
return new SysSize(_width, _height);
}
#endif
#if GDI
/// <summary>
/// Creates an XSize from a System.Drawing.Size.
/// </summary>
public static XSize FromSize(System.Drawing.Size size)
{
return new XSize(size.Width, size.Height);
}
/// <summary>
/// Implicit conversion from XSize to System.Drawing.Size. The conversion must be implicit because the
/// WinForms designer uses it.
/// </summary>
public static implicit operator XSize(System.Drawing.Size size)
{
return new XSize(size.Width, size.Height);
}
#endif
#if WPF || NETFX_CORE
/// <summary>
/// Creates an XSize from a System.Drawing.Size.
/// </summary>
public static XSize FromSize(SysSize size)
{
return new XSize(size.Width, size.Height);
}
#endif
#if GDI
/// <summary>
/// Creates an XSize from a System.Drawing.Size.
/// </summary>
public static XSize FromSizeF(SizeF size)
{
return new XSize(size.Width, size.Height);
}
#endif
/// <summary>
/// Converts this XSize to a human readable string.
/// </summary>
public override string ToString()
{
return ConvertToString(null, null);
}
/// <summary>
/// Converts this XSize to a human readable string.
/// </summary>
public string ToString(IFormatProvider provider)
{
return ConvertToString(null, provider);
}
/// <summary>
/// Converts this XSize to a human readable string.
/// </summary>
string IFormattable.ToString(string format, IFormatProvider provider)
{
return ConvertToString(format, provider);
}
internal string ConvertToString(string format, IFormatProvider provider)
{
if (IsEmpty)
return "Empty";
char numericListSeparator = TokenizerHelper.GetNumericListSeparator(provider);
provider = provider ?? CultureInfo.InvariantCulture;
// ReSharper disable FormatStringProblem
return string.Format(provider, "{1:" + format + "}{0}{2:" + format + "}", new object[] { numericListSeparator, _width, _height });
// ReSharper restore FormatStringProblem
}
/// <summary>
/// Returns an empty size, i.e. a size with a width or height less than 0.
/// </summary>
public static XSize Empty
{
get { return s_empty; }
}
static readonly XSize s_empty;
/// <summary>
/// Gets a value indicating whether this instance is empty.
/// </summary>
public bool IsEmpty
{
get { return _width < 0; }
}
/// <summary>
/// Gets or sets the width.
/// </summary>
public double Width
{
get { return _width; }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptySize"); //SR.Get(SRID.Size_CannotModifyEmptySize, new object[0]));
if (value < 0)
throw new ArgumentException("WidthCannotBeNegative"); //SR.Get(SRID.Size_WidthCannotBeNegative, new object[0]));
_width = value;
}
}
double _width;
/// <summary>
/// Gets or sets the height.
/// </summary>
public double Height
{
get { return _height; }
set
{
if (IsEmpty)
throw new InvalidOperationException("CannotModifyEmptySize"); // SR.Get(SRID.Size_CannotModifyEmptySize, new object[0]));
if (value < 0)
throw new ArgumentException("HeightCannotBeNegative"); //SR.Get(SRID.Size_HeightCannotBeNegative, new object[0]));
_height = value;
}
}
double _height;
/// <summary>
/// Performs an explicit conversion from XSize to XVector.
/// </summary>
public static explicit operator XVector(XSize size)
{
return new XVector(size._width, size._height);
}
/// <summary>
/// Performs an explicit conversion from XSize to XPoint.
/// </summary>
public static explicit operator XPoint(XSize size)
{
return new XPoint(size._width, size._height);
}
#if WPF || NETFX_CORE
/// <summary>
/// Performs an explicit conversion from Size to XSize.
/// </summary>
public static explicit operator XSize(SysSize size)
{
return new XSize(size.Width, size.Height);
}
#endif
private static XSize CreateEmptySize()
{
XSize size = new XSize();
size._width = double.NegativeInfinity;
size._height = double.NegativeInfinity;
return size;
}
static XSize()
{
s_empty = CreateEmptySize();
}
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
/// <value>The debugger display.</value>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
const string format = Config.SignificantFigures10;
return String.Format(CultureInfo.InvariantCulture,
"size=({2}{0:" + format + "}, {1:" + format + "})",
_width, _height, IsEmpty ? "Empty " : "");
}
}
}
}

View File

@@ -0,0 +1,178 @@
#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;
#endif
#if WPF
using System.Windows;
using System.Windows.Media;
#endif
#if UWP
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Brushes;
using UwpBrush = Windows.UI.Xaml.Media.Brush;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Defines a single color object used to fill shapes and draw text.
/// </summary>
public sealed class XSolidBrush : XBrush
{
/// <summary>
/// Initializes a new instance of the <see cref="XSolidBrush"/> class.
/// </summary>
public XSolidBrush()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="XSolidBrush"/> class.
/// </summary>
public XSolidBrush(XColor color)
: this(color, false)
{ }
internal XSolidBrush(XColor color, bool immutable)
{
_color = color;
_immutable = immutable;
}
/// <summary>
/// Initializes a new instance of the <see cref="XSolidBrush"/> class.
/// </summary>
public XSolidBrush(XSolidBrush brush)
{
_color = brush.Color;
}
/// <summary>
/// Gets or sets the color of this brush.
/// </summary>
public XColor Color
{
get { return _color; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XSolidBrush"));
#if GDI
_gdiDirty = _gdiDirty || _color != value;
#endif
#if WPF
_wpfDirty = _wpfDirty || _color != value;
#endif
#if GDI && WPF
_gdiDirty = _wpfDirty = true;
#endif
_color = value;
}
}
internal XColor _color;
/// <summary>
/// Gets or sets a value indicating whether the brush enables overprint when used in a PDF document.
/// Experimental, takes effect only on CMYK color mode.
/// </summary>
public bool Overprint
{
get { return _overprint; }
set
{
if (_immutable)
throw new ArgumentException(PSSR.CannotChangeImmutableObject("XSolidBrush"));
_overprint = value;
}
}
internal bool _overprint;
#if GDI
internal override System.Drawing.Brush RealizeGdiBrush()
{
if (_gdiDirty)
{
if (_gdiBrush == null)
_gdiBrush = new SolidBrush(_color.ToGdiColor());
else
_gdiBrush.Color = _color.ToGdiColor();
_gdiDirty = false;
}
#if DEBUG
System.Drawing.Color clr = _color.ToGdiColor();
SolidBrush brush1 = new SolidBrush(clr);
Debug.Assert(_gdiBrush.Color == brush1.Color);
#endif
return _gdiBrush;
}
#endif
#if WPF
internal override System.Windows.Media.Brush RealizeWpfBrush()
{
if (_wpfDirty)
{
if (_wpfBrush == null)
_wpfBrush = new SolidColorBrush(_color.ToWpfColor());
else
_wpfBrush.Color = _color.ToWpfColor();
_wpfDirty = false;
}
#if DEBUG_
System.Windows.Media.Color clr = _color.ToWpfColor();
System.Windows.Media.SolidColorBrush brush1 = new System.Windows.Media.SolidColorBrush(clr); //System.Drawing.Color.FromArgb(128, 128, 0, 0));
Debug.Assert(_wpfBrush.Color == brush1.Color); // Crashes during unit testing
#endif
return _wpfBrush;
}
#endif
#if UWP
internal override ICanvasBrush RealizeCanvasBrush()
{
return new CanvasSolidColorBrush(CanvasDevice.GetSharedDevice(), _color.ToUwpColor());
}
#endif
#if GDI
bool _gdiDirty = true;
SolidBrush _gdiBrush;
#endif
#if WPF
bool _wpfDirty = true;
SolidColorBrush _wpfBrush;
#endif
readonly bool _immutable;
}
}

View File

@@ -0,0 +1,223 @@
#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 CORE
#endif
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
#if true_
/// <summary>
/// Not used in this implementation.
/// </summary>
[Flags]
public enum XStringFormatFlags
{
//DirectionRightToLeft = 0x0001,
//DirectionVertical = 0x0002,
//FitBlackBox = 0x0004,
//DisplayFormatControl = 0x0020,
//NoFontFallback = 0x0400,
/// <summary>
/// The default value.
/// </summary>
MeasureTrailingSpaces = 0x0800,
//NoWrap = 0x1000,
//LineLimit = 0x2000,
//NoClip = 0x4000,
}
#endif
/// <summary>
/// Represents the text layout information.
/// </summary>
public class XStringFormat
{
/// <summary>
/// Initializes a new instance of the <see cref="XStringFormat"/> class.
/// </summary>
public XStringFormat()
{
#if WPF
GetType(); // Make ReSharper happy.
#endif
}
//TODO public StringFormat(StringFormat format);
//public StringFormat(StringFormatFlags options);
//public StringFormat(StringFormatFlags options, int language);
//public object Clone();
//public void Dispose();
//private void Dispose(bool disposing);
//protected override void Finalize();
//public float[] GetTabStops(out float firstTabOffset);
//public void SetDigitSubstitution(int language, StringDigitSubstitute substitute);
//public void SetMeasurableCharacterRanges(CharacterRange[] ranges);
//public void SetTabStops(float firstTabOffset, float[] tabStops);
//public override string ToString();
/// <summary>
/// Gets or sets horizontal text alignment information.
/// </summary>
public XStringAlignment Alignment
{
get { return _alignment; }
set
{
_alignment = value;
#if CORE || GDI
#if UseGdiObjects
// Update StringFormat only if it exists.
if (_stringFormat != null)
{
_stringFormat.Alignment = (StringAlignment)value;
}
#endif
#endif
}
}
XStringAlignment _alignment;
//public int DigitSubstitutionLanguage { get; }
//public StringDigitSubstitute DigitSubstitutionMethod { get; }
//public StringFormatFlags FormatFlags { get; set; }
//public static StringFormat GenericDefault { get; }
//public static StringFormat GenericTypographic { get; }
//public HotkeyPrefix HotkeyPrefix { get; set; }
/// <summary>
/// Gets or sets the line alignment.
/// </summary>
public XLineAlignment LineAlignment
{
get { return _lineAlignment; }
set
{
_lineAlignment = value;
#if CORE || GDI
#if UseGdiObjects
// Update StringFormat only if it exists.
if (_stringFormat != null)
{
// BaseLine is specific to PDFsharp.
if (value == XLineAlignment.BaseLine)
_stringFormat.LineAlignment = StringAlignment.Near;
else
_stringFormat.LineAlignment = (StringAlignment)value;
}
#endif
#endif
}
}
XLineAlignment _lineAlignment;
//public StringTrimming Trimming { get; set; }
/// <summary>
/// Gets a new XStringFormat object that aligns the text left on the base line.
/// </summary>
[Obsolete("Use XStringFormats.Default. (Note plural in class name.)")]
public static XStringFormat Default
{
get { return XStringFormats.Default; }
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text top left of the layout rectangle.
/// </summary>
[Obsolete("Use XStringFormats.Default. (Note plural in class name.)")]
public static XStringFormat TopLeft
{
get { return XStringFormats.TopLeft; }
}
/// <summary>
/// Gets a new XStringFormat object that centers the text in the middle of the layout rectangle.
/// </summary>
[Obsolete("Use XStringFormats.Center. (Note plural in class name.)")]
public static XStringFormat Center
{
get { return XStringFormats.Center; }
}
/// <summary>
/// Gets a new XStringFormat object that centers the text at the top of the layout rectangle.
/// </summary>
[Obsolete("Use XStringFormats.TopCenter. (Note plural in class name.)")]
public static XStringFormat TopCenter
{
get { return XStringFormats.TopCenter; }
}
/// <summary>
/// Gets a new XStringFormat object that centers the text at the bottom of the layout rectangle.
/// </summary>
[Obsolete("Use XStringFormats.BottomCenter. (Note plural in class name.)")]
public static XStringFormat BottomCenter
{
get { return XStringFormats.BottomCenter; }
}
#if GDI
//#if UseGdiObjects
internal StringFormat RealizeGdiStringFormat()
{
if (_stringFormat == null)
{
// It seems that StringFormat.GenericTypographic is a global object and we need "Clone()" to avoid side effects.
_stringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
_stringFormat.Alignment = (StringAlignment)_alignment;
// BaseLine is specific to PDFsharp.
if (_lineAlignment == XLineAlignment.BaseLine)
_stringFormat.LineAlignment = StringAlignment.Near;
else
_stringFormat.LineAlignment = (StringAlignment)_lineAlignment;
//_stringFormat.FormatFlags = (StringFormatFlags)_formatFlags;
// Bugfix: Set MeasureTrailingSpaces to get the correct width with Graphics.MeasureString().
// Before, MeasureString() didn't include blanks in width calculation, which could result in text overflowing table or page border before wrapping. $MaOs
_stringFormat.FormatFlags = _stringFormat.FormatFlags | StringFormatFlags.MeasureTrailingSpaces;
}
return _stringFormat;
}
StringFormat _stringFormat;
//#endif
#endif
}
}

View File

@@ -0,0 +1,235 @@
#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.Drawing2D;
#endif
#if WPF
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents predefined text layouts.
/// </summary>
public static class XStringFormats
{
/// <summary>
/// Gets a new XStringFormat object that aligns the text left on the base line.
/// This is the same as BaseLineLeft.
/// </summary>
public static XStringFormat Default
{
get { return BaseLineLeft; }
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text left on the base line.
/// This is the same as Default.
/// </summary>
public static XStringFormat BaseLineLeft
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.BaseLine;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text top left of the layout rectangle.
/// </summary>
public static XStringFormat TopLeft
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Near;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text center left of the layout rectangle.
/// </summary>
public static XStringFormat CenterLeft
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Center;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text bottom left of the layout rectangle.
/// </summary>
public static XStringFormat BottomLeft
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Far;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that centers the text in the middle of the base line.
/// </summary>
public static XStringFormat BaseLineCenter
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.BaseLine;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that centers the text at the top of the layout rectangle.
/// </summary>
public static XStringFormat TopCenter
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.Near;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that centers the text in the middle of the layout rectangle.
/// </summary>
public static XStringFormat Center
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.Center;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that centers the text at the bottom of the layout rectangle.
/// </summary>
public static XStringFormat BottomCenter
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Center;
format.LineAlignment = XLineAlignment.Far;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text in right on the base line.
/// </summary>
public static XStringFormat BaseLineRight
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Far;
format.LineAlignment = XLineAlignment.BaseLine;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text top right of the layout rectangle.
/// </summary>
public static XStringFormat TopRight
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Far;
format.LineAlignment = XLineAlignment.Near;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text center right of the layout rectangle.
/// </summary>
public static XStringFormat CenterRight
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Far;
format.LineAlignment = XLineAlignment.Center;
return format;
}
}
/// <summary>
/// Gets a new XStringFormat object that aligns the text at the bottom right of the layout rectangle.
/// </summary>
public static XStringFormat BottomRight
{
get
{
// Create new format to allow changes.
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Far;
format.LineAlignment = XLineAlignment.Far;
return format;
}
}
}
}

View 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
#if GDI
using System.Drawing;
using System.Drawing.Drawing2D;
#endif
#if WPF
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
#endif
namespace PdfSharp.Drawing
{
#if true_ // Not yet used
/// <summary>
/// no: Specifies a physical font face that corresponds to a font file on the disk or in memory.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
internal class XTypeface_not_yet_used
{
public XTypeface_not_yet_used(XFontFamily family, XFontStyle style)
{
_family = family;
_style = style;
}
public XFontFamily Family
{
get { return _family; }
}
XFontFamily _family;
public XFontStyle Style
{
get { return _style; }
}
XFontStyle _style;
public bool TryGetGlyphTypeface(out XGlyphTypeface glyphTypeface)
{
glyphTypeface = null;
return false;
}
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get { return string.Format(CultureInfo.InvariantCulture, "XTypeface"); }
}
}
#endif
}

597
PdfSharp/Drawing/XUnit.cs Normal file
View File

@@ -0,0 +1,597 @@
#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.Globalization;
namespace PdfSharp.Drawing
{
/// <summary>
/// Represents a value and its unit of measure. The structure converts implicitly from and to
/// double with a value measured in point.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
public struct XUnit : IFormattable
{
internal const double PointFactor = 1;
internal const double InchFactor = 72;
internal const double MillimeterFactor = 72 / 25.4;
internal const double CentimeterFactor = 72 / 2.54;
internal const double PresentationFactor = 72 / 96.0;
internal const double PointFactorWpf = 96 / 72.0;
internal const double InchFactorWpf = 96;
internal const double MillimeterFactorWpf = 96 / 25.4;
internal const double CentimeterFactorWpf = 96 / 2.54;
internal const double PresentationFactorWpf = 1;
/// <summary>
/// Initializes a new instance of the XUnit class with type set to point.
/// </summary>
public XUnit(double point)
{
_value = point;
_type = XGraphicsUnit.Point;
}
/// <summary>
/// Initializes a new instance of the XUnit class.
/// </summary>
public XUnit(double value, XGraphicsUnit type)
{
if (!Enum.IsDefined(typeof(XGraphicsUnit), type))
#if !SILVERLIGHT && !NETFX_CORE && !UWP
throw new System.ComponentModel.InvalidEnumArgumentException(nameof(type), (int)type, typeof(XGraphicsUnit));
#else
throw new ArgumentException("type");
#endif
_value = value;
_type = type;
}
/// <summary>
/// Gets the raw value of the object without any conversion.
/// To determine the XGraphicsUnit use property <code>Type</code>.
/// To get the value in point use the implicit conversion to double.
/// </summary>
public double Value
{
get { return _value; }
}
/// <summary>
/// Gets the unit of measure.
/// </summary>
public XGraphicsUnit Type
{
get { return _type; }
}
/// <summary>
/// Gets or sets the value in point.
/// </summary>
public double Point
{
get
{
switch (_type)
{
case XGraphicsUnit.Point:
return _value;
case XGraphicsUnit.Inch:
return _value * 72;
case XGraphicsUnit.Millimeter:
return _value * 72 / 25.4;
case XGraphicsUnit.Centimeter:
return _value * 72 / 2.54;
case XGraphicsUnit.Presentation:
return _value * 72 / 96;
default:
throw new InvalidCastException();
}
}
set
{
_value = value;
_type = XGraphicsUnit.Point;
}
}
/// <summary>
/// Gets or sets the value in inch.
/// </summary>
public double Inch
{
get
{
switch (_type)
{
case XGraphicsUnit.Point:
return _value / 72;
case XGraphicsUnit.Inch:
return _value;
case XGraphicsUnit.Millimeter:
return _value / 25.4;
case XGraphicsUnit.Centimeter:
return _value / 2.54;
case XGraphicsUnit.Presentation:
return _value / 96;
default:
throw new InvalidCastException();
}
}
set
{
_value = value;
_type = XGraphicsUnit.Inch;
}
}
/// <summary>
/// Gets or sets the value in millimeter.
/// </summary>
public double Millimeter
{
get
{
switch (_type)
{
case XGraphicsUnit.Point:
return _value * 25.4 / 72;
case XGraphicsUnit.Inch:
return _value * 25.4;
case XGraphicsUnit.Millimeter:
return _value;
case XGraphicsUnit.Centimeter:
return _value * 10;
case XGraphicsUnit.Presentation:
return _value * 25.4 / 96;
default:
throw new InvalidCastException();
}
}
set
{
_value = value;
_type = XGraphicsUnit.Millimeter;
}
}
/// <summary>
/// Gets or sets the value in centimeter.
/// </summary>
public double Centimeter
{
get
{
switch (_type)
{
case XGraphicsUnit.Point:
return _value * 2.54 / 72;
case XGraphicsUnit.Inch:
return _value * 2.54;
case XGraphicsUnit.Millimeter:
return _value / 10;
case XGraphicsUnit.Centimeter:
return _value;
case XGraphicsUnit.Presentation:
return _value * 2.54 / 96;
default:
throw new InvalidCastException();
}
}
set
{
_value = value;
_type = XGraphicsUnit.Centimeter;
}
}
/// <summary>
/// Gets or sets the value in presentation units (1/96 inch).
/// </summary>
public double Presentation
{
get
{
switch (_type)
{
case XGraphicsUnit.Point:
return _value * 96 / 72;
case XGraphicsUnit.Inch:
return _value * 96;
case XGraphicsUnit.Millimeter:
return _value * 96 / 25.4;
case XGraphicsUnit.Centimeter:
return _value * 96 / 2.54;
case XGraphicsUnit.Presentation:
return _value;
default:
throw new InvalidCastException();
}
}
set
{
_value = value;
_type = XGraphicsUnit.Point;
}
}
/// <summary>
/// Returns the object as string using the format information.
/// The unit of measure is appended to the end of the string.
/// </summary>
public string ToString(IFormatProvider formatProvider)
{
string valuestring = _value.ToString(formatProvider) + GetSuffix();
return valuestring;
}
/// <summary>
/// Returns the object as string using the specified format and format information.
/// The unit of measure is appended to the end of the string.
/// </summary>
string IFormattable.ToString(string format, IFormatProvider formatProvider)
{
string valuestring = _value.ToString(format, formatProvider) + GetSuffix();
return valuestring;
}
/// <summary>
/// Returns the object as string. The unit of measure is appended to the end of the string.
/// </summary>
public override string ToString()
{
string valuestring = _value.ToString(CultureInfo.InvariantCulture) + GetSuffix();
return valuestring;
}
/// <summary>
/// Returns the unit of measure of the object as a string like 'pt', 'cm', or 'in'.
/// </summary>
string GetSuffix()
{
switch (_type)
{
case XGraphicsUnit.Point:
return "pt";
case XGraphicsUnit.Inch:
return "in";
case XGraphicsUnit.Millimeter:
return "mm";
case XGraphicsUnit.Centimeter:
return "cm";
case XGraphicsUnit.Presentation:
return "pu";
//case XGraphicsUnit.Pica:
// return "pc";
//case XGraphicsUnit.Line:
// return "li";
default:
throw new InvalidCastException();
}
}
/// <summary>
/// Returns an XUnit object. Sets type to point.
/// </summary>
public static XUnit FromPoint(double value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Point;
return unit;
}
/// <summary>
/// Returns an XUnit object. Sets type to inch.
/// </summary>
public static XUnit FromInch(double value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Inch;
return unit;
}
/// <summary>
/// Returns an XUnit object. Sets type to millimeters.
/// </summary>
public static XUnit FromMillimeter(double value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Millimeter;
return unit;
}
/// <summary>
/// Returns an XUnit object. Sets type to centimeters.
/// </summary>
public static XUnit FromCentimeter(double value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Centimeter;
return unit;
}
/// <summary>
/// Returns an XUnit object. Sets type to Presentation.
/// </summary>
public static XUnit FromPresentation(double value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Presentation;
return unit;
}
/// <summary>
/// Converts a string to an XUnit object.
/// If the string contains a suffix like 'cm' or 'in' the object will be converted
/// to the appropriate type, otherwise point is assumed.
/// </summary>
public static implicit operator XUnit(string value)
{
XUnit unit;
value = value.Trim();
// HACK for Germans...
value = value.Replace(',', '.');
int count = value.Length;
int valLen = 0;
for (; valLen < count;)
{
char ch = value[valLen];
if (ch == '.' || ch == '-' || ch == '+' || char.IsNumber(ch))
valLen++;
else
break;
}
try
{
unit._value = Double.Parse(value.Substring(0, valLen).Trim(), CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
unit._value = 1;
string message = String.Format("String '{0}' is not a valid value for structure 'XUnit'.", value);
throw new ArgumentException(message, ex);
}
string typeStr = value.Substring(valLen).Trim().ToLower();
unit._type = XGraphicsUnit.Point;
switch (typeStr)
{
case "cm":
unit._type = XGraphicsUnit.Centimeter;
break;
case "in":
unit._type = XGraphicsUnit.Inch;
break;
case "mm":
unit._type = XGraphicsUnit.Millimeter;
break;
case "":
case "pt":
unit._type = XGraphicsUnit.Point;
break;
case "pu": // presentation units
unit._type = XGraphicsUnit.Presentation;
break;
default:
throw new ArgumentException("Unknown unit type: '" + typeStr + "'");
}
return unit;
}
/// <summary>
/// Converts an int to an XUnit object with type set to point.
/// </summary>
public static implicit operator XUnit(int value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Point;
return unit;
}
/// <summary>
/// Converts a double to an XUnit object with type set to point.
/// </summary>
public static implicit operator XUnit(double value)
{
XUnit unit;
unit._value = value;
unit._type = XGraphicsUnit.Point;
return unit;
}
/// <summary>
/// Returns a double value as point.
/// </summary>
public static implicit operator double(XUnit value)
{
return value.Point;
}
/// <summary>
/// Memberwise comparison. To compare by value,
/// use code like Math.Abs(a.Pt - b.Pt) &lt; 1e-5.
/// </summary>
public static bool operator ==(XUnit value1, XUnit value2)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return value1._type == value2._type && value1._value == value2._value;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Memberwise comparison. To compare by value,
/// use code like Math.Abs(a.Pt - b.Pt) &lt; 1e-5.
/// </summary>
public static bool operator !=(XUnit value1, XUnit value2)
{
return !(value1 == value2);
}
/// <summary>
/// Calls base class Equals.
/// </summary>
public override bool Equals(Object obj)
{
if (obj is XUnit)
return this == (XUnit)obj;
return false;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
// ReSharper disable NonReadonlyFieldInGetHashCode
return _value.GetHashCode() ^ _type.GetHashCode();
// ReSharper restore NonReadonlyFieldInGetHashCode
}
/// <summary>
/// This member is intended to be used by XmlDomainObjectReader only.
/// </summary>
public static XUnit Parse(string value)
{
XUnit unit = value;
return unit;
}
/// <summary>
/// Converts an existing object from one unit into another unit type.
/// </summary>
public void ConvertType(XGraphicsUnit type)
{
if (_type == type)
return;
switch (type)
{
case XGraphicsUnit.Point:
_value = Point;
_type = XGraphicsUnit.Point;
break;
case XGraphicsUnit.Inch:
_value = Inch;
_type = XGraphicsUnit.Inch;
break;
case XGraphicsUnit.Centimeter:
_value = Centimeter;
_type = XGraphicsUnit.Centimeter;
break;
case XGraphicsUnit.Millimeter:
_value = Millimeter;
_type = XGraphicsUnit.Millimeter;
break;
case XGraphicsUnit.Presentation:
_value = Presentation;
_type = XGraphicsUnit.Presentation;
break;
default:
throw new ArgumentException("Unknown unit type: '" + type + "'");
}
}
/// <summary>
/// Represents a unit with all values zero.
/// </summary>
public static readonly XUnit Zero = new XUnit();
double _value;
XGraphicsUnit _type;
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
/// <value>The debugger display.</value>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
const string format = Config.SignificantFigures10;
return String.Format(CultureInfo.InvariantCulture, "unit=({0:" + format + "} {1})", _value, GetSuffix());
}
}
}
}

299
PdfSharp/Drawing/XVector.cs Normal file
View File

@@ -0,0 +1,299 @@
#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.Globalization;
using System.Runtime.InteropServices;
using PdfSharp.Internal;
#if GDI
using System.Drawing;
#endif
#if WPF
using System.Windows.Media;
#endif
#pragma warning disable 1591
#if !EDF_CORE
namespace PdfSharp.Drawing
#else
namespace Edf.Drawing
#endif
{
/// <summary>
/// Represents a two-dimensional vector specified by x- and y-coordinates.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct XVector : IFormattable
{
public XVector(double x, double y)
{
_x = x;
_y = y;
}
public static bool operator ==(XVector vector1, XVector vector2)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return vector1._x == vector2._x && vector1._y == vector2._y;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
public static bool operator !=(XVector vector1, XVector vector2)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return vector1._x != vector2._x || vector1._y != vector2._y;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
public static bool Equals(XVector vector1, XVector vector2)
{
if (vector1.X.Equals(vector2.X))
return vector1.Y.Equals(vector2.Y);
return false;
}
public override bool Equals(object o)
{
if (!(o is XVector))
return false;
return Equals(this, (XVector)o);
}
public bool Equals(XVector value)
{
return Equals(this, value);
}
public override int GetHashCode()
{
// ReSharper disable NonReadonlyFieldInGetHashCode
return _x.GetHashCode() ^ _y.GetHashCode();
// ReSharper restore NonReadonlyFieldInGetHashCode
}
public static XVector Parse(string source)
{
TokenizerHelper helper = new TokenizerHelper(source, CultureInfo.InvariantCulture);
string str = helper.NextTokenRequired();
XVector vector = new XVector(Convert.ToDouble(str, CultureInfo.InvariantCulture), Convert.ToDouble(helper.NextTokenRequired(), CultureInfo.InvariantCulture));
helper.LastTokenRequired();
return vector;
}
public double X
{
get { return _x; }
set { _x = value; }
}
double _x;
public double Y
{
get { return _y; }
set { _y = value; }
}
double _y;
public override string ToString()
{
return ConvertToString(null, null);
}
public string ToString(IFormatProvider provider)
{
return ConvertToString(null, provider);
}
string IFormattable.ToString(string format, IFormatProvider provider)
{
return ConvertToString(format, provider);
}
internal string ConvertToString(string format, IFormatProvider provider)
{
const char numericListSeparator = ',';
provider = provider ?? CultureInfo.InvariantCulture;
// ReSharper disable once FormatStringProblem
return string.Format(provider, "{1:" + format + "}{0}{2:" + format + "}", numericListSeparator, _x, _y);
}
public double Length
{
get { return Math.Sqrt(_x * _x + _y * _y); }
}
public double LengthSquared
{
get { return _x * _x + _y * _y; }
}
public void Normalize()
{
this = this / Math.Max(Math.Abs(_x), Math.Abs(_y));
this = this / Length;
}
public static double CrossProduct(XVector vector1, XVector vector2)
{
return vector1._x * vector2._y - vector1._y * vector2._x;
}
public static double AngleBetween(XVector vector1, XVector vector2)
{
double y = vector1._x * vector2._y - vector2._x * vector1._y;
double x = vector1._x * vector2._x + vector1._y * vector2._y;
return (Math.Atan2(y, x) * 57.295779513082323);
}
public static XVector operator -(XVector vector)
{
return new XVector(-vector._x, -vector._y);
}
public void Negate()
{
_x = -_x;
_y = -_y;
}
public static XVector operator +(XVector vector1, XVector vector2)
{
return new XVector(vector1._x + vector2._x, vector1._y + vector2._y);
}
public static XVector Add(XVector vector1, XVector vector2)
{
return new XVector(vector1._x + vector2._x, vector1._y + vector2._y);
}
public static XVector operator -(XVector vector1, XVector vector2)
{
return new XVector(vector1._x - vector2._x, vector1._y - vector2._y);
}
public static XVector Subtract(XVector vector1, XVector vector2)
{
return new XVector(vector1._x - vector2._x, vector1._y - vector2._y);
}
public static XPoint operator +(XVector vector, XPoint point)
{
return new XPoint(point.X + vector._x, point.Y + vector._y);
}
public static XPoint Add(XVector vector, XPoint point)
{
return new XPoint(point.X + vector._x, point.Y + vector._y);
}
public static XVector operator *(XVector vector, double scalar)
{
return new XVector(vector._x * scalar, vector._y * scalar);
}
public static XVector Multiply(XVector vector, double scalar)
{
return new XVector(vector._x * scalar, vector._y * scalar);
}
public static XVector operator *(double scalar, XVector vector)
{
return new XVector(vector._x * scalar, vector._y * scalar);
}
public static XVector Multiply(double scalar, XVector vector)
{
return new XVector(vector._x * scalar, vector._y * scalar);
}
public static XVector operator /(XVector vector, double scalar)
{
return vector * (1.0 / scalar);
}
public static XVector Divide(XVector vector, double scalar)
{
return vector * (1.0 / scalar);
}
public static XVector operator *(XVector vector, XMatrix matrix)
{
return matrix.Transform(vector);
}
public static XVector Multiply(XVector vector, XMatrix matrix)
{
return matrix.Transform(vector);
}
public static double operator *(XVector vector1, XVector vector2)
{
return vector1._x * vector2._x + vector1._y * vector2._y;
}
public static double Multiply(XVector vector1, XVector vector2)
{
return vector1._x * vector2._x + vector1._y * vector2._y;
}
public static double Determinant(XVector vector1, XVector vector2)
{
return vector1._x * vector2._y - vector1._y * vector2._x;
}
public static explicit operator XSize(XVector vector)
{
return new XSize(Math.Abs(vector._x), Math.Abs(vector._y));
}
public static explicit operator XPoint(XVector vector)
{
return new XPoint(vector._x, vector._y);
}
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
/// <value>The debugger display.</value>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
const string format = Config.SignificantFigures10;
return string.Format(CultureInfo.InvariantCulture, "vector=({0:" + format + "}, {1:" + format + "})", _x, _y);
}
}
}
}

View File

@@ -0,0 +1,54 @@
#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
// ReSharper disable InconsistentNaming
namespace PdfSharp.Drawing
{
/// <summary>
/// Indicates how to handle the first point of a path.
/// </summary>
internal enum PathStart
{
/// <summary>
/// Set the current position to the first point.
/// </summary>
MoveTo1st,
/// <summary>
/// Draws a line to the first point.
/// </summary>
LineTo1st,
/// <summary>
/// Ignores the first point.
/// </summary>
Ignore1st,
}
}

View File

@@ -0,0 +1,52 @@
#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.Drawing
{
///<summary>
/// Currently not used. Only DeviceRGB is rendered in PDF.
/// </summary>
public enum XColorSpace
{
/// <summary>
/// Identifies the RGB color space.
/// </summary>
Rgb,
/// <summary>
/// Identifies the CMYK color space.
/// </summary>
Cmyk,
/// <summary>
/// Identifies the gray scale color space.
/// </summary>
GrayScale,
}
}

View File

@@ -0,0 +1,67 @@
#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.Drawing
{
/// <summary>
/// Specifies how different clipping regions can be combined.
/// </summary>
public enum XCombineMode // Same values as System.Drawing.Drawing2D.CombineMode.
{
/// <summary>
/// One clipping region is replaced by another.
/// </summary>
Replace = 0,
/// <summary>
/// Two clipping regions are combined by taking their intersection.
/// </summary>
Intersect = 1,
/// <summary>
/// Not yet implemented in PDFsharp.
/// </summary>
Union = 2,
/// <summary>
/// Not yet implemented in PDFsharp.
/// </summary>
Xor = 3,
/// <summary>
/// Not yet implemented in PDFsharp.
/// </summary>
Exclude = 4,
/// <summary>
/// Not yet implemented in PDFsharp.
/// </summary>
Complement = 5,
}
}

View File

@@ -0,0 +1,67 @@
#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.Drawing
{
/// <summary>
/// Specifies the style of dashed lines drawn with an XPen object.
/// </summary>
public enum XDashStyle // Same values as System.Drawing.Drawing2D.DashStyle.
{
/// <summary>
/// Specifies a solid line.
/// </summary>
Solid = 0,
/// <summary>
/// Specifies a line consisting of dashes.
/// </summary>
Dash = 1,
/// <summary>
/// Specifies a line consisting of dots.
/// </summary>
Dot = 2,
/// <summary>
/// Specifies a line consisting of a repeating pattern of dash-dot.
/// </summary>
DashDot = 3,
/// <summary>
/// Specifies a line consisting of a repeating pattern of dash-dot-dot.
/// </summary>
DashDotDot = 4,
/// <summary>
/// Specifies a user-defined custom dash style.
/// </summary>
Custom = 5,
}
}

View File

@@ -0,0 +1,47 @@
#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.Drawing
{
/// <summary>
/// Specifies how the interior of a closed path is filled.
/// </summary>
public enum XFillMode // Same values as System.Drawing.FillMode.
{
/// <summary>
/// Specifies the alternate fill mode. Called the 'odd-even rule' in PDF terminology.
/// </summary>
Alternate = 0,
/// <summary>
/// Specifies the winding fill mode. Called the 'nonzero winding number rule' in PDF terminology.
/// </summary>
Winding = 1,
}
}

View File

@@ -0,0 +1,74 @@
#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.Drawing
{
/// <summary>
/// Specifies style information applied to text.
/// </summary>
[Flags]
public enum XFontStyle // Same values as System.Drawing.FontStyle.
{
/// <summary>
/// Normal text.
/// </summary>
Regular = XGdiFontStyle.Regular,
/// <summary>
/// Bold text.
/// </summary>
Bold = XGdiFontStyle.Bold,
/// <summary>
/// Italic text.
/// </summary>
Italic = XGdiFontStyle.Italic,
/// <summary>
/// Bold and italic text.
/// </summary>
BoldItalic = XGdiFontStyle.BoldItalic,
/// <summary>
/// Underlined text.
/// </summary>
Underline = XGdiFontStyle.Underline,
/// <summary>
/// Text with a line through the middle.
/// </summary>
Strikeout = XGdiFontStyle.Strikeout,
// Additional flags:
// BoldSimulation
// ItalicSimulation // It is not ObliqueSimulation, because oblique is what is what you get and this simulates italic.
}
}

View File

@@ -0,0 +1,76 @@
#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;
namespace PdfSharp.Drawing
{
/// <summary>
/// Backward compatibility.
/// </summary>
[Flags]
internal enum XGdiFontStyle // Same values as System.Drawing.FontStyle.
{
// Must be identical to both:
// System.Drawing.FontStyle and
// PdfSharp.Drawing.FontStyle
/// <summary>
/// Normal text.
/// </summary>
Regular = 0,
/// <summary>
/// Bold text.
/// </summary>
Bold = 1,
/// <summary>
/// Italic text.
/// </summary>
Italic = 2,
/// <summary>
/// Bold and italic text.
/// </summary>
BoldItalic = 3,
/// <summary>
/// Underlined text.
/// </summary>
Underline = 4,
/// <summary>
/// Text with a line through the middle.
/// </summary>
Strikeout = 8,
}
}

View File

@@ -0,0 +1,63 @@
#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
// ReSharper disable InconsistentNaming
namespace PdfSharp.Drawing
{
///<summary>
/// Determines whether rendering based on GDI+ or WPF.
/// For internal use in hybrid build only only.
/// </summary>
enum XGraphicTargetContext
{
// NETFX_CORE_TODO
NONE = 0,
/// <summary>
/// Rendering does not depent on a particular technology.
/// </summary>
CORE = 1,
/// <summary>
/// Renders using GDI+.
/// </summary>
GDI = 2,
/// <summary>
/// Renders using WPF (including Silverlight).
/// </summary>
WPF = 3,
/// <summary>
/// Universal Windows Platform.
/// </summary>
UWP = 10,
}
}

View 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
namespace PdfSharp.Drawing
{
/// <summary>
/// Type of the path data.
/// </summary>
internal enum XGraphicsPathItemType
{
Lines,
Beziers,
Curve,
Arc,
Rectangle,
RoundedRectangle,
Ellipse,
Polygon,
CloseFigure,
StartFigure,
}
}

View File

@@ -0,0 +1,52 @@
#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.Drawing
{
/// <summary>
/// Specifies how the content of an existing PDF page and new content is combined.
/// </summary>
public enum XGraphicsPdfPageOptions
{
/// <summary>
/// The new content is inserted behind the old content and any subsequent drawing in done above the existing graphic.
/// </summary>
Append,
/// <summary>
/// The new content is inserted before the old content and any subsequent drawing in done beneath the existing graphic.
/// </summary>
Prepend,
/// <summary>
/// The new content entirely replaces the old content and any subsequent drawing in done on a blank page.
/// </summary>
Replace,
}
}

View File

@@ -0,0 +1,62 @@
#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.Drawing
{
/// <summary>
/// Specifies the unit of measure.
/// </summary>
public enum XGraphicsUnit // NOT the same values as System.Drawing.GraphicsUnit
{
/// <summary>
/// Specifies a printer's point (1/72 inch) as the unit of measure.
/// </summary>
Point = 0, // Must be 0 to let a new XUnit be 0 point.
/// <summary>
/// Specifies the inch (2.54 cm) as the unit of measure.
/// </summary>
Inch = 1,
/// <summary>
/// Specifies the millimeter as the unit of measure.
/// </summary>
Millimeter = 2,
/// <summary>
/// Specifies the centimeter as the unit of measure.
/// </summary>
Centimeter = 3,
/// <summary>
/// Specifies a presentation point (1/96 inch) as the unit of measure.
/// </summary>
Presentation = 4,
}
}

View File

@@ -0,0 +1,461 @@
#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.Drawing
{
///<summary>
/// Specifies all pre-defined colors. Used to identify the pre-defined colors and to
/// localize their names.
/// </summary>
public enum XKnownColor
{
/// <summary>A pre-defined color.</summary>
AliceBlue = 0,
/// <summary>A pre-defined color.</summary>
AntiqueWhite = 1,
/// <summary>A pre-defined color.</summary>
Aqua = 2,
/// <summary>A pre-defined color.</summary>
Aquamarine = 3,
/// <summary>A pre-defined color.</summary>
Azure = 4,
/// <summary>A pre-defined color.</summary>
Beige = 5,
/// <summary>A pre-defined color.</summary>
Bisque = 6,
/// <summary>A pre-defined color.</summary>
Black = 7,
/// <summary>A pre-defined color.</summary>
BlanchedAlmond = 8,
/// <summary>A pre-defined color.</summary>
Blue = 9,
/// <summary>A pre-defined color.</summary>
BlueViolet = 10,
/// <summary>A pre-defined color.</summary>
Brown = 11,
/// <summary>A pre-defined color.</summary>
BurlyWood = 12,
/// <summary>A pre-defined color.</summary>
CadetBlue = 13,
/// <summary>A pre-defined color.</summary>
Chartreuse = 14,
/// <summary>A pre-defined color.</summary>
Chocolate = 15,
/// <summary>A pre-defined color.</summary>
Coral = 16,
/// <summary>A pre-defined color.</summary>
CornflowerBlue = 17,
/// <summary>A pre-defined color.</summary>
Cornsilk = 18,
/// <summary>A pre-defined color.</summary>
Crimson = 19,
/// <summary>A pre-defined color.</summary>
Cyan = 20,
/// <summary>A pre-defined color.</summary>
DarkBlue = 21,
/// <summary>A pre-defined color.</summary>
DarkCyan = 22,
/// <summary>A pre-defined color.</summary>
DarkGoldenrod = 23,
/// <summary>A pre-defined color.</summary>
DarkGray = 24,
/// <summary>A pre-defined color.</summary>
DarkGreen = 25,
/// <summary>A pre-defined color.</summary>
DarkKhaki = 26,
/// <summary>A pre-defined color.</summary>
DarkMagenta = 27,
/// <summary>A pre-defined color.</summary>
DarkOliveGreen = 28,
/// <summary>A pre-defined color.</summary>
DarkOrange = 29,
/// <summary>A pre-defined color.</summary>
DarkOrchid = 30,
/// <summary>A pre-defined color.</summary>
DarkRed = 31,
/// <summary>A pre-defined color.</summary>
DarkSalmon = 32,
/// <summary>A pre-defined color.</summary>
DarkSeaGreen = 33,
/// <summary>A pre-defined color.</summary>
DarkSlateBlue = 34,
/// <summary>A pre-defined color.</summary>
DarkSlateGray = 35,
/// <summary>A pre-defined color.</summary>
DarkTurquoise = 36,
/// <summary>A pre-defined color.</summary>
DarkViolet = 37,
/// <summary>A pre-defined color.</summary>
DeepPink = 38,
/// <summary>A pre-defined color.</summary>
DeepSkyBlue = 39,
/// <summary>A pre-defined color.</summary>
DimGray = 40,
/// <summary>A pre-defined color.</summary>
DodgerBlue = 41,
/// <summary>A pre-defined color.</summary>
Firebrick = 42,
/// <summary>A pre-defined color.</summary>
FloralWhite = 43,
/// <summary>A pre-defined color.</summary>
ForestGreen = 44,
/// <summary>A pre-defined color.</summary>
Fuchsia = 45,
/// <summary>A pre-defined color.</summary>
Gainsboro = 46,
/// <summary>A pre-defined color.</summary>
GhostWhite = 47,
/// <summary>A pre-defined color.</summary>
Gold = 48,
/// <summary>A pre-defined color.</summary>
Goldenrod = 49,
/// <summary>A pre-defined color.</summary>
Gray = 50,
/// <summary>A pre-defined color.</summary>
Green = 51,
/// <summary>A pre-defined color.</summary>
GreenYellow = 52,
/// <summary>A pre-defined color.</summary>
Honeydew = 53,
/// <summary>A pre-defined color.</summary>
HotPink = 54,
/// <summary>A pre-defined color.</summary>
IndianRed = 55,
/// <summary>A pre-defined color.</summary>
Indigo = 56,
/// <summary>A pre-defined color.</summary>
Ivory = 57,
/// <summary>A pre-defined color.</summary>
Khaki = 58,
/// <summary>A pre-defined color.</summary>
Lavender = 59,
/// <summary>A pre-defined color.</summary>
LavenderBlush = 60,
/// <summary>A pre-defined color.</summary>
LawnGreen = 61,
/// <summary>A pre-defined color.</summary>
LemonChiffon = 62,
/// <summary>A pre-defined color.</summary>
LightBlue = 63,
/// <summary>A pre-defined color.</summary>
LightCoral = 64,
/// <summary>A pre-defined color.</summary>
LightCyan = 65,
/// <summary>A pre-defined color.</summary>
LightGoldenrodYellow = 66,
/// <summary>A pre-defined color.</summary>
LightGray = 67,
/// <summary>A pre-defined color.</summary>
LightGreen = 68,
/// <summary>A pre-defined color.</summary>
LightPink = 69,
/// <summary>A pre-defined color.</summary>
LightSalmon = 70,
/// <summary>A pre-defined color.</summary>
LightSeaGreen = 71,
/// <summary>A pre-defined color.</summary>
LightSkyBlue = 72,
/// <summary>A pre-defined color.</summary>
LightSlateGray = 73,
/// <summary>A pre-defined color.</summary>
LightSteelBlue = 74,
/// <summary>A pre-defined color.</summary>
LightYellow = 75,
/// <summary>A pre-defined color.</summary>
Lime = 76,
/// <summary>A pre-defined color.</summary>
LimeGreen = 77,
/// <summary>A pre-defined color.</summary>
Linen = 78,
/// <summary>A pre-defined color.</summary>
Magenta = 79,
/// <summary>A pre-defined color.</summary>
Maroon = 80,
/// <summary>A pre-defined color.</summary>
MediumAquamarine = 81,
/// <summary>A pre-defined color.</summary>
MediumBlue = 82,
/// <summary>A pre-defined color.</summary>
MediumOrchid = 83,
/// <summary>A pre-defined color.</summary>
MediumPurple = 84,
/// <summary>A pre-defined color.</summary>
MediumSeaGreen = 85,
/// <summary>A pre-defined color.</summary>
MediumSlateBlue = 86,
/// <summary>A pre-defined color.</summary>
MediumSpringGreen = 87,
/// <summary>A pre-defined color.</summary>
MediumTurquoise = 88,
/// <summary>A pre-defined color.</summary>
MediumVioletRed = 89,
/// <summary>A pre-defined color.</summary>
MidnightBlue = 90,
/// <summary>A pre-defined color.</summary>
MintCream = 91,
/// <summary>A pre-defined color.</summary>
MistyRose = 92,
/// <summary>A pre-defined color.</summary>
Moccasin = 93,
/// <summary>A pre-defined color.</summary>
NavajoWhite = 94,
/// <summary>A pre-defined color.</summary>
Navy = 95,
/// <summary>A pre-defined color.</summary>
OldLace = 96,
/// <summary>A pre-defined color.</summary>
Olive = 97,
/// <summary>A pre-defined color.</summary>
OliveDrab = 98,
/// <summary>A pre-defined color.</summary>
Orange = 99,
/// <summary>A pre-defined color.</summary>
OrangeRed = 100,
/// <summary>A pre-defined color.</summary>
Orchid = 101,
/// <summary>A pre-defined color.</summary>
PaleGoldenrod = 102,
/// <summary>A pre-defined color.</summary>
PaleGreen = 103,
/// <summary>A pre-defined color.</summary>
PaleTurquoise = 104,
/// <summary>A pre-defined color.</summary>
PaleVioletRed = 105,
/// <summary>A pre-defined color.</summary>
PapayaWhip = 106,
/// <summary>A pre-defined color.</summary>
PeachPuff = 107,
/// <summary>A pre-defined color.</summary>
Peru = 108,
/// <summary>A pre-defined color.</summary>
Pink = 109,
/// <summary>A pre-defined color.</summary>
Plum = 110,
/// <summary>A pre-defined color.</summary>
PowderBlue = 111,
/// <summary>A pre-defined color.</summary>
Purple = 112,
/// <summary>A pre-defined color.</summary>
Red = 113,
/// <summary>A pre-defined color.</summary>
RosyBrown = 114,
/// <summary>A pre-defined color.</summary>
RoyalBlue = 115,
/// <summary>A pre-defined color.</summary>
SaddleBrown = 116,
/// <summary>A pre-defined color.</summary>
Salmon = 117,
/// <summary>A pre-defined color.</summary>
SandyBrown = 118,
/// <summary>A pre-defined color.</summary>
SeaGreen = 119,
/// <summary>A pre-defined color.</summary>
SeaShell = 120,
/// <summary>A pre-defined color.</summary>
Sienna = 121,
/// <summary>A pre-defined color.</summary>
Silver = 122,
/// <summary>A pre-defined color.</summary>
SkyBlue = 123,
/// <summary>A pre-defined color.</summary>
SlateBlue = 124,
/// <summary>A pre-defined color.</summary>
SlateGray = 125,
/// <summary>A pre-defined color.</summary>
Snow = 126,
/// <summary>A pre-defined color.</summary>
SpringGreen = 127,
/// <summary>A pre-defined color.</summary>
SteelBlue = 128,
/// <summary>A pre-defined color.</summary>
Tan = 129,
/// <summary>A pre-defined color.</summary>
Teal = 130,
/// <summary>A pre-defined color.</summary>
Thistle = 131,
/// <summary>A pre-defined color.</summary>
Tomato = 132,
/// <summary>A pre-defined color.</summary>
Transparent = 133,
/// <summary>A pre-defined color.</summary>
Turquoise = 134,
/// <summary>A pre-defined color.</summary>
Violet = 135,
/// <summary>A pre-defined color.</summary>
Wheat = 136,
/// <summary>A pre-defined color.</summary>
White = 137,
/// <summary>A pre-defined color.</summary>
WhiteSmoke = 138,
/// <summary>A pre-defined color.</summary>
Yellow = 139,
/// <summary>A pre-defined color.</summary>
YellowGreen = 140,
}
}

View File

@@ -0,0 +1,62 @@
#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.Drawing
{
/// <summary>
/// Specifies the alignment of a text string relative to its layout rectangle
/// </summary>
public enum XLineAlignment // same values as System.Drawing.StringAlignment (except BaseLine)
{
/// <summary>
/// Specifies the text be aligned near the layout.
/// In a left-to-right layout, the near position is left. In a right-to-left layout, the near
/// position is right.
/// </summary>
Near = 0,
/// <summary>
/// Specifies that text is aligned in the center of the layout rectangle.
/// </summary>
Center = 1,
/// <summary>
/// Specifies that text is aligned far from the origin position of the layout rectangle.
/// In a left-to-right layout, the far position is right. In a right-to-left layout, the far
/// position is left.
/// </summary>
Far = 2,
/// <summary>
/// Specifies that text is aligned relative to its base line.
/// With this option the layout rectangle must have a height of 0.
/// </summary>
BaseLine = 3,
}
}

Some files were not shown because too many files have changed in this diff Show More