mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-09-20 11:37:57 +08:00
use tryget rather than lambdas for union type
avoid the allocations caused by lambda expressions for performance reasons.
This commit is contained in:
@@ -19,6 +19,16 @@ namespace UglyToad.PdfPig.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract TResult Match<TResult>(Func<A, TResult> first, Func<B, TResult> second);
|
public abstract TResult Match<TResult>(Func<A, TResult> first, Func<B, TResult> second);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the item if it is of the specific type.
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool TryGetFirst(out A a);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the item if it is of the specific type.
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool TryGetSecond(out B b);
|
||||||
|
|
||||||
private Union() { }
|
private Union() { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -69,6 +79,20 @@ namespace UglyToad.PdfPig.Core
|
|||||||
return first(Item);
|
return first(Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryGetFirst(out A a)
|
||||||
|
{
|
||||||
|
a = Item;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryGetSecond(out B b)
|
||||||
|
{
|
||||||
|
b = default(B);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@@ -108,6 +132,20 @@ namespace UglyToad.PdfPig.Core
|
|||||||
return second(Item);
|
return second(Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryGetFirst(out A a)
|
||||||
|
{
|
||||||
|
a = default(A);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryGetSecond(out B b)
|
||||||
|
{
|
||||||
|
b = Item;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
@@ -48,21 +48,26 @@
|
|||||||
var defaultWidthX = GetDefaultWidthX(characterName);
|
var defaultWidthX = GetDefaultWidthX(characterName);
|
||||||
var nominalWidthX = GetNominalWidthX(characterName);
|
var nominalWidthX = GetNominalWidthX(characterName);
|
||||||
|
|
||||||
var result = CharStrings.Match(x => throw new NotImplementedException("Type 1 CharStrings in a CFF font are currently unsupported."),
|
if (CharStrings.TryGetFirst(out var _))
|
||||||
x =>
|
{
|
||||||
{
|
throw new NotImplementedException("Type 1 CharStrings in a CFF font are currently unsupported.");
|
||||||
var glyph = x.Generate(characterName, (double)defaultWidthX, (double)nominalWidthX);
|
}
|
||||||
var rectangle = glyph.Path.GetBoundingRectangle();
|
|
||||||
if (rectangle.HasValue)
|
|
||||||
{
|
|
||||||
return rectangle;
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultBoundingBox = TopDictionary.FontBoundingBox;
|
if (!CharStrings.TryGetSecond(out var type2CharStrings))
|
||||||
return new PdfRectangle(0, 0, glyph.Width.GetValueOrDefault(), defaultBoundingBox.Height);
|
{
|
||||||
});
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var glyph = type2CharStrings.Generate(characterName, (double)defaultWidthX, (double)nominalWidthX);
|
||||||
|
var rectangle = glyph.Path.GetBoundingRectangle();
|
||||||
|
if (rectangle.HasValue)
|
||||||
|
{
|
||||||
|
return rectangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultBoundingBox = TopDictionary.FontBoundingBox;
|
||||||
|
return new PdfRectangle(0, 0, glyph.Width.GetValueOrDefault(), defaultBoundingBox.Height);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -88,8 +93,8 @@
|
|||||||
public IReadOnlyList<CompactFontFormatPrivateDictionary> PrivateDictionaries { get; }
|
public IReadOnlyList<CompactFontFormatPrivateDictionary> PrivateDictionaries { get; }
|
||||||
public ICompactFontFormatFdSelect FdSelect { get; }
|
public ICompactFontFormatFdSelect FdSelect { get; }
|
||||||
|
|
||||||
public CompactFontFormatCidFont(CompactFontFormatTopLevelDictionary topDictionary, CompactFontFormatPrivateDictionary privateDictionary,
|
public CompactFontFormatCidFont(CompactFontFormatTopLevelDictionary topDictionary, CompactFontFormatPrivateDictionary privateDictionary,
|
||||||
ICompactFontFormatCharset charset,
|
ICompactFontFormatCharset charset,
|
||||||
Union<Type1CharStrings, Type2CharStrings> charStrings,
|
Union<Type1CharStrings, Type2CharStrings> charStrings,
|
||||||
IReadOnlyList<CompactFontFormatTopLevelDictionary> fontDictionaries,
|
IReadOnlyList<CompactFontFormatTopLevelDictionary> fontDictionaries,
|
||||||
IReadOnlyList<CompactFontFormatPrivateDictionary> privateDictionaries,
|
IReadOnlyList<CompactFontFormatPrivateDictionary> privateDictionaries,
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Core;
|
using Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -21,6 +20,11 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyDictionary<string, CompactFontFormatFont> Fonts { get; }
|
public IReadOnlyDictionary<string, CompactFontFormatFont> Fonts { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The first font contained in the collection.
|
||||||
|
/// </summary>
|
||||||
|
public CompactFontFormatFont FirstFont { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="CompactFontFormatFontCollection"/>.
|
/// Create a new <see cref="CompactFontFormatFontCollection"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -30,6 +34,11 @@
|
|||||||
{
|
{
|
||||||
Header = header;
|
Header = header;
|
||||||
Fonts = fontSet ?? throw new ArgumentNullException(nameof(fontSet));
|
Fonts = fontSet ?? throw new ArgumentNullException(nameof(fontSet));
|
||||||
|
foreach (var pair in fontSet)
|
||||||
|
{
|
||||||
|
FirstFont = pair.Value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -50,7 +59,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PdfRectangle? GetCharacterBoundingBox(string characterName)
|
public PdfRectangle? GetCharacterBoundingBox(string characterName)
|
||||||
{
|
{
|
||||||
return Fonts.First().Value.GetCharacterBoundingBox(characterName);
|
return FirstFont.GetCharacterBoundingBox(characterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -58,7 +67,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string GetCharacterName(int characterCode)
|
public string GetCharacterName(int characterCode)
|
||||||
{
|
{
|
||||||
var font = Fonts.First().Value;
|
var font = FirstFont;
|
||||||
|
|
||||||
if (font.Encoding != null)
|
if (font.Encoding != null)
|
||||||
{
|
{
|
||||||
|
@@ -23,8 +23,14 @@
|
|||||||
|
|
||||||
foreach (var command in subroutine.Commands)
|
foreach (var command in subroutine.Commands)
|
||||||
{
|
{
|
||||||
command.Match(x => context.Stack.Push(x),
|
if (command.TryGetFirst(out var num))
|
||||||
x => x.Run(context));
|
{
|
||||||
|
context.Stack.Push(num);
|
||||||
|
}
|
||||||
|
else if (command.TryGetSecond(out var lazyCommand))
|
||||||
|
{
|
||||||
|
lazyCommand.Run(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -92,8 +92,14 @@
|
|||||||
|
|
||||||
foreach (var command in sequence.Commands)
|
foreach (var command in sequence.Commands)
|
||||||
{
|
{
|
||||||
command.Match(x => context.Stack.Push(x),
|
if (command.TryGetFirst(out var num))
|
||||||
x => x.Run(context));
|
{
|
||||||
|
context.Stack.Push(num);
|
||||||
|
}
|
||||||
|
else if (command.TryGetSecond(out var lazyCommand))
|
||||||
|
{
|
||||||
|
lazyCommand.Run(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.Path;
|
return context.Path;
|
||||||
|
@@ -54,10 +54,14 @@
|
|||||||
{
|
{
|
||||||
foreach (var image in images)
|
foreach (var image in images)
|
||||||
{
|
{
|
||||||
var result = image.Match<IPdfImage>(x => XObjectFactory.ReadImage(x, pdfScanner, filterProvider, resourceStore),
|
if (image.TryGetFirst(out var xObjectContentRecord))
|
||||||
x => x);
|
{
|
||||||
|
yield return XObjectFactory.ReadImage(xObjectContentRecord, pdfScanner, filterProvider, resourceStore);
|
||||||
yield return result;
|
}
|
||||||
|
else if (image.TryGetSecond(out var inlineImage))
|
||||||
|
{
|
||||||
|
yield return inlineImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,7 +71,7 @@
|
|||||||
throw new NotSupportedException("Multiple fonts in a CFF");
|
throw new NotSupportedException("Multiple fonts in a CFF");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return fontCollection.Fonts.First().Value;
|
return fontCollection.FirstFont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
namespace UglyToad.PdfPig.PdfFonts.Parser.Handlers
|
namespace UglyToad.PdfPig.PdfFonts.Parser.Handlers
|
||||||
{
|
{
|
||||||
using System.Linq;
|
|
||||||
using Cmap;
|
using Cmap;
|
||||||
using Core;
|
using Core;
|
||||||
using Filters;
|
using Filters;
|
||||||
@@ -101,21 +100,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Encoding fromFont = font?.Match(x => x.Encoding != null ? new BuiltInEncoding(x.Encoding) : default(Encoding), x =>
|
|
||||||
|
var fromFont = default(Encoding);
|
||||||
|
if (font != null)
|
||||||
{
|
{
|
||||||
if (x.Fonts != null && x.Fonts.Count > 0)
|
if (font.TryGetFirst(out var t1Font))
|
||||||
{
|
{
|
||||||
return x.Fonts.First().Value.Encoding;
|
fromFont = t1Font.Encoding != null ? new BuiltInEncoding(t1Font.Encoding) : default(Encoding);
|
||||||
}
|
}
|
||||||
|
else if (font.TryGetSecond(out var cffFont))
|
||||||
|
{
|
||||||
|
fromFont = cffFont.FirstFont?.Encoding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return default(Encoding);
|
var encoding = encodingReader.Read(dictionary, descriptor, fromFont);
|
||||||
});
|
|
||||||
|
|
||||||
Encoding encoding = encodingReader.Read(dictionary, descriptor, fromFont);
|
if (encoding == null && font != null && font.TryGetFirst(out var t1FontReplacment))
|
||||||
|
|
||||||
if (encoding == null)
|
|
||||||
{
|
{
|
||||||
font?.Match(x => encoding = new BuiltInEncoding(x.Encoding), _ => { });
|
encoding = new BuiltInEncoding(t1FontReplacment.Encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Type1FontSimple(name, firstCharacter, lastCharacter, widths, descriptor, encoding, toUnicodeCMap, font);
|
return new Type1FontSimple(name, firstCharacter, lastCharacter, widths, descriptor, encoding, toUnicodeCMap, font);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
namespace UglyToad.PdfPig.PdfFonts.Simple
|
namespace UglyToad.PdfPig.PdfFonts.Simple
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Cmap;
|
using Cmap;
|
||||||
using Composite;
|
using Composite;
|
||||||
using Core;
|
using Core;
|
||||||
@@ -17,6 +16,8 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class Type1FontSimple : IFont
|
internal class Type1FontSimple : IFont
|
||||||
{
|
{
|
||||||
|
private static readonly TransformationMatrix DefaultTransformationMatrix = TransformationMatrix.FromValues(0.001, 0, 0, 0.001, 0, 0);
|
||||||
|
|
||||||
private readonly Dictionary<int, CharacterBoundingBox> cachedBoundingBoxes = new Dictionary<int, CharacterBoundingBox>();
|
private readonly Dictionary<int, CharacterBoundingBox> cachedBoundingBoxes = new Dictionary<int, CharacterBoundingBox>();
|
||||||
|
|
||||||
private readonly int firstChar;
|
private readonly int firstChar;
|
||||||
@@ -52,8 +53,19 @@
|
|||||||
this.fontProgram = fontProgram;
|
this.fontProgram = fontProgram;
|
||||||
this.toUnicodeCMap = new ToUnicodeCMap(toUnicodeCMap);
|
this.toUnicodeCMap = new ToUnicodeCMap(toUnicodeCMap);
|
||||||
|
|
||||||
var matrix = TransformationMatrix.FromValues(0.001, 0, 0, 0.001, 0, 0);
|
var matrix = DefaultTransformationMatrix;
|
||||||
fontProgram?.Match(x => matrix = x.FontMatrix, x => { matrix = x.GetFirstTransformationMatrix(); });
|
|
||||||
|
if (fontProgram != null)
|
||||||
|
{
|
||||||
|
if (fontProgram.TryGetFirst(out var t1Font))
|
||||||
|
{
|
||||||
|
matrix = t1Font.FontMatrix;
|
||||||
|
}
|
||||||
|
else if (fontProgram.TryGetSecond(out var cffFont))
|
||||||
|
{
|
||||||
|
matrix = cffFont.GetFirstTransformationMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fontMatrix = matrix;
|
fontMatrix = matrix;
|
||||||
|
|
||||||
@@ -90,10 +102,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var containsEncoding = false;
|
var containsEncoding = false;
|
||||||
var capturedValue = default(string);
|
if (fontProgram.TryGetFirst(out var t1Font))
|
||||||
fontProgram.Match(x => { containsEncoding = x.Encoding.TryGetValue(characterCode, out capturedValue); },
|
{
|
||||||
_ => {});
|
containsEncoding = t1Font.Encoding.TryGetValue(characterCode, out value);
|
||||||
value = capturedValue;
|
}
|
||||||
|
|
||||||
return containsEncoding;
|
return containsEncoding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,14 +176,15 @@
|
|||||||
return new PdfRectangle(0, 0, widths[characterCode - firstChar], 0);
|
return new PdfRectangle(0, 0, widths[characterCode - firstChar], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var rect = fontProgram.Match(x =>
|
PdfRectangle? rect = null;
|
||||||
{
|
if (fontProgram.TryGetFirst(out var t1Font))
|
||||||
var name = encoding.GetName(characterCode);
|
{
|
||||||
return x.GetCharacterBoundingBox(name);
|
var name = encoding.GetName(characterCode);
|
||||||
},
|
rect = t1Font.GetCharacterBoundingBox(name);
|
||||||
x =>
|
}
|
||||||
{
|
else if (fontProgram.TryGetSecond(out var cffFont))
|
||||||
var first = x.Fonts.First().Value;
|
{
|
||||||
|
var first = cffFont.FirstFont;
|
||||||
string characterName;
|
string characterName;
|
||||||
if (encoding != null)
|
if (encoding != null)
|
||||||
{
|
{
|
||||||
@@ -178,11 +192,12 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
characterName = x.GetCharacterName(characterCode);
|
characterName = cffFont.GetCharacterName(characterCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return first.GetCharacterBoundingBox(characterName);
|
rect = first.GetCharacterBoundingBox(characterName);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!rect.HasValue)
|
if (!rect.HasValue)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user