vendor: import KillerPDF 1.7.5 source (GPL-3.0) as the base for MMD PDF

This commit is contained in:
2026-08-27 06:58:22 +02:00
commit 532485a830
577 changed files with 149058 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using PdfSharpCore.Drawing;
namespace PdfSharpCore.Internal
{
/// <summary>
/// Some static helper functions for calculations.
/// </summary>
internal static class Calc
{
/// <summary>
/// Degree to radiant factor.
/// </summary>
public const double Deg2Rad = Math.PI / 180;
///// <summary>
///// Half of pi.
///// </summary>
//public const double πHalf = Math.PI / 2;
//// α - β κ
/// <summary>
/// Get page size in point from specified PageSize.
/// </summary>
public static XSize PageSizeToSize(PageSize value)
{
switch (value)
{
case PageSize.A0:
return new XSize(2380, 3368);
case PageSize.A1:
return new XSize(1684, 2380);
case PageSize.A2:
return new XSize(1190, 1684);
case PageSize.A3:
return new XSize(842, 1190);
case PageSize.A4:
return new XSize(595, 842);
case PageSize.A6:
return new XSize(298, 420);
case PageSize.A5:
return new XSize(420, 595);
case PageSize.B4:
return new XSize(729, 1032);
case PageSize.B5:
return new XSize(516, 729);
// The strange sizes from overseas...
case PageSize.Letter:
return new XSize(612, 792);
case PageSize.Legal:
return new XSize(612, 1008);
case PageSize.Tabloid:
return new XSize(792, 1224);
case PageSize.Ledger:
return new XSize(1224, 792);
case PageSize.Statement:
return new XSize(396, 612);
case PageSize.Executive:
return new XSize(540, 720);
case PageSize.Folio:
return new XSize(612, 936);
case PageSize.Quarto:
return new XSize(610, 780);
case PageSize.Size10x14:
return new XSize(720, 1008);
}
throw new ArgumentException("Invalid PageSize.");
}
}
}
+76
View File
@@ -0,0 +1,76 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
#pragma warning disable 649
namespace PdfSharpCore.Internal
{
struct SColor
{
public byte a;
public byte r;
public byte g;
public byte b;
}
struct SCColor
{
public float a;
public float r;
public float g;
public float b;
}
static class ColorHelper
{
public static float sRgbToScRgb(byte bval)
{
float num = ((float)bval) / 255f;
if (num <= 0.0)
return 0f;
if (num <= 0.04045)
return (num / 12.92f);
if (num < 1f)
return (float)Math.Pow((num + 0.055) / 1.055, 2.4);
return 1f;
}
public static byte ScRgbTosRgb(float val)
{
if (val <= 0.0)
return 0;
if (val <= 0.0031308)
return (byte)(((255f * val) * 12.92f) + 0.5f);
if (val < 1.0)
return (byte)((255f * ((1.055f * ((float)Math.Pow((double)val, 0.41666666666666669))) - 0.055f)) + 0.5f);
return 0xff;
}
}
}
+110
View File
@@ -0,0 +1,110 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Globalization;
using PdfSharpCore.Pdf.Content;
using PdfSharpCore.Pdf.IO;
namespace PdfSharpCore.Internal
{
enum NotImplementedBehaviour
{
DoNothing, Log, Throw
}
/// <summary>
/// A bunch of internal helper functions.
/// </summary>
internal static class Diagnostics
{
public static NotImplementedBehaviour NotImplementedBehaviour
{
get { return _notImplementedBehaviour; }
set { _notImplementedBehaviour = value; }
}
static NotImplementedBehaviour _notImplementedBehaviour;
}
internal static class ParserDiagnostics
{
public static void ThrowParserException(string message)
{
throw new PdfReaderException(message);
}
public static void ThrowParserException(string message, Exception innerException)
{
throw new PdfReaderException(message, innerException);
}
public static void HandleUnexpectedCharacter(char ch)
{
// Hex formatting does not work with type char. It must be casted to integer.
string message = string.Format(CultureInfo.InvariantCulture,
"Unexpected character '0x{0:x4}' in PDF stream. The file may be corrupted. " +
"If you think this is a bug in PDFsharp, please send us your PDF file.", (int)ch);
ThrowParserException(message);
}
public static void HandleUnexpectedToken(string token)
{
string message = string.Format(CultureInfo.InvariantCulture,
"Unexpected token '{0}' in PDF stream. The file may be corrupted. " +
"If you think this is a bug in PDFsharp, please send us your PDF file.", token);
ThrowParserException(message);
}
}
internal static class ContentReaderDiagnostics
{
public static void ThrowContentReaderException(string message)
{
throw new ContentReaderException(message);
}
public static void ThrowContentReaderException(string message, Exception innerException)
{
throw new ContentReaderException(message, innerException);
}
public static void ThrowNumberOutOfIntegerRange(long value)
{
string message = string.Format(CultureInfo.InvariantCulture, "Number '{0}' out of integer range.", value);
ThrowContentReaderException(message);
}
public static void HandleUnexpectedCharacter(char ch)
{
string message = string.Format(CultureInfo.InvariantCulture,
"Unexpected character '0x{0:x4}' in content stream. The stream may be corrupted or the feature is not implemented. " +
"If you think this is a bug in PDFsharp, please send us your PDF file.", ch);
ThrowContentReaderException(message);
}
}
}
+140
View File
@@ -0,0 +1,140 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using PdfSharpCore.Drawing;
using PdfSharpCore.Fonts;
namespace PdfSharpCore.Internal
{
/// <summary>
/// A bunch of internal helper functions.
/// </summary>
internal static class DiagnosticsHelper
{
public static void HandleNotImplemented(string message)
{
string text = "Not implemented: " + message;
switch (Diagnostics.NotImplementedBehaviour)
{
case NotImplementedBehaviour.DoNothing:
break;
case NotImplementedBehaviour.Log:
Logger.Log(text);
break;
case NotImplementedBehaviour.Throw:
ThrowNotImplementedException(text);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
/// <summary>
/// Indirectly throws NotImplementedException.
/// Required because PDFsharp Release builds tread warnings as errors and
/// throwing NotImplementedException may lead to unreachable code which
/// crashes the build.
/// </summary>
public static void ThrowNotImplementedException(string message)
{
throw new NotImplementedException(message);
}
}
internal static class Logger
{
public static void Log(string format, params object[] args)
{
Debug.WriteLine("Log...");
}
}
class Logging
{
}
class Tracing
{
[Conditional("DEBUG")]
public void Foo()
{ }
}
/// <summary>
/// Helper class around the Debugger class.
/// </summary>
public static class DebugBreak
{
/// <summary>
/// Call Debugger.Break() if a debugger is attached.
/// </summary>
public static void Break()
{
Break(false);
}
/// <summary>
/// Call Debugger.Break() if a debugger is attached or when always is set to true.
/// </summary>
public static void Break(bool always)
{
if (always || Debugger.IsAttached)
Debugger.Break();
}
}
/// <summary>
/// Internal stuff for development of PdfSharpCore.
/// </summary>
public static class FontsDevHelper
{
/// <summary>
/// Creates font and enforces bold/italic simulation.
/// </summary>
public static XFont CreateSpecialFont(string familyName, double emSize, XFontStyle style,
XPdfFontOptions pdfOptions, XStyleSimulations styleSimulations)
{
return new XFont(familyName, emSize, style, pdfOptions, styleSimulations);
}
/// <summary>
/// Dumps the font caches to a string.
/// </summary>
public static string GetFontCachesState()
{
return FontFactory.GetFontCachesState();
}
}
}
+199
View File
@@ -0,0 +1,199 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Microsoft
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Runtime.InteropServices;
using PdfSharpCore.Drawing;
namespace PdfSharpCore.Internal
{
/// <summary>
/// Some floating point utilities. Partially reflected from WPF, later equalized with original source code.
/// </summary>
internal static class DoubleUtil
{
const double Epsilon = 2.2204460492503131E-16; // smallest such that 1.0 + Epsilon != 1.0
private const double TenTimesEpsilon = 10.0 * Epsilon;
const float FloatMinimum = 1.175494E-38f;
/// <summary>
/// Indicates whether the values are so close that they can be considered as equal.
/// </summary>
public static bool AreClose(double value1, double value2)
{
//if (value1 == value2)
if (value1.Equals(value2))
return true;
// This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < Epsilon
double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * Epsilon;
double delta = value1 - value2;
return (-eps < delta) && (eps > delta);
}
/// <summary>
/// Indicates whether the values are so close that they can be considered as equal.
/// </summary>
public static bool AreRoughlyEqual(double value1, double value2, int decimalPlace)
{
if (value1 == value2)
return true;
return Math.Abs(value1 - value2) < decs[decimalPlace];
}
static readonly double[] decs = { 1, 1E-1, 1E-2, 1E-3, 1E-4, 1E-5, 1E-6, 1E-7, 1E-8, 1E-9, 1E-10, 1E-11, 1E-12, 1E-13, 1E-14, 1E-15, 1E-16 };
/// <summary>
/// Indicates whether the values are so close that they can be considered as equal.
/// </summary>
public static bool AreClose(XPoint point1, XPoint point2)
{
return AreClose(point1.X, point2.X) && AreClose(point1.Y, point2.Y);
}
/// <summary>
/// Indicates whether the values are so close that they can be considered as equal.
/// </summary>
public static bool AreClose(XRect rect1, XRect rect2)
{
if (rect1.IsEmpty)
return rect2.IsEmpty;
return !rect2.IsEmpty && AreClose(rect1.X, rect2.X) && AreClose(rect1.Y, rect2.Y) &&
AreClose(rect1.Height, rect2.Height) && AreClose(rect1.Width, rect2.Width);
}
/// <summary>
/// Indicates whether the values are so close that they can be considered as equal.
/// </summary>
public static bool AreClose(XSize size1, XSize size2)
{
return AreClose(size1.Width, size2.Width) && AreClose(size1.Height, size2.Height);
}
/// <summary>
/// Indicates whether the values are so close that they can be considered as equal.
/// </summary>
public static bool AreClose(XVector vector1, XVector vector2)
{
return AreClose(vector1.X, vector2.X) && AreClose(vector1.Y, vector2.Y);
}
/// <summary>
/// Indicates whether value1 is greater than value2 and the values are not close to each other.
/// </summary>
public static bool GreaterThan(double value1, double value2)
{
return value1 > value2 && !AreClose(value1, value2);
}
/// <summary>
/// Indicates whether value1 is greater than value2 or the values are close to each other.
/// </summary>
public static bool GreaterThanOrClose(double value1, double value2)
{
return value1 > value2 || AreClose(value1, value2);
}
/// <summary>
/// Indicates whether value1 is less than value2 and the values are not close to each other.
/// </summary>
public static bool LessThan(double value1, double value2)
{
return value1 < value2 && !AreClose(value1, value2);
}
/// <summary>
/// Indicates whether value1 is less than value2 or the values are close to each other.
/// </summary>
public static bool LessThanOrClose(double value1, double value2)
{
return value1 < value2 || AreClose(value1, value2);
}
/// <summary>
/// Indicates whether the value is between 0 and 1 or close to 0 or 1.
/// </summary>
public static bool IsBetweenZeroAndOne(double value)
{
return GreaterThanOrClose(value, 0) && LessThanOrClose(value, 1);
}
/// <summary>
/// Indicates whether the value is not a number.
/// </summary>
public static bool IsNaN(double value)
{
NanUnion t = new NanUnion();
t.DoubleValue = value;
ulong exp = t.UintValue & 0xfff0000000000000;
ulong man = t.UintValue & 0x000fffffffffffff;
return (exp == 0x7ff0000000000000 || exp == 0xfff0000000000000) && (man != 0);
}
/// <summary>
/// Indicates whether at least one of the four rectangle values is not a number.
/// </summary>
public static bool RectHasNaN(XRect r)
{
return IsNaN(r.X) || IsNaN(r.Y) || IsNaN(r.Height) || IsNaN(r.Width);
}
/// <summary>
/// Indicates whether the value is 1 or close to 1.
/// </summary>
public static bool IsOne(double value)
{
return Math.Abs(value - 1.0) < TenTimesEpsilon;
}
/// <summary>
/// Indicates whether the value is 0 or close to 0.
/// </summary>
public static bool IsZero(double value)
{
return Math.Abs(value) < TenTimesEpsilon;
}
/// <summary>
/// Converts a double to integer.
/// </summary>
public static int DoubleToInt(double value)
{
return 0 < value ? (int)(value + 0.5) : (int)(value - 0.5);
}
[StructLayout(LayoutKind.Explicit)]
struct NanUnion
{
[FieldOffset(0)]
internal double DoubleValue;
[FieldOffset(0)]
internal readonly ulong UintValue;
}
}
}
+17
View File
@@ -0,0 +1,17 @@
using System.Collections.Generic;
using PdfSharpCore.Drawing;
namespace PdfSharpCore.Internal
{
public class FontFamilyModel
{
public string Name { get; set; }
public Dictionary<XFontStyle, string> FontFiles = new Dictionary<XFontStyle, string>();
public bool IsStyleAvailable(XFontStyle fontStyle)
{
return FontFiles.ContainsKey(fontStyle);
}
}
}
+75
View File
@@ -0,0 +1,75 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.ComponentModel;
using System.Threading;
using PdfSharpCore.Pdf.Internal;
namespace PdfSharpCore.Internal
{
/// <summary>
/// Static locking functions to make PDFsharp thread save.
/// </summary>
internal static class Lock
{
public static void EnterGdiPlus()
{
//if (_fontFactoryLockCount > 0)
// throw new InvalidOperationException("");
Monitor.Enter(GdiPlus);
_gdiPlusLockCount++;
}
public static void ExitGdiPlus()
{
_gdiPlusLockCount--;
Monitor.Exit(GdiPlus);
}
static readonly object GdiPlus = new object();
static int _gdiPlusLockCount;
public static void EnterFontFactory()
{
Monitor.Enter(FontFactory);
_fontFactoryLockCount++;
}
public static void ExitFontFactory()
{
_fontFactoryLockCount--;
Monitor.Exit(FontFactory);
}
static readonly object FontFactory = new object();
[ThreadStatic]
static int _fontFactoryLockCount;
}
}
+255
View File
@@ -0,0 +1,255 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Microsoft
//
// Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany)
//
// http://www.PdfSharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Globalization;
namespace PdfSharpCore.Internal
{
// Reflected from WPF to ensure compatibility
// Use netmassdownloader -d "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0" -output g:\cachetest -v
class TokenizerHelper
{
/// <summary>
/// Initializes a new instance of the <see cref="TokenizerHelper"/> class.
/// </summary>
public TokenizerHelper(string str, IFormatProvider formatProvider)
{
char numericListSeparator = GetNumericListSeparator(formatProvider);
Initialize(str, '\'', numericListSeparator);
}
/// <summary>
/// Initializes a new instance of the <see cref="TokenizerHelper"/> class.
/// </summary>
public TokenizerHelper(string str, char quoteChar, char separator)
{
Initialize(str, quoteChar, separator);
}
void Initialize(string str, char quoteChar, char separator)
{
_str = str;
_strLen = str == null ? 0 : str.Length;
_currentTokenIndex = -1;
_quoteChar = quoteChar;
_argSeparator = separator;
// Skip any whitespace.
while (_charIndex < _strLen)
{
if (!char.IsWhiteSpace(_str, _charIndex))
return;
_charIndex++;
}
}
public string NextTokenRequired()
{
if (!NextToken(false))
throw new InvalidOperationException("PrematureStringTermination"); //SR.Get(SRID.TokenizerHelperPrematureStringTermination, new object[0]));
return GetCurrentToken();
}
public string NextTokenRequired(bool allowQuotedToken)
{
if (!NextToken(allowQuotedToken))
throw new InvalidOperationException("PrematureStringTermination"); //SR.Get(SRID.TokenizerHelperPrematureStringTermination, new object[0]));
return GetCurrentToken();
}
public string GetCurrentToken()
{
if (_currentTokenIndex < 0)
return null;
return _str.Substring(_currentTokenIndex, _currentTokenLength);
}
public void LastTokenRequired()
{
if (_charIndex != _strLen)
throw new InvalidOperationException("Extra data encountered"); //SR.Get(SRID.TokenizerHelperExtraDataEncountered, new object[0]));
}
/// <summary>
/// Move to next token.
/// </summary>
public bool NextToken()
{
return NextToken(false);
}
/// <summary>
/// Move to next token.
/// </summary>
public bool NextToken(bool allowQuotedToken)
{
return NextToken(allowQuotedToken, _argSeparator);
}
public bool NextToken(bool allowQuotedToken, char separator)
{
// Reset index.
_currentTokenIndex = -1;
_foundSeparator = false;
// Already at the end of the string?
if (_charIndex >= _strLen)
return false;
char currentChar = _str[_charIndex];
// Setup the quoteCount .
int quoteCount = 0;
// If we are allowing a quoted token and this token begins with a quote,
// set up the quote count and skip the initial quote
if (allowQuotedToken &&
currentChar == _quoteChar)
{
quoteCount++;
_charIndex++;
}
int newTokenIndex = _charIndex;
int newTokenLength = 0;
// Loop until hit end of string or hit a separator or whitespace.
while (_charIndex < _strLen)
{
currentChar = _str[_charIndex];
// If have a quoteCount and this is a quote decrement the quoteCount.
if (quoteCount > 0)
{
// If anything but a quoteChar we move on.
if (currentChar == _quoteChar)
{
quoteCount--;
// If at zero which it always should for now break out of the loop.
if (quoteCount == 0)
{
++_charIndex;
break;
}
}
}
else if ((char.IsWhiteSpace(currentChar)) || (currentChar == separator))
{
if (currentChar == separator)
_foundSeparator = true;
break;
}
_charIndex++;
newTokenLength++;
}
// If quoteCount isn't zero we hit the end of the string before the ending quote.
if (quoteCount > 0)
throw new InvalidOperationException("Missing end quote"); //SR.Get(SRID.TokenizerHelperMissingEndQuote, new object[0]));
// Move at the start of the nextToken.
ScanToNextToken(separator);
// Update the _currentToken values.
_currentTokenIndex = newTokenIndex;
_currentTokenLength = newTokenLength;
if (_currentTokenLength < 1)
throw new InvalidOperationException("Empty token"); // SR.Get(SRID.TokenizerHelperEmptyToken, new object[0]));
return true;
}
private void ScanToNextToken(char separator)
{
// Do nothing if already at end of the string.
if (_charIndex < _strLen)
{
char currentChar = _str[_charIndex];
// Ensure that currentChar is a white space or separator.
if (currentChar != separator && !char.IsWhiteSpace(currentChar))
throw new InvalidOperationException("ExtraDataEncountered"); //SR.Get(SRID.TokenizerHelperExtraDataEncountered, new object[0]));
// Loop until a character that isn't the separator or white space.
int argSepCount = 0;
while (_charIndex < _strLen)
{
currentChar = _str[_charIndex];
if (currentChar == separator)
{
_foundSeparator = true;
argSepCount++;
_charIndex++;
if (argSepCount > 1)
throw new InvalidOperationException("EmptyToken"); //SR.Get(SRID.TokenizerHelperEmptyToken, new object[0]));
}
else if (char.IsWhiteSpace(currentChar))
{
// Skip white space.
++_charIndex;
}
else
break;
}
// If there was a separatorChar then we shouldn't be at the end of string or means there was a separator but there isn't an arg.
if (argSepCount > 0 && _charIndex >= _strLen)
throw new InvalidOperationException("EmptyToken"); // SR.Get(SRID.TokenizerHelperEmptyToken, new object[0]));
}
}
public static char GetNumericListSeparator(IFormatProvider provider)
{
char numericSeparator = ',';
NumberFormatInfo numberFormat = NumberFormatInfo.GetInstance(provider);
if (numberFormat.NumberDecimalSeparator.Length > 0 && numericSeparator == numberFormat.NumberDecimalSeparator[0])
numericSeparator = ';';
return numericSeparator;
}
public bool FoundSeparator
{
get { return _foundSeparator; }
}
bool _foundSeparator;
char _argSeparator;
int _charIndex;
int _currentTokenIndex;
int _currentTokenLength;
char _quoteChar;
string _str;
int _strLen;
}
}