mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Finishing graphic state parameters
This commit is contained in:
@ -148,6 +148,15 @@ enum class RendererEngine
|
|||||||
OpenGL
|
OpenGL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class RenderingIntent
|
||||||
|
{
|
||||||
|
Perceptual,
|
||||||
|
AbsoluteColorimetric,
|
||||||
|
RelativeColorimetric,
|
||||||
|
Saturation,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
|
||||||
#endif // PDFGLOBAL_H
|
#endif // PDFGLOBAL_H
|
||||||
|
@ -1593,7 +1593,7 @@ void PDFPageContentProcessor::operatorSetLineDashPattern()
|
|||||||
|
|
||||||
void PDFPageContentProcessor::operatorSetRenderingIntent(PDFOperandName intent)
|
void PDFPageContentProcessor::operatorSetRenderingIntent(PDFOperandName intent)
|
||||||
{
|
{
|
||||||
m_graphicState.setRenderingIntent(intent.name);
|
setRenderingIntentByName(intent.name);
|
||||||
updateGraphicState();
|
updateGraphicState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1604,6 +1604,30 @@ void PDFPageContentProcessor::operatorSetFlatness(PDFReal flatness)
|
|||||||
updateGraphicState();
|
updateGraphicState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::setRenderingIntentByName(QByteArray renderingIntentName)
|
||||||
|
{
|
||||||
|
RenderingIntent renderingIntent = RenderingIntent::Unknown;
|
||||||
|
|
||||||
|
if (renderingIntentName == "Perceptual")
|
||||||
|
{
|
||||||
|
renderingIntent = RenderingIntent::Perceptual;
|
||||||
|
}
|
||||||
|
else if (renderingIntentName == "AbsoluteColorimetric")
|
||||||
|
{
|
||||||
|
renderingIntent = RenderingIntent::AbsoluteColorimetric;
|
||||||
|
}
|
||||||
|
else if (renderingIntentName == "RelativeColorimetric")
|
||||||
|
{
|
||||||
|
renderingIntent = RenderingIntent::RelativeColorimetric;
|
||||||
|
}
|
||||||
|
else if (renderingIntentName == "Saturation")
|
||||||
|
{
|
||||||
|
renderingIntent = RenderingIntent::Saturation;
|
||||||
|
}
|
||||||
|
m_graphicState.setRenderingIntent(renderingIntent);
|
||||||
|
m_graphicState.setRenderingIntentName(renderingIntentName);
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* graphicStateDictionary)
|
void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* graphicStateDictionary)
|
||||||
{
|
{
|
||||||
PDFDocumentDataLoaderDecorator loader(m_document);
|
PDFDocumentDataLoaderDecorator loader(m_document);
|
||||||
@ -1623,18 +1647,14 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PDFObject& renderingIntentObject = m_document->getObject(graphicStateDictionary->get("RI"));
|
|
||||||
if (renderingIntentObject.isName())
|
|
||||||
{
|
|
||||||
m_graphicState.setRenderingIntent(renderingIntentObject.getString());
|
|
||||||
}
|
|
||||||
|
|
||||||
const PDFReal flatness = loader.readNumberFromDictionary(graphicStateDictionary, "FL", m_graphicState.getFlatness());
|
const PDFReal flatness = loader.readNumberFromDictionary(graphicStateDictionary, "FL", m_graphicState.getFlatness());
|
||||||
const PDFReal smoothness = loader.readNumberFromDictionary(graphicStateDictionary, "SM", m_graphicState.getSmoothness());
|
const PDFReal smoothness = loader.readNumberFromDictionary(graphicStateDictionary, "SM", m_graphicState.getSmoothness());
|
||||||
const bool textKnockout = loader.readBooleanFromDictionary(graphicStateDictionary, "TK", m_graphicState.getTextKnockout());
|
const bool textKnockout = loader.readBooleanFromDictionary(graphicStateDictionary, "TK", m_graphicState.getTextKnockout());
|
||||||
const PDFReal strokingAlpha = loader.readNumberFromDictionary(graphicStateDictionary, "CA", m_graphicState.getAlphaStroking());
|
const PDFReal strokingAlpha = loader.readNumberFromDictionary(graphicStateDictionary, "CA", m_graphicState.getAlphaStroking());
|
||||||
const PDFReal fillingAlpha = loader.readNumberFromDictionary(graphicStateDictionary, "ca", m_graphicState.getAlphaFilling());
|
const PDFReal fillingAlpha = loader.readNumberFromDictionary(graphicStateDictionary, "ca", m_graphicState.getAlphaFilling());
|
||||||
QByteArray blendModeName = loader.readNameFromDictionary(graphicStateDictionary, "BM");
|
QByteArray blendModeName = loader.readNameFromDictionary(graphicStateDictionary, "BM");
|
||||||
|
QByteArray renderingIntentName = loader.readNameFromDictionary(graphicStateDictionary, "RI");
|
||||||
|
const bool alphaIsShape = loader.readBooleanFromDictionary(graphicStateDictionary, "AIS", m_graphicState.getAlphaIsShape());
|
||||||
|
|
||||||
if (!blendModeName.isEmpty())
|
if (!blendModeName.isEmpty())
|
||||||
{
|
{
|
||||||
@ -1648,6 +1668,20 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
m_graphicState.setBlendMode(blendMode);
|
m_graphicState.setBlendMode(blendMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!renderingIntentName.isEmpty())
|
||||||
|
{
|
||||||
|
setRenderingIntentByName(renderingIntentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFOverprintMode overprintMode = m_graphicState.getOverprintMode();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
m_graphicState.setLineWidth(lineWidth);
|
m_graphicState.setLineWidth(lineWidth);
|
||||||
m_graphicState.setLineCapStyle(penCapStyle);
|
m_graphicState.setLineCapStyle(penCapStyle);
|
||||||
m_graphicState.setLineJoinStyle(penJoinStyle);
|
m_graphicState.setLineJoinStyle(penJoinStyle);
|
||||||
@ -1657,7 +1691,35 @@ void PDFPageContentProcessor::processApplyGraphicState(const PDFDictionary* grap
|
|||||||
m_graphicState.setTextKnockout(textKnockout);
|
m_graphicState.setTextKnockout(textKnockout);
|
||||||
m_graphicState.setAlphaStroking(strokingAlpha);
|
m_graphicState.setAlphaStroking(strokingAlpha);
|
||||||
m_graphicState.setAlphaFilling(fillingAlpha);
|
m_graphicState.setAlphaFilling(fillingAlpha);
|
||||||
|
m_graphicState.setOverprintMode(overprintMode);
|
||||||
|
m_graphicState.setAlphaIsShape(alphaIsShape);
|
||||||
updateGraphicState();
|
updateGraphicState();
|
||||||
|
|
||||||
|
if (graphicStateDictionary->hasKey("Font"))
|
||||||
|
{
|
||||||
|
const PDFObject& fontObject = m_document->getObject(graphicStateDictionary->get("Font"));
|
||||||
|
if (fontObject.isArray())
|
||||||
|
{
|
||||||
|
const PDFArray* fontObjectArray = fontObject.getArray();
|
||||||
|
if (fontObjectArray->getCount() == 2)
|
||||||
|
{
|
||||||
|
PDFOperandName operandName;
|
||||||
|
operandName.name = loader.readName(fontObjectArray->getItem(0));
|
||||||
|
operatorTextSetFontAndFontSize(operandName, loader.readNumber(fontObjectArray->getItem(1), 1.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (graphicStateDictionary->hasKey("SMask"))
|
||||||
|
{
|
||||||
|
const PDFObject& softMaskObject = m_document->getObject(graphicStateDictionary->get("SMask"));
|
||||||
|
|
||||||
|
bool isNone = (softMaskObject.isName() && softMaskObject.getString() == "None");
|
||||||
|
if (!isNone)
|
||||||
|
{
|
||||||
|
reportRenderError(RenderErrorType::NotSupported, PDFTranslationContext::tr("Soft masks not supported."));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::operatorSetGraphicState(PDFOperandName dictionaryName)
|
void PDFPageContentProcessor::operatorSetGraphicState(PDFOperandName dictionaryName)
|
||||||
@ -3000,7 +3062,7 @@ PDFPageContentProcessor::PDFPageContentProcessorState::PDFPageContentProcessorSt
|
|||||||
m_lineCapStyle(Qt::FlatCap),
|
m_lineCapStyle(Qt::FlatCap),
|
||||||
m_lineJoinStyle(Qt::MiterJoin),
|
m_lineJoinStyle(Qt::MiterJoin),
|
||||||
m_mitterLimit(10.0),
|
m_mitterLimit(10.0),
|
||||||
m_renderingIntent(),
|
m_renderingIntentName(),
|
||||||
m_flatness(1.0),
|
m_flatness(1.0),
|
||||||
m_smoothness(0.01),
|
m_smoothness(0.01),
|
||||||
m_textCharacterSpacing(0.0),
|
m_textCharacterSpacing(0.0),
|
||||||
@ -3014,6 +3076,9 @@ PDFPageContentProcessor::PDFPageContentProcessorState::PDFPageContentProcessorSt
|
|||||||
m_alphaStroking(1.0),
|
m_alphaStroking(1.0),
|
||||||
m_alphaFilling(1.0),
|
m_alphaFilling(1.0),
|
||||||
m_blendMode(BlendMode::Normal),
|
m_blendMode(BlendMode::Normal),
|
||||||
|
m_renderingIntent(RenderingIntent::Perceptual),
|
||||||
|
m_overprintMode(),
|
||||||
|
m_alphaIsShape(false),
|
||||||
m_stateFlags(StateUnchanged)
|
m_stateFlags(StateUnchanged)
|
||||||
{
|
{
|
||||||
m_fillColorSpace.reset(new PDFDeviceGrayColorSpace);
|
m_fillColorSpace.reset(new PDFDeviceGrayColorSpace);
|
||||||
@ -3037,7 +3102,7 @@ PDFPageContentProcessor::PDFPageContentProcessorState& PDFPageContentProcessor::
|
|||||||
setLineJoinStyle(other.getLineJoinStyle());
|
setLineJoinStyle(other.getLineJoinStyle());
|
||||||
setMitterLimit(other.getMitterLimit());
|
setMitterLimit(other.getMitterLimit());
|
||||||
setLineDashPattern(other.getLineDashPattern());
|
setLineDashPattern(other.getLineDashPattern());
|
||||||
setRenderingIntent(other.getRenderingIntent());
|
setRenderingIntentName(other.getRenderingIntentName());
|
||||||
setFlatness(other.getFlatness());
|
setFlatness(other.getFlatness());
|
||||||
setSmoothness(other.getSmoothness());
|
setSmoothness(other.getSmoothness());
|
||||||
setTextCharacterSpacing(other.getTextCharacterSpacing());
|
setTextCharacterSpacing(other.getTextCharacterSpacing());
|
||||||
@ -3054,6 +3119,9 @@ PDFPageContentProcessor::PDFPageContentProcessorState& PDFPageContentProcessor::
|
|||||||
setAlphaStroking(other.getAlphaStroking());
|
setAlphaStroking(other.getAlphaStroking());
|
||||||
setAlphaFilling(other.getAlphaFilling());
|
setAlphaFilling(other.getAlphaFilling());
|
||||||
setBlendMode(other.getBlendMode());
|
setBlendMode(other.getBlendMode());
|
||||||
|
setRenderingIntent(other.getRenderingIntent());
|
||||||
|
setOverprintMode(other.getOverprintMode());
|
||||||
|
setAlphaIsShape(other.getAlphaIsShape());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3147,12 +3215,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setLineDashPattern(P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntent(const QByteArray& renderingIntent)
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntentName(const QByteArray& renderingIntentName)
|
||||||
{
|
{
|
||||||
if (m_renderingIntent != renderingIntent)
|
if (m_renderingIntentName != renderingIntentName)
|
||||||
{
|
{
|
||||||
m_renderingIntent = renderingIntent;
|
m_renderingIntentName = renderingIntentName;
|
||||||
m_stateFlags |= StateRenderingIntent;
|
m_stateFlags |= StateRenderingIntentName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3237,6 +3305,15 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setBlendMode(BlendMo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntent(RenderingIntent renderingIntent)
|
||||||
|
{
|
||||||
|
if (m_renderingIntent != renderingIntent)
|
||||||
|
{
|
||||||
|
m_renderingIntent = renderingIntent;
|
||||||
|
m_stateFlags |= StateRenderingIntent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QColor PDFPageContentProcessor::PDFPageContentProcessorState::getStrokeColorWithAlpha() const
|
QColor PDFPageContentProcessor::PDFPageContentProcessorState::getStrokeColorWithAlpha() const
|
||||||
{
|
{
|
||||||
QColor color = getStrokeColor();
|
QColor color = getStrokeColor();
|
||||||
@ -3251,6 +3328,24 @@ QColor PDFPageContentProcessor::PDFPageContentProcessorState::getFillColorWithAl
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setOverprintMode(PDFOverprintMode overprintMode)
|
||||||
|
{
|
||||||
|
if (m_overprintMode != overprintMode)
|
||||||
|
{
|
||||||
|
m_overprintMode = overprintMode;
|
||||||
|
m_stateFlags |= StateOverprint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaIsShape(bool alphaIsShape)
|
||||||
|
{
|
||||||
|
if (m_alphaIsShape != alphaIsShape)
|
||||||
|
{
|
||||||
|
m_alphaIsShape = alphaIsShape;
|
||||||
|
m_stateFlags |= StateAlphaIsShape;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextMatrix(const QMatrix& textMatrix)
|
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextMatrix(const QMatrix& textMatrix)
|
||||||
{
|
{
|
||||||
if (m_textMatrix != textMatrix)
|
if (m_textMatrix != textMatrix)
|
||||||
|
@ -205,6 +205,22 @@ protected:
|
|||||||
bool knockout = false;
|
bool knockout = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PDFOverprintMode
|
||||||
|
{
|
||||||
|
bool overprintStroking = false;
|
||||||
|
bool overprintFilling = false;
|
||||||
|
int overprintMode = 0;
|
||||||
|
|
||||||
|
inline bool operator==(const PDFOverprintMode& other) const
|
||||||
|
{
|
||||||
|
return std::tie(overprintStroking, overprintFilling, overprintMode) == std::tie(other.overprintStroking, other.overprintFilling, other.overprintMode);
|
||||||
|
}
|
||||||
|
inline bool operator!=(const PDFOverprintMode& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Represents graphic state of the PDF (holding current graphic state parameters).
|
/// Represents graphic state of the PDF (holding current graphic state parameters).
|
||||||
/// Please see PDF Reference 1.7, Chapter 4.3 "Graphic State"
|
/// Please see PDF Reference 1.7, Chapter 4.3 "Graphic State"
|
||||||
class PDFPageContentProcessorState
|
class PDFPageContentProcessorState
|
||||||
@ -232,7 +248,7 @@ protected:
|
|||||||
StateLineJoinStyle = 0x00000080,
|
StateLineJoinStyle = 0x00000080,
|
||||||
StateMitterLimit = 0x00000100,
|
StateMitterLimit = 0x00000100,
|
||||||
StateLineDashPattern = 0x00000200,
|
StateLineDashPattern = 0x00000200,
|
||||||
StateRenderingIntent = 0x00000400,
|
StateRenderingIntentName = 0x00000400,
|
||||||
StateFlatness = 0x00000800,
|
StateFlatness = 0x00000800,
|
||||||
StateSmoothness = 0x00001000,
|
StateSmoothness = 0x00001000,
|
||||||
StateTextMatrix = 0x00002000,
|
StateTextMatrix = 0x00002000,
|
||||||
@ -249,6 +265,9 @@ protected:
|
|||||||
StateAlphaStroking = 0x01000000,
|
StateAlphaStroking = 0x01000000,
|
||||||
StateAlphaFilling = 0x02000000,
|
StateAlphaFilling = 0x02000000,
|
||||||
StateBlendMode = 0x04000000,
|
StateBlendMode = 0x04000000,
|
||||||
|
StateRenderingIntent = 0x08000000,
|
||||||
|
StateOverprint = 0x10000000,
|
||||||
|
StateAlphaIsShape = 0x20000000,
|
||||||
StateAll = 0xFFFFFFFF
|
StateAll = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,8 +303,8 @@ protected:
|
|||||||
const PDFLineDashPattern& getLineDashPattern() const { return m_lineDashPattern; }
|
const PDFLineDashPattern& getLineDashPattern() const { return m_lineDashPattern; }
|
||||||
void setLineDashPattern(PDFLineDashPattern pattern);
|
void setLineDashPattern(PDFLineDashPattern pattern);
|
||||||
|
|
||||||
const QByteArray& getRenderingIntent() const { return m_renderingIntent; }
|
const QByteArray& getRenderingIntentName() const { return m_renderingIntentName; }
|
||||||
void setRenderingIntent(const QByteArray& renderingIntent);
|
void setRenderingIntentName(const QByteArray& renderingIntentName);
|
||||||
|
|
||||||
PDFReal getFlatness() const { return m_flatness; }
|
PDFReal getFlatness() const { return m_flatness; }
|
||||||
void setFlatness(PDFReal flatness);
|
void setFlatness(PDFReal flatness);
|
||||||
@ -338,12 +357,21 @@ protected:
|
|||||||
BlendMode getBlendMode() const { return m_blendMode; }
|
BlendMode getBlendMode() const { return m_blendMode; }
|
||||||
void setBlendMode(BlendMode mode);
|
void setBlendMode(BlendMode mode);
|
||||||
|
|
||||||
|
RenderingIntent getRenderingIntent() const { return m_renderingIntent; }
|
||||||
|
void setRenderingIntent(RenderingIntent renderingIntent);
|
||||||
|
|
||||||
/// Returns stroke color with alpha channel
|
/// Returns stroke color with alpha channel
|
||||||
QColor getStrokeColorWithAlpha() const;
|
QColor getStrokeColorWithAlpha() const;
|
||||||
|
|
||||||
/// Returns fill color with alpha channel
|
/// Returns fill color with alpha channel
|
||||||
QColor getFillColorWithAlpha() const;
|
QColor getFillColorWithAlpha() const;
|
||||||
|
|
||||||
|
PDFOverprintMode getOverprintMode() const { return m_overprintMode; }
|
||||||
|
void setOverprintMode(PDFOverprintMode overprintMode);
|
||||||
|
|
||||||
|
bool getAlphaIsShape() const { return m_alphaIsShape; }
|
||||||
|
void setAlphaIsShape(bool alphaIsShape);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMatrix m_currentTransformationMatrix;
|
QMatrix m_currentTransformationMatrix;
|
||||||
PDFColorSpacePointer m_strokeColorSpace;
|
PDFColorSpacePointer m_strokeColorSpace;
|
||||||
@ -355,7 +383,7 @@ protected:
|
|||||||
Qt::PenJoinStyle m_lineJoinStyle;
|
Qt::PenJoinStyle m_lineJoinStyle;
|
||||||
PDFReal m_mitterLimit;
|
PDFReal m_mitterLimit;
|
||||||
PDFLineDashPattern m_lineDashPattern;
|
PDFLineDashPattern m_lineDashPattern;
|
||||||
QByteArray m_renderingIntent;
|
QByteArray m_renderingIntentName;
|
||||||
PDFReal m_flatness;
|
PDFReal m_flatness;
|
||||||
PDFReal m_smoothness;
|
PDFReal m_smoothness;
|
||||||
PDFReal m_textCharacterSpacing; // T_c
|
PDFReal m_textCharacterSpacing; // T_c
|
||||||
@ -372,6 +400,9 @@ protected:
|
|||||||
PDFReal m_alphaStroking;
|
PDFReal m_alphaStroking;
|
||||||
PDFReal m_alphaFilling;
|
PDFReal m_alphaFilling;
|
||||||
BlendMode m_blendMode;
|
BlendMode m_blendMode;
|
||||||
|
RenderingIntent m_renderingIntent;
|
||||||
|
PDFOverprintMode m_overprintMode;
|
||||||
|
bool m_alphaIsShape;
|
||||||
StateFlags m_stateFlags;
|
StateFlags m_stateFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -802,6 +833,9 @@ private:
|
|||||||
/// Report warning about color operators in uncolored tiling pattern
|
/// Report warning about color operators in uncolored tiling pattern
|
||||||
void reportWarningAboutColorOperatorsInUTP();
|
void reportWarningAboutColorOperatorsInUTP();
|
||||||
|
|
||||||
|
/// Set rendering intent by name
|
||||||
|
void setRenderingIntentByName(QByteArray renderingIntentName);
|
||||||
|
|
||||||
const PDFPage* m_page;
|
const PDFPage* m_page;
|
||||||
const PDFDocument* m_document;
|
const PDFDocument* m_document;
|
||||||
const PDFFontCache* m_fontCache;
|
const PDFFontCache* m_fontCache;
|
||||||
|
Reference in New Issue
Block a user