diff --git a/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsParser.cs b/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsParser.cs index 6c1da918..c56be615 100644 --- a/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsParser.cs +++ b/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsParser.cs @@ -1,4 +1,6 @@ -namespace UglyToad.PdfPig.Fonts.AdobeFontMetrics +using System.Collections.Generic; + +namespace UglyToad.PdfPig.Fonts.AdobeFontMetrics { using System; using System.Globalization; @@ -11,6 +13,9 @@ /// public static class AdobeFontMetricsParser { + private static readonly object Locker = new object(); + private static readonly Dictionary CharacterNames = new Dictionary(); + /// /// This is a comment in a AFM file. /// @@ -603,7 +608,18 @@ } case CharmetricsN: { - metric.Name = parts[1]; + lock (Locker) + { + var name = parts[1]; + + if (!CharacterNames.TryGetValue(name, out var cached)) + { + cached = name; + CharacterNames[name] = cached; + } + + metric.Name = cached; + } break; } case CharmetricsB: diff --git a/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsWritingDirections.cs b/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsWritingDirections.cs index 0f1f6b3f..efdf31e3 100644 --- a/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsWritingDirections.cs +++ b/src/UglyToad.PdfPig.Fonts/AdobeFontMetrics/AdobeFontMetricsWritingDirections.cs @@ -3,7 +3,7 @@ /// /// The meaning of the metric sets field. /// - public enum AdobeFontMetricsWritingDirections + public enum AdobeFontMetricsWritingDirections : byte { /// /// Writing direction 0 only. diff --git a/src/UglyToad.PdfPig.Fonts/Standard14Fonts/Standard14.cs b/src/UglyToad.PdfPig.Fonts/Standard14Fonts/Standard14.cs index 17979a8a..f30f3f31 100644 --- a/src/UglyToad.PdfPig.Fonts/Standard14Fonts/Standard14.cs +++ b/src/UglyToad.PdfPig.Fonts/Standard14Fonts/Standard14.cs @@ -33,8 +33,8 @@ { private static readonly HashSet Standard14Names = new HashSet(); private static readonly Dictionary Standard14Mapping = new Dictionary(34); - private static readonly Dictionary Standard14AfmMap = new Dictionary(34); - private static readonly Dictionary Standard14AfmTypeMap = new Dictionary(14); + private static readonly Dictionary BuilderTypesToNames = new Dictionary(14); + private static readonly Dictionary Standard14Cache = new Dictionary(34); static Standard14() { @@ -88,9 +88,14 @@ Standard14Names.Add(fontName); Standard14Mapping.Add(fontName, afmName); - if (Standard14AfmMap.TryGetValue(afmName, out var metrics)) + if (type.HasValue) { - Standard14AfmMap[fontName] = metrics; + BuilderTypesToNames[type.Value] = afmName; + } + + if (Standard14Cache.TryGetValue(afmName, out var metrics)) + { + Standard14Cache[fontName] = metrics; } try @@ -112,11 +117,7 @@ bytes = new ByteArrayInputBytes(memory.ToArray()); } - Standard14AfmMap[fontName] = AdobeFontMetricsParser.Parse(bytes, true); - if (type.HasValue) - { - Standard14AfmTypeMap[type.Value] = Standard14AfmMap[fontName]; - } + Standard14Cache[fontName] = AdobeFontMetricsParser.Parse(bytes, true); } catch (Exception ex) { @@ -130,7 +131,7 @@ /// public static AdobeFontMetrics GetAdobeFontMetrics(string baseName) { - Standard14AfmMap.TryGetValue(baseName, out var metrics); + Standard14Cache.TryGetValue(baseName, out var metrics); return metrics; } @@ -140,7 +141,7 @@ /// public static AdobeFontMetrics GetAdobeFontMetrics(Standard14Font fontType) { - return Standard14AfmTypeMap[fontType]; + return Standard14Cache[BuilderTypesToNames[fontType]]; } /// diff --git a/src/UglyToad.PdfPig/Content/TextDirection.cs b/src/UglyToad.PdfPig/Content/TextDirection.cs index 2f4ae4f9..85b2b7d0 100644 --- a/src/UglyToad.PdfPig/Content/TextDirection.cs +++ b/src/UglyToad.PdfPig/Content/TextDirection.cs @@ -3,31 +3,31 @@ /// /// Direction of the text. /// - public enum TextDirection + public enum TextDirection : byte { /// /// Other text direction. /// - Other, + Other = 0, /// /// Usual text direction (Left to Right). /// - Horizontal, + Horizontal = 1, /// /// Horizontal text, upside down. /// - Rotate180, + Rotate180 = 2, /// /// Rotated text going down. /// - Rotate90, + Rotate90 = 3, /// /// Rotated text going up. /// - Rotate270 + Rotate270 = 4 } } diff --git a/src/UglyToad.PdfPig/Graphics/PerformantRectangleTransformer.cs b/src/UglyToad.PdfPig/Graphics/PerformantRectangleTransformer.cs index aed6eb30..9dd10433 100644 --- a/src/UglyToad.PdfPig/Graphics/PerformantRectangleTransformer.cs +++ b/src/UglyToad.PdfPig/Graphics/PerformantRectangleTransformer.cs @@ -1,87 +1,93 @@ -using UglyToad.PdfPig.Core; - -namespace UglyToad.PdfPig.Graphics +namespace UglyToad.PdfPig.Graphics { + using PdfPig.Core; + internal static class PerformantRectangleTransformer { public static PdfRectangle Transform(TransformationMatrix first, TransformationMatrix second, TransformationMatrix third, PdfRectangle rectangle) { - var mutable = new MutableRectangle(rectangle); + var tl = rectangle.TopLeft; + var tr = rectangle.TopRight; + var bl = rectangle.BottomLeft; + var br = rectangle.BottomRight; - mutable.Transform(first); - mutable.Transform(second); - mutable.Transform(third); + var topLeftX = tl.X; + var topLeftY = tl.Y; - return mutable.ToRectangle(); - } + var topRightX = tr.X; + var topRightY = tr.Y; - private struct MutableRectangle - { - private double topLeftX; - private double topLeftY; + var bottomLeftX = bl.X; + var bottomLeftY = bl.Y; - private double topRightX; - private double topRightY; + var bottomRightX = br.X; + var bottomRightY = br.Y; - private double bottomLeftX; - private double bottomLeftY; + // First + var x = first.A * topLeftX + first.C * topLeftY + first.E; + var y = first.B * topLeftX + first.D * topLeftY + first.F; + topLeftX = x; + topLeftY = y; - private double bottomRightX; - private double bottomRightY; + x = first.A * topRightX + first.C * topRightY + first.E; + y = first.B * topRightX + first.D * topRightY + first.F; + topRightX = x; + topRightY = y; - public MutableRectangle(PdfRectangle rectangle) - { - topLeftX = rectangle.TopLeft.X; - topLeftY = rectangle.TopLeft.Y; + x = first.A * bottomLeftX + first.C * bottomLeftY + first.E; + y = first.B * bottomLeftX + first.D * bottomLeftY + first.F; + bottomLeftX = x; + bottomLeftY = y; - topRightX = rectangle.TopRight.X; - topRightY = rectangle.TopRight.Y; + x = first.A * bottomRightX + first.C * bottomRightY + first.E; + y = first.B * bottomRightX + first.D * bottomRightY + first.F; + bottomRightX = x; + bottomRightY = y; - bottomLeftX = rectangle.BottomLeft.X; - bottomLeftY = rectangle.BottomLeft.Y; + // Second + x = second.A * topLeftX + second.C * topLeftY + second.E; + y = second.B * topLeftX + second.D * topLeftY + second.F; + topLeftX = x; + topLeftY = y; - bottomRightX = rectangle.BottomRight.X; - bottomRightY = rectangle.BottomRight.Y; - } + x = second.A * topRightX + second.C * topRightY + second.E; + y = second.B * topRightX + second.D * topRightY + second.F; + topRightX = x; + topRightY = y; - public void Transform(TransformationMatrix matrix) - { - /* - * TransformationMatrix.Transform(PdfPoint original) - * var x = A * original.X + C * original.Y + E; - * var y = B * original.X + D * original.Y + F; - * return new PdfPoint(x, y); - * - * For a rectangle runs on TopLeft, TopRight, BottomLeft and BottomRight - * and returns a new rectangle. - */ + x = second.A * bottomLeftX + second.C * bottomLeftY + second.E; + y = second.B * bottomLeftX + second.D * bottomLeftY + second.F; + bottomLeftX = x; + bottomLeftY = y; - var x = matrix.A * topLeftX + matrix.C * topLeftY + matrix.E; - var y = matrix.B * topLeftX + matrix.D * topLeftY + matrix.F; - topLeftX = x; - topLeftY = y; + x = second.A * bottomRightX + second.C * bottomRightY + second.E; + y = second.B * bottomRightX + second.D * bottomRightY + second.F; + bottomRightX = x; + bottomRightY = y; - x = matrix.A * topRightX + matrix.C * topRightY + matrix.E; - y = matrix.B * topRightX + matrix.D * topRightY + matrix.F; - topRightX = x; - topRightY = y; + // Third + x = third.A * topLeftX + third.C * topLeftY + third.E; + y = third.B * topLeftX + third.D * topLeftY + third.F; + topLeftX = x; + topLeftY = y; - x = matrix.A * bottomLeftX + matrix.C * bottomLeftY + matrix.E; - y = matrix.B * bottomLeftX + matrix.D * bottomLeftY + matrix.F; - bottomLeftX = x; - bottomLeftY = y; + x = third.A * topRightX + third.C * topRightY + third.E; + y = third.B * topRightX + third.D * topRightY + third.F; + topRightX = x; + topRightY = y; - x = matrix.A * bottomRightX + matrix.C * bottomRightY + matrix.E; - y = matrix.B * bottomRightX + matrix.D * bottomRightY + matrix.F; - bottomRightX = x; - bottomRightY = y; - } + x = third.A * bottomLeftX + third.C * bottomLeftY + third.E; + y = third.B * bottomLeftX + third.D * bottomLeftY + third.F; + bottomLeftX = x; + bottomLeftY = y; - public PdfRectangle ToRectangle() - { - return new PdfRectangle(new PdfPoint(topLeftX, topLeftY), new PdfPoint(topRightX, topRightY), - new PdfPoint(bottomLeftX, bottomLeftY), new PdfPoint(bottomRightX, bottomRightY)); - } + x = third.A * bottomRightX + third.C * bottomRightY + third.E; + y = third.B * bottomRightX + third.D * bottomRightY + third.F; + bottomRightX = x; + bottomRightY = y; + + return new PdfRectangle(new PdfPoint(topLeftX, topLeftY), new PdfPoint(topRightX, topRightY), + new PdfPoint(bottomLeftX, bottomLeftY), new PdfPoint(bottomRightX, bottomRightY)); } } }