320 lines
11 KiB
C#
320 lines
11 KiB
C#
|
#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;
|
||
|
}
|
||
|
}
|