diff --git a/src/UglyToad.PdfPig/Fonts/AdobeStylePrivateDictionary.cs b/src/UglyToad.PdfPig/Fonts/AdobeStylePrivateDictionary.cs new file mode 100644 index 00000000..4333e3e9 --- /dev/null +++ b/src/UglyToad.PdfPig/Fonts/AdobeStylePrivateDictionary.cs @@ -0,0 +1,245 @@ +namespace UglyToad.PdfPig.Fonts +{ + using System; + using System.Collections.Generic; + using Util.JetBrains.Annotations; + + /// + /// Holds common properties between Type 1 and Compact Font Format private dictionaries. + /// + internal abstract class AdobeStylePrivateDictionary + { + /// + /// 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; + + /// + /// 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. + /// + [NotNull] + public IReadOnlyList BlueValues { get; } + + /// + /// Optional: Pairs of integers similar to . + /// These only describe bottom zones. + /// + [NotNull] + 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. + /// + [NotNull] + 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 . + /// + [NotNull] + 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. + /// + [NotNull] + public IReadOnlyList StemSnapHorizontalWidths { get; } + + /// + /// Optional: Up to 12 numbers with the most common widths for vertical stems horizontally in character space units. + /// + [NotNull] + 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. + /// Default: 0 + /// + public int LanguageGroup { get; } + + /// + /// Optional: The limit for changing the size of a character bounding box for + /// 1 counters during font processing. + /// + public decimal ExpansionFactor { get; } + + /// + /// Creates a new . + /// + /// The builder used to gather property values. + protected AdobeStylePrivateDictionary([NotNull] BaseBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + 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; + ExpansionFactor = builder.ExpansionFactor ?? DefaultExpansionFactor; + } + + /// + /// A mutable builder which can set any property of the private dictionary and performs no validation. + /// + public abstract class BaseBuilder + { + /// + /// . + /// + 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 decimal? ExpansionFactor { get; set; } + } + } +} diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs index df857c44..5db00f0c 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/CompactFontFormatIndividualFontParser.cs @@ -34,7 +34,7 @@ var topDictionary = topLevelDictionaryReader.Read(individualData, stringIndex); - var privateDictionary = new CompactFontFormatPrivateDictionary(); + var privateDictionary = CompactFontFormatPrivateDictionary.GetDefault(); if (topDictionary.PrivateDictionarySizeAndOffset.Item2 >= 0) { @@ -49,9 +49,9 @@ } var localSubroutines = CompactFontFormatIndex.None; - if (privateDictionary.LocalSubroutineLocalOffset.HasValue) + if (privateDictionary.LocalSubroutineOffset.HasValue) { - data.Seek(privateDictionary.LocalSubroutineLocalOffset.Value); + data.Seek(privateDictionary.LocalSubroutineOffset.Value); localSubroutines = indexReader.ReadDictionaryData(data); } diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatDictionaryReader.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatDictionaryReader.cs index 86533b9e..33ceba66 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatDictionaryReader.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatDictionaryReader.cs @@ -5,13 +5,13 @@ using System.Text; using Geometry; - internal abstract class CompactFontFormatDictionaryReader + internal abstract class CompactFontFormatDictionaryReader { private readonly List operands = new List(); - public abstract T Read(CompactFontFormatData data, IReadOnlyList stringIndex); + public abstract TResult Read(CompactFontFormatData data, IReadOnlyList stringIndex); - protected T ReadDictionary(T dictionary, CompactFontFormatData data, IReadOnlyList stringIndex) + protected TBuilder ReadDictionary(TBuilder builder, CompactFontFormatData data, IReadOnlyList stringIndex) { while (data.CanRead()) { @@ -35,7 +35,7 @@ { var key = byte0 == 12 ? new OperandKey(byte0, data.ReadByte()) : new OperandKey(byte0); - ApplyOperation(dictionary, operands, key, stringIndex); + ApplyOperation(builder, operands, key, stringIndex); break; } @@ -87,7 +87,7 @@ } } - return dictionary; + return builder; } private static decimal ReadRealNumber(CompactFontFormatData data) @@ -162,7 +162,7 @@ return decimal.Parse(sb.ToString()); } - protected abstract void ApplyOperation(T dictionary, List operands, OperandKey operandKey, IReadOnlyList stringIndex); + protected abstract void ApplyOperation(TBuilder builder, List operands, OperandKey operandKey, IReadOnlyList stringIndex); protected static string GetString(List operands, IReadOnlyList stringIndex) { @@ -232,6 +232,28 @@ return defaultValue; } + protected static int[] ReadDeltaToIntArray(List operands) + { + var results = new int[operands.Count]; + + if (operands.Count == 0) + { + return results; + } + + results[0] = (int)operands[0].Decimal; + + for (var i = 1; i < operands.Count; i++) + { + var previous = results[i - 1]; + var current = operands[i].Decimal; + + results[i] = (int)(previous + current); + } + + return results; + } + protected static decimal[] ReadDeltaToArray(List operands) { var results = new decimal[operands.Count]; diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionary.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionary.cs index 6e1e8f80..6e2f2d31 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionary.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionary.cs @@ -1,47 +1,65 @@ namespace UglyToad.PdfPig.Fonts.CompactFontFormat.Dictionaries { - internal class CompactFontFormatPrivateDictionary + internal class CompactFontFormatPrivateDictionary : AdobeStylePrivateDictionary { - public decimal[] BlueValues { get; set; } + /// + /// Compatibility entry. + /// + public decimal InitialRandomSeed { get; } - public decimal[] OtherBlues { get; set; } - - public decimal[] FamilyBlues { get; set; } - - public decimal[] FamilyOtherBlues { get; set; } - - public decimal BlueScale { get; set; } = 0.039625m; - - public decimal BlueShift { get; set; } = 7; - - public decimal BlueFuzz { get; set; } = 1; - - public decimal StandardHorizontalWidth { get; set; } - - public decimal StandardVerticalWidth { get; set; } - - public decimal[] StemSnapHorizontal { get; set; } - - public decimal[] StemStapVertical { get; set; } - - public bool ForceBold { get; set; } - - public decimal LanguageGroup { get; set; } - - public decimal ExpansionFactor { get; set; } - - public decimal InitialRandomSeed { get; set; } - - public int? LocalSubroutineLocalOffset { get; set; } + /// + /// The offset in bytes for the local subroutine index in this font. The value is relative to this private dictionary. + /// + public int? LocalSubroutineOffset { get; } /// /// If a glyph's width equals the default width X it can be omitted from the charstring. /// - public decimal DefaultWidthX { get; set; } + public decimal DefaultWidthX { get; } /// /// If not equal to , Glyph width is computed by adding the charstring width to the nominal width X value. /// - public decimal NominalWidthX { get; set; } + public decimal NominalWidthX { get; } + + /// + /// + /// Create a new . + /// + /// The builder used to gather property values. + public CompactFontFormatPrivateDictionary(Builder builder) : base(builder) + { + InitialRandomSeed = builder.InitialRandomSeed; + LocalSubroutineOffset = builder.LocalSubroutineOffset; + DefaultWidthX = builder.DefaultWidthX; + NominalWidthX = builder.NominalWidthX; + } + + public static CompactFontFormatPrivateDictionary GetDefault() + { + return new Builder().Build(); + } + + public class Builder : BaseBuilder + { + public decimal InitialRandomSeed { get; set; } + + public int? LocalSubroutineOffset { get; set; } + + /// + /// If a glyph's width equals the default width X it can be omitted from the charstring. + /// + public decimal DefaultWidthX { get; set; } + + /// + /// If not equal to , Glyph width is computed by adding the charstring width to the nominal width X value. + /// + public decimal NominalWidthX { get; set; } + + public CompactFontFormatPrivateDictionary Build() + { + return new CompactFontFormatPrivateDictionary(this); + } + } } } \ No newline at end of file diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionaryReader.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionaryReader.cs index 22584651..34b75e11 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionaryReader.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatPrivateDictionaryReader.cs @@ -3,32 +3,32 @@ using System; using System.Collections.Generic; - internal class CompactFontFormatPrivateDictionaryReader : CompactFontFormatDictionaryReader + internal class CompactFontFormatPrivateDictionaryReader : CompactFontFormatDictionaryReader { public override CompactFontFormatPrivateDictionary Read(CompactFontFormatData data, IReadOnlyList stringIndex) { - var dictionary = new CompactFontFormatPrivateDictionary(); + var builder = new CompactFontFormatPrivateDictionary.Builder(); - ReadDictionary(dictionary, data, stringIndex); + ReadDictionary(builder, data, stringIndex); - return dictionary; + return builder.Build(); } - protected override void ApplyOperation(CompactFontFormatPrivateDictionary dictionary, List operands, OperandKey operandKey, IReadOnlyList stringIndex) + protected override void ApplyOperation(CompactFontFormatPrivateDictionary.Builder dictionary, List operands, OperandKey operandKey, IReadOnlyList stringIndex) { switch (operandKey.Byte0) { case 6: - dictionary.BlueValues = ReadDeltaToArray(operands); + dictionary.BlueValues = ReadDeltaToIntArray(operands); break; case 7: - dictionary.OtherBlues = ReadDeltaToArray(operands); + dictionary.OtherBlues = ReadDeltaToIntArray(operands); break; case 8: - dictionary.FamilyBlues = ReadDeltaToArray(operands); + dictionary.FamilyBlues = ReadDeltaToIntArray(operands); break; case 9: - dictionary.FamilyOtherBlues = ReadDeltaToArray(operands); + dictionary.FamilyOtherBlues = ReadDeltaToIntArray(operands); break; case 10: dictionary.StandardHorizontalWidth = operands[0].Decimal; @@ -49,22 +49,22 @@ dictionary.BlueScale = operands[0].Decimal; break; case 10: - dictionary.BlueShift = operands[0].Decimal; + dictionary.BlueShift = operands[0].Int; break; case 11: - dictionary.BlueFuzz = operands[0].Decimal; + dictionary.BlueFuzz = operands[0].Int; break; case 12: - dictionary.StemSnapHorizontal = ReadDeltaToArray(operands); + dictionary.StemSnapHorizontalWidths = ReadDeltaToArray(operands); break; case 13: - dictionary.StemStapVertical = ReadDeltaToArray(operands); + dictionary.StemSnapVerticalWidths = ReadDeltaToArray(operands); break; case 14: dictionary.ForceBold = operands[0].Decimal == 1; break; case 17: - dictionary.LanguageGroup = operands[0].Decimal; + dictionary.LanguageGroup = operands[0].Int; break; case 18: dictionary.ExpansionFactor = operands[0].Decimal; @@ -76,7 +76,7 @@ } break; case 19: - dictionary.LocalSubroutineLocalOffset = GetIntOrDefault(operands, -1); + dictionary.LocalSubroutineOffset = GetIntOrDefault(operands, -1); break; case 20: dictionary.DefaultWidthX = operands[0].Decimal; diff --git a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatTopLevelDictionaryReader.cs b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatTopLevelDictionaryReader.cs index f4dfde26..6dce2a0d 100644 --- a/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatTopLevelDictionaryReader.cs +++ b/src/UglyToad.PdfPig/Fonts/CompactFontFormat/Dictionaries/CompactFontFormatTopLevelDictionaryReader.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using Core; - internal class CompactFontFormatTopLevelDictionaryReader : CompactFontFormatDictionaryReader + internal class CompactFontFormatTopLevelDictionaryReader : CompactFontFormatDictionaryReader { public override CompactFontFormatTopLevelDictionary Read(CompactFontFormatData data, IReadOnlyList stringIndex) { diff --git a/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs b/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs index 96955a5d..aa1a3b94 100644 --- a/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs +++ b/src/UglyToad.PdfPig/Fonts/Type1/Type1PrivateDictionary.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using Parser; + using Util.JetBrains.Annotations; /// /// The Private dictionary for a Type 1 font contains hints that apply across all characters in the font. These hints @@ -12,132 +13,13 @@ /// 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 + internal class Type1PrivateDictionary : AdobeStylePrivateDictionary { - /// - /// 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 @@ -145,16 +27,10 @@ public int LenIv { get; } /// - /// Optional: Preserved for backwards compatibility. Must be set if the is 1. + /// 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 @@ -165,13 +41,15 @@ /// Required: Backwards compatibility. /// Default: {16 16} /// + [NotNull] public MinFeature MinFeature { get; } = new MinFeature(16, 16); + /// /// - /// Creates a new . + /// Creates a new . /// /// The builder used to gather property values. - public Type1PrivateDictionary(Builder builder) + public Type1PrivateDictionary([NotNull] Builder builder) : base(builder) { if (builder == null) { @@ -179,28 +57,19 @@ } 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; + + if (builder.Password.HasValue) + { + Password = builder.Password.Value; + } } /// /// A mutable builder which can set any property of the private dictionary and performs no validation. /// - public class Builder + public class Builder : BaseBuilder { /// /// Temporary storage for the Rd procedure tokens. @@ -231,72 +100,7 @@ /// . /// 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; } - + /// /// . /// @@ -317,16 +121,12 @@ /// public bool? RoundStemUp { get; set; } - /// - /// . - /// - public decimal? ExpansionFactor { get; set; } - /// /// Generate a from the values in this builder. /// /// The generated . - public Type1PrivateDictionary Build() + [NotNull] + public Type1PrivateDictionary Build() { return new Type1PrivateDictionary(this); }