From 1fb2f879d9197014b633dc6bd3c203569df5cd99 Mon Sep 17 00:00:00 2001 From: Eliot Jones Date: Thu, 1 Nov 2018 22:08:40 +0000 Subject: [PATCH] prepare type 1 private dictionary for public api. fix typo --- src/UglyToad.PdfPig/Fonts/Type1/MinFeature.cs | 40 ++ .../Parser/Type1EncryptedPortionParser.cs | 4 +- .../Fonts/Type1/Type1PrivateDictionary.cs | 364 +++++++++++++++--- 3 files changed, 351 insertions(+), 57 deletions(-) create mode 100644 src/UglyToad.PdfPig/Fonts/Type1/MinFeature.cs diff --git a/src/UglyToad.PdfPig/Fonts/Type1/MinFeature.cs b/src/UglyToad.PdfPig/Fonts/Type1/MinFeature.cs new file mode 100644 index 00000000..8def8439 --- /dev/null +++ b/src/UglyToad.PdfPig/Fonts/Type1/MinFeature.cs @@ -0,0 +1,40 @@ +namespace UglyToad.PdfPig.Fonts.Type1 +{ + /// + /// Represents the MinFeature entry which is required for compatibility + /// and must have the value 16, 16. + /// + internal class MinFeature + { + /// + /// The first value. + /// + public int First { get; } + + /// + /// The second value. + /// + public int Second { get; } + + /// + /// The required default value of . + /// + public static MinFeature Default { get; } = new MinFeature(16, 16); + + /// + /// Creates a array. + /// + /// The first value. + /// The second value. + public MinFeature(int first, int second) + { + First = first; + Second = second; + } + + public override string ToString() + { + return $"{{{First} {Second}}}"; + } + } +} \ No newline at end of file diff --git a/src/UglyToad.PdfPig/Fonts/Type1/Parser/Type1EncryptedPortionParser.cs b/src/UglyToad.PdfPig/Fonts/Type1/Parser/Type1EncryptedPortionParser.cs index 44636b78..880591d0 100644 --- a/src/UglyToad.PdfPig/Fonts/Type1/Parser/Type1EncryptedPortionParser.cs +++ b/src/UglyToad.PdfPig/Fonts/Type1/Parser/Type1EncryptedPortionParser.cs @@ -131,7 +131,7 @@ case Type1Symbols.StemSnapHorizontalWidths: { var widths = ReadArrayValues(tokenizer, x => x.AsDecimal()); - builder.StempSnapHorizontalWidths = widths; + builder.StemSnapHorizontalWidths = widths; break; } case Type1Symbols.StemSnapVerticalWidths: @@ -168,7 +168,7 @@ } } - builder.MinFeature = new Type1PrivateDictionary.MinFeature(procedureTokens[0].AsInt(), procedureTokens[1].AsInt()); + builder.MinFeature = new MinFeature(procedureTokens[0].AsInt(), procedureTokens[1].AsInt()); ReadTillDef(tokenizer); diff --git a/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs b/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs index 459afbe0..dd27b3d0 100644 --- a/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs +++ b/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs @@ -1,72 +1,326 @@ namespace UglyToad.PdfPig.Fonts.Type1 { + using System; using System.Collections.Generic; using Parser; + /// + /// The Private dictionary for a Type 1 font contains hints that apply across all characters in the font. These hints + /// help preserve properties of character outline shapes when rendered at smaller sizes and lower resolutions. + /// These hints help ensure that the shape is as close as possible to the original design even where the character + /// must be represented in few pixels. + /// Note that subroutines are also defined in the private dictionary however for the purposes of this API they are + /// stored on the parent . + /// internal class Type1PrivateDictionary { - public class Builder + /// + /// Default value of . + /// + public static readonly decimal DefaultBlueScale = 0.039625m; + + /// + /// Default value of . + /// + public static readonly decimal DefaultExpansionFactor = 0.06m; + + /// + /// Default value of . + /// + public const int DefaultBlueFuzz = 1; + + /// + /// Default value of . + /// + public const int DefaultBlueShift = 7; + + /// + /// Default value of . + /// + public const int DefaultLanguageGroup = 0; + + /// + /// Optional: Uniquely identifies this font. + /// + public int? UniqueId { get; set; } + + /// + /// Required. An array containing an even number of integers. + /// The first pair is the baseline overshoot position and the baseline. + /// All following pairs describe top-zones. + /// + public IReadOnlyList BlueValues { get; } + + /// + /// Optional: Pairs of integers similar to . + /// These only describe bottom zones. + /// + public IReadOnlyList OtherBlues { get; } + + /// + /// Optional: Integer pairs similar to however these + /// are used to enforce consistency across a font family when there are small differences (<1px) in + /// font alignment. + /// + public IReadOnlyList FamilyBlues { get; } + + /// + /// Optional: Integer pairs similar to however these + /// are used to enforce consistency across a font family with small differences + /// in alignment similarly to . + /// + public IReadOnlyList FamilyOtherBlues { get; } + + /// + /// Optional: The point size at which overshoot suppression stops. + /// The value is a related to the number of pixels tall that one character space unit will be + /// before overshoot suppression is switched off. Overshoot suppression enforces features to snap + /// to alignment zones when the point size is below that affected by this value. + /// Default: 0.039625 + /// + /// + /// A blue scale of 0.039625 switches overshoot suppression off at 10 points + /// on a 300 dpi device using the formula (for 300 dpi): + /// BlueScale = (pointsize - 0.49)/240 + /// For example, if you wish overshoot suppression to turn off at 11 + /// points on a 300-dpi device, you should set BlueScale to + /// (11 − 0.49) ÷ 240 or 0.04379 + /// + public decimal BlueScale { get; } + + /// + /// Optional: The character space distance beyond the flat position of alignment zones + /// at which overshoot enforcement occurs. + /// Default: 7 + /// + public int BlueShift { get; } + + /// + /// Optional: The number of character space units to extend an alignment zone + /// on a horizontal stem. + /// If the top or bottom of a horizontal stem is within BlueFuzz units outside a top-zone + /// then the stem top/bottom is treated as if it were within the zone. + /// Default: 1 + /// + public int BlueFuzz { get; } + + /// + /// Optional: The dominant width of horizontal stems vertically in character space units. + /// + public decimal? StandardHorizontalWidth { get; } + + /// + /// Optional: The dominant width of vertical stems horizontally in character space units. + /// + public decimal? StandardVerticalWidth { get; } + + /// + /// Optional: Up to 12 numbers with the most common widths for horizontal stems vertically in character space units. + /// + public IReadOnlyList StemSnapHorizontalWidths { get; } + + /// + /// Optional: Up to 12 numbers with the most common widths for vertical stems horizontally in character space units. + /// + public IReadOnlyList StemSnapVerticalWidths { get; } + + /// + /// Optional: At small sizes at low resolutions this controls whether bold characters should appear thicker using + /// special techniques. + /// + public bool ForceBold { get; } + + /// + /// Optional: Language group 0 includes Latin, Greek and Cyrillic as well as similar alphabets. + /// Language group 1 includes Chinese, Japanese Kanji and Korean Hangul as well as similar alphabets. + /// If language group is 1 then should also be set. + /// Default: 0 + /// + public int LanguageGroup { get; } + + /// + /// Optional: Indicates the number of random bytes used for charstring encryption/decryption. + /// Default: 4 + /// + public int LenIv { get; } + + /// + /// Optional: Preserved for backwards compatibility. Must be set if the is 1. + /// + public bool? RoundStemUp { get; } + + /// + /// Optional: The limit for changing the size of a character bounding box for + /// 1 counters during font processing. + /// + public decimal ExpansionFactor { get; } + + /// + /// Required: Backwards compatibility. + /// Default: 5839 + /// + public int Password { get; } = 5839; + + /// + /// Required: Backwards compatibility. + /// Default: {16 16} + /// + public MinFeature MinFeature { get; } = new MinFeature(16, 16); + + /// + /// Creates a new . + /// + /// The builder used to gather property values. + public Type1PrivateDictionary(Builder builder) { - public object Rd { get; set; } + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } - public object NoAccessPut { get; set; } - - public object NoAccessDef { get; set; } - - public IReadOnlyList Subroutines { get; set; } - - public object[] OtherSubroutines { get; set; } - - public int? UniqueId { get; set; } - - public IReadOnlyList BlueValues { get; set; } - - public IReadOnlyList OtherBlues { get; set; } - - public IReadOnlyList FamilyBlues { get; set; } - - public IReadOnlyList FamilyOtherBlues { get; set; } - - public decimal? BlueScale { get; set; } - - public int? BlueShift { get; set; } - - public int? BlueFuzz { get; set; } - - public decimal? StandardHorizontalWidth { get; set; } - - public decimal? StandardVerticalWidth { get; set; } - - public IReadOnlyList StempSnapHorizontalWidths { get; set; } - - public IReadOnlyList StemSnapVerticalWidths { get; set; } - - public bool ForceBold { get; set; } - - public int LanguageGroup { get; set; } - - public int? Password { get; set; } - - public int LenIv { get; set; } - - public MinFeature MinFeature { get; set; } - - public bool RoundStemUp { get; set; } - - public decimal? ExpansionFactor { get; set; } + UniqueId = builder.UniqueId; + BlueValues = builder.BlueValues ?? Array.Empty(); + OtherBlues = builder.OtherBlues ?? Array.Empty(); + FamilyBlues = builder.FamilyBlues ?? Array.Empty(); + FamilyOtherBlues = builder.FamilyOtherBlues ?? Array.Empty(); + BlueScale = builder.BlueScale ?? DefaultBlueScale; + BlueFuzz = builder.BlueFuzz ?? DefaultBlueFuzz; + BlueShift = builder.BlueShift ?? DefaultBlueShift; + StandardHorizontalWidth = builder.StandardHorizontalWidth; + StandardVerticalWidth = builder.StandardVerticalWidth; + StemSnapHorizontalWidths = builder.StemSnapHorizontalWidths ?? Array.Empty(); + StemSnapVerticalWidths = builder.StemSnapVerticalWidths ?? Array.Empty(); + ForceBold = builder.ForceBold ?? false; + LanguageGroup = builder.LanguageGroup ?? DefaultLanguageGroup; + RoundStemUp = builder.RoundStemUp; + LenIv = builder.LenIv; + ExpansionFactor = builder.ExpansionFactor ?? DefaultExpansionFactor; } - public class MinFeature + /// + /// A mutable builder which can set any property of the private dictionary and performs no validation. + /// + public class Builder { - public int First { get; } + /// + /// Temporary storage for the Rd procedure tokens. + /// + public object Rd { get; set; } - public int Second { get; } + /// + /// Temporary storage for the No Access Put procedure tokens. + /// + public object NoAccessPut { get; set; } - public MinFeature(int first, int second) - { - First = first; - Second = second; - } + /// + /// Temporary storage for the No Access Def procedure tokens. + /// + public object NoAccessDef { get; set; } + + /// + /// Temporary storage for the decrypted but raw bytes of the subroutines in this private dictionary. + /// + public IReadOnlyList Subroutines { get; set; } + + /// + /// Temporary storage for the tokens of the other subroutine procedures. + /// + public object[] OtherSubroutines { get; set; } + + /// + /// . + /// + public int? UniqueId { get; set; } + + /// + /// . + /// + public IReadOnlyList BlueValues { get; set; } + + /// + /// . + /// + public IReadOnlyList OtherBlues { get; set; } + + /// + /// . + /// + public IReadOnlyList FamilyBlues { get; set; } + + /// + /// . + /// + public IReadOnlyList FamilyOtherBlues { get; set; } + + /// + /// . + /// + public decimal? BlueScale { get; set; } + + /// + /// . + /// + public int? BlueShift { get; set; } + + /// + /// . + /// + public int? BlueFuzz { get; set; } + + /// + /// . + /// + public decimal? StandardHorizontalWidth { get; set; } + + /// + /// . + /// + public decimal? StandardVerticalWidth { get; set; } + + /// + /// . + /// + public IReadOnlyList StemSnapHorizontalWidths { get; set; } + + /// + /// . + /// + public IReadOnlyList StemSnapVerticalWidths { get; set; } + + /// + /// . + /// + public bool? ForceBold { get; set; } + + /// + /// . + /// + public int? LanguageGroup { get; set; } + + /// + /// . + /// + public int? Password { get; set; } + + /// + /// . + /// + public int LenIv { get; set; } + + /// + /// . + /// + public MinFeature MinFeature { get; set; } + + /// + /// . + /// + public bool? RoundStemUp { get; set; } + + /// + /// . + /// + public decimal? ExpansionFactor { get; set; } } } }