mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
make converter public and add separation color space
This commit is contained in:
@@ -103,6 +103,13 @@
|
|||||||
"UglyToad.PdfPig.Graphics.Colors.GrayColor",
|
"UglyToad.PdfPig.Graphics.Colors.GrayColor",
|
||||||
"UglyToad.PdfPig.Graphics.Colors.IColor",
|
"UglyToad.PdfPig.Graphics.Colors.IColor",
|
||||||
"UglyToad.PdfPig.Graphics.Colors.RGBColor",
|
"UglyToad.PdfPig.Graphics.Colors.RGBColor",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.ColorSpaceDetails",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.DeviceGrayColorSpaceDetails",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.DeviceRgbColorSpaceDetails",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.DeviceCmykColorSpaceDetails",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.IndexedColorSpaceDetails",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.SeparationColorSpaceDetails",
|
||||||
|
"UglyToad.PdfPig.Graphics.Colors.UnsupportedColorSpaceDetails",
|
||||||
"UglyToad.PdfPig.Graphics.Core.LineCapStyle",
|
"UglyToad.PdfPig.Graphics.Core.LineCapStyle",
|
||||||
"UglyToad.PdfPig.Graphics.Core.LineDashPattern",
|
"UglyToad.PdfPig.Graphics.Core.LineDashPattern",
|
||||||
"UglyToad.PdfPig.Graphics.Core.LineJoinStyle",
|
"UglyToad.PdfPig.Graphics.Core.LineJoinStyle",
|
||||||
@@ -187,6 +194,7 @@
|
|||||||
"UglyToad.PdfPig.Graphics.Operations.TextState.Type3SetGlyphWidth",
|
"UglyToad.PdfPig.Graphics.Operations.TextState.Type3SetGlyphWidth",
|
||||||
"UglyToad.PdfPig.Graphics.Operations.TextState.Type3SetGlyphWidthAndBoundingBox",
|
"UglyToad.PdfPig.Graphics.Operations.TextState.Type3SetGlyphWidthAndBoundingBox",
|
||||||
"UglyToad.PdfPig.Graphics.TextMatrices",
|
"UglyToad.PdfPig.Graphics.TextMatrices",
|
||||||
|
"UglyToad.PdfPig.Images.ColorSpaceDetailsByteConverter",
|
||||||
"UglyToad.PdfPig.Logging.ILog",
|
"UglyToad.PdfPig.Logging.ILog",
|
||||||
"UglyToad.PdfPig.Outline.Bookmarks",
|
"UglyToad.PdfPig.Outline.Bookmarks",
|
||||||
"UglyToad.PdfPig.Outline.BookmarkNode",
|
"UglyToad.PdfPig.Outline.BookmarkNode",
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using PdfPig.Core;
|
||||||
|
using Tokens;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains more document-specific information about the <see cref="ColorSpace"/>.
|
/// Contains more document-specific information about the <see cref="ColorSpace"/>.
|
||||||
@@ -112,6 +114,59 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A Separation color space provides a means for specifying the use of additional colorants or
|
||||||
|
/// for isolating the control of individual color components of a device color space for a subtractive device.
|
||||||
|
/// When such a space is the current color space, the current color is a single-component value, called a tint,
|
||||||
|
/// that controls the application of the given colorant or color components only.
|
||||||
|
/// </summary>
|
||||||
|
public class SeparationColorSpaceDetails : ColorSpaceDetails
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the name of the colorant that this Separation color space is intended to represent.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// The special colorant name All refers collectively to all colorants available on an output device,
|
||||||
|
/// including those for the standard process colorants.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// The special colorant name None never produces any visible output.
|
||||||
|
/// Painting operations in a Separation space with this colorant name have no effect on the current page.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public NameToken Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the colorant name associated with a Separation color space does not correspond to a colorant available on the device,
|
||||||
|
/// the application arranges for subsequent painting operations to be performed in an alternate color space.
|
||||||
|
/// The intended colors can be approximated by colors in a device or CIE-based color space
|
||||||
|
/// which are then rendered with the usual primary or process colorants.
|
||||||
|
/// </summary>
|
||||||
|
public ColorSpaceDetails AlternateColorSpaceDetails { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// During subsequent painting operations, an application calls this function to transform a tint value into
|
||||||
|
/// color component values in the alternate color space.
|
||||||
|
/// The function is called with the tint value and must return the corresponding color component values.
|
||||||
|
/// That is, the number of components and the interpretation of their values depend on the <see cref="AlternateColorSpaceDetails"/>.
|
||||||
|
/// </summary>
|
||||||
|
public Union<DictionaryToken, StreamToken> TintFunction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="SeparationColorSpaceDetails"/>.
|
||||||
|
/// </summary>
|
||||||
|
public SeparationColorSpaceDetails(NameToken name,
|
||||||
|
ColorSpaceDetails alternateColorSpaceDetails,
|
||||||
|
Union<DictionaryToken, StreamToken> tintFunction)
|
||||||
|
: base(ColorSpace.Separation)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
AlternateColorSpaceDetails = alternateColorSpaceDetails;
|
||||||
|
TintFunction = tintFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A ColorSpace which the PdfPig library does not currently support. Please raise a PR if you need support for this ColorSpace.
|
/// A ColorSpace which the PdfPig library does not currently support. Please raise a PR if you need support for this ColorSpace.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -3,12 +3,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content;
|
||||||
|
using Core;
|
||||||
using Graphics.Colors;
|
using Graphics.Colors;
|
||||||
|
|
||||||
internal static class ColorSpaceDetailsByteConverter
|
/// <summary>
|
||||||
|
/// Utility for working with the bytes in <see cref="IPdfImage"/>s and converting according to their <see cref="ColorSpaceDetails"/>.s
|
||||||
|
/// </summary>
|
||||||
|
public static class ColorSpaceDetailsByteConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the output bytes (if available) of <see cref="IPdfImage.TryGetBytes"/>
|
||||||
|
/// to actual pixel values using the <see cref="IPdfImage.ColorSpaceDetails"/>. For most images this doesn't
|
||||||
|
/// change the data but for <see cref="ColorSpace.Indexed"/> it will convert the bytes which are indexes into the
|
||||||
|
/// real pixel data into the real pixel data.
|
||||||
|
/// </summary>
|
||||||
public static byte[] Convert(ColorSpaceDetails details, IReadOnlyList<byte> decoded)
|
public static byte[] Convert(ColorSpaceDetails details, IReadOnlyList<byte> decoded)
|
||||||
{
|
{
|
||||||
|
if (decoded == null)
|
||||||
|
{
|
||||||
|
return EmptyArray<byte>.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (details == null)
|
||||||
|
{
|
||||||
|
return decoded.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
switch (details)
|
switch (details)
|
||||||
{
|
{
|
||||||
case IndexedColorSpaceDetails indexed:
|
case IndexedColorSpaceDetails indexed:
|
||||||
@@ -41,7 +62,7 @@
|
|||||||
transformer = x =>
|
transformer = x =>
|
||||||
{
|
{
|
||||||
var r = new byte[4];
|
var r = new byte[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (var i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
r[i] = indexed.ColorTable[x * 4 + i];
|
r[i] = indexed.ColorTable[x * 4 + i];
|
||||||
}
|
}
|
||||||
@@ -52,7 +73,7 @@
|
|||||||
multiplier = 4;
|
multiplier = 4;
|
||||||
break;
|
break;
|
||||||
case ColorSpace.DeviceGray:
|
case ColorSpace.DeviceGray:
|
||||||
transformer = x => new[] {indexed.ColorTable[x]};
|
transformer = x => new[] { indexed.ColorTable[x] };
|
||||||
multiplier = 1;
|
multiplier = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content;
|
using Content;
|
||||||
|
using Core;
|
||||||
using Filters;
|
using Filters;
|
||||||
using Graphics.Colors;
|
using Graphics.Colors;
|
||||||
using Parser.Parts;
|
using Parser.Parts;
|
||||||
@@ -135,10 +136,11 @@
|
|||||||
&& baseColorSpaceArrayToken.Length > 0 && baseColorSpaceArrayToken[0] is NameToken baseColorSpaceArrayNameToken
|
&& baseColorSpaceArrayToken.Length > 0 && baseColorSpaceArrayToken[0] is NameToken baseColorSpaceArrayNameToken
|
||||||
&& ColorSpaceMapper.TryMap(baseColorSpaceArrayNameToken, resourceStore, out var baseColorSpaceArrayColorSpace))
|
&& ColorSpaceMapper.TryMap(baseColorSpaceArrayNameToken, resourceStore, out var baseColorSpaceArrayColorSpace))
|
||||||
{
|
{
|
||||||
var pseudoImageDictionary = new DictionaryToken(new Dictionary<NameToken, IToken>
|
var pseudoImageDictionary = new DictionaryToken(
|
||||||
{
|
new Dictionary<NameToken, IToken>
|
||||||
{NameToken.ColorSpace, baseColorSpaceArrayToken}
|
{
|
||||||
});
|
{NameToken.ColorSpace, baseColorSpaceArrayToken}
|
||||||
|
});
|
||||||
|
|
||||||
baseDetails = GetColorSpaceDetails(
|
baseDetails = GetColorSpaceDetails(
|
||||||
baseColorSpaceArrayColorSpace,
|
baseColorSpaceArrayColorSpace,
|
||||||
@@ -189,7 +191,79 @@
|
|||||||
case ColorSpace.Pattern:
|
case ColorSpace.Pattern:
|
||||||
return UnsupportedColorSpaceDetails.Instance;
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
case ColorSpace.Separation:
|
case ColorSpace.Separation:
|
||||||
return UnsupportedColorSpaceDetails.Instance;
|
{
|
||||||
|
if (!imageDictionary.TryGet(NameToken.ColorSpace, scanner, out ArrayToken colorSpaceArray)
|
||||||
|
|| colorSpaceArray.Length != 4)
|
||||||
|
{
|
||||||
|
// Error instead?
|
||||||
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DirectObjectFinder.TryGet(colorSpaceArray[0], scanner, out NameToken separationColorSpaceNameToken)
|
||||||
|
|| !separationColorSpaceNameToken.Equals(NameToken.Separation))
|
||||||
|
{
|
||||||
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DirectObjectFinder.TryGet(colorSpaceArray[1], scanner, out NameToken separationNameToken))
|
||||||
|
{
|
||||||
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorSpaceDetails alternateColorSpaceDetails;
|
||||||
|
if (DirectObjectFinder.TryGet(colorSpaceArray[2], scanner, out NameToken alternateNameToken)
|
||||||
|
&& ColorSpaceMapper.TryMap(alternateNameToken, resourceStore, out var baseColorSpaceName))
|
||||||
|
{
|
||||||
|
alternateColorSpaceDetails = GetColorSpaceDetails(
|
||||||
|
baseColorSpaceName,
|
||||||
|
imageDictionary,
|
||||||
|
scanner,
|
||||||
|
resourceStore,
|
||||||
|
filterProvider,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
else if (DirectObjectFinder.TryGet(colorSpaceArray[2], scanner, out ArrayToken alternateArrayToken)
|
||||||
|
&& alternateArrayToken.Length > 0
|
||||||
|
&& alternateArrayToken[0] is NameToken alternateColorSpaceNameToken
|
||||||
|
&& ColorSpaceMapper.TryMap(alternateColorSpaceNameToken, resourceStore, out var alternateArrayColorSpace))
|
||||||
|
{
|
||||||
|
var pseudoImageDictionary = new DictionaryToken(
|
||||||
|
new Dictionary<NameToken, IToken>
|
||||||
|
{
|
||||||
|
{NameToken.ColorSpace, alternateArrayToken}
|
||||||
|
});
|
||||||
|
|
||||||
|
alternateColorSpaceDetails = GetColorSpaceDetails(
|
||||||
|
alternateArrayColorSpace,
|
||||||
|
pseudoImageDictionary,
|
||||||
|
scanner,
|
||||||
|
resourceStore,
|
||||||
|
filterProvider,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Union<DictionaryToken, StreamToken> functionTokensUnion;
|
||||||
|
var func = colorSpaceArray[3];
|
||||||
|
|
||||||
|
if (DirectObjectFinder.TryGet(func, scanner, out DictionaryToken functionDictionary))
|
||||||
|
{
|
||||||
|
functionTokensUnion = Union<DictionaryToken, StreamToken>.One(functionDictionary);
|
||||||
|
}
|
||||||
|
else if (DirectObjectFinder.TryGet(func, scanner, out StreamToken functionStream))
|
||||||
|
{
|
||||||
|
functionTokensUnion = Union<DictionaryToken, StreamToken>.Two(functionStream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SeparationColorSpaceDetails(separationNameToken, alternateColorSpaceDetails, functionTokensUnion);
|
||||||
|
}
|
||||||
case ColorSpace.DeviceN:
|
case ColorSpace.DeviceN:
|
||||||
return UnsupportedColorSpaceDetails.Instance;
|
return UnsupportedColorSpaceDetails.Instance;
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user