mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-10-14 19:05:01 +08:00
#6 fix bugs with vlineto and hlineto and decoding of charsets. dump results of type 2 path decoding to file for visual verification while debugging
This commit is contained in:
@@ -146,7 +146,7 @@ namespace UglyToad.PdfPig.Fonts
|
||||
var path = $"<path d='{glyph}' stroke='cyan' stroke-width='3'></path>";
|
||||
var bboxRect = bbox.HasValue ? BboxToRect(bbox.Value, "yellow") : string.Empty;
|
||||
var others = string.Join(" ", bboxes.Select(x => BboxToRect(x, "gray")));
|
||||
var result = $"<svg transform='scale(1, -1)' width='2000' height='2000'>{path} {bboxRect} {others}</svg>";
|
||||
var result = $"<svg transform='scale(0.2, -0.2)' width='500' height='500'>{path} {bboxRect} {others}</svg>";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Charsets;
|
||||
using Geometry;
|
||||
using Util;
|
||||
using Util.JetBrains.Annotations;
|
||||
@@ -118,22 +119,25 @@
|
||||
*/
|
||||
var isOdd = ctx.Stack.Length % 2 != 0;
|
||||
|
||||
var numberOfAdditionalLines = ctx.Stack.Length - (isOdd ? 1 : 0);
|
||||
|
||||
if (isOdd)
|
||||
{
|
||||
var dx1 = ctx.Stack.PopBottom();
|
||||
ctx.AddRelativeHorizontalLine(dx1);
|
||||
|
||||
var numberOfAdditionalLines = ctx.Stack.Length;
|
||||
for (var i = 0; i < numberOfAdditionalLines; i++)
|
||||
for (var i = 0; i < numberOfAdditionalLines; i+= 2)
|
||||
{
|
||||
var isDeltaY = (isOdd && i % 2 == 0) || (!isOdd && i % 2 != 0);
|
||||
if (isDeltaY)
|
||||
{
|
||||
var dya = ctx.Stack.PopBottom();
|
||||
ctx.AddRelativeVerticalLine(dya);
|
||||
ctx.AddRelativeVerticalLine(ctx.Stack.PopBottom());
|
||||
ctx.AddRelativeHorizontalLine(ctx.Stack.PopBottom());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var dxa = ctx.Stack.PopBottom();
|
||||
ctx.AddRelativeHorizontalLine(dxa);
|
||||
for (var i = 0; i < numberOfAdditionalLines; i+= 2)
|
||||
{
|
||||
ctx.AddRelativeHorizontalLine(ctx.Stack.PopBottom());
|
||||
ctx.AddRelativeVerticalLine(ctx.Stack.PopBottom());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,23 +149,25 @@
|
||||
{
|
||||
var isOdd = ctx.Stack.Length % 2 != 0;
|
||||
|
||||
var numberOfAdditionalLines = ctx.Stack.Length - (isOdd ? 1 : 0);
|
||||
|
||||
if (isOdd)
|
||||
{
|
||||
var dy1 = ctx.Stack.PopBottom();
|
||||
ctx.AddRelativeVerticalLine(dy1);
|
||||
|
||||
var numberOfAdditionalLines = ctx.Stack.Length;
|
||||
for (var i = 0; i < numberOfAdditionalLines; i++)
|
||||
for (var i = 0; i < numberOfAdditionalLines; i+=2)
|
||||
{
|
||||
var isDeltaY = (isOdd && i % 2 != 0) || (!isOdd && i % 2 == 0);
|
||||
|
||||
if (isDeltaY)
|
||||
{
|
||||
var dya = ctx.Stack.PopBottom();
|
||||
ctx.AddRelativeVerticalLine(dya);
|
||||
ctx.AddRelativeHorizontalLine(ctx.Stack.PopBottom());
|
||||
ctx.AddRelativeVerticalLine(ctx.Stack.PopBottom());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var dxa = ctx.Stack.PopBottom();
|
||||
ctx.AddRelativeHorizontalLine(dxa);
|
||||
for (var i = 0; i < numberOfAdditionalLines; i+=2)
|
||||
{
|
||||
ctx.AddRelativeVerticalLine(ctx.Stack.PopBottom());
|
||||
ctx.AddRelativeHorizontalLine(ctx.Stack.PopBottom());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,7 +679,7 @@
|
||||
|
||||
public static Type2CharStrings Parse([NotNull] IReadOnlyList<IReadOnlyList<byte>> charStringBytes,
|
||||
[NotNull] CompactFontFormatIndex localSubroutines,
|
||||
[NotNull] CompactFontFormatIndex globalSubroutines)
|
||||
[NotNull] CompactFontFormatIndex globalSubroutines, ICompactFontFormatCharset charset)
|
||||
{
|
||||
if (charStringBytes == null)
|
||||
{
|
||||
@@ -690,12 +696,12 @@
|
||||
throw new ArgumentNullException(nameof(globalSubroutines));
|
||||
}
|
||||
|
||||
var charStrings = new Dictionary<int, Type2CharStrings.CommandSequence>();
|
||||
var charStrings = new Dictionary<string, Type2CharStrings.CommandSequence>();
|
||||
for (var i = 0; i < charStringBytes.Count; i++)
|
||||
{
|
||||
var charString = charStringBytes[i];
|
||||
var sequence = ParseSingle(charString);
|
||||
charStrings[i] = new Type2CharStrings.CommandSequence(sequence);
|
||||
charStrings[charset.GetNameByGlyphId(i)] = new Type2CharStrings.CommandSequence(sequence);
|
||||
}
|
||||
|
||||
return new Type2CharStrings(charStrings, new Dictionary<int, Type2CharStrings.CommandSequence>());
|
||||
|
@@ -10,11 +10,11 @@
|
||||
private readonly object locker = new object();
|
||||
private readonly Dictionary<string, CharacterPath> glyphs = new Dictionary<string, CharacterPath>();
|
||||
|
||||
public IReadOnlyDictionary<int, CommandSequence> CharStrings { get; }
|
||||
public IReadOnlyDictionary<string, CommandSequence> CharStrings { get; }
|
||||
|
||||
public IReadOnlyDictionary<int, CommandSequence> Subroutines { get; }
|
||||
|
||||
public Type2CharStrings(IReadOnlyDictionary<int, CommandSequence> charStrings, IReadOnlyDictionary<int, CommandSequence> subroutines)
|
||||
public Type2CharStrings(IReadOnlyDictionary<string, CommandSequence> charStrings, IReadOnlyDictionary<int, CommandSequence> subroutines)
|
||||
{
|
||||
CharStrings = charStrings ?? throw new ArgumentNullException(nameof(charStrings));
|
||||
Subroutines = subroutines ?? throw new ArgumentNullException(nameof(subroutines));
|
||||
@@ -30,7 +30,7 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!CharStrings.TryGetValue(0, out var sequence))
|
||||
if (!CharStrings.TryGetValue(name, out var sequence))
|
||||
{
|
||||
throw new InvalidOperationException($"No charstring sequence with the name /{name} in this font.");
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
public virtual string GetNameByGlyphId(int glyphId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return GlyphIdToStringIdAndName[glyphId].name;
|
||||
}
|
||||
|
||||
public virtual string GetNameByStringId(int stringId)
|
||||
|
@@ -195,7 +195,7 @@
|
||||
|
||||
public string GetNameByGlyphId(int glyphId)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return characterIdToStringIdAndName[glyphId].Value;
|
||||
}
|
||||
|
||||
public string GetNameByStringId(int stringId)
|
||||
|
@@ -116,7 +116,7 @@
|
||||
|
||||
public string GetNameByGlyphId(int glyphId)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return characterIdToStringIdAndName[glyphId].Value;
|
||||
}
|
||||
|
||||
public string GetNameByStringId(int stringId)
|
||||
|
@@ -258,7 +258,7 @@
|
||||
|
||||
public string GetNameByGlyphId(int glyphId)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
return characterIdToStringIdAndName[glyphId].Value;
|
||||
}
|
||||
|
||||
public string GetNameByStringId(int stringId)
|
||||
|
@@ -3,7 +3,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Charsets;
|
||||
using CharStrings;
|
||||
using Dictionaries;
|
||||
@@ -108,12 +110,11 @@
|
||||
var numberInRange = format == 1 ? data.ReadCard8() : data.ReadCard16();
|
||||
|
||||
glyphToNamesAndStringId.Add((glyphId, firstSid, ReadString(firstSid, stringIndex)));
|
||||
glyphId++;
|
||||
for (var i = 0; i < numberInRange; i++)
|
||||
{
|
||||
glyphId++;
|
||||
var sid = firstSid + i + 1;
|
||||
glyphToNamesAndStringId.Add((glyphId, sid, ReadString(sid, stringIndex)));
|
||||
glyphId++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@
|
||||
case CompactFontFormatCharStringType.Type1:
|
||||
throw new NotImplementedException();
|
||||
case CompactFontFormatCharStringType.Type2:
|
||||
charStrings = Type2CharStringParser.Parse(charStringIndex, localSubroutines, globalSubroutineIndex);
|
||||
charStrings = Type2CharStringParser.Parse(charStringIndex, localSubroutines, globalSubroutineIndex, charset);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException($"Unexpected CharString type in CFF font: {topDictionary.CharStringType}.");
|
||||
@@ -150,11 +151,17 @@
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
var builder = new StringBuilder("<!DOCTYPE html><html><head></head><body>");
|
||||
foreach (var pair in charStrings.CharStrings)
|
||||
{
|
||||
var path = Type2CharStrings.Run(pair.Value);
|
||||
var svg = path.ToFullSvg();
|
||||
builder.AppendLine(svg);
|
||||
}
|
||||
|
||||
builder.Append("</body></html>");
|
||||
|
||||
File.WriteAllText(@"C:\git\index.html", builder.ToString());
|
||||
}
|
||||
|
||||
return new CompactFontFormatFont(topDictionary, privateDictionary, charset, Union<Type1CharStrings, Type2CharStrings>.Two(charStrings));
|
||||
|
Reference in New Issue
Block a user