mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-15 10:50:18 +01:00
Adjust graphic state according to the PDF 2.0 specification
This commit is contained in:
parent
8262654b0e
commit
c033de6917
@ -79,6 +79,13 @@ static constexpr const char* ICCBASED_ALTERNATE = "Alternate";
|
|||||||
static constexpr const char* ICCBASED_N = "N";
|
static constexpr const char* ICCBASED_N = "N";
|
||||||
static constexpr const char* ICCBASED_RANGE = "Range";
|
static constexpr const char* ICCBASED_RANGE = "Range";
|
||||||
|
|
||||||
|
enum class BlackPointCompensationMode
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
ON,
|
||||||
|
OFF
|
||||||
|
};
|
||||||
|
|
||||||
/// Image raw data - containing data for image. Image data are row-ordered, and by components.
|
/// Image raw data - containing data for image. Image data are row-ordered, and by components.
|
||||||
/// So the row can be for 3-components RGB like 'RGBRGBRGB...RGB', where size of row in bytes is 3 * width of image.
|
/// So the row can be for 3-components RGB like 'RGBRGBRGB...RGB', where size of row in bytes is 3 * width of image.
|
||||||
class PDFImageData
|
class PDFImageData
|
||||||
|
@ -1722,7 +1722,7 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
const PDFReal lineWidth = loader.readNumberFromDictionary(graphicStateDictionary, "LW", m_graphicState.getLineWidth());
|
const PDFReal lineWidth = loader.readNumberFromDictionary(graphicStateDictionary, "LW", m_graphicState.getLineWidth());
|
||||||
const Qt::PenCapStyle penCapStyle = convertLineCapToPenCapStyle(loader.readNumberFromDictionary(graphicStateDictionary, "LC", convertPenCapStyleToLineCap(m_graphicState.getLineCapStyle())));
|
const Qt::PenCapStyle penCapStyle = convertLineCapToPenCapStyle(loader.readNumberFromDictionary(graphicStateDictionary, "LC", convertPenCapStyleToLineCap(m_graphicState.getLineCapStyle())));
|
||||||
const Qt::PenJoinStyle penJoinStyle = convertLineJoinToPenJoinStyle(loader.readNumberFromDictionary(graphicStateDictionary, "LJ", convertPenJoinStyleToLineJoin(m_graphicState.getLineJoinStyle())));
|
const Qt::PenJoinStyle penJoinStyle = convertLineJoinToPenJoinStyle(loader.readNumberFromDictionary(graphicStateDictionary, "LJ", convertPenJoinStyleToLineJoin(m_graphicState.getLineJoinStyle())));
|
||||||
const PDFReal mitterLimit = loader.readNumberFromDictionary(graphicStateDictionary, "MT", m_graphicState.getMitterLimit());
|
const PDFReal mitterLimit = loader.readNumberFromDictionary(graphicStateDictionary, "ML", m_graphicState.getMitterLimit());
|
||||||
|
|
||||||
const PDFObject& lineDashPatternObject = m_document->getObject(graphicStateDictionary->get("D"));
|
const PDFObject& lineDashPatternObject = m_document->getObject(graphicStateDictionary->get("D"));
|
||||||
if (lineDashPatternObject.isArray())
|
if (lineDashPatternObject.isArray())
|
||||||
@ -1731,6 +1731,7 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
if (lineDashPatternDefinitionArray->getCount() == 2)
|
if (lineDashPatternDefinitionArray->getCount() == 2)
|
||||||
{
|
{
|
||||||
PDFLineDashPattern pattern(loader.readNumberArray(lineDashPatternDefinitionArray->getItem(0)), loader.readNumber(lineDashPatternDefinitionArray->getItem(1), 0.0));
|
PDFLineDashPattern pattern(loader.readNumberArray(lineDashPatternDefinitionArray->getItem(0)), loader.readNumber(lineDashPatternDefinitionArray->getItem(1), 0.0));
|
||||||
|
pattern.fix();
|
||||||
m_graphicState.setLineDashPattern(pattern);
|
m_graphicState.setLineDashPattern(pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1744,7 +1745,7 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
QByteArray renderingIntentName = loader.readNameFromDictionary(graphicStateDictionary, "RI");
|
QByteArray renderingIntentName = loader.readNameFromDictionary(graphicStateDictionary, "RI");
|
||||||
const bool alphaIsShape = loader.readBooleanFromDictionary(graphicStateDictionary, "AIS", m_graphicState.getAlphaIsShape());
|
const bool alphaIsShape = loader.readBooleanFromDictionary(graphicStateDictionary, "AIS", m_graphicState.getAlphaIsShape());
|
||||||
const bool strokeAdjustment = loader.readBooleanFromDictionary(graphicStateDictionary, "SA", m_graphicState.getStrokeAdjustment());
|
const bool strokeAdjustment = loader.readBooleanFromDictionary(graphicStateDictionary, "SA", m_graphicState.getStrokeAdjustment());
|
||||||
const PDFDictionary* softMask = m_document->getDictionaryFromObject(graphicStateDictionary->get("SMask"));
|
const PDFDictionary* softMask = graphicStateDictionary->hasKey("SMask") ? m_document->getDictionaryFromObject(graphicStateDictionary->get("SMask")) : m_graphicState.getSoftMask();
|
||||||
|
|
||||||
// We will try to get blend mode name from the array (if BM is array). First supported blend mode should
|
// We will try to get blend mode name from the array (if BM is array). First supported blend mode should
|
||||||
// be used. In PDF 2.0, array is deprecated, so for backward compatibility, we extract first blend mode
|
// be used. In PDF 2.0, array is deprecated, so for backward compatibility, we extract first blend mode
|
||||||
@ -1777,11 +1778,63 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
|
|
||||||
PDFOverprintMode overprintMode = m_graphicState.getOverprintMode();
|
PDFOverprintMode overprintMode = m_graphicState.getOverprintMode();
|
||||||
overprintMode.overprintMode = loader.readIntegerFromDictionary(graphicStateDictionary, "OPM", overprintMode.overprintMode);
|
overprintMode.overprintMode = loader.readIntegerFromDictionary(graphicStateDictionary, "OPM", overprintMode.overprintMode);
|
||||||
if (graphicStateDictionary->hasKey("OP"))
|
|
||||||
|
// Overprint for filling is ruled by overprint for stroking, if "op" is not present, according to the specification
|
||||||
|
overprintMode.overprintStroking = loader.readBooleanFromDictionary(graphicStateDictionary, "OP", overprintMode.overprintStroking);
|
||||||
|
overprintMode.overprintFilling = loader.readBooleanFromDictionary(graphicStateDictionary, "op", overprintMode.overprintStroking);
|
||||||
|
|
||||||
|
constexpr std::array blackPointCompensationModes = {
|
||||||
|
std::pair<const char*, BlackPointCompensationMode>{ "Default", BlackPointCompensationMode::Default },
|
||||||
|
std::pair<const char*, BlackPointCompensationMode>{ "ON", BlackPointCompensationMode::ON },
|
||||||
|
std::pair<const char*, BlackPointCompensationMode>{ "OFF", BlackPointCompensationMode::OFF },
|
||||||
|
};
|
||||||
|
|
||||||
|
BlackPointCompensationMode blackPointCompensationMode = m_graphicState.getBlackPointCompensationMode();
|
||||||
|
if (graphicStateDictionary->hasKey("UseBlackPtComp"))
|
||||||
{
|
{
|
||||||
// Overprint for filling is ruled by overprint for stroking, if "op" is not present, according to the specification
|
blackPointCompensationMode = loader.readEnumByName(graphicStateDictionary->get("UseBlackPtComp"), blackPointCompensationModes.cbegin(), blackPointCompensationModes.cend(), BlackPointCompensationMode::Default);
|
||||||
overprintMode.overprintStroking = loader.readBooleanFromDictionary(graphicStateDictionary, "OP", overprintMode.overprintStroking);
|
}
|
||||||
overprintMode.overprintFilling = loader.readBooleanFromDictionary(graphicStateDictionary, "op", overprintMode.overprintStroking);
|
|
||||||
|
PDFObject blackGenerationFunctionObject = m_graphicState.getBlackGenerationFunction();
|
||||||
|
if (graphicStateDictionary->hasKey("BG") || graphicStateDictionary->hasKey("BG2"))
|
||||||
|
{
|
||||||
|
blackGenerationFunctionObject = m_document->getObject(graphicStateDictionary->get("BG2"));
|
||||||
|
if (blackGenerationFunctionObject.isNull())
|
||||||
|
{
|
||||||
|
blackGenerationFunctionObject = m_document->getObject(graphicStateDictionary->get("BG"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject undercolorRemovalFunctionObject = m_graphicState.getUndercolorRemovalFunction();
|
||||||
|
if (graphicStateDictionary->hasKey("UCR") || graphicStateDictionary->hasKey("UCR2"))
|
||||||
|
{
|
||||||
|
undercolorRemovalFunctionObject = m_document->getObject(graphicStateDictionary->get("UCR2"));
|
||||||
|
if (undercolorRemovalFunctionObject.isNull())
|
||||||
|
{
|
||||||
|
undercolorRemovalFunctionObject = m_document->getObject(graphicStateDictionary->get("UCR"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject transferFunctionObject = m_graphicState.getTransferFunction();
|
||||||
|
if (graphicStateDictionary->hasKey("TR") || graphicStateDictionary->hasKey("TR2"))
|
||||||
|
{
|
||||||
|
transferFunctionObject = m_document->getObject(graphicStateDictionary->get("TR2"));
|
||||||
|
if (transferFunctionObject.isNull())
|
||||||
|
{
|
||||||
|
transferFunctionObject = m_document->getObject(graphicStateDictionary->get("TR"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject halftoneObject = graphicStateDictionary->hasKey("HT") ? m_document->getObject(graphicStateDictionary->get("HT")) : m_graphicState.getHalftone();
|
||||||
|
|
||||||
|
QPointF halftoneOrigin = m_graphicState.getHalftoneOrigin();
|
||||||
|
if (graphicStateDictionary->hasKey("HTO"))
|
||||||
|
{
|
||||||
|
std::vector<PDFReal> halftoneOriginArray = loader.readNumberArrayFromDictionary(graphicStateDictionary, "HTO");
|
||||||
|
if (halftoneOriginArray.size() >= 2)
|
||||||
|
{
|
||||||
|
halftoneOrigin = QPointF(halftoneOriginArray[0], halftoneOriginArray[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_graphicState.setLineWidth(lineWidth);
|
m_graphicState.setLineWidth(lineWidth);
|
||||||
@ -1797,6 +1850,12 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
m_graphicState.setAlphaIsShape(alphaIsShape);
|
m_graphicState.setAlphaIsShape(alphaIsShape);
|
||||||
m_graphicState.setStrokeAdjustment(strokeAdjustment);
|
m_graphicState.setStrokeAdjustment(strokeAdjustment);
|
||||||
m_graphicState.setSoftMask(softMask);
|
m_graphicState.setSoftMask(softMask);
|
||||||
|
m_graphicState.setBlackPointCompensationMode(blackPointCompensationMode);
|
||||||
|
m_graphicState.setBlackGenerationFunction(qMove(blackGenerationFunctionObject));
|
||||||
|
m_graphicState.setUndercolorRemovalFunction(qMove(undercolorRemovalFunctionObject));
|
||||||
|
m_graphicState.setTransferFunction(qMove(transferFunctionObject));
|
||||||
|
m_graphicState.setHalftone(qMove(halftoneObject));
|
||||||
|
m_graphicState.setHalftoneOrigin(halftoneOrigin);
|
||||||
updateGraphicState();
|
updateGraphicState();
|
||||||
|
|
||||||
if (graphicStateDictionary->hasKey("Font"))
|
if (graphicStateDictionary->hasKey("Font"))
|
||||||
@ -3208,6 +3267,7 @@ PDFPageContentProcessor::PDFPageContentProcessorState::PDFPageContentProcessorSt
|
|||||||
m_alphaIsShape(false),
|
m_alphaIsShape(false),
|
||||||
m_strokeAdjustment(false),
|
m_strokeAdjustment(false),
|
||||||
m_softMask(nullptr),
|
m_softMask(nullptr),
|
||||||
|
m_blackPointCompensationMode(BlackPointCompensationMode::Default),
|
||||||
m_stateFlags(StateUnchanged)
|
m_stateFlags(StateUnchanged)
|
||||||
{
|
{
|
||||||
m_fillColorSpace.reset(new PDFDeviceGrayColorSpace);
|
m_fillColorSpace.reset(new PDFDeviceGrayColorSpace);
|
||||||
@ -3253,6 +3313,12 @@ PDFPageContentProcessor::PDFPageContentProcessorState& PDFPageContentProcessor::
|
|||||||
setAlphaIsShape(other.getAlphaIsShape());
|
setAlphaIsShape(other.getAlphaIsShape());
|
||||||
setStrokeAdjustment(other.getStrokeAdjustment());
|
setStrokeAdjustment(other.getStrokeAdjustment());
|
||||||
setSoftMask(other.getSoftMask());
|
setSoftMask(other.getSoftMask());
|
||||||
|
setBlackPointCompensationMode(other.getBlackPointCompensationMode());
|
||||||
|
setBlackGenerationFunction(other.getBlackGenerationFunction());
|
||||||
|
setUndercolorRemovalFunction(other.getUndercolorRemovalFunction());
|
||||||
|
setTransferFunction(other.getTransferFunction());
|
||||||
|
setHalftone(other.getHalftone());
|
||||||
|
setHalftoneOrigin(other.getHalftoneOrigin());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3505,6 +3571,90 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setSoftMask(const PD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlackPointCompensationMode PDFPageContentProcessor::PDFPageContentProcessorState::getBlackPointCompensationMode() const
|
||||||
|
{
|
||||||
|
return m_blackPointCompensationMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setBlackPointCompensationMode(BlackPointCompensationMode blackPointCompensationMode)
|
||||||
|
{
|
||||||
|
if (m_blackPointCompensationMode != blackPointCompensationMode)
|
||||||
|
{
|
||||||
|
m_blackPointCompensationMode = blackPointCompensationMode;
|
||||||
|
m_stateFlags |= StateBlackPointCompensation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getHalftone() const
|
||||||
|
{
|
||||||
|
return m_halftone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setHalftone(const PDFObject& halftone)
|
||||||
|
{
|
||||||
|
if (m_halftone != halftone)
|
||||||
|
{
|
||||||
|
m_halftone = halftone;
|
||||||
|
m_stateFlags |= StateHalftone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PDFPageContentProcessor::PDFPageContentProcessorState::getHalftoneOrigin() const
|
||||||
|
{
|
||||||
|
return m_halftoneOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setHalftoneOrigin(const QPointF& halftoneOrigin)
|
||||||
|
{
|
||||||
|
if (m_halftoneOrigin != halftoneOrigin)
|
||||||
|
{
|
||||||
|
m_halftoneOrigin = halftoneOrigin;
|
||||||
|
m_stateFlags |= StateHalftoneOrigin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getTransferFunction() const
|
||||||
|
{
|
||||||
|
return m_transferFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setTransferFunction(const PDFObject& transferFunction)
|
||||||
|
{
|
||||||
|
if (m_transferFunction != transferFunction)
|
||||||
|
{
|
||||||
|
m_transferFunction = transferFunction;
|
||||||
|
m_stateFlags |= StateTransferFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getUndercolorRemovalFunction() const
|
||||||
|
{
|
||||||
|
return m_undercolorRemovalFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setUndercolorRemovalFunction(const PDFObject& undercolorRemovalFunction)
|
||||||
|
{
|
||||||
|
if (m_undercolorRemovalFunction != undercolorRemovalFunction)
|
||||||
|
{
|
||||||
|
m_undercolorRemovalFunction = undercolorRemovalFunction;
|
||||||
|
m_stateFlags |= StateUndercolorRemovalFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getBlackGenerationFunction() const
|
||||||
|
{
|
||||||
|
return m_blackGenerationFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setBlackGenerationFunction(const PDFObject& blackGenerationFunction)
|
||||||
|
{
|
||||||
|
if (m_blackGenerationFunction != blackGenerationFunction)
|
||||||
|
{
|
||||||
|
m_blackGenerationFunction = blackGenerationFunction;
|
||||||
|
m_stateFlags |= StateBlackGenerationFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextMatrix(const QMatrix& textMatrix)
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextMatrix(const QMatrix& textMatrix)
|
||||||
{
|
{
|
||||||
if (m_textMatrix != textMatrix)
|
if (m_textMatrix != textMatrix)
|
||||||
@ -3613,4 +3763,35 @@ PDFPageContentProcessor::PDFTransparencyGroupGuard::~PDFTransparencyGroupGuard()
|
|||||||
m_processor->performEndTransparencyGroup(ProcessOrder::AfterOperation, group);
|
m_processor->performEndTransparencyGroup(ProcessOrder::AfterOperation, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFLineDashPattern::PDFLineDashPattern(const std::vector<PDFReal>& dashArray, PDFReal dashOffset) :
|
||||||
|
m_dashArray(dashArray),
|
||||||
|
m_dashOffset(dashOffset)
|
||||||
|
{
|
||||||
|
if (m_dashArray.size() % 2 == 1)
|
||||||
|
{
|
||||||
|
m_dashArray.push_back(m_dashArray.back());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFLineDashPattern::fix()
|
||||||
|
{
|
||||||
|
if (m_dashOffset < 0.0)
|
||||||
|
{
|
||||||
|
// According to the PDF 2.0 specification, if dash offset is negative,
|
||||||
|
// then twice of sum of lengths in the dash array should be added
|
||||||
|
// so dash offset will become positive.
|
||||||
|
|
||||||
|
const PDFReal totalLength = 2 * std::accumulate(m_dashArray.cbegin(), m_dashArray.cend(), 0.0);
|
||||||
|
if (totalLength > 0.0)
|
||||||
|
{
|
||||||
|
m_dashOffset += (std::floor(std::abs(m_dashOffset / totalLength)) + 1.0) * totalLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Reset to default solid line, dash pattern is invalid
|
||||||
|
*this = PDFLineDashPattern();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -48,15 +48,7 @@ class PDFLineDashPattern
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit inline PDFLineDashPattern() = default;
|
explicit inline PDFLineDashPattern() = default;
|
||||||
explicit inline PDFLineDashPattern(const std::vector<PDFReal>& dashArray, PDFReal dashOffset) :
|
explicit PDFLineDashPattern(const std::vector<PDFReal>& dashArray, PDFReal dashOffset);
|
||||||
m_dashArray(dashArray),
|
|
||||||
m_dashOffset(dashOffset)
|
|
||||||
{
|
|
||||||
if (m_dashArray.size() % 2 == 1)
|
|
||||||
{
|
|
||||||
m_dashArray.push_back(m_dashArray.back());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const std::vector<PDFReal>& getDashArray() const { return m_dashArray; }
|
inline const std::vector<PDFReal>& getDashArray() const { return m_dashArray; }
|
||||||
inline void setDashArray(const std::vector<PDFReal>& dashArray) { m_dashArray = dashArray; }
|
inline void setDashArray(const std::vector<PDFReal>& dashArray) { m_dashArray = dashArray; }
|
||||||
@ -70,6 +62,9 @@ public:
|
|||||||
/// Is line solid? Function returns true, if yes.
|
/// Is line solid? Function returns true, if yes.
|
||||||
bool isSolid() const { return m_dashArray.empty(); }
|
bool isSolid() const { return m_dashArray.empty(); }
|
||||||
|
|
||||||
|
/// Fix line dash pattern according to the specification
|
||||||
|
void fix();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<PDFReal> m_dashArray;
|
std::vector<PDFReal> m_dashArray;
|
||||||
PDFReal m_dashOffset = 0.0;
|
PDFReal m_dashOffset = 0.0;
|
||||||
@ -273,45 +268,51 @@ protected:
|
|||||||
PDFPageContentProcessorState& operator=(PDFPageContentProcessorState&&) = delete;
|
PDFPageContentProcessorState& operator=(PDFPageContentProcessorState&&) = delete;
|
||||||
PDFPageContentProcessorState& operator=(const PDFPageContentProcessorState& other);
|
PDFPageContentProcessorState& operator=(const PDFPageContentProcessorState& other);
|
||||||
|
|
||||||
enum StateFlag : uint32_t
|
enum StateFlag : uint64_t
|
||||||
{
|
{
|
||||||
StateUnchanged = 0x00000000,
|
StateUnchanged = 0x0000000000000000,
|
||||||
StateCurrentTransformationMatrix = 0x00000001,
|
StateCurrentTransformationMatrix = 0x0000000000000001,
|
||||||
StateStrokeColorSpace = 0x00000002,
|
StateStrokeColorSpace = 0x0000000000000002,
|
||||||
StateFillColorSpace = 0x00000004,
|
StateFillColorSpace = 0x0000000000000004,
|
||||||
StateStrokeColor = 0x00000008,
|
StateStrokeColor = 0x0000000000000008,
|
||||||
StateFillColor = 0x00000010,
|
StateFillColor = 0x0000000000000010,
|
||||||
StateLineWidth = 0x00000020,
|
StateLineWidth = 0x0000000000000020,
|
||||||
StateLineCapStyle = 0x00000040,
|
StateLineCapStyle = 0x0000000000000040,
|
||||||
StateLineJoinStyle = 0x00000080,
|
StateLineJoinStyle = 0x0000000000000080,
|
||||||
StateMitterLimit = 0x00000100,
|
StateMitterLimit = 0x0000000000000100,
|
||||||
StateLineDashPattern = 0x00000200,
|
StateLineDashPattern = 0x0000000000000200,
|
||||||
StateRenderingIntentName = 0x00000400,
|
StateRenderingIntentName = 0x0000000000000400,
|
||||||
StateFlatness = 0x00000800,
|
StateFlatness = 0x0000000000000800,
|
||||||
StateSmoothness = 0x00001000,
|
StateSmoothness = 0x0000000000001000,
|
||||||
StateTextMatrix = 0x00002000,
|
StateTextMatrix = 0x0000000000002000,
|
||||||
StateTextLineMatrix = 0x00004000,
|
StateTextLineMatrix = 0x0000000000004000,
|
||||||
StateTextCharacterSpacing = 0x00008000,
|
StateTextCharacterSpacing = 0x0000000000008000,
|
||||||
StateTextWordSpacing = 0x00010000,
|
StateTextWordSpacing = 0x0000000000010000,
|
||||||
StateTextHorizontalScaling = 0x00020000,
|
StateTextHorizontalScaling = 0x0000000000020000,
|
||||||
StateTextLeading = 0x00040000,
|
StateTextLeading = 0x0000000000040000,
|
||||||
StateTextFont = 0x00080000,
|
StateTextFont = 0x0000000000080000,
|
||||||
StateTextFontSize = 0x00100000,
|
StateTextFontSize = 0x0000000000100000,
|
||||||
StateTextRenderingMode = 0x00200000,
|
StateTextRenderingMode = 0x0000000000200000,
|
||||||
StateTextRise = 0x00400000,
|
StateTextRise = 0x0000000000400000,
|
||||||
StateTextKnockout = 0x00800000,
|
StateTextKnockout = 0x0000000000800000,
|
||||||
StateAlphaStroking = 0x01000000,
|
StateAlphaStroking = 0x0000000001000000,
|
||||||
StateAlphaFilling = 0x02000000,
|
StateAlphaFilling = 0x0000000002000000,
|
||||||
StateBlendMode = 0x04000000,
|
StateBlendMode = 0x0000000004000000,
|
||||||
StateRenderingIntent = 0x08000000,
|
StateRenderingIntent = 0x0000000008000000,
|
||||||
StateOverprint = 0x10000000,
|
StateOverprint = 0x0000000010000000,
|
||||||
StateAlphaIsShape = 0x20000000,
|
StateAlphaIsShape = 0x0000000020000000,
|
||||||
StateStrokeAdjustment = 0x40000000,
|
StateStrokeAdjustment = 0x0000000040000000,
|
||||||
StateSoftMask = 0x80000000,
|
StateSoftMask = 0x0000000080000000,
|
||||||
StateAll = 0xFFFFFFFF
|
StateBlackPointCompensation = 0x0000000100000000,
|
||||||
|
StateBlackGenerationFunction = 0x0000000200000000,
|
||||||
|
StateUndercolorRemovalFunction = 0x0000000400000000,
|
||||||
|
StateTransferFunction = 0x0000000800000000,
|
||||||
|
StateHalftone = 0x0000001000000000,
|
||||||
|
StateHalftoneOrigin = 0x0000002000000000,
|
||||||
|
StateAll = 0xFFFFFFFFFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(StateFlags, StateFlag)
|
using StateFlags = PDFFlags<StateFlag>;
|
||||||
|
|
||||||
const QMatrix& getCurrentTransformationMatrix() const { return m_currentTransformationMatrix; }
|
const QMatrix& getCurrentTransformationMatrix() const { return m_currentTransformationMatrix; }
|
||||||
void setCurrentTransformationMatrix(const QMatrix& currentTransformationMatrix);
|
void setCurrentTransformationMatrix(const QMatrix& currentTransformationMatrix);
|
||||||
@ -418,6 +419,24 @@ protected:
|
|||||||
const PDFDictionary* getSoftMask() const;
|
const PDFDictionary* getSoftMask() const;
|
||||||
void setSoftMask(const PDFDictionary* softMask);
|
void setSoftMask(const PDFDictionary* softMask);
|
||||||
|
|
||||||
|
BlackPointCompensationMode getBlackPointCompensationMode() const;
|
||||||
|
void setBlackPointCompensationMode(BlackPointCompensationMode blackPointCompensationMode);
|
||||||
|
|
||||||
|
PDFObject getBlackGenerationFunction() const;
|
||||||
|
void setBlackGenerationFunction(const PDFObject& blackGenerationFunction);
|
||||||
|
|
||||||
|
PDFObject getUndercolorRemovalFunction() const;
|
||||||
|
void setUndercolorRemovalFunction(const PDFObject& undercolorRemovalFunction);
|
||||||
|
|
||||||
|
PDFObject getTransferFunction() const;
|
||||||
|
void setTransferFunction(const PDFObject& transferFunction);
|
||||||
|
|
||||||
|
PDFObject getHalftone() const;
|
||||||
|
void setHalftone(const PDFObject& halftone);
|
||||||
|
|
||||||
|
QPointF getHalftoneOrigin() const;
|
||||||
|
void setHalftoneOrigin(const QPointF& halftoneOrigin);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMatrix m_currentTransformationMatrix;
|
QMatrix m_currentTransformationMatrix;
|
||||||
PDFColorSpacePointer m_strokeColorSpace;
|
PDFColorSpacePointer m_strokeColorSpace;
|
||||||
@ -451,6 +470,12 @@ protected:
|
|||||||
bool m_alphaIsShape;
|
bool m_alphaIsShape;
|
||||||
bool m_strokeAdjustment;
|
bool m_strokeAdjustment;
|
||||||
const PDFDictionary* m_softMask;
|
const PDFDictionary* m_softMask;
|
||||||
|
BlackPointCompensationMode m_blackPointCompensationMode;
|
||||||
|
PDFObject m_blackGenerationFunction;
|
||||||
|
PDFObject m_undercolorRemovalFunction;
|
||||||
|
PDFObject m_transferFunction;
|
||||||
|
PDFObject m_halftone;
|
||||||
|
QPointF m_halftoneOrigin;
|
||||||
StateFlags m_stateFlags;
|
StateFlags m_stateFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -527,6 +527,61 @@ private:
|
|||||||
QString m_errorMessage;
|
QString m_errorMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Enum>
|
||||||
|
class PDFFlags
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Integer = typename std::underlying_type<Enum>::type;
|
||||||
|
|
||||||
|
constexpr inline PDFFlags() noexcept = default;
|
||||||
|
constexpr inline PDFFlags(Integer flags) noexcept : m_flags(flags) { }
|
||||||
|
constexpr inline PDFFlags(Enum flag) noexcept : m_flags(flag) { }
|
||||||
|
|
||||||
|
constexpr inline PDFFlags& operator|=(Integer flags) { m_flags |= flags; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator|=(PDFFlags flags) { m_flags |= flags.m_flags; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator|=(Enum flag) { m_flags |= flag; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator&=(Integer flags) { m_flags &= flags; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator&=(PDFFlags flags) { m_flags &= flags.m_flags; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator&=(Enum flag) { m_flags &= flag; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator^=(Integer flags) { m_flags ^= flags; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator^=(PDFFlags flags) { m_flags ^= flags.m_flags; return *this; }
|
||||||
|
constexpr inline PDFFlags& operator^=(Enum flag) { m_flags ^= flag; return *this; }
|
||||||
|
|
||||||
|
constexpr inline operator Integer() const { return m_flags; }
|
||||||
|
|
||||||
|
constexpr inline PDFFlags operator|(Integer flags) const { return PDFFlags(m_flags | flags); }
|
||||||
|
constexpr inline PDFFlags operator|(PDFFlags flags) const { return PDFFlags(m_flags | flags.m_flags); }
|
||||||
|
constexpr inline PDFFlags operator|(Enum flag) const { return PDFFlags(m_flags | flag); }
|
||||||
|
constexpr inline PDFFlags operator&(Integer flags) const { return PDFFlags(m_flags & flags); }
|
||||||
|
constexpr inline PDFFlags operator&(PDFFlags flags) const { return PDFFlags(m_flags & flags.m_flags); }
|
||||||
|
constexpr inline PDFFlags operator&(Enum flag) const { return PDFFlags(m_flags & flag); }
|
||||||
|
constexpr inline PDFFlags operator^(Integer flags) const { return PDFFlags(m_flags ^ flags); }
|
||||||
|
constexpr inline PDFFlags operator^(PDFFlags flags) const { return PDFFlags(m_flags ^ flags.m_flags); }
|
||||||
|
constexpr inline PDFFlags operator^(Enum flag) const { return PDFFlags(m_flags ^ flag); }
|
||||||
|
constexpr inline PDFFlags operator~() const { return PDFFlags(~m_flags); }
|
||||||
|
|
||||||
|
// Explicit bool operator to disallow implicit conversion
|
||||||
|
constexpr inline explicit operator bool() const { return m_flags != 0; }
|
||||||
|
constexpr inline bool operator!() const { return m_flags == 0; }
|
||||||
|
|
||||||
|
constexpr inline bool testFlag(Enum flag) const { return (m_flags & flag) == flag; }
|
||||||
|
constexpr inline PDFFlags& setFlag(Enum flag, bool on = true)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
m_flags |= Integer(flag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_flags &= ~Integer(flag);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Integer m_flags = Integer();
|
||||||
|
};
|
||||||
|
|
||||||
/// Set of closed intervals
|
/// Set of closed intervals
|
||||||
class PDFClosedIntervalSet
|
class PDFClosedIntervalSet
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user