mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-09-20 03:17:57 +08:00
inline transformation code and cache afm strings
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
namespace UglyToad.PdfPig.Fonts.AdobeFontMetrics
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace UglyToad.PdfPig.Fonts.AdobeFontMetrics
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -11,6 +13,9 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class AdobeFontMetricsParser
|
public static class AdobeFontMetricsParser
|
||||||
{
|
{
|
||||||
|
private static readonly object Locker = new object();
|
||||||
|
private static readonly Dictionary<string, string> CharacterNames = new Dictionary<string, string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is a comment in a AFM file.
|
/// This is a comment in a AFM file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -603,7 +608,18 @@
|
|||||||
}
|
}
|
||||||
case CharmetricsN:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case CharmetricsB:
|
case CharmetricsB:
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The meaning of the metric sets field.
|
/// The meaning of the metric sets field.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum AdobeFontMetricsWritingDirections
|
public enum AdobeFontMetricsWritingDirections : byte
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writing direction 0 only.
|
/// Writing direction 0 only.
|
||||||
|
@@ -33,8 +33,8 @@
|
|||||||
{
|
{
|
||||||
private static readonly HashSet<string> Standard14Names = new HashSet<string>();
|
private static readonly HashSet<string> Standard14Names = new HashSet<string>();
|
||||||
private static readonly Dictionary<string, string> Standard14Mapping = new Dictionary<string, string>(34);
|
private static readonly Dictionary<string, string> Standard14Mapping = new Dictionary<string, string>(34);
|
||||||
private static readonly Dictionary<string, AdobeFontMetrics> Standard14AfmMap = new Dictionary<string, AdobeFontMetrics>(34);
|
private static readonly Dictionary<Standard14Font, string> BuilderTypesToNames = new Dictionary<Standard14Font, string>(14);
|
||||||
private static readonly Dictionary<Standard14Font, AdobeFontMetrics> Standard14AfmTypeMap = new Dictionary<Standard14Font, AdobeFontMetrics>(14);
|
private static readonly Dictionary<string, AdobeFontMetrics> Standard14Cache = new Dictionary<string, AdobeFontMetrics>(34);
|
||||||
|
|
||||||
static Standard14()
|
static Standard14()
|
||||||
{
|
{
|
||||||
@@ -88,9 +88,14 @@
|
|||||||
Standard14Names.Add(fontName);
|
Standard14Names.Add(fontName);
|
||||||
Standard14Mapping.Add(fontName, afmName);
|
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
|
try
|
||||||
@@ -112,11 +117,7 @@
|
|||||||
bytes = new ByteArrayInputBytes(memory.ToArray());
|
bytes = new ByteArrayInputBytes(memory.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard14AfmMap[fontName] = AdobeFontMetricsParser.Parse(bytes, true);
|
Standard14Cache[fontName] = AdobeFontMetricsParser.Parse(bytes, true);
|
||||||
if (type.HasValue)
|
|
||||||
{
|
|
||||||
Standard14AfmTypeMap[type.Value] = Standard14AfmMap[fontName];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -130,7 +131,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static AdobeFontMetrics GetAdobeFontMetrics(string baseName)
|
public static AdobeFontMetrics GetAdobeFontMetrics(string baseName)
|
||||||
{
|
{
|
||||||
Standard14AfmMap.TryGetValue(baseName, out var metrics);
|
Standard14Cache.TryGetValue(baseName, out var metrics);
|
||||||
|
|
||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
@@ -140,7 +141,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static AdobeFontMetrics GetAdobeFontMetrics(Standard14Font fontType)
|
public static AdobeFontMetrics GetAdobeFontMetrics(Standard14Font fontType)
|
||||||
{
|
{
|
||||||
return Standard14AfmTypeMap[fontType];
|
return Standard14Cache[BuilderTypesToNames[fontType]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -3,31 +3,31 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Direction of the text.
|
/// Direction of the text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum TextDirection
|
public enum TextDirection : byte
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Other text direction.
|
/// Other text direction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Other,
|
Other = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Usual text direction (Left to Right).
|
/// Usual text direction (Left to Right).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Horizontal,
|
Horizontal = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Horizontal text, upside down.
|
/// Horizontal text, upside down.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Rotate180,
|
Rotate180 = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotated text going down.
|
/// Rotated text going down.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Rotate90,
|
Rotate90 = 3,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotated text going up.
|
/// Rotated text going up.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Rotate270
|
Rotate270 = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,87 +1,93 @@
|
|||||||
using UglyToad.PdfPig.Core;
|
namespace UglyToad.PdfPig.Graphics
|
||||||
|
|
||||||
namespace UglyToad.PdfPig.Graphics
|
|
||||||
{
|
{
|
||||||
|
using PdfPig.Core;
|
||||||
|
|
||||||
internal static class PerformantRectangleTransformer
|
internal static class PerformantRectangleTransformer
|
||||||
{
|
{
|
||||||
public static PdfRectangle Transform(TransformationMatrix first, TransformationMatrix second, TransformationMatrix third, PdfRectangle rectangle)
|
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);
|
var topLeftX = tl.X;
|
||||||
mutable.Transform(second);
|
var topLeftY = tl.Y;
|
||||||
mutable.Transform(third);
|
|
||||||
|
|
||||||
return mutable.ToRectangle();
|
var topRightX = tr.X;
|
||||||
}
|
var topRightY = tr.Y;
|
||||||
|
|
||||||
private struct MutableRectangle
|
var bottomLeftX = bl.X;
|
||||||
{
|
var bottomLeftY = bl.Y;
|
||||||
private double topLeftX;
|
|
||||||
private double topLeftY;
|
|
||||||
|
|
||||||
private double topRightX;
|
var bottomRightX = br.X;
|
||||||
private double topRightY;
|
var bottomRightY = br.Y;
|
||||||
|
|
||||||
private double bottomLeftX;
|
// First
|
||||||
private double bottomLeftY;
|
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;
|
x = first.A * topRightX + first.C * topRightY + first.E;
|
||||||
private double bottomRightY;
|
y = first.B * topRightX + first.D * topRightY + first.F;
|
||||||
|
topRightX = x;
|
||||||
|
topRightY = y;
|
||||||
|
|
||||||
public MutableRectangle(PdfRectangle rectangle)
|
x = first.A * bottomLeftX + first.C * bottomLeftY + first.E;
|
||||||
{
|
y = first.B * bottomLeftX + first.D * bottomLeftY + first.F;
|
||||||
topLeftX = rectangle.TopLeft.X;
|
bottomLeftX = x;
|
||||||
topLeftY = rectangle.TopLeft.Y;
|
bottomLeftY = y;
|
||||||
|
|
||||||
topRightX = rectangle.TopRight.X;
|
x = first.A * bottomRightX + first.C * bottomRightY + first.E;
|
||||||
topRightY = rectangle.TopRight.Y;
|
y = first.B * bottomRightX + first.D * bottomRightY + first.F;
|
||||||
|
bottomRightX = x;
|
||||||
|
bottomRightY = y;
|
||||||
|
|
||||||
bottomLeftX = rectangle.BottomLeft.X;
|
// Second
|
||||||
bottomLeftY = rectangle.BottomLeft.Y;
|
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;
|
x = second.A * topRightX + second.C * topRightY + second.E;
|
||||||
bottomRightY = rectangle.BottomRight.Y;
|
y = second.B * topRightX + second.D * topRightY + second.F;
|
||||||
}
|
topRightX = x;
|
||||||
|
topRightY = y;
|
||||||
|
|
||||||
public void Transform(TransformationMatrix matrix)
|
x = second.A * bottomLeftX + second.C * bottomLeftY + second.E;
|
||||||
{
|
y = second.B * bottomLeftX + second.D * bottomLeftY + second.F;
|
||||||
/*
|
bottomLeftX = x;
|
||||||
* TransformationMatrix.Transform(PdfPoint original)
|
bottomLeftY = y;
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var x = matrix.A * topLeftX + matrix.C * topLeftY + matrix.E;
|
x = second.A * bottomRightX + second.C * bottomRightY + second.E;
|
||||||
var y = matrix.B * topLeftX + matrix.D * topLeftY + matrix.F;
|
y = second.B * bottomRightX + second.D * bottomRightY + second.F;
|
||||||
topLeftX = x;
|
bottomRightX = x;
|
||||||
topLeftY = y;
|
bottomRightY = y;
|
||||||
|
|
||||||
x = matrix.A * topRightX + matrix.C * topRightY + matrix.E;
|
// Third
|
||||||
y = matrix.B * topRightX + matrix.D * topRightY + matrix.F;
|
x = third.A * topLeftX + third.C * topLeftY + third.E;
|
||||||
topRightX = x;
|
y = third.B * topLeftX + third.D * topLeftY + third.F;
|
||||||
topRightY = y;
|
topLeftX = x;
|
||||||
|
topLeftY = y;
|
||||||
|
|
||||||
x = matrix.A * bottomLeftX + matrix.C * bottomLeftY + matrix.E;
|
x = third.A * topRightX + third.C * topRightY + third.E;
|
||||||
y = matrix.B * bottomLeftX + matrix.D * bottomLeftY + matrix.F;
|
y = third.B * topRightX + third.D * topRightY + third.F;
|
||||||
bottomLeftX = x;
|
topRightX = x;
|
||||||
bottomLeftY = y;
|
topRightY = y;
|
||||||
|
|
||||||
x = matrix.A * bottomRightX + matrix.C * bottomRightY + matrix.E;
|
x = third.A * bottomLeftX + third.C * bottomLeftY + third.E;
|
||||||
y = matrix.B * bottomRightX + matrix.D * bottomRightY + matrix.F;
|
y = third.B * bottomLeftX + third.D * bottomLeftY + third.F;
|
||||||
bottomRightX = x;
|
bottomLeftX = x;
|
||||||
bottomRightY = y;
|
bottomLeftY = y;
|
||||||
}
|
|
||||||
|
|
||||||
public PdfRectangle ToRectangle()
|
x = third.A * bottomRightX + third.C * bottomRightY + third.E;
|
||||||
{
|
y = third.B * bottomRightX + third.D * bottomRightY + third.F;
|
||||||
return new PdfRectangle(new PdfPoint(topLeftX, topLeftY), new PdfPoint(topRightX, topRightY),
|
bottomRightX = x;
|
||||||
new PdfPoint(bottomLeftX, bottomLeftY), new PdfPoint(bottomRightX, bottomRightY));
|
bottomRightY = y;
|
||||||
}
|
|
||||||
|
return new PdfRectangle(new PdfPoint(topLeftX, topLeftY), new PdfPoint(topRightX, topRightY),
|
||||||
|
new PdfPoint(bottomLeftX, bottomLeftY), new PdfPoint(bottomRightX, bottomRightY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user