mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Document content flow basics
This commit is contained in:
@ -244,11 +244,14 @@ PDFPageContentProcessor::PDFPageContentProcessor(const PDFPage* page,
|
||||
m_drawingUncoloredTilingPatternState(0),
|
||||
m_patternBaseMatrix(pagePointToDevicePointMatrix),
|
||||
m_pagePointToDevicePointMatrix(pagePointToDevicePointMatrix),
|
||||
m_meshQualitySettings(meshQualitySettings)
|
||||
m_meshQualitySettings(meshQualitySettings),
|
||||
m_structuralParentKey(0)
|
||||
{
|
||||
Q_ASSERT(page);
|
||||
Q_ASSERT(document);
|
||||
|
||||
m_structuralParentKey = page->getStructureParentKey();
|
||||
|
||||
PDFExecutionPolicy::startProcessingContentStream();
|
||||
|
||||
QPainterPath pageRectPath;
|
||||
@ -338,6 +341,7 @@ QList<PDFRenderError> PDFPageContentProcessor::processContents()
|
||||
}
|
||||
}
|
||||
|
||||
finishMarkedContent();
|
||||
return m_errorList;
|
||||
}
|
||||
|
||||
@ -659,9 +663,11 @@ void PDFPageContentProcessor::processForm(const QMatrix& matrix,
|
||||
const QRectF& boundingBox,
|
||||
const PDFObject& resources,
|
||||
const PDFObject& transparencyGroup,
|
||||
const QByteArray& content)
|
||||
const QByteArray& content,
|
||||
PDFInteger formStructuralParent)
|
||||
{
|
||||
PDFPageContentProcessorStateGuard guard(this);
|
||||
PDFTemporaryValueChange structuralParentChangeGuard(&m_structuralParentKey, formStructuralParent);
|
||||
|
||||
std::unique_ptr<PDFTransparencyGroupGuard> guard2;
|
||||
if (transparencyGroup.isDictionary())
|
||||
@ -1738,6 +1744,19 @@ void PDFPageContentProcessor::setRenderingIntentByName(QByteArray renderingInten
|
||||
m_graphicState.setRenderingIntentName(renderingIntentName);
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::finishMarkedContent()
|
||||
{
|
||||
if (!m_markedContentStack.empty())
|
||||
{
|
||||
m_errorList.append(PDFRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Marked content is not well formed (not enough EMC operators).")));
|
||||
}
|
||||
|
||||
while (!m_markedContentStack.empty())
|
||||
{
|
||||
operatorMarkedContentEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::reportRenderErrorOnce(RenderErrorType type, QString message)
|
||||
{
|
||||
if (!m_onceReportedErrors.count(message))
|
||||
@ -2936,7 +2955,10 @@ void PDFPageContentProcessor::operatorPaintXObject(PDFPageContentProcessor::PDFO
|
||||
// Transparency group
|
||||
PDFObject transparencyGroup = m_document->getObject(streamDictionary->get("Group"));
|
||||
|
||||
processForm(transformationMatrix, boundingBox, resources, transparencyGroup, content);
|
||||
// Form structural parent key
|
||||
const PDFInteger formStructuralParentKey = loader.readIntegerFromDictionary(streamDictionary, "StructParent", m_structuralParentKey);
|
||||
|
||||
processForm(transformationMatrix, boundingBox, resources, transparencyGroup, content, formStructuralParentKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3075,32 +3097,34 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
|
||||
if (item.glyph)
|
||||
{
|
||||
const QPainterPath& glyphPath = *item.glyph;
|
||||
|
||||
QMatrix textRenderingMatrix = adjustMatrix * textMatrix;
|
||||
QMatrix toDeviceSpaceTransform = textRenderingMatrix * m_graphicState.getCurrentTransformationMatrix();
|
||||
|
||||
if (!glyphPath.isEmpty())
|
||||
{
|
||||
QMatrix textRenderingMatrix = adjustMatrix * textMatrix;
|
||||
QMatrix toDeviceSpaceTransform = textRenderingMatrix * m_graphicState.getCurrentTransformationMatrix();
|
||||
QPainterPath transformedGlyph = textRenderingMatrix.map(glyphPath);
|
||||
processPathPainting(transformedGlyph, stroke, fill, true, transformedGlyph.fillRule());
|
||||
|
||||
if (!item.character.isNull() && !item.character.isSpace())
|
||||
{
|
||||
// Output character
|
||||
PDFTextCharacterInfo info;
|
||||
info.character = item.character;
|
||||
info.isVerticalWritingSystem = !isHorizontalWritingSystem;
|
||||
info.advance = item.advance;
|
||||
info.fontSize = fontSize;
|
||||
info.outline = glyphPath;
|
||||
info.matrix = toDeviceSpaceTransform;
|
||||
performOutputCharacter(info);
|
||||
}
|
||||
|
||||
if (clipped)
|
||||
{
|
||||
// Clipping is enabled, we must transform to the device coordinates
|
||||
m_textClippingPath = m_textClippingPath.united(toDeviceSpaceTransform.map(glyphPath));
|
||||
}
|
||||
}
|
||||
|
||||
if (!item.character.isNull())
|
||||
{
|
||||
// Output character
|
||||
PDFTextCharacterInfo info;
|
||||
info.character = item.character;
|
||||
info.isVerticalWritingSystem = !isHorizontalWritingSystem;
|
||||
info.advance = item.advance;
|
||||
info.fontSize = fontSize;
|
||||
info.outline = glyphPath;
|
||||
info.matrix = toDeviceSpaceTransform;
|
||||
performOutputCharacter(info);
|
||||
}
|
||||
}
|
||||
|
||||
displacementX = advance.x();
|
||||
@ -3170,7 +3194,7 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
|
||||
|
||||
processContent(*item.characterContentStream);
|
||||
|
||||
if (!item.character.isNull() && !item.character.isSpace())
|
||||
if (!item.character.isNull())
|
||||
{
|
||||
// Output character
|
||||
PDFTextCharacterInfo info;
|
||||
|
Reference in New Issue
Block a user