Editor plugin: WIP

This commit is contained in:
Jakub Melka 2023-03-06 16:09:09 +01:00
parent 1e52c0c063
commit 1b6bb6086c
32 changed files with 2243 additions and 311 deletions

View File

@ -1,4 +1,4 @@
# Copyright (C) 2022 Jakub Melka
# Copyright (C) 2022-2023 Jakub Melka
#
# This file is part of PDF4QT.
#
@ -28,3 +28,4 @@ add_subdirectory(OutputPreviewPlugin)
add_subdirectory(RedactPlugin)
add_subdirectory(SignaturePlugin)
add_subdirectory(SoftProofingPlugin)
add_subdirectory(EditorPlugin)

View File

@ -148,6 +148,8 @@ add_library(Pdf4QtLibCore SHARED
sources/pdfcertificatestore.cpp
sources/pdfblpainter.h
sources/pdfblpainter.cpp
sources/pdfpagecontenteditorprocessor.h
sources/pdfpagecontenteditorprocessor.cpp
)
include(GenerateExportHeader)

View File

@ -749,7 +749,7 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
if (glyphIndex)
{
const Glyph& glyph = getGlyph(glyphIndex);
textSequence.items.emplace_back(&glyph.glyph, (*encoding)[static_cast<uint8_t>(byteArray[i])], glyph.advance);
textSequence.items.emplace_back(&glyph.glyph, (*encoding)[static_cast<uint8_t>(byteArray[i])], glyph.advance, static_cast<CID>(byteArray[i]));
}
else
{
@ -757,7 +757,7 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
if (glyphWidth > 0)
{
const QPainterPath* nullpath = nullptr;
textSequence.items.emplace_back(nullpath, QChar(), glyphWidth * m_pixelSize * FONT_WIDTH_MULTIPLIER);
textSequence.items.emplace_back(nullpath, QChar(), glyphWidth * m_pixelSize * FONT_WIDTH_MULTIPLIER, static_cast<CID>(byteArray[i]));
}
}
}
@ -784,7 +784,7 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
{
QChar character = toUnicode->getToUnicode(cid);
const Glyph& glyph = getGlyph(glyphIndex);
textSequence.items.emplace_back(&glyph.glyph, character, glyph.advance);
textSequence.items.emplace_back(&glyph.glyph, character, glyph.advance, cid);
}
else
{
@ -799,7 +799,7 @@ void PDFRealizedFontImpl::fillTextSequence(const QByteArray& byteArray, TextSequ
// We do not multiply advance with font size and FONT_WIDTH_MULTIPLIER, because in the code,
// "advance" is treated as in font space.
const QPainterPath* nullpath = nullptr;
textSequence.items.emplace_back(nullpath, QChar(), -glyphWidth);
textSequence.items.emplace_back(nullpath, QChar(), -glyphWidth, cid);
}
}
}
@ -2680,7 +2680,7 @@ void PDFRealizedType3FontImpl::fillTextSequence(const QByteArray& byteArray, Tex
if (contentStream)
{
textSequence.items.emplace_back(contentStream, character, width);
textSequence.items.emplace_back(contentStream, character, width, index);
}
else
{

View File

@ -70,9 +70,9 @@ public:
struct TextSequenceItem
{
inline explicit TextSequenceItem() = default;
inline explicit TextSequenceItem(const QPainterPath* glyph, QChar character, PDFReal advance) : glyph(glyph), character(character), advance(advance) { }
inline explicit TextSequenceItem(const QPainterPath* glyph, QChar character, PDFReal advance, CID cid) : glyph(glyph), character(character), advance(advance), cid(cid) { }
inline explicit TextSequenceItem(PDFReal advance) : character(), advance(advance) { }
inline explicit TextSequenceItem(const QByteArray* characterContentStream, QChar character, PDFReal advance) : characterContentStream(characterContentStream), character(character), advance(advance) { }
inline explicit TextSequenceItem(const QByteArray* characterContentStream, QChar character, PDFReal advance, uint cid) : characterContentStream(characterContentStream), character(character), advance(advance), cid(cid) { }
inline bool isContentStream() const { return characterContentStream; }
inline bool isCharacter() const { return glyph; }
@ -83,6 +83,7 @@ struct TextSequenceItem
const QByteArray* characterContentStream = nullptr;
QChar character;
PDFReal advance = 0;
CID cid = 0;
};
struct TextSequence

View File

@ -0,0 +1,589 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "pdfpagecontenteditorprocessor.h"
namespace pdf
{
PDFPageContentEditorProcessor::PDFPageContentEditorProcessor(const PDFPage* page,
const PDFDocument* document,
const PDFFontCache* fontCache,
const PDFCMS* CMS,
const PDFOptionalContentActivity* optionalContentActivity,
QTransform pagePointToDevicePointMatrix,
const PDFMeshQualitySettings& meshQualitySettings) :
BaseClass(page, document, fontCache, CMS, optionalContentActivity, pagePointToDevicePointMatrix, meshQualitySettings)
{
m_clippingPaths.push(QPainterPath());
}
const PDFEditedPageContent& PDFPageContentEditorProcessor::getEditedPageContent() const
{
return m_content;
}
PDFEditedPageContent PDFPageContentEditorProcessor::takeEditedPageContent()
{
return std::move(m_content);
}
void PDFPageContentEditorProcessor::performInterceptInstruction(Operator currentOperator,
ProcessOrder processOrder,
const QByteArray& operatorAsText)
{
Q_UNUSED(operatorAsText);
if (processOrder == ProcessOrder::BeforeOperation)
{
if (currentOperator == Operator::TextBegin && !isTextProcessing())
{
m_contentElementText.reset(new PDFEditedPageContentElementText(*getGraphicState()));
}
}
else
{
if (currentOperator == Operator::TextEnd && !isTextProcessing())
{
if (m_contentElementText && !m_contentElementText->isEmpty())
{
m_content.addContentElement(std::move(m_contentElementText));
}
m_contentElementText.reset();
m_textBoundingRect = QRectF();
}
}
}
void PDFPageContentEditorProcessor::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
{
if (path.isEmpty())
{
return;
}
Q_UNUSED(fillRule);
Q_UNUSED(stroke);
Q_UNUSED(fill);
Q_UNUSED(text);
if (text)
{
QPainterPath mappedPath = getCurrentWorldMatrix().map(path);
QRectF boundingRect = mappedPath.boundingRect();
m_textBoundingRect = m_textBoundingRect.united(boundingRect);
}
else
{
m_content.addContentPath(*getGraphicState(), path, stroke, fill);
}
}
void PDFPageContentEditorProcessor::performUpdateGraphicsState(const PDFPageContentProcessorState& state)
{
if (isTextProcessing() && m_contentElementText)
{
PDFEditedPageContentElementText::Item item;
item.isUpdateGraphicState = true;
item.state = state;
m_contentElementText->addItem(item);
}
}
void PDFPageContentEditorProcessor::performProcessTextSequence(const TextSequence& textSequence, ProcessOrder order)
{
if (order == ProcessOrder::BeforeOperation)
{
PDFEditedPageContentElementText::Item item;
item.isText = true;
item.textSequence = textSequence;
m_contentElementText->addItem(item);
}
}
bool PDFPageContentEditorProcessor::performOriginalImagePainting(const PDFImage& image, const PDFStream* stream)
{
Q_UNUSED(image);
PDFObject imageObject = PDFObject::createStream(std::make_shared<PDFStream>(*stream));
m_content.addContentImage(*getGraphicState(), std::move(imageObject), QImage());
return false;
}
void PDFPageContentEditorProcessor::performImagePainting(const QImage& image)
{
PDFEditedPageContentElement* backElement = m_content.getBackElement();
Q_ASSERT(backElement);
PDFEditedPageContentElementImage* imageElement = backElement->asImage();
imageElement->setImage(image);
}
void PDFPageContentEditorProcessor::performSaveGraphicState(ProcessOrder order)
{
if (order == ProcessOrder::BeforeOperation)
{
m_clippingPaths.push(m_clippingPaths.top());
}
}
void PDFPageContentEditorProcessor::performRestoreGraphicState(ProcessOrder order)
{
if (order == ProcessOrder::AfterOperation)
{
m_clippingPaths.pop();
}
}
void PDFPageContentEditorProcessor::performClipping(const QPainterPath& path, Qt::FillRule fillRule)
{
Q_UNUSED(fillRule);
if (m_clippingPaths.top().isEmpty())
{
m_clippingPaths.top() = path;
}
else
{
m_clippingPaths.top() = m_clippingPaths.top().intersected(path);
}
}
bool PDFPageContentEditorProcessor::isContentKindSuppressed(ContentKind kind) const
{
switch (kind)
{
case ContentKind::Shading:
case ContentKind::Tiling:
return true;
default:
break;
}
return false;
}
QString PDFEditedPageContent::getOperatorToString(PDFPageContentProcessor::Operator operatorValue)
{
switch (operatorValue)
{
case pdf::PDFPageContentProcessor::Operator::SetLineWidth:
return "set_line_width";
case pdf::PDFPageContentProcessor::Operator::SetLineCap:
return "set_line_cap";
case pdf::PDFPageContentProcessor::Operator::SetLineJoin:
return "set_line_join";
case pdf::PDFPageContentProcessor::Operator::SetMitterLimit:
return "set_mitter_limit";
case pdf::PDFPageContentProcessor::Operator::SetLineDashPattern:
return "set_line_dash_pattern";
case pdf::PDFPageContentProcessor::Operator::SetRenderingIntent:
return "set_rendering_intent";
case pdf::PDFPageContentProcessor::Operator::SetFlatness:
return "set_flatness";
case pdf::PDFPageContentProcessor::Operator::SetGraphicState:
return "set_graphic_state";
case pdf::PDFPageContentProcessor::Operator::SaveGraphicState:
return "save";
case pdf::PDFPageContentProcessor::Operator::RestoreGraphicState:
return "restore";
case pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix:
return "set_cm";
case pdf::PDFPageContentProcessor::Operator::MoveCurrentPoint:
return "move_to";
case pdf::PDFPageContentProcessor::Operator::LineTo:
return "line_to";
case pdf::PDFPageContentProcessor::Operator::Bezier123To:
return "cubic123_to";
case pdf::PDFPageContentProcessor::Operator::Bezier23To:
return "cubic23_to";
case pdf::PDFPageContentProcessor::Operator::Bezier13To:
return "cubic13_to";
case pdf::PDFPageContentProcessor::Operator::EndSubpath:
return "close_path";
case pdf::PDFPageContentProcessor::Operator::Rectangle:
return "rect";
case pdf::PDFPageContentProcessor::Operator::PathStroke:
return "path_stroke";
case pdf::PDFPageContentProcessor::Operator::PathCloseStroke:
return "path_close_and_stroke";
case pdf::PDFPageContentProcessor::Operator::PathFillWinding:
return "path_fill_winding";
case pdf::PDFPageContentProcessor::Operator::PathFillWinding2:
return "path_fill_winding";
case pdf::PDFPageContentProcessor::Operator::PathFillEvenOdd:
return "path_fill_even_odd";
case pdf::PDFPageContentProcessor::Operator::PathFillStrokeWinding:
return "path_fill_stroke_winding";
case pdf::PDFPageContentProcessor::Operator::PathFillStrokeEvenOdd:
return "path_fill_stroke_even_odd";
case pdf::PDFPageContentProcessor::Operator::PathCloseFillStrokeWinding:
return "path_close_fill_stroke_winding";
case pdf::PDFPageContentProcessor::Operator::PathCloseFillStrokeEvenOdd:
return "path_close_fill_stroke_even_odd";
case pdf::PDFPageContentProcessor::Operator::PathClear:
return "path_clear";
case pdf::PDFPageContentProcessor::Operator::ClipWinding:
return "clip_winding";
case pdf::PDFPageContentProcessor::Operator::ClipEvenOdd:
return "clip_even_odd";
case pdf::PDFPageContentProcessor::Operator::TextBegin:
return "text_begin";
case pdf::PDFPageContentProcessor::Operator::TextEnd:
return "text_end";
case pdf::PDFPageContentProcessor::Operator::TextSetCharacterSpacing:
return "set_char_spacing";
case pdf::PDFPageContentProcessor::Operator::TextSetWordSpacing:
return "set_word_spacing";
case pdf::PDFPageContentProcessor::Operator::TextSetHorizontalScale:
return "set_hor_scale";
case pdf::PDFPageContentProcessor::Operator::TextSetLeading:
return "set_leading";
case pdf::PDFPageContentProcessor::Operator::TextSetFontAndFontSize:
return "set_font";
case pdf::PDFPageContentProcessor::Operator::TextSetRenderMode:
return "set_text_render_mode";
case pdf::PDFPageContentProcessor::Operator::TextSetRise:
return "set_text_rise";
case pdf::PDFPageContentProcessor::Operator::TextMoveByOffset:
return "text_move_by_offset";
case pdf::PDFPageContentProcessor::Operator::TextSetLeadingAndMoveByOffset:
return "text_set_leading_and_move_by_offset";
case pdf::PDFPageContentProcessor::Operator::TextSetMatrix:
return "text_set_matrix";
case pdf::PDFPageContentProcessor::Operator::TextMoveByLeading:
return "text_move_by_leading";
case pdf::PDFPageContentProcessor::Operator::TextShowTextString:
return "text_show_string";
case pdf::PDFPageContentProcessor::Operator::TextShowTextIndividualSpacing:
return "text_show_string_with_spacing";
case pdf::PDFPageContentProcessor::Operator::TextNextLineShowText:
return "text_next_line_and_show_text";
case pdf::PDFPageContentProcessor::Operator::TextSetSpacingAndShowText:
return "text_set_spacing_and_show_text";
case pdf::PDFPageContentProcessor::Operator::Type3FontSetOffset:
return "text_t3_set_offset";
case pdf::PDFPageContentProcessor::Operator::Type3FontSetOffsetAndBB:
return "text_t3_set_offset_and_bb";
case pdf::PDFPageContentProcessor::Operator::ColorSetStrokingColorSpace:
return "set_stroke_color_space";
case pdf::PDFPageContentProcessor::Operator::ColorSetFillingColorSpace:
return "set_filling_color_space";
case pdf::PDFPageContentProcessor::Operator::ColorSetStrokingColor:
return "set_stroke_color";
case pdf::PDFPageContentProcessor::Operator::ColorSetStrokingColorN:
return "set_stroke_color_n";
case pdf::PDFPageContentProcessor::Operator::ColorSetFillingColor:
return "set_filling_color";
case pdf::PDFPageContentProcessor::Operator::ColorSetFillingColorN:
return "set_filling_color_n";
case pdf::PDFPageContentProcessor::Operator::ColorSetDeviceGrayStroking:
return "set_stroke_gray_cs";
case pdf::PDFPageContentProcessor::Operator::ColorSetDeviceGrayFilling:
return "set_filling_gray_cs";
case pdf::PDFPageContentProcessor::Operator::ColorSetDeviceRGBStroking:
return "set_stroke_rgb_cs";
case pdf::PDFPageContentProcessor::Operator::ColorSetDeviceRGBFilling:
return "set_filling_rgb_cs";
case pdf::PDFPageContentProcessor::Operator::ColorSetDeviceCMYKStroking:
return "set_stroke_cmyk_cs";
case pdf::PDFPageContentProcessor::Operator::ColorSetDeviceCMYKFilling:
return "set_filling_cmyk_cs";
case pdf::PDFPageContentProcessor::Operator::ShadingPaintShape:
return "shading_paint";
case pdf::PDFPageContentProcessor::Operator::InlineImageBegin:
return "ib";
case pdf::PDFPageContentProcessor::Operator::InlineImageData:
return "id";
case pdf::PDFPageContentProcessor::Operator::InlineImageEnd:
return "ie";
case pdf::PDFPageContentProcessor::Operator::PaintXObject:
return "paint_object";
case pdf::PDFPageContentProcessor::Operator::MarkedContentPoint:
return "mc_point";
case pdf::PDFPageContentProcessor::Operator::MarkedContentPointWithProperties:
return "mc_point_prop";
case pdf::PDFPageContentProcessor::Operator::MarkedContentBegin:
return "mc_begin";
case pdf::PDFPageContentProcessor::Operator::MarkedContentBeginWithProperties:
return "mc_begin_prop";
case pdf::PDFPageContentProcessor::Operator::MarkedContentEnd:
return "mc_end";
case pdf::PDFPageContentProcessor::Operator::CompatibilityBegin:
return "compat_begin";
case pdf::PDFPageContentProcessor::Operator::CompatibilityEnd:
return "compat_end";
default:
break;
}
return QString();
}
QString PDFEditedPageContent::getOperandName(PDFPageContentProcessor::Operator operatorValue, int operandIndex)
{
static const std::map<std::pair<PDFPageContentProcessor::Operator, int>, QString> operands =
{
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetLineWidth, 0), "lineWidth" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetLineCap, 0), "lineCap" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetLineJoin, 0), "lineJoin" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetMitterLimit, 0), "mitterLimit" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetRenderingIntent, 0), "renderingIntent" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetFlatness, 0), "flatness" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::SetGraphicState, 0), "graphicState" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix, 0), "a" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix, 1), "b" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix, 2), "c" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix, 3), "d" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix, 4), "e" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::AdjustCurrentTransformationMatrix, 5), "f" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::MoveCurrentPoint, 0), "x" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::MoveCurrentPoint, 1), "y" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::LineTo, 0), "x" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::LineTo, 1), "y" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier123To, 0), "x1" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier123To, 1), "y1" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier123To, 2), "x2" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier123To, 3), "y2" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier123To, 4), "x3" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier123To, 5), "y3" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier23To, 0), "x2" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier23To, 1), "y2" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier23To, 2), "x3" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier23To, 3), "y3" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier13To, 0), "x1" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier13To, 1), "y1" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier13To, 2), "x3" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Bezier13To, 3), "y3" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Rectangle, 0), "x" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Rectangle, 1), "y" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Rectangle, 2), "width" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::Rectangle, 3), "height" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetCharacterSpacing, 0), "charSpacing" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetWordSpacing, 0), "wordSpacing" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetHorizontalScale, 0), "scale" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetLeading, 0), "leading" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetFontAndFontSize, 0), "font" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetFontAndFontSize, 1), "fontSize" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetRenderMode, 0), "renderMode" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetRise, 0), "rise" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextMoveByOffset, 0), "tx" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextMoveByOffset, 1), "ty" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetLeadingAndMoveByOffset, 0), "tx" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetLeadingAndMoveByOffset, 1), "ty" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetMatrix, 0), "a" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetMatrix, 1), "b" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetMatrix, 2), "c" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetMatrix, 3), "d" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetMatrix, 4), "e" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetMatrix, 5), "f" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextShowTextString, 0), "string" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextNextLineShowText, 0), "string" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextShowTextIndividualSpacing, 0), "wSpacing" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextShowTextIndividualSpacing, 1), "chSpacing" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextShowTextIndividualSpacing, 2), "string" },
{ std::make_pair(pdf::PDFPageContentProcessor::Operator::TextSetSpacingAndShowText, 0), "string" },
};
auto it = operands.find(std::make_pair(operatorValue, operandIndex));
if (it != operands.cend())
{
return it->second;
}
return QString("op%1").arg(operandIndex);
}
void PDFEditedPageContent::addContentPath(PDFPageContentProcessorState state, QPainterPath path, bool strokePath, bool fillPath)
{
m_contentElements.emplace_back(new PDFEditedPageContentElementPath(std::move(state), std::move(path), strokePath, fillPath));
}
void PDFEditedPageContent::addContentImage(PDFPageContentProcessorState state, PDFObject imageObject, QImage image)
{
m_contentElements.emplace_back(new PDFEditedPageContentElementImage(std::move(state), std::move(imageObject), std::move(image)));
}
void PDFEditedPageContent::addContentElement(std::unique_ptr<PDFEditedPageContentElement> element)
{
m_contentElements.emplace_back(std::move(element));
}
PDFEditedPageContentElement* PDFEditedPageContent::getBackElement() const
{
if (m_contentElements.empty())
{
return nullptr;
}
return m_contentElements.back().get();
}
PDFEditedPageContentElement::PDFEditedPageContentElement(PDFPageContentProcessorState state) :
m_state(std::move(state))
{
}
const PDFPageContentProcessorState& PDFEditedPageContentElement::getState() const
{
return m_state;
}
void PDFEditedPageContentElement::setState(const PDFPageContentProcessorState& newState)
{
m_state = newState;
}
PDFEditedPageContentElementPath::PDFEditedPageContentElementPath(PDFPageContentProcessorState state, QPainterPath path, bool strokePath, bool fillPath) :
PDFEditedPageContentElement(std::move(state)),
m_path(std::move(path)),
m_strokePath(strokePath),
m_fillPath(fillPath)
{
}
PDFEditedPageContentElement::Type PDFEditedPageContentElementPath::getType() const
{
return Type::Path;
}
PDFEditedPageContentElementPath* PDFEditedPageContentElementPath::clone() const
{
return new PDFEditedPageContentElementPath(getState(), getPath(), getStrokePath(), getFillPath());
}
QRectF PDFEditedPageContentElementPath::getBoundingBox() const
{
QPainterPath mappedPath = getState().getCurrentTransformationMatrix().map(m_path);
return mappedPath.boundingRect();
}
QPainterPath PDFEditedPageContentElementPath::getPath() const
{
return m_path;
}
void PDFEditedPageContentElementPath::setPath(QPainterPath newPath)
{
m_path = newPath;
}
bool PDFEditedPageContentElementPath::getStrokePath() const
{
return m_strokePath;
}
void PDFEditedPageContentElementPath::setStrokePath(bool newStrokePath)
{
m_strokePath = newStrokePath;
}
bool PDFEditedPageContentElementPath::getFillPath() const
{
return m_fillPath;
}
void PDFEditedPageContentElementPath::setFillPath(bool newFillPath)
{
m_fillPath = newFillPath;
}
PDFEditedPageContentElementImage::PDFEditedPageContentElementImage(PDFPageContentProcessorState state, PDFObject imageObject, QImage image) :
PDFEditedPageContentElement(std::move(state)),
m_imageObject(std::move(imageObject)),
m_image(std::move(image))
{
}
PDFEditedPageContentElement::Type PDFEditedPageContentElementImage::getType() const
{
return PDFEditedPageContentElement::Type::Image;
}
PDFEditedPageContentElementImage* PDFEditedPageContentElementImage::clone() const
{
return new PDFEditedPageContentElementImage(getState(), getImageObject(), getImage());
}
PDFObject PDFEditedPageContentElementImage::getImageObject() const
{
return m_imageObject;
}
void PDFEditedPageContentElementImage::setImageObject(const PDFObject& newImageObject)
{
m_imageObject = newImageObject;
}
QImage PDFEditedPageContentElementImage::getImage() const
{
return m_image;
}
void PDFEditedPageContentElementImage::setImage(const QImage& newImage)
{
m_image = newImage;
}
PDFEditedPageContentElementText::PDFEditedPageContentElementText(PDFPageContentProcessorState state) :
PDFEditedPageContentElement(state)
{
}
PDFEditedPageContentElementText::PDFEditedPageContentElementText(PDFPageContentProcessorState state, std::vector<Item> items) :
PDFEditedPageContentElement(state),
m_items(std::move(items))
{
}
PDFEditedPageContentElement::Type PDFEditedPageContentElementText::getType() const
{
return Type::Text;
}
PDFEditedPageContentElementText* PDFEditedPageContentElementText::clone() const
{
return new PDFEditedPageContentElementText(getState(), getItems());
}
void PDFEditedPageContentElementText::addItem(Item item)
{
m_items.emplace_back(std::move(item));
}
const std::vector<PDFEditedPageContentElementText::Item>& PDFEditedPageContentElementText::getItems() const
{
return m_items;
}
void PDFEditedPageContentElementText::setItems(const std::vector<Item>& newItems)
{
m_items = newItems;
}
} // namespace pdf

View File

@ -0,0 +1,212 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef PDFPAGECONTENTEDITORPROCESSOR_H
#define PDFPAGECONTENTEDITORPROCESSOR_H
#include "pdfpagecontentprocessor.h"
#include <memory>
namespace pdf
{
class PDFEditedPageContentElementPath;
class PDFEditedPageContentElementText;
class PDFEditedPageContentElementImage;
class PDFEditedPageContentElement
{
public:
PDFEditedPageContentElement() = default;
PDFEditedPageContentElement(PDFPageContentProcessorState state);
virtual ~PDFEditedPageContentElement() = default;
enum class Type
{
Path,
Text,
Image
};
virtual Type getType() const = 0;
virtual PDFEditedPageContentElement* clone() const = 0;
virtual PDFEditedPageContentElementPath* asPath() { return nullptr; }
virtual const PDFEditedPageContentElementPath* asPath() const { return nullptr; }
virtual PDFEditedPageContentElementText* asText() { return nullptr; }
virtual const PDFEditedPageContentElementText* asText() const { return nullptr; }
virtual PDFEditedPageContentElementImage* asImage() { return nullptr; }
virtual const PDFEditedPageContentElementImage* asImage() const { return nullptr; }
const PDFPageContentProcessorState& getState() const;
void setState(const PDFPageContentProcessorState& newState);
virtual QRectF getBoundingBox() const = 0;
protected:
PDFPageContentProcessorState m_state;
};
class PDFEditedPageContentElementPath : public PDFEditedPageContentElement
{
public:
PDFEditedPageContentElementPath(PDFPageContentProcessorState state, QPainterPath path, bool strokePath, bool fillPath);
virtual ~PDFEditedPageContentElementPath() = default;
virtual Type getType() const override;
virtual PDFEditedPageContentElementPath* clone() const override;
virtual PDFEditedPageContentElementPath* asPath() override { return this; }
virtual const PDFEditedPageContentElementPath* asPath() const override { return this; }
virtual QRectF getBoundingBox() const override;
QPainterPath getPath() const;
void setPath(QPainterPath newPath);
bool getStrokePath() const;
void setStrokePath(bool newStrokePath);
bool getFillPath() const;
void setFillPath(bool newFillPath);
private:
QPainterPath m_path;
bool m_strokePath;
bool m_fillPath;
};
class PDFEditedPageContentElementImage : public PDFEditedPageContentElement
{
public:
PDFEditedPageContentElementImage(PDFPageContentProcessorState state, PDFObject imageObject, QImage image);
virtual ~PDFEditedPageContentElementImage() = default;
virtual Type getType() const override;
virtual PDFEditedPageContentElementImage* clone() const override;
virtual PDFEditedPageContentElementImage* asImage() override { return this; }
virtual const PDFEditedPageContentElementImage* asImage() const override { return this; }
PDFObject getImageObject() const;
void setImageObject(const PDFObject& newImageObject);
QImage getImage() const;
void setImage(const QImage& newImage);
private:
PDFObject m_imageObject;
QImage m_image;
};
class PDFEditedPageContentElementText : public PDFEditedPageContentElement
{
public:
struct Item
{
bool isUpdateGraphicState = false;
bool isText = false;
TextSequence textSequence;
PDFPageContentProcessorState state;
};
PDFEditedPageContentElementText(PDFPageContentProcessorState state);
PDFEditedPageContentElementText(PDFPageContentProcessorState state, std::vector<Item> items);
virtual ~PDFEditedPageContentElementText() = default;
virtual Type getType() const override;
virtual PDFEditedPageContentElementText* clone() const override;
virtual PDFEditedPageContentElementText* asText() override { return this; }
virtual const PDFEditedPageContentElementText* asText() const override { return this; }
void addItem(Item item);
const std::vector<Item>& getItems() const;
void setItems(const std::vector<Item>& newItems);
bool isEmpty() const { return m_items.empty(); }
private:
std::vector<Item> m_items;
};
class PDFEditedPageContent
{
public:
PDFEditedPageContent() = default;
PDFEditedPageContent(const PDFEditedPageContent&) = delete;
PDFEditedPageContent(PDFEditedPageContent&&) = default;
PDFEditedPageContent& operator=(const PDFEditedPageContent&) = delete;
PDFEditedPageContent& operator=(PDFEditedPageContent&&) = default;
static QString getOperatorToString(PDFPageContentProcessor::Operator operatorValue);
static QString getOperandName(PDFPageContentProcessor::Operator operatorValue, int operandIndex);
void addContentPath(PDFPageContentProcessorState state, QPainterPath path, bool strokePath, bool fillPath);
void addContentImage(PDFPageContentProcessorState state, PDFObject imageObject, QImage image);
void addContentClipping(PDFPageContentProcessorState state, QPainterPath path);
void addContentElement(std::unique_ptr<PDFEditedPageContentElement> element);
std::size_t getElementCount() const { return m_contentElements.size(); }
PDFEditedPageContentElement* getElement(size_t index) const { return m_contentElements.at(index).get(); }
PDFEditedPageContentElement* getBackElement() const;
private:
std::vector<std::unique_ptr<PDFEditedPageContentElement>> m_contentElements;
};
class PDF4QTLIBCORESHARED_EXPORT PDFPageContentEditorProcessor : public PDFPageContentProcessor
{
using BaseClass = PDFPageContentProcessor;
public:
PDFPageContentEditorProcessor(const PDFPage* page,
const PDFDocument* document,
const PDFFontCache* fontCache,
const PDFCMS* CMS,
const PDFOptionalContentActivity* optionalContentActivity,
QTransform pagePointToDevicePointMatrix,
const PDFMeshQualitySettings& meshQualitySettings);
const PDFEditedPageContent& getEditedPageContent() const;
PDFEditedPageContent takeEditedPageContent();
protected:
virtual void performInterceptInstruction(Operator currentOperator, ProcessOrder processOrder, const QByteArray& operatorAsText) override;
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) override;
virtual bool isContentKindSuppressed(ContentKind kind) const override;
virtual bool performOriginalImagePainting(const PDFImage& image, const PDFStream* stream) override;
virtual void performImagePainting(const QImage& image) override;
virtual void performClipping(const QPainterPath& path, Qt::FillRule fillRule) override;
virtual void performSaveGraphicState(ProcessOrder order) override;
virtual void performRestoreGraphicState(ProcessOrder order) override;
virtual void performUpdateGraphicsState(const PDFPageContentProcessorState& state) override;
virtual void performProcessTextSequence(const TextSequence& textSequence, ProcessOrder order) override;
private:
PDFEditedPageContent m_content;
QRectF m_textBoundingRect;
std::stack<QPainterPath> m_clippingPaths;
std::unique_ptr<PDFEditedPageContentElementText> m_contentElementText;
};
} // namespace pdf
#endif // PDFPAGECONTENTEDITORPROCESSOR_H

View File

@ -23,6 +23,7 @@
#include "pdfexecutionpolicy.h"
#include "pdfstreamfilters.h"
#include <QScopeGuard>
#include <QPainterPathStroker>
#include <QtMath>
@ -390,9 +391,10 @@ void PDFPageContentProcessor::performClipping(const QPainterPath& path, Qt::Fill
Q_UNUSED(fillRule);
}
bool PDFPageContentProcessor::performOriginalImagePainting(const PDFImage& image)
bool PDFPageContentProcessor::performOriginalImagePainting(const PDFImage& image, const PDFStream* stream)
{
Q_UNUSED(image);
Q_UNUSED(stream);
return false;
}
@ -485,6 +487,12 @@ void PDFPageContentProcessor::performTextEnd(ProcessOrder order)
Q_UNUSED(order);
}
void PDFPageContentProcessor::performProcessTextSequence(const TextSequence& textSequence, ProcessOrder order)
{
Q_UNUSED(textSequence);
Q_UNUSED(order);
}
bool PDFPageContentProcessor::isContentKindSuppressed(ContentKind kind) const
{
Q_UNUSED(kind);
@ -528,6 +536,15 @@ PDFPageContentProcessor::PDFTransparencyGroup PDFPageContentProcessor::parseTran
return group;
}
void PDFPageContentProcessor::performInterceptInstruction(Operator currentOperator,
ProcessOrder processOrder,
const QByteArray& operatorAsText)
{
Q_UNUSED(currentOperator);
Q_UNUSED(processOrder);
Q_UNUSED(operatorAsText);
}
void PDFPageContentProcessor::processContent(const QByteArray& content)
{
PDFLexicalAnalyzer parser(content.constBegin(), content.constEnd());
@ -738,6 +755,12 @@ void PDFPageContentProcessor::processForm(const QTransform& matrix,
const QByteArray& content,
PDFInteger formStructuralParent)
{
if (isContentKindSuppressed(ContentKind::Forms))
{
// Process of forms is suppressed
return;
}
PDFPageContentProcessorStateGuard guard(this);
PDFTemporaryValueChange structuralParentChangeGuard(&m_structuralParentKey, formStructuralParent);
@ -1129,6 +1152,9 @@ void PDFPageContentProcessor::processCommand(const QByteArray& command)
}
}
performInterceptInstruction(op, ProcessOrder::BeforeOperation, command);
auto callInterceptInstAtEnd = qScopeGuard([&, this](){ performInterceptInstruction(op, ProcessOrder::AfterOperation, command); });
switch (op)
{
case Operator::SetLineWidth:
@ -1855,6 +1881,11 @@ bool PDFPageContentProcessor::isProcessingCancelled() const
return m_operationControl && m_operationControl->isOperationCancelled();
}
bool PDFPageContentProcessor::isTextProcessing() const
{
return m_textBeginEndState > 0;
}
void PDFPageContentProcessor::reportRenderErrorOnce(RenderErrorType type, QString message)
{
if (!m_onceReportedErrors.count(message))
@ -2973,7 +3004,7 @@ void PDFPageContentProcessor::paintXObjectImage(const PDFStream* stream)
PDFImage pdfImage = PDFImage::createImage(m_document, stream, qMove(colorSpace), false, m_graphicState.getRenderingIntent(), this);
if (!performOriginalImagePainting(pdfImage))
if (!performOriginalImagePainting(pdfImage, stream))
{
QImage image = pdfImage.getImage(m_CMS, this, m_operationControl);
@ -3007,6 +3038,12 @@ void PDFPageContentProcessor::reportWarningAboutColorOperatorsInUTP()
void PDFPageContentProcessor::processForm(const PDFStream* stream)
{
if (isContentKindSuppressed(ContentKind::Forms))
{
// Process of forms is suppressed
return;
}
PDFDocumentDataLoaderDecorator loader(getDocument());
const PDFDictionary* streamDictionary = stream->getDictionary();
@ -3165,6 +3202,8 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
return;
}
performProcessTextSequence(textSequence, ProcessOrder::BeforeOperation);
const PDFRealizedFontPointer& font = getRealizedFont();
if (font)
{
@ -3340,6 +3379,8 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
{
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Invalid font, text can't be printed."));
}
performProcessTextSequence(textSequence, ProcessOrder::AfterOperation);
}
PDFRealizedFontPointer PDFPageContentProcessor::getRealizedFontImpl()
@ -3415,7 +3456,7 @@ bool PDFPageContentProcessor::isContentSuppressedByOC(PDFObjectReference ocgOrOc
return false;
}
PDFPageContentProcessor::PDFPageContentProcessorState::PDFPageContentProcessorState() :
PDFPageContentProcessorState::PDFPageContentProcessorState() :
m_currentTransformationMatrix(),
m_strokeColorSpace(),
m_fillColorSpace(),
@ -3456,12 +3497,12 @@ PDFPageContentProcessor::PDFPageContentProcessorState::PDFPageContentProcessorSt
m_strokeColorOriginal = m_fillColorOriginal;
}
PDFPageContentProcessor::PDFPageContentProcessorState::~PDFPageContentProcessorState()
PDFPageContentProcessorState::~PDFPageContentProcessorState()
{
}
PDFPageContentProcessor::PDFPageContentProcessorState& PDFPageContentProcessor::PDFPageContentProcessorState::operator=(const PDFPageContentProcessor::PDFPageContentProcessorState& other)
PDFPageContentProcessorState& PDFPageContentProcessorState::operator=(const PDFPageContentProcessorState& other)
{
setCurrentTransformationMatrix(other.getCurrentTransformationMatrix());
setStrokeColorSpace(other.m_strokeColorSpace);
@ -3504,7 +3545,7 @@ PDFPageContentProcessor::PDFPageContentProcessorState& PDFPageContentProcessor::
return *this;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setCurrentTransformationMatrix(const QTransform& currentTransformationMatrix)
void PDFPageContentProcessorState::setCurrentTransformationMatrix(const QTransform& currentTransformationMatrix)
{
if (m_currentTransformationMatrix != currentTransformationMatrix)
{
@ -3513,7 +3554,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setCurrentTransforma
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setStrokeColorSpace(const QSharedPointer<PDFAbstractColorSpace>& strokeColorSpace)
void PDFPageContentProcessorState::setStrokeColorSpace(const QSharedPointer<PDFAbstractColorSpace>& strokeColorSpace)
{
if (m_strokeColorSpace != strokeColorSpace)
{
@ -3522,7 +3563,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setStrokeColorSpace(
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setFillColorSpace(const QSharedPointer<PDFAbstractColorSpace>& fillColorSpace)
void PDFPageContentProcessorState::setFillColorSpace(const QSharedPointer<PDFAbstractColorSpace>& fillColorSpace)
{
if (m_fillColorSpace != fillColorSpace)
{
@ -3531,7 +3572,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setFillColorSpace(co
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setStrokeColor(const QColor& strokeColor, const PDFColor& originalColor)
void PDFPageContentProcessorState::setStrokeColor(const QColor& strokeColor, const PDFColor& originalColor)
{
if (m_strokeColor != strokeColor || m_strokeColorOriginal != originalColor)
{
@ -3541,7 +3582,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setStrokeColor(const
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setFillColor(const QColor& fillColor, const PDFColor& originalColor)
void PDFPageContentProcessorState::setFillColor(const QColor& fillColor, const PDFColor& originalColor)
{
if (m_fillColor != fillColor || m_fillColorOriginal != originalColor)
{
@ -3551,7 +3592,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setFillColor(const Q
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setLineWidth(PDFReal lineWidth)
void PDFPageContentProcessorState::setLineWidth(PDFReal lineWidth)
{
if (m_lineWidth != lineWidth)
{
@ -3560,7 +3601,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setLineWidth(PDFReal
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setLineCapStyle(Qt::PenCapStyle lineCapStyle)
void PDFPageContentProcessorState::setLineCapStyle(Qt::PenCapStyle lineCapStyle)
{
if (m_lineCapStyle != lineCapStyle)
{
@ -3569,7 +3610,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setLineCapStyle(Qt::
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setLineJoinStyle(Qt::PenJoinStyle lineJoinStyle)
void PDFPageContentProcessorState::setLineJoinStyle(Qt::PenJoinStyle lineJoinStyle)
{
if (m_lineJoinStyle != lineJoinStyle)
{
@ -3578,7 +3619,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setLineJoinStyle(Qt:
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setMitterLimit(PDFReal mitterLimit)
void PDFPageContentProcessorState::setMitterLimit(PDFReal mitterLimit)
{
if (m_mitterLimit != mitterLimit)
{
@ -3587,7 +3628,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setMitterLimit(PDFRe
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setLineDashPattern(PDFLineDashPattern pattern)
void PDFPageContentProcessorState::setLineDashPattern(PDFLineDashPattern pattern)
{
if (m_lineDashPattern != pattern)
{
@ -3596,7 +3637,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setLineDashPattern(P
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntentName(const QByteArray& renderingIntentName)
void PDFPageContentProcessorState::setRenderingIntentName(const QByteArray& renderingIntentName)
{
if (m_renderingIntentName != renderingIntentName)
{
@ -3605,7 +3646,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntentNa
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setFlatness(PDFReal flatness)
void PDFPageContentProcessorState::setFlatness(PDFReal flatness)
{
if (m_flatness != flatness)
{
@ -3614,7 +3655,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setFlatness(PDFReal
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setSmoothness(PDFReal smoothness)
void PDFPageContentProcessorState::setSmoothness(PDFReal smoothness)
{
if (m_smoothness != smoothness)
{
@ -3623,7 +3664,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setSmoothness(PDFRea
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextLeading(PDFReal textLeading)
void PDFPageContentProcessorState::setTextLeading(PDFReal textLeading)
{
if (m_textLeading != textLeading)
{
@ -3632,7 +3673,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextLeading(PDFRe
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextFontSize(PDFReal textFontSize)
void PDFPageContentProcessorState::setTextFontSize(PDFReal textFontSize)
{
if (m_textFontSize != textFontSize)
{
@ -3641,7 +3682,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextFontSize(PDFR
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextKnockout(bool textKnockout)
void PDFPageContentProcessorState::setTextKnockout(bool textKnockout)
{
if (m_textKnockout != textKnockout)
{
@ -3650,7 +3691,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextKnockout(bool
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextLineMatrix(const QTransform& textLineMatrix)
void PDFPageContentProcessorState::setTextLineMatrix(const QTransform& textLineMatrix)
{
if (m_textLineMatrix != textLineMatrix)
{
@ -3659,7 +3700,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextLineMatrix(co
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaStroking(PDFReal alpha)
void PDFPageContentProcessorState::setAlphaStroking(PDFReal alpha)
{
if (m_alphaStroking != alpha)
{
@ -3668,7 +3709,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaStroking(PDF
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaFilling(PDFReal alpha)
void PDFPageContentProcessorState::setAlphaFilling(PDFReal alpha)
{
if (m_alphaFilling != alpha)
{
@ -3677,7 +3718,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaFilling(PDFR
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setBlendMode(BlendMode mode)
void PDFPageContentProcessorState::setBlendMode(BlendMode mode)
{
if (m_blendMode != mode)
{
@ -3686,7 +3727,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setBlendMode(BlendMo
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntent(RenderingIntent renderingIntent)
void PDFPageContentProcessorState::setRenderingIntent(RenderingIntent renderingIntent)
{
if (m_renderingIntent != renderingIntent)
{
@ -3695,21 +3736,21 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setRenderingIntent(R
}
}
QColor PDFPageContentProcessor::PDFPageContentProcessorState::getStrokeColorWithAlpha() const
QColor PDFPageContentProcessorState::getStrokeColorWithAlpha() const
{
QColor color = getStrokeColor();
color.setAlphaF(m_alphaStroking);
return color;
}
QColor PDFPageContentProcessor::PDFPageContentProcessorState::getFillColorWithAlpha() const
QColor PDFPageContentProcessorState::getFillColorWithAlpha() const
{
QColor color = getFillColor();
color.setAlphaF(m_alphaFilling);
return color;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setOverprintMode(PDFOverprintMode overprintMode)
void PDFPageContentProcessorState::setOverprintMode(PDFOverprintMode overprintMode)
{
if (m_overprintMode != overprintMode)
{
@ -3718,7 +3759,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setOverprintMode(PDF
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaIsShape(bool alphaIsShape)
void PDFPageContentProcessorState::setAlphaIsShape(bool alphaIsShape)
{
if (m_alphaIsShape != alphaIsShape)
{
@ -3727,12 +3768,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setAlphaIsShape(bool
}
}
bool PDFPageContentProcessor::PDFPageContentProcessorState::getStrokeAdjustment() const
bool PDFPageContentProcessorState::getStrokeAdjustment() const
{
return m_strokeAdjustment;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setStrokeAdjustment(bool strokeAdjustment)
void PDFPageContentProcessorState::setStrokeAdjustment(bool strokeAdjustment)
{
if (m_strokeAdjustment != strokeAdjustment)
{
@ -3741,12 +3782,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setStrokeAdjustment(
}
}
const PDFDictionary* PDFPageContentProcessor::PDFPageContentProcessorState::getSoftMask() const
const PDFDictionary* PDFPageContentProcessorState::getSoftMask() const
{
return m_softMask;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setSoftMask(const PDFDictionary* softMask)
void PDFPageContentProcessorState::setSoftMask(const PDFDictionary* softMask)
{
if (m_softMask != softMask)
{
@ -3755,12 +3796,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setSoftMask(const PD
}
}
BlackPointCompensationMode PDFPageContentProcessor::PDFPageContentProcessorState::getBlackPointCompensationMode() const
BlackPointCompensationMode PDFPageContentProcessorState::getBlackPointCompensationMode() const
{
return m_blackPointCompensationMode;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setBlackPointCompensationMode(BlackPointCompensationMode blackPointCompensationMode)
void PDFPageContentProcessorState::setBlackPointCompensationMode(BlackPointCompensationMode blackPointCompensationMode)
{
if (m_blackPointCompensationMode != blackPointCompensationMode)
{
@ -3769,12 +3810,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setBlackPointCompens
}
}
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getHalftone() const
PDFObject PDFPageContentProcessorState::getHalftone() const
{
return m_halftone;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setHalftone(const PDFObject& halftone)
void PDFPageContentProcessorState::setHalftone(const PDFObject& halftone)
{
if (m_halftone != halftone)
{
@ -3783,12 +3824,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setHalftone(const PD
}
}
QPointF PDFPageContentProcessor::PDFPageContentProcessorState::getHalftoneOrigin() const
QPointF PDFPageContentProcessorState::getHalftoneOrigin() const
{
return m_halftoneOrigin;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setHalftoneOrigin(const QPointF& halftoneOrigin)
void PDFPageContentProcessorState::setHalftoneOrigin(const QPointF& halftoneOrigin)
{
if (m_halftoneOrigin != halftoneOrigin)
{
@ -3797,12 +3838,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setHalftoneOrigin(co
}
}
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getTransferFunction() const
PDFObject PDFPageContentProcessorState::getTransferFunction() const
{
return m_transferFunction;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTransferFunction(const PDFObject& transferFunction)
void PDFPageContentProcessorState::setTransferFunction(const PDFObject& transferFunction)
{
if (m_transferFunction != transferFunction)
{
@ -3811,12 +3852,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTransferFunction(
}
}
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getUndercolorRemovalFunction() const
PDFObject PDFPageContentProcessorState::getUndercolorRemovalFunction() const
{
return m_undercolorRemovalFunction;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setUndercolorRemovalFunction(const PDFObject& undercolorRemovalFunction)
void PDFPageContentProcessorState::setUndercolorRemovalFunction(const PDFObject& undercolorRemovalFunction)
{
if (m_undercolorRemovalFunction != undercolorRemovalFunction)
{
@ -3825,12 +3866,12 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setUndercolorRemoval
}
}
PDFObject PDFPageContentProcessor::PDFPageContentProcessorState::getBlackGenerationFunction() const
PDFObject PDFPageContentProcessorState::getBlackGenerationFunction() const
{
return m_blackGenerationFunction;
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setBlackGenerationFunction(const PDFObject& blackGenerationFunction)
void PDFPageContentProcessorState::setBlackGenerationFunction(const PDFObject& blackGenerationFunction)
{
if (m_blackGenerationFunction != blackGenerationFunction)
{
@ -3839,7 +3880,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setBlackGenerationFu
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextMatrix(const QTransform& textMatrix)
void PDFPageContentProcessorState::setTextMatrix(const QTransform& textMatrix)
{
if (m_textMatrix != textMatrix)
{
@ -3848,7 +3889,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextMatrix(const
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextRise(PDFReal textRise)
void PDFPageContentProcessorState::setTextRise(PDFReal textRise)
{
if (m_textRise != textRise)
{
@ -3857,7 +3898,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextRise(PDFReal
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextRenderingMode(TextRenderingMode textRenderingMode)
void PDFPageContentProcessorState::setTextRenderingMode(TextRenderingMode textRenderingMode)
{
if (m_textRenderingMode != textRenderingMode)
{
@ -3866,7 +3907,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextRenderingMode
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextFont(const PDFFontPointer& textFont)
void PDFPageContentProcessorState::setTextFont(const PDFFontPointer& textFont)
{
if (m_textFont != textFont)
{
@ -3875,7 +3916,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextFont(const PD
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextHorizontalScaling(PDFReal textHorizontalScaling)
void PDFPageContentProcessorState::setTextHorizontalScaling(PDFReal textHorizontalScaling)
{
if (m_textHorizontalScaling != textHorizontalScaling)
{
@ -3884,7 +3925,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextHorizontalSca
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextWordSpacing(PDFReal textWordSpacing)
void PDFPageContentProcessorState::setTextWordSpacing(PDFReal textWordSpacing)
{
if (m_textWordSpacing != textWordSpacing)
{
@ -3893,7 +3934,7 @@ void PDFPageContentProcessor::PDFPageContentProcessorState::setTextWordSpacing(P
}
}
void PDFPageContentProcessor::PDFPageContentProcessorState::setTextCharacterSpacing(PDFReal textCharacterSpacing)
void PDFPageContentProcessorState::setTextCharacterSpacing(PDFReal textCharacterSpacing)
{
if (m_textCharacterSpacing != textCharacterSpacing)
{

View File

@ -48,6 +48,7 @@ class PDFOptionalContentActivity;
static constexpr const char* PDF_RESOURCE_EXTGSTATE = "ExtGState";
class PDFLineDashPattern
{
public:
@ -79,6 +80,251 @@ private:
PDFReal m_dashOffset = 0.0;
};
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).
/// Please see PDF Reference 1.7, Chapter 4.3 "Graphic State"
class PDFPageContentProcessorState
{
public:
explicit PDFPageContentProcessorState();
~PDFPageContentProcessorState();
PDFPageContentProcessorState(const PDFPageContentProcessorState&) = default;
PDFPageContentProcessorState(PDFPageContentProcessorState&&) = default;
PDFPageContentProcessorState& operator=(PDFPageContentProcessorState&&) = delete;
PDFPageContentProcessorState& operator=(const PDFPageContentProcessorState& other);
enum StateFlag : uint64_t
{
StateUnchanged = 0x0000000000000000,
StateCurrentTransformationMatrix = 0x0000000000000001,
StateStrokeColorSpace = 0x0000000000000002,
StateFillColorSpace = 0x0000000000000004,
StateStrokeColor = 0x0000000000000008,
StateFillColor = 0x0000000000000010,
StateLineWidth = 0x0000000000000020,
StateLineCapStyle = 0x0000000000000040,
StateLineJoinStyle = 0x0000000000000080,
StateMitterLimit = 0x0000000000000100,
StateLineDashPattern = 0x0000000000000200,
StateRenderingIntentName = 0x0000000000000400,
StateFlatness = 0x0000000000000800,
StateSmoothness = 0x0000000000001000,
StateTextMatrix = 0x0000000000002000,
StateTextLineMatrix = 0x0000000000004000,
StateTextCharacterSpacing = 0x0000000000008000,
StateTextWordSpacing = 0x0000000000010000,
StateTextHorizontalScaling = 0x0000000000020000,
StateTextLeading = 0x0000000000040000,
StateTextFont = 0x0000000000080000,
StateTextFontSize = 0x0000000000100000,
StateTextRenderingMode = 0x0000000000200000,
StateTextRise = 0x0000000000400000,
StateTextKnockout = 0x0000000000800000,
StateAlphaStroking = 0x0000000001000000,
StateAlphaFilling = 0x0000000002000000,
StateBlendMode = 0x0000000004000000,
StateRenderingIntent = 0x0000000008000000,
StateOverprint = 0x0000000010000000,
StateAlphaIsShape = 0x0000000020000000,
StateStrokeAdjustment = 0x0000000040000000,
StateSoftMask = 0x0000000080000000,
StateBlackPointCompensation = 0x0000000100000000,
StateBlackGenerationFunction = 0x0000000200000000,
StateUndercolorRemovalFunction = 0x0000000400000000,
StateTransferFunction = 0x0000000800000000,
StateHalftone = 0x0000001000000000,
StateHalftoneOrigin = 0x0000002000000000,
StateAll = 0xFFFFFFFFFFFFFFFF
};
using StateFlags = PDFFlags<StateFlag>;
const QTransform& getCurrentTransformationMatrix() const { return m_currentTransformationMatrix; }
void setCurrentTransformationMatrix(const QTransform& currentTransformationMatrix);
const PDFAbstractColorSpace* getStrokeColorSpace() const { return m_strokeColorSpace.data(); }
void setStrokeColorSpace(const QSharedPointer<PDFAbstractColorSpace>& strokeColorSpace);
const PDFAbstractColorSpace* getFillColorSpace() const { return m_fillColorSpace.data(); }
void setFillColorSpace(const QSharedPointer<PDFAbstractColorSpace>& fillColorSpace);
const QColor& getStrokeColor() const { return m_strokeColor; }
const PDFColor& getStrokeColorOriginal() const { return m_strokeColorOriginal; }
void setStrokeColor(const QColor& strokeColor, const PDFColor& originalColor);
const QColor& getFillColor() const { return m_fillColor; }
const PDFColor& getFillColorOriginal() const { return m_fillColorOriginal; }
void setFillColor(const QColor& fillColor, const PDFColor& originalColor);
PDFReal getLineWidth() const { return m_lineWidth; }
void setLineWidth(PDFReal lineWidth);
Qt::PenCapStyle getLineCapStyle() const { return m_lineCapStyle; }
void setLineCapStyle(Qt::PenCapStyle lineCapStyle);
Qt::PenJoinStyle getLineJoinStyle() const { return m_lineJoinStyle; }
void setLineJoinStyle(Qt::PenJoinStyle lineJoinStyle);
PDFReal getMitterLimit() const { return m_mitterLimit; }
void setMitterLimit(PDFReal mitterLimit);
const PDFLineDashPattern& getLineDashPattern() const { return m_lineDashPattern; }
void setLineDashPattern(PDFLineDashPattern pattern);
const QByteArray& getRenderingIntentName() const { return m_renderingIntentName; }
void setRenderingIntentName(const QByteArray& renderingIntentName);
PDFReal getFlatness() const { return m_flatness; }
void setFlatness(PDFReal flatness);
PDFReal getSmoothness() const { return m_smoothness; }
void setSmoothness(PDFReal smoothness);
StateFlags getStateFlags() const { return m_stateFlags; }
void setStateFlags(StateFlags stateFlags) { m_stateFlags = stateFlags; }
PDFReal getTextCharacterSpacing() const { return m_textCharacterSpacing; }
void setTextCharacterSpacing(PDFReal textCharacterSpacing);
PDFReal getTextWordSpacing() const { return m_textWordSpacing; }
void setTextWordSpacing(PDFReal textWordSpacing);
PDFReal getTextHorizontalScaling() const { return m_textHorizontalScaling; }
void setTextHorizontalScaling(PDFReal textHorizontalScaling);
PDFReal getTextLeading() const { return m_textLeading; }
void setTextLeading(PDFReal textLeading);
const PDFFontPointer& getTextFont() const { return m_textFont; }
void setTextFont(const PDFFontPointer& textFont);
PDFReal getTextFontSize() const { return m_textFontSize; }
void setTextFontSize(PDFReal textFontSize);
TextRenderingMode getTextRenderingMode() const { return m_textRenderingMode; }
void setTextRenderingMode(TextRenderingMode textRenderingMode);
PDFReal getTextRise() const { return m_textRise; }
void setTextRise(PDFReal textRise);
bool getTextKnockout() const { return m_textKnockout; }
void setTextKnockout(bool textKnockout);
const QTransform& getTextMatrix() const { return m_textMatrix; }
void setTextMatrix(const QTransform& textMatrix);
const QTransform& getTextLineMatrix() const { return m_textLineMatrix; }
void setTextLineMatrix(const QTransform& textLineMatrix);
PDFReal getAlphaStroking() const { return m_alphaStroking; }
void setAlphaStroking(PDFReal alpha);
PDFReal getAlphaFilling() const { return m_alphaFilling; }
void setAlphaFilling(PDFReal alpha);
BlendMode getBlendMode() const { return m_blendMode; }
void setBlendMode(BlendMode mode);
RenderingIntent getRenderingIntent() const { return m_renderingIntent; }
void setRenderingIntent(RenderingIntent renderingIntent);
/// Returns stroke color with alpha channel
QColor getStrokeColorWithAlpha() const;
/// Returns fill color with alpha channel
QColor getFillColorWithAlpha() const;
PDFOverprintMode getOverprintMode() const { return m_overprintMode; }
void setOverprintMode(PDFOverprintMode overprintMode);
bool getAlphaIsShape() const { return m_alphaIsShape; }
void setAlphaIsShape(bool alphaIsShape);
bool getStrokeAdjustment() const;
void setStrokeAdjustment(bool strokeAdjustment);
const PDFDictionary* getSoftMask() const;
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:
QTransform m_currentTransformationMatrix;
PDFColorSpacePointer m_strokeColorSpace;
PDFColorSpacePointer m_fillColorSpace;
QColor m_strokeColor;
PDFColor m_strokeColorOriginal;
QColor m_fillColor;
PDFColor m_fillColorOriginal;
PDFReal m_lineWidth;
Qt::PenCapStyle m_lineCapStyle;
Qt::PenJoinStyle m_lineJoinStyle;
PDFReal m_mitterLimit;
PDFLineDashPattern m_lineDashPattern;
QByteArray m_renderingIntentName;
PDFReal m_flatness;
PDFReal m_smoothness;
PDFReal m_textCharacterSpacing; // T_c
PDFReal m_textWordSpacing; // T_w
PDFReal m_textHorizontalScaling; // T_h, percentage
PDFReal m_textLeading; // T_l
PDFFontPointer m_textFont; // Text font
PDFReal m_textFontSize; // T_fs
TextRenderingMode m_textRenderingMode; // Text rendering mode
PDFReal m_textRise; // T_rise
bool m_textKnockout;
QTransform m_textMatrix;
QTransform m_textLineMatrix;
PDFReal m_alphaStroking;
PDFReal m_alphaFilling;
BlendMode m_blendMode;
RenderingIntent m_renderingIntent;
PDFOverprintMode m_overprintMode;
bool m_alphaIsShape;
bool m_strokeAdjustment;
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;
};
/// Process the contents of the page.
class PDF4QTLIBCORESHARED_EXPORT PDFPageContentProcessor : public PDFRenderErrorReporter
{
@ -253,6 +499,9 @@ public:
/// Returns true, if page content processing is being cancelled
bool isProcessingCancelled() const;
/// Returns true, if we are in a text processing
bool isTextProcessing() const;
protected:
struct PDFTransparencyGroup
@ -296,257 +545,21 @@ protected:
friend class PDFPageContentProcessor;
};
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).
/// Please see PDF Reference 1.7, Chapter 4.3 "Graphic State"
class PDFPageContentProcessorState
{
public:
explicit PDFPageContentProcessorState();
~PDFPageContentProcessorState();
PDFPageContentProcessorState(const PDFPageContentProcessorState&) = default;
PDFPageContentProcessorState(PDFPageContentProcessorState&&) = default;
PDFPageContentProcessorState& operator=(PDFPageContentProcessorState&&) = delete;
PDFPageContentProcessorState& operator=(const PDFPageContentProcessorState& other);
enum StateFlag : uint64_t
{
StateUnchanged = 0x0000000000000000,
StateCurrentTransformationMatrix = 0x0000000000000001,
StateStrokeColorSpace = 0x0000000000000002,
StateFillColorSpace = 0x0000000000000004,
StateStrokeColor = 0x0000000000000008,
StateFillColor = 0x0000000000000010,
StateLineWidth = 0x0000000000000020,
StateLineCapStyle = 0x0000000000000040,
StateLineJoinStyle = 0x0000000000000080,
StateMitterLimit = 0x0000000000000100,
StateLineDashPattern = 0x0000000000000200,
StateRenderingIntentName = 0x0000000000000400,
StateFlatness = 0x0000000000000800,
StateSmoothness = 0x0000000000001000,
StateTextMatrix = 0x0000000000002000,
StateTextLineMatrix = 0x0000000000004000,
StateTextCharacterSpacing = 0x0000000000008000,
StateTextWordSpacing = 0x0000000000010000,
StateTextHorizontalScaling = 0x0000000000020000,
StateTextLeading = 0x0000000000040000,
StateTextFont = 0x0000000000080000,
StateTextFontSize = 0x0000000000100000,
StateTextRenderingMode = 0x0000000000200000,
StateTextRise = 0x0000000000400000,
StateTextKnockout = 0x0000000000800000,
StateAlphaStroking = 0x0000000001000000,
StateAlphaFilling = 0x0000000002000000,
StateBlendMode = 0x0000000004000000,
StateRenderingIntent = 0x0000000008000000,
StateOverprint = 0x0000000010000000,
StateAlphaIsShape = 0x0000000020000000,
StateStrokeAdjustment = 0x0000000040000000,
StateSoftMask = 0x0000000080000000,
StateBlackPointCompensation = 0x0000000100000000,
StateBlackGenerationFunction = 0x0000000200000000,
StateUndercolorRemovalFunction = 0x0000000400000000,
StateTransferFunction = 0x0000000800000000,
StateHalftone = 0x0000001000000000,
StateHalftoneOrigin = 0x0000002000000000,
StateAll = 0xFFFFFFFFFFFFFFFF
};
using StateFlags = PDFFlags<StateFlag>;
const QTransform& getCurrentTransformationMatrix() const { return m_currentTransformationMatrix; }
void setCurrentTransformationMatrix(const QTransform& currentTransformationMatrix);
const PDFAbstractColorSpace* getStrokeColorSpace() const { return m_strokeColorSpace.data(); }
void setStrokeColorSpace(const QSharedPointer<PDFAbstractColorSpace>& strokeColorSpace);
const PDFAbstractColorSpace* getFillColorSpace() const { return m_fillColorSpace.data(); }
void setFillColorSpace(const QSharedPointer<PDFAbstractColorSpace>& fillColorSpace);
const QColor& getStrokeColor() const { return m_strokeColor; }
const PDFColor& getStrokeColorOriginal() const { return m_strokeColorOriginal; }
void setStrokeColor(const QColor& strokeColor, const PDFColor& originalColor);
const QColor& getFillColor() const { return m_fillColor; }
const PDFColor& getFillColorOriginal() const { return m_fillColorOriginal; }
void setFillColor(const QColor& fillColor, const PDFColor& originalColor);
PDFReal getLineWidth() const { return m_lineWidth; }
void setLineWidth(PDFReal lineWidth);
Qt::PenCapStyle getLineCapStyle() const { return m_lineCapStyle; }
void setLineCapStyle(Qt::PenCapStyle lineCapStyle);
Qt::PenJoinStyle getLineJoinStyle() const { return m_lineJoinStyle; }
void setLineJoinStyle(Qt::PenJoinStyle lineJoinStyle);
PDFReal getMitterLimit() const { return m_mitterLimit; }
void setMitterLimit(PDFReal mitterLimit);
const PDFLineDashPattern& getLineDashPattern() const { return m_lineDashPattern; }
void setLineDashPattern(PDFLineDashPattern pattern);
const QByteArray& getRenderingIntentName() const { return m_renderingIntentName; }
void setRenderingIntentName(const QByteArray& renderingIntentName);
PDFReal getFlatness() const { return m_flatness; }
void setFlatness(PDFReal flatness);
PDFReal getSmoothness() const { return m_smoothness; }
void setSmoothness(PDFReal smoothness);
StateFlags getStateFlags() const { return m_stateFlags; }
void setStateFlags(StateFlags stateFlags) { m_stateFlags = stateFlags; }
PDFReal getTextCharacterSpacing() const { return m_textCharacterSpacing; }
void setTextCharacterSpacing(PDFReal textCharacterSpacing);
PDFReal getTextWordSpacing() const { return m_textWordSpacing; }
void setTextWordSpacing(PDFReal textWordSpacing);
PDFReal getTextHorizontalScaling() const { return m_textHorizontalScaling; }
void setTextHorizontalScaling(PDFReal textHorizontalScaling);
PDFReal getTextLeading() const { return m_textLeading; }
void setTextLeading(PDFReal textLeading);
const PDFFontPointer& getTextFont() const { return m_textFont; }
void setTextFont(const PDFFontPointer& textFont);
PDFReal getTextFontSize() const { return m_textFontSize; }
void setTextFontSize(PDFReal textFontSize);
TextRenderingMode getTextRenderingMode() const { return m_textRenderingMode; }
void setTextRenderingMode(TextRenderingMode textRenderingMode);
PDFReal getTextRise() const { return m_textRise; }
void setTextRise(PDFReal textRise);
bool getTextKnockout() const { return m_textKnockout; }
void setTextKnockout(bool textKnockout);
const QTransform& getTextMatrix() const { return m_textMatrix; }
void setTextMatrix(const QTransform& textMatrix);
const QTransform& getTextLineMatrix() const { return m_textLineMatrix; }
void setTextLineMatrix(const QTransform& textLineMatrix);
PDFReal getAlphaStroking() const { return m_alphaStroking; }
void setAlphaStroking(PDFReal alpha);
PDFReal getAlphaFilling() const { return m_alphaFilling; }
void setAlphaFilling(PDFReal alpha);
BlendMode getBlendMode() const { return m_blendMode; }
void setBlendMode(BlendMode mode);
RenderingIntent getRenderingIntent() const { return m_renderingIntent; }
void setRenderingIntent(RenderingIntent renderingIntent);
/// Returns stroke color with alpha channel
QColor getStrokeColorWithAlpha() const;
/// Returns fill color with alpha channel
QColor getFillColorWithAlpha() const;
PDFOverprintMode getOverprintMode() const { return m_overprintMode; }
void setOverprintMode(PDFOverprintMode overprintMode);
bool getAlphaIsShape() const { return m_alphaIsShape; }
void setAlphaIsShape(bool alphaIsShape);
bool getStrokeAdjustment() const;
void setStrokeAdjustment(bool strokeAdjustment);
const PDFDictionary* getSoftMask() const;
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:
QTransform m_currentTransformationMatrix;
PDFColorSpacePointer m_strokeColorSpace;
PDFColorSpacePointer m_fillColorSpace;
QColor m_strokeColor;
PDFColor m_strokeColorOriginal;
QColor m_fillColor;
PDFColor m_fillColorOriginal;
PDFReal m_lineWidth;
Qt::PenCapStyle m_lineCapStyle;
Qt::PenJoinStyle m_lineJoinStyle;
PDFReal m_mitterLimit;
PDFLineDashPattern m_lineDashPattern;
QByteArray m_renderingIntentName;
PDFReal m_flatness;
PDFReal m_smoothness;
PDFReal m_textCharacterSpacing; // T_c
PDFReal m_textWordSpacing; // T_w
PDFReal m_textHorizontalScaling; // T_h, percentage
PDFReal m_textLeading; // T_l
PDFFontPointer m_textFont; // Text font
PDFReal m_textFontSize; // T_fs
TextRenderingMode m_textRenderingMode; // Text rendering mode
PDFReal m_textRise; // T_rise
bool m_textKnockout;
QTransform m_textMatrix;
QTransform m_textLineMatrix;
PDFReal m_alphaStroking;
PDFReal m_alphaFilling;
BlendMode m_blendMode;
RenderingIntent m_renderingIntent;
PDFOverprintMode m_overprintMode;
bool m_alphaIsShape;
bool m_strokeAdjustment;
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;
};
enum class ProcessOrder
{
BeforeOperation,
AfterOperation
};
/// This function is used, when we directly want to intercept content
/// stream instructions and operands.
/// \param currentOperator Current operator
/// \param processOrder Mark before/after instruction is executed
/// \param operatorAsText Operator converted to text
virtual void performInterceptInstruction(Operator currentOperator,
ProcessOrder processOrder,
const QByteArray& operatorAsText);
/// This function has to be implemented in the client drawing implementation, it should
/// draw the path according to the parameters.
/// \param path Path, which should be drawn (can be emtpy - in that case nothing happens)
@ -575,8 +588,9 @@ protected:
/// original image, it should return true, so no conversion to QImage occurs,
/// which can be performance bottleneck.
/// \param image Image
/// \param stream Stream, from which image originated
/// \returns true, if image is successfully processed
virtual bool performOriginalImagePainting(const PDFImage& image);
virtual bool performOriginalImagePainting(const PDFImage& image, const PDFStream* stream);
/// This function has to be implemented in the client drawing implementation, it should
/// draw the image.
@ -645,6 +659,9 @@ protected:
/// Implement to respond to text end operator
virtual void performTextEnd(ProcessOrder order);
/// Implement to respond to text sequence processing
virtual void performProcessTextSequence(const TextSequence& textSequence, ProcessOrder order);
enum class ContentKind
{
Shapes, ///< General shapes (they can be also shaded / tiled)
@ -652,6 +669,7 @@ protected:
Images, ///< Images
Shading, ///< Shading
Tiling, ///< Tiling
Forms, ///< Forms
};
/// Override this function to disable particular content type (for example
@ -706,6 +724,9 @@ protected:
/// Returns optional content activity
const PDFOptionalContentActivity* getOptionalContentActivity() const { return m_optionalContentActivity; }
/// Returns operand for current operator
const PDFFlatArray<PDFLexicalAnalyzer::Token, 33>& getOperands() const { return m_operands; }
class PDF4QTLIBCORESHARED_EXPORT PDFTransparencyGroupGuard
{
public:
@ -857,8 +878,6 @@ private:
template<typename... Operands>
inline QColor getColorFromColorSpace(const PDFAbstractColorSpace* colorSpace, Operands... operands)
{
constexpr const size_t operandCount = sizeof...(Operands);
const size_t colorSpaceComponentCount = colorSpace->getColorComponentCount();
if (operandCount == colorSpaceComponentCount)

View File

@ -2615,8 +2615,10 @@ void PDFTransparencyRenderer::performTextEnd(ProcessOrder order)
}
}
bool PDFTransparencyRenderer::performOriginalImagePainting(const PDFImage& image)
bool PDFTransparencyRenderer::performOriginalImagePainting(const PDFImage& image, const PDFStream* stream)
{
Q_UNUSED(stream);
PDFFloatBitmap texture = getImage(image);
if (m_settings.flags.testFlag(PDFTransparencyRendererSettings::SmoothImageTransformation) && image.isInterpolated())

View File

@ -703,7 +703,7 @@ public:
virtual void performEndTransparencyGroup(ProcessOrder order, const PDFTransparencyGroup& transparencyGroup) override;
virtual void performTextBegin(ProcessOrder order) override;
virtual void performTextEnd(ProcessOrder order) override;
virtual bool performOriginalImagePainting(const PDFImage& image) override;
virtual bool performOriginalImagePainting(const PDFImage& image, const PDFStream* stream) override;
virtual void performImagePainting(const QImage& image) override;
virtual void performMeshPainting(const PDFMesh& mesh) override;

View File

@ -21,6 +21,7 @@
#include "pdfdrawspacecontroller.h"
#include "pdfwidgetutils.h"
#include "pdfutils.h"
#include "pdfpagecontenteditorprocessor.h"
#include <QBuffer>
#include <QPainter>
@ -61,6 +62,7 @@ Qt::CursorShape PDFPageContentElement::getCursorShapeForManipulationMode(uint mo
case Pt1:
case Pt2:
case Translate:
case Select:
return Qt::ArrowCursor;
case Top:
@ -154,6 +156,7 @@ void PDFPageContentElement::performRectangleManipulation(QRectF& rectangle,
switch (mode)
{
case None:
case Select:
break;
case Translate:
@ -2533,4 +2536,52 @@ void PDFPageContentElementTextBox::setAlignment(const Qt::Alignment& newAlignmen
m_alignment = newAlignment;
}
PDFPageContentElementEdited::PDFPageContentElementEdited(const PDFEditedPageContentElement* element) :
m_element(element->clone())
{
}
PDFPageContentElementEdited::~PDFPageContentElementEdited()
{
}
PDFPageContentElementEdited* PDFPageContentElementEdited::clone() const
{
return new PDFPageContentElementEdited(m_element.get());
}
void PDFPageContentElementEdited::drawPage(QPainter* painter, PDFInteger pageIndex, const PDFPrecompiledPage* compiledPage, PDFTextLayoutGetter& layoutGetter, const QTransform& pagePointToDevicePointMatrix, QList<PDFRenderError>& errors) const
{
}
uint PDFPageContentElementEdited::getManipulationMode(const QPointF& point, PDFReal snapPointDistanceThreshold) const
{
Q_UNUSED(point);
Q_UNUSED(snapPointDistanceThreshold);
return None;
}
void PDFPageContentElementEdited::performManipulation(uint mode, const QPointF& offset)
{
Q_UNUSED(mode);
Q_UNUSED(offset);
}
QRectF PDFPageContentElementEdited::getBoundingBox() const
{
return m_element->getState()
}
void PDFPageContentElementEdited::setSize(QSizeF size)
{
}
QString PDFPageContentElementEdited::getDescription() const
{
}
} // namespace pdf

View File

@ -37,6 +37,7 @@ namespace pdf
class PDFWidget;
class PDFDocument;
class PDFPageContentScene;
class PDFEditedPageContentElement;
class PDF4QTLIBWIDGETSSHARED_EXPORT PDFPageContentElement
{
@ -89,6 +90,7 @@ public:
enum ManipulationModes : uint
{
None = 0,
Select,
Translate,
Top,
Left,
@ -353,6 +355,24 @@ private:
Qt::Alignment m_alignment = Qt::AlignCenter;
};
class PDF4QTLIBWIDGETSSHARED_EXPORT PDFPageContentElementEdited : public PDFPageContentElement
{
public:
PDFPageContentElementEdited(const PDFEditedPageContentElement* element);
virtual ~PDFPageContentElementEdited();
virtual PDFPageContentElementEdited* clone() const override;
virtual void drawPage(QPainter* painter, PDFInteger pageIndex, const PDFPrecompiledPage* compiledPage, PDFTextLayoutGetter& layoutGetter, const QTransform& pagePointToDevicePointMatrix, QList<PDFRenderError>& errors) const override;
virtual uint getManipulationMode(const QPointF& point, PDFReal snapPointDistanceThreshold) const override;
virtual void performManipulation(uint mode, const QPointF& offset) override;
virtual QRectF getBoundingBox() const override;
virtual void setSize(QSizeF size) override;
virtual QString getDescription() const override;
private:
std::unique_ptr<PDFEditedPageContentElement> m_element;
};
class PDF4QTLIBWIDGETSSHARED_EXPORT PDFPageContentElementManipulator : public QObject
{
Q_OBJECT

View File

@ -0,0 +1,32 @@
# Copyright (C) 2023 Jakub Melka
#
# This file is part of PDF4QT.
#
# PDF4QT is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# with the written consent of the copyright owner, any later version.
#
# PDF4QT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
add_library(EditorPlugin SHARED
editorplugin.cpp
icons.qrc
)
target_link_libraries(EditorPlugin PRIVATE Pdf4QtLibCore Pdf4QtLibWidgets Qt6::Core Qt6::Gui Qt6::Widgets Qt6::OpenGLWidgets Qt6::Xml)
set_target_properties(EditorPlugin PROPERTIES
VERSION ${PDF4QT_VERSION}
SOVERSION ${PDF4QT_VERSION}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PDF4QT_PLUGINS_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PDF4QT_PLUGINS_DIR})
install(TARGETS EditorPlugin RUNTIME DESTINATION ${PDF4QT_PLUGINS_DIR} LIBRARY DESTINATION ${PDF4QT_PLUGINS_DIR})

View File

@ -0,0 +1,7 @@
{
"Name" : "Editor",
"Author" : "Jakub Melka",
"Version" : "1.0.0",
"License" : "LGPL v3",
"Description" : "Edit content of PDF document."
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#21E900" cx="12" cy="12" r="11.098"/>
<g>
<path fill="#FFFFFF" d="M10.896,18.354c-0.24,0-0.474-0.087-0.658-0.247L6.28,14.649c-0.416-0.363-0.459-0.995-0.095-1.411
c0.363-0.414,0.996-0.458,1.411-0.095l3.042,2.656l5.56-9.652c0.274-0.478,0.887-0.643,1.365-0.368
c0.479,0.276,0.644,0.887,0.367,1.366l-6.167,10.707c-0.149,0.26-0.407,0.438-0.702,0.487
C11.005,18.349,10.95,18.354,10.896,18.354z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 889 B

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M22.52,5.539c-0.157-0.208-0.406-0.292-0.655-0.239c-0.214,0.042-0.379,0.179-0.491,0.411
c-0.093,0.199-0.189,0.396-0.286,0.594L21,6.484l-0.076-0.036l0.385-0.784c0.228-0.49,0.318-0.908,0.283-1.315
c-0.098-1.286-0.982-2.325-2.247-2.646C19.099,1.643,18.85,1.611,18.6,1.611c-1.073,0-2.012,0.56-2.448,1.46
c-2.148,4.415-4.288,8.831-6.421,13.249c-0.104,0.213-0.163,0.475-0.158,0.72c0.017,1.006,0.06,2.014,0.102,2.961
c0.009,0.183,0.021,0.43,0.146,0.596c0.143,0.19,0.136,0.335-0.034,0.595c-0.023,0.038-0.041,0.081-0.062,0.13
c-0.147,0.347-0.01,0.728,0.319,0.886c0.087,0.043,0.179,0.065,0.274,0.065c0.238,0,0.458-0.135,0.586-0.355
c0.042-0.071,0.077-0.146,0.112-0.221c0.03-0.067,0.062-0.132,0.093-0.187c0.012-0.017,0.042-0.037,0.049-0.041
c0.349-0.018,0.665-0.14,0.964-0.369c0.743-0.55,1.489-1.097,2.238-1.637c0.252-0.182,0.443-0.413,0.588-0.707
c1.016-2.102,2.035-4.198,3.055-6.297c0.771-1.588,1.544-3.177,2.314-4.767c0.008-0.017,0.016-0.033,0.024-0.05
c0.024,0.012,0.049,0.025,0.073,0.037l-2.31,4.762c-0.052,0.104-0.095,0.209-0.124,0.317c-0.086,0.35,0.112,0.688,0.463,0.782
c0.063,0.018,0.123,0.026,0.183,0.026c0.182,0,0.441-0.083,0.637-0.477l2.249-4.64c0.224-0.458,0.446-0.915,0.67-1.373
l0.401-0.827C22.709,6.001,22.686,5.755,22.52,5.539z M18.052,9.316c-0.135,0.285-0.27,0.563-0.401,0.838l-1.302,2.679
c-0.826,1.701-1.652,3.403-2.476,5.104c-0.075,0.152-0.108,0.107-0.187,0.093c-1.024-0.164-1.89-0.596-2.646-1.32
c-0.025-0.023-0.032-0.034-0.014-0.061c1.055-2.166,2.105-4.33,3.156-6.496l1.064-2.195C16.184,8.41,17.113,8.861,18.052,9.316z
M18.562,2.766v0.169c0.666,0,1.169,0.278,1.497,0.825c0.266,0.446,0.273,0.889,0.022,1.395c-0.349,0.691-0.685,1.388-1.021,2.084
l-0.405,0.841c-0.008,0.012-0.014,0.024-0.02,0.038l-2.804-1.358c0.071-0.151,0.143-0.298,0.212-0.442l0.466-0.963
c0.253-0.521,0.506-1.042,0.756-1.563c0.271-0.564,0.704-0.852,1.281-0.858L18.562,2.766L18.562,2.766z M12.541,19.15l-0.27,0.198
c-0.317,0.231-0.635,0.463-0.948,0.695c-0.119,0.086-0.185,0.105-0.25,0.071c-0.055-0.028-0.081-0.068-0.086-0.237
c-0.012-0.349-0.025-0.693-0.039-1.053l-0.02-0.496C11.438,18.672,11.96,18.939,12.541,19.15z"/>
</g>
<g>
<path fill="#292D32" d="M7.684,22.389c-1.105,0-1.947-0.215-2.457-0.847C4.544,20.695,4.598,19.261,5.4,16.89
c0.505-1.492,0.518-2.515,0.035-2.955c-0.804-0.737-2.982-0.025-3.682,0.282l-0.418-0.951c0.339-0.147,3.359-1.42,4.801-0.098
c0.82,0.751,0.903,2.116,0.247,4.055c-0.648,1.916-0.766,3.15-0.349,3.667c0.465,0.578,1.855,0.505,3.152,0.358l0.116,1.032
C8.716,22.346,8.174,22.389,7.684,22.389z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M22.52,5.539c-0.156-0.208-0.406-0.292-0.654-0.239c-0.215,0.042-0.379,0.179-0.491,0.411
c-0.093,0.199-0.188,0.396-0.286,0.594L21,6.484l-0.076-0.036l0.385-0.784c0.229-0.49,0.318-0.908,0.283-1.315
c-0.098-1.286-0.982-2.325-2.246-2.646C19.1,1.643,18.85,1.611,18.6,1.611c-1.072,0-2.012,0.56-2.447,1.46
c-2.148,4.415-4.289,8.831-6.421,13.25c-0.104,0.213-0.163,0.475-0.158,0.72c0.017,1.006,0.06,2.015,0.102,2.961
c0.009,0.183,0.021,0.431,0.146,0.597c0.143,0.189,0.136,0.334-0.034,0.594c-0.023,0.039-0.041,0.082-0.062,0.131
c-0.147,0.347-0.01,0.728,0.319,0.886c0.087,0.043,0.179,0.065,0.274,0.065c0.238,0,0.458-0.135,0.586-0.355
c0.042-0.07,0.077-0.146,0.112-0.221c0.03-0.067,0.062-0.133,0.093-0.188c0.012-0.017,0.042-0.037,0.049-0.041
c0.349-0.018,0.665-0.14,0.964-0.369c0.743-0.55,1.489-1.097,2.237-1.637c0.252-0.182,0.443-0.413,0.589-0.707
c1.016-2.102,2.034-4.197,3.055-6.297c0.771-1.588,1.544-3.177,2.313-4.767c0.009-0.017,0.017-0.033,0.024-0.05
c0.024,0.012,0.05,0.025,0.073,0.037l-2.311,4.762c-0.051,0.104-0.095,0.209-0.123,0.317c-0.086,0.35,0.111,0.688,0.463,0.782
c0.063,0.019,0.123,0.026,0.183,0.026c0.183,0,0.44-0.084,0.638-0.478l2.248-4.64c0.225-0.458,0.446-0.915,0.67-1.373l0.401-0.827
C22.709,6.001,22.686,5.755,22.52,5.539z M18.052,9.316c-0.135,0.285-0.27,0.563-0.401,0.838l-1.301,2.679
c-0.826,1.701-1.652,3.403-2.477,5.104c-0.075,0.151-0.107,0.106-0.188,0.092c-1.023-0.163-1.89-0.596-2.646-1.319
c-0.025-0.022-0.032-0.034-0.014-0.062c1.055-2.166,2.105-4.33,3.156-6.496l1.064-2.195C16.184,8.41,17.113,8.861,18.052,9.316z
M18.563,2.766v0.169c0.666,0,1.168,0.278,1.496,0.825c0.267,0.446,0.273,0.889,0.022,1.395c-0.349,0.691-0.685,1.388-1.021,2.084
L18.654,8.08c-0.008,0.012-0.014,0.024-0.02,0.038L15.831,6.76c0.071-0.151,0.144-0.298,0.212-0.442l0.466-0.963
c0.253-0.521,0.507-1.042,0.757-1.563c0.271-0.564,0.703-0.852,1.28-0.858L18.563,2.766L18.563,2.766z M12.541,19.15l-0.27,0.197
c-0.317,0.231-0.635,0.463-0.948,0.695c-0.119,0.086-0.185,0.105-0.25,0.07c-0.055-0.027-0.081-0.067-0.086-0.236
c-0.012-0.35-0.025-0.693-0.039-1.053l-0.02-0.496C11.438,18.672,11.96,18.939,12.541,19.15z"/>
</g>
<g>
<path fill="#292D32" d="M7.684,22.389c-1.105,0-1.947-0.215-2.457-0.847c-0.683-0.847-0.629-2.28,0.173-4.651
c0.505-1.492,0.518-2.516,0.035-2.955c-0.804-0.738-2.982-0.025-3.682,0.281l-0.418-0.951c0.339-0.146,3.359-1.419,4.801-0.098
c0.82,0.751,0.903,2.116,0.247,4.055c-0.648,1.916-0.766,3.15-0.349,3.668c0.465,0.578,1.855,0.504,3.152,0.357l0.116,1.031
C8.716,22.346,8.174,22.389,7.684,22.389z"/>
</g>
</g>
<circle fill="#F12D32" cx="8.572" cy="5.808" r="4.197"/>
<g>
<path fill="#FFFFFF" d="M6.366,7.536c0-0.004,0-0.009,0-0.013C6.367,7.508,6.375,7.502,6.377,7.49
c0.006-0.127,0.07-0.231,0.157-0.32c0.438-0.433,0.866-0.871,1.301-1.302c0.066-0.063,0.066-0.049,0-0.115
C7.401,5.316,6.969,4.88,6.531,4.446C6.457,4.373,6.402,4.285,6.384,4.18c-0.006-0.028-0.012-0.051-0.018-0.08
c0-0.004,0-0.011,0-0.016C6.37,4.071,6.377,4.057,6.377,4.042c0.019-0.201,0.161-0.374,0.365-0.419
c0.033-0.008,0.07-0.015,0.106-0.022c0.005,0,0.008,0,0.008,0C6.867,3.604,6.878,3.61,6.886,3.61
c0.141,0.005,0.249,0.076,0.344,0.174c0.435,0.437,0.874,0.873,1.312,1.31c0.027,0.026,0.048,0.032,0.073,0
c0.006-0.009,0.015-0.02,0.027-0.027C9.076,4.63,9.51,4.199,9.945,3.765c0.072-0.076,0.159-0.125,0.259-0.147
c0.032-0.004,0.059-0.011,0.091-0.016h0.005c0.018,0.002,0.036,0.009,0.049,0.009c0.237,0.017,0.442,0.261,0.429,0.495
c-0.013,0.14-0.069,0.251-0.164,0.345c-0.44,0.438-0.88,0.875-1.315,1.315c-0.042,0.042-0.042,0.042,0,0.086
c0.435,0.437,0.871,0.868,1.306,1.307c0.019,0.013,0.034,0.035,0.051,0.048c0.227,0.247,0.136,0.652-0.177,0.768
c-0.2,0.076-0.38,0.035-0.531-0.116C9.51,7.421,9.064,6.976,8.629,6.539c-0.048-0.05-0.048-0.05-0.096,0
c-0.444,0.44-0.887,0.888-1.329,1.328C7.068,8,6.907,8.042,6.727,7.992c-0.184-0.05-0.293-0.178-0.339-0.365
C6.375,7.595,6.372,7.565,6.366,7.536z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M4.679,14.168c0-2.972,2.008-5.06,4.817-5.06c2.811,0,4.735,2.088,4.735,5.06
c0,2.889-1.848,5.057-4.815,5.057C6.604,19.225,4.679,17.057,4.679,14.168z"/>
</g>
<path fill="#292D32" d="M12.926,7.973c0,0.318,0.227,0.577,0.506,0.577h5.382c0.277,0,0.507-0.259,0.507-0.577l0,0
c0-0.318-0.229-0.576-0.507-0.576h-5.382C13.152,7.396,12.926,7.655,12.926,7.973L12.926,7.973z"/>
<path fill="#292D32" d="M16.121,11.169c0.317,0,0.576-0.228,0.576-0.508V5.283c0-0.279-0.259-0.508-0.576-0.508l0,0
c-0.315,0-0.574,0.229-0.574,0.508v5.38C15.547,10.943,15.806,11.169,16.121,11.169L16.121,11.169z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="none" stroke="#292D32" stroke-width="1.5" stroke-miterlimit="10" d="M2.219,16.916c0,0,1.829-5.375,9.253-3.27
c7.8,2.213,8.95,1.967,10.308-0.605"/>
<path fill="#292D32" d="M14.854,9.8c0,0.271,0.192,0.49,0.429,0.49h4.568c0.236,0,0.431-0.22,0.431-0.49l0,0
c0-0.27-0.193-0.489-0.431-0.489h-4.568C15.047,9.311,14.854,9.53,14.854,9.8L14.854,9.8z"/>
<path fill="#292D32" d="M17.567,12.516c0.27,0,0.489-0.196,0.489-0.433V7.517c0-0.237-0.22-0.432-0.489-0.432l0,0
c-0.269,0-0.488,0.194-0.488,0.432v4.565C17.079,12.322,17.299,12.516,17.567,12.516L17.567,12.516z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<circle fill="#292D32" cx="3.012" cy="14.734" r="1.631"/>
<path fill="#292D32" d="M22.55,14.455c-0.039-0.09-0.091-0.176-0.163-0.242l-2.266-2.265c-0.294-0.297-0.771-0.297-1.064,0
c-0.293,0.292-0.293,0.767,0,1.062l0.948,0.938h-7.672H5.83v1.584h14.18l-0.938,0.939c-0.295,0.293-0.295,0.771,0,1.057
c0.144,0.15,0.337,0.221,0.527,0.221c0.194,0,0.38-0.07,0.528-0.221l2.263-2.27c0.074-0.061,0.134-0.143,0.164-0.236
c0.049-0.082,0.065-0.184,0.065-0.285C22.604,14.645,22.586,14.543,22.55,14.455z"/>
</g>
<path fill="#292D32" d="M13.716,9.075c0,0.281,0.2,0.51,0.445,0.51h4.749c0.246,0,0.448-0.229,0.448-0.51l0,0
c0-0.28-0.201-0.509-0.448-0.509h-4.749C13.916,8.566,13.716,8.794,13.716,9.075L13.716,9.075z"/>
<path fill="#292D32" d="M16.536,6.252c-0.279,0-0.508,0.202-0.508,0.449v4.746c0,0.25,0.229,0.451,0.508,0.451l0,0
c0.28,0,0.509-0.203,0.509-0.45V6.701C17.045,6.455,16.816,6.252,16.536,6.252"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<rect x="3.138" y="12.585" transform="matrix(-0.7801 0.6256 -0.6256 -0.7801 29.7118 16.3621)" fill="#292D32" width="17.685" height="1.633"/>
<path fill="#292D32" d="M14.923,5.652h-1.865V3.788c0-0.247-0.229-0.449-0.511-0.449c-0.279,0-0.508,0.202-0.508,0.449v1.864
h-1.867C9.928,5.653,9.727,5.881,9.727,6.161c0,0.281,0.201,0.51,0.445,0.51h1.867v1.862c0,0.25,0.229,0.451,0.508,0.451
c0.282,0,0.511-0.203,0.511-0.449V6.671h1.865c0.246,0,0.447-0.229,0.447-0.51C15.37,5.881,15.169,5.652,14.923,5.652z"/>
<path fill="#292D32" d="M3.815,20.035c0.579,0.721,1.634,0.836,2.356,0.256c0.723-0.58,0.839-1.633,0.261-2.354
c-0.58-0.725-1.635-0.842-2.358-0.262C3.352,18.256,3.236,19.313,3.815,20.035z"/>
<circle fill="#292D32" cx="18.878" cy="7.87" r="1.677"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<circle fill="#F12D32" cx="10.482" cy="13.178" r="7.749"/>
<g>
<path fill="#FFFFFF" d="M6.412,16.367c0-0.009,0-0.015,0-0.023c0.002-0.028,0.013-0.04,0.02-0.062
c0.01-0.233,0.13-0.426,0.289-0.586c0.81-0.802,1.6-1.61,2.403-2.405c0.122-0.117,0.122-0.09,0-0.211
c-0.803-0.808-1.602-1.614-2.411-2.411c-0.132-0.142-0.234-0.306-0.269-0.494c-0.01-0.053-0.019-0.096-0.032-0.147
c0-0.008,0-0.021,0-0.028c0.006-0.027,0.02-0.049,0.02-0.078c0.033-0.371,0.298-0.688,0.671-0.778
c0.065-0.012,0.131-0.024,0.201-0.037c0.004,0,0.01,0,0.01,0c0.021,0.002,0.038,0.017,0.055,0.017
C7.63,9.131,7.826,9.262,8.002,9.443c0.803,0.807,1.612,1.614,2.419,2.416c0.049,0.051,0.09,0.062,0.137,0
c0.01-0.017,0.027-0.037,0.048-0.047c0.803-0.803,1.603-1.604,2.41-2.402c0.131-0.143,0.293-0.233,0.477-0.274
c0.06-0.008,0.113-0.021,0.169-0.031h0.008c0.034,0.002,0.067,0.019,0.096,0.019c0.435,0.032,0.814,0.479,0.79,0.913
c-0.027,0.258-0.127,0.465-0.305,0.641c-0.813,0.804-1.626,1.615-2.427,2.418c-0.082,0.082-0.082,0.082,0,0.164
c0.801,0.805,1.605,1.604,2.409,2.412c0.032,0.024,0.064,0.066,0.094,0.091c0.417,0.454,0.25,1.204-0.326,1.421
c-0.368,0.137-0.702,0.057-0.976-0.217c-0.815-0.812-1.637-1.626-2.439-2.443c-0.088-0.086-0.088-0.086-0.176,0
c-0.82,0.817-1.638,1.645-2.454,2.455c-0.251,0.244-0.548,0.323-0.883,0.231c-0.335-0.092-0.539-0.329-0.623-0.675
C6.428,16.475,6.425,16.422,6.412,16.367z"/>
</g>
<path fill="#292D32" d="M15.623,5.896c0,0.281,0.2,0.51,0.445,0.51h4.749c0.246,0,0.448-0.229,0.448-0.51l0,0
c0-0.28-0.201-0.509-0.448-0.509h-4.749C15.823,5.388,15.623,5.616,15.623,5.896L15.623,5.896z"/>
<path fill="#292D32" d="M18.443,3.074c-0.279,0-0.508,0.202-0.508,0.449v4.746c0,0.25,0.229,0.451,0.508,0.451l0,0
c0.28,0,0.509-0.203,0.509-0.45V3.523C18.952,3.276,18.724,3.074,18.443,3.074"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<rect x="3.069" y="8.156" fill="none" stroke="#292D32" stroke-width="1.4" stroke-miterlimit="10" width="12.628" height="12.629"/>
<path fill="#292D32" d="M15.287,6.038c0,0.281,0.2,0.51,0.445,0.51h4.749c0.246,0,0.448-0.229,0.448-0.51l0,0
c0-0.279-0.201-0.508-0.448-0.508h-4.749C15.487,5.53,15.287,5.758,15.287,6.038L15.287,6.038z"/>
<path fill="#292D32" d="M18.107,3.215c-0.279,0-0.508,0.203-0.508,0.449v4.746c0,0.25,0.229,0.451,0.508,0.451l0,0
c0.28,0,0.509-0.203,0.509-0.45V3.665C18.616,3.418,18.388,3.215,18.107,3.215"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1014 B

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="none" stroke="#292D32" stroke-width="1.4" stroke-miterlimit="10" d="M5.069,8.156h8.628c1.104,0,2,0.896,2,2v8.629
c0,1.104-0.896,2-2,2H5.069c-1.104,0-2-0.896-2-2v-8.629C3.069,9.051,3.965,8.156,5.069,8.156z"/>
<path fill="#292D32" d="M15.287,6.038c0,0.281,0.2,0.51,0.445,0.51h4.749c0.246,0,0.448-0.229,0.448-0.51l0,0
c0-0.279-0.201-0.508-0.448-0.508h-4.749C15.487,5.53,15.287,5.758,15.287,6.038L15.287,6.038z"/>
<path fill="#292D32" d="M18.107,3.215c-0.279,0-0.508,0.203-0.508,0.449v4.746c0,0.25,0.229,0.451,0.508,0.451l0,0
c0.28,0,0.509-0.203,0.509-0.45V3.665C18.616,3.418,18.388,3.215,18.107,3.215"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<path fill="none" stroke="#292D32" stroke-width="1.4" stroke-miterlimit="10" d="M5.069,8.156h8.628c1.104,0,2,0.896,2,2v8.629
c0,1.104-0.896,2-2,2H5.069c-1.104,0-2-0.896-2-2v-8.629C3.069,9.051,3.965,8.156,5.069,8.156z"/>
<path fill="#292D32" d="M15.287,6.038c0,0.281,0.199,0.51,0.445,0.51h4.748c0.246,0,0.449-0.229,0.449-0.51l0,0
c0-0.279-0.201-0.508-0.449-0.508h-4.748C15.486,5.53,15.287,5.758,15.287,6.038L15.287,6.038z"/>
<path fill="#292D32" d="M18.107,3.215c-0.279,0-0.508,0.203-0.508,0.449V8.41c0,0.25,0.229,0.451,0.508,0.451l0,0
c0.279,0,0.509-0.203,0.509-0.45V3.665C18.616,3.418,18.389,3.215,18.107,3.215"/>
</g>
<path fill="#292D32" d="M13.564,12.111c0.007,1.156-0.962,2.128-2.12,2.13c-1.174,0-2.135-0.961-2.135-2.13
c0-1.165,0.947-2.117,2.12-2.128C12.591,9.969,13.559,10.933,13.564,12.111z M11.429,13.078c0.525,0.007,0.974-0.435,0.975-0.963
c0.002-0.53-0.437-0.972-0.969-0.972c-0.52,0-0.955,0.43-0.965,0.955C10.458,12.627,10.894,13.072,11.429,13.078z"/>
<path fill="#292D32" d="M15.411,17.156c-0.478-0.384-0.938-0.75-1.396-1.104c-0.638-0.505-1.34-0.527-1.999-0.055
c-0.583,0.417-1.176,0.846-1.758,1.273c-0.252,0.176-0.407,0.165-0.627-0.044c-0.57-0.582-1.141-1.153-1.713-1.724
c-0.681-0.681-1.526-0.715-2.263-0.088c-0.935,0.79-1.867,1.57-2.802,2.361c-0.011,0.011-0.021,0.022-0.044,0.032v1.594
c0.056-0.109,0.154-0.221,0.275-0.319c1.121-0.912,2.23-1.856,3.351-2.789c0.252-0.221,0.428-0.21,0.658,0.033
c0.572,0.581,1.143,1.164,1.713,1.746c0.649,0.659,1.461,0.715,2.197,0.153c0.55-0.428,1.099-0.856,1.66-1.285
c0.23-0.187,0.384-0.187,0.614,0c0.704,0.56,1.417,1.132,2.109,1.702c0.01,0.007,0.015,0.02,0.023,0.027V17.156z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<path fill="#292D32" d="M6.694,16.22h-3.22l-0.465,1.132H1.275l2.947-7.224h1.734l2.949,7.224H7.157L6.694,16.22z M6.155,14.905
l-1.072-2.64l-1.072,2.64H6.155z"/>
<path fill="#292D32" d="M15.564,14.633c0,1.666-1.047,2.851-2.5,2.851c-0.763,0-1.388-0.327-1.82-0.897v0.766H9.706v-7.349h1.539
v2.672c0.432-0.557,1.057-0.881,1.82-0.881C14.518,11.794,15.564,12.968,15.564,14.633z M14.072,14.633
c0-0.905-0.598-1.545-1.453-1.545c-0.748,0-1.292,0.546-1.375,1.331v0.425c0.083,0.794,0.626,1.347,1.375,1.347
C13.475,16.188,14.072,15.545,14.072,14.633z"/>
<path fill="#292D32" d="M16.34,14.633c0-1.545,1.367-2.839,2.98-2.839c0.879,0,1.605,0.354,2.133,0.921l-1.021,0.875
c-0.273-0.307-0.705-0.505-1.125-0.505c-0.799,0-1.48,0.708-1.48,1.536c0,0.851,0.682,1.568,1.494,1.568
c0.422,0,0.859-0.208,1.146-0.53l1.02,0.86c-0.539,0.592-1.271,0.961-2.178,0.961C17.697,17.483,16.34,16.169,16.34,14.633z"/>
</g>
<path fill="#292D32" d="M18.639,8.562c0,0.203,0.145,0.369,0.322,0.369h3.438c0.18,0,0.326-0.166,0.326-0.369l0,0
c0-0.202-0.146-0.368-0.326-0.368h-3.438C18.783,8.193,18.639,8.359,18.639,8.562L18.639,8.562z"/>
<path fill="#292D32" d="M20.682,6.518c-0.203,0-0.369,0.146-0.369,0.325v3.436c0,0.183,0.166,0.328,0.369,0.328l0,0
c0.201,0,0.367-0.147,0.367-0.326V6.843C21.049,6.664,20.885,6.518,20.682,6.518"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<circle fill="#292D32" cx="8.556" cy="20.988" r="1.631"/>
<path fill="#292D32" d="M8.277,1.45c-0.09,0.038-0.176,0.091-0.242,0.163L5.77,3.879c-0.297,0.294-0.297,0.771,0,1.064
c0.292,0.293,0.767,0.293,1.062,0l0.938-0.948v7.672v6.503h1.584V3.99l0.939,0.938c0.293,0.295,0.772,0.295,1.057,0
c0.15-0.144,0.222-0.337,0.222-0.527c0-0.193-0.069-0.379-0.222-0.527L9.08,1.609C9.019,1.536,8.937,1.477,8.843,1.445
C8.761,1.396,8.66,1.381,8.558,1.381C8.466,1.396,8.365,1.414,8.277,1.45z"/>
</g>
<path fill="#292D32" d="M12.793,4.273c0,0.281,0.2,0.51,0.445,0.51h4.749c0.246,0,0.447-0.229,0.447-0.51l0,0
c0-0.28-0.2-0.509-0.447-0.509h-4.749C12.993,3.764,12.793,3.992,12.793,4.273L12.793,4.273z"/>
<path fill="#292D32" d="M15.613,1.45c-0.279,0-0.509,0.202-0.509,0.449v4.746c0,0.25,0.229,0.451,0.509,0.451l0,0
c0.28,0,0.509-0.203,0.509-0.45V1.899C16.122,1.653,15.894,1.45,15.613,1.45"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#57B400" cx="10.453" cy="13.176" r="7.736"/>
<g>
<path fill="#FFFFFF" d="M15.982,10.202c-0.053,0.27-0.221,0.466-0.413,0.657c-1.996,1.992-3.996,3.988-5.987,5.976
c-0.271,0.276-0.585,0.392-0.961,0.259c-0.131-0.047-0.262-0.134-0.364-0.235c-1.016-1.004-2.024-2.022-3.038-3.034
c-0.152-0.15-0.243-0.329-0.291-0.535c0-0.074,0-0.147,0-0.22c0.049-0.203,0.127-0.39,0.287-0.536
c0.378-0.332,0.881-0.307,1.255,0.068c0.783,0.776,1.562,1.557,2.346,2.342c0.026,0.03,0.05,0.06,0.089,0.121
c0.047-0.057,0.063-0.091,0.094-0.116c1.812-1.81,3.625-3.625,5.441-5.445c0.262-0.262,0.568-0.376,0.931-0.262
c0.32,0.104,0.507,0.323,0.591,0.648c0.008,0.026,0.016,0.047,0.022,0.065C15.982,10.043,15.982,10.121,15.982,10.202z"/>
</g>
<g>
<path fill="#292D32" d="M15.623,5.896c0,0.281,0.2,0.51,0.445,0.51h4.748c0.246,0,0.449-0.229,0.449-0.51l0,0
c0-0.28-0.201-0.509-0.449-0.509h-4.748C15.823,5.388,15.623,5.616,15.623,5.896L15.623,5.896z"/>
<path fill="#292D32" d="M18.443,3.074c-0.279,0-0.508,0.202-0.508,0.449v4.746c0,0.25,0.229,0.451,0.508,0.451l0,0
c0.279,0,0.509-0.203,0.509-0.45V3.523C18.952,3.276,18.725,3.074,18.443,3.074"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,490 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#include "editorplugin.h"
#include "pdfdrawwidget.h"
#include "pdfutils.h"
#include "pdfpagecontenteditorwidget.h"
#include "pdfpagecontenteditorstylesettings.h"
#include "pdfdocumentbuilder.h"
#include "pdfcertificatemanagerdialog.h"
#include "pdfdocumentwriter.h"
#include <QAction>
#include <QToolButton>
#include <QMainWindow>
#include <QMessageBox>
#include <QFileDialog>
namespace pdfplugin
{
EditorPlugin::EditorPlugin() :
pdf::PDFPlugin(nullptr),
m_actions({ }),
m_tools({ }),
m_editorWidget(nullptr),
m_scene(nullptr),
m_sceneSelectionChangeEnabled(true)
{
}
void EditorPlugin::setWidget(pdf::PDFWidget* widget)
{
Q_ASSERT(!m_widget);
BaseClass::setWidget(widget);
QAction* activateAction = new QAction(QIcon(":/pdfplugins/editorplugin/activate.svg"), tr("Edit page content"), this);
QAction* createTextAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-text.svg"), tr("Create Text Label"), this);
QAction* createFreehandCurveAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-freehand-curve.svg"), tr("Create Freehand Curve"), this);
QAction* createAcceptMarkAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-yes-mark.svg"), tr("Create Accept Mark"), this);
QAction* createRejectMarkAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-no-mark.svg"), tr("Create Reject Mark"), this);
QAction* createRectangleAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-rectangle.svg"), tr("Create Rectangle"), this);
QAction* createRoundedRectangleAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-rounded-rectangle.svg"), tr("Create Rounded Rectangle"), this);
QAction* createHorizontalLineAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-horizontal-line.svg"), tr("Create Horizontal Line"), this);
QAction* createVerticalLineAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-vertical-line.svg"), tr("Create Vertical Line"), this);
QAction* createLineAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-line.svg"), tr("Create Line"), this);
QAction* createDotAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-dot.svg"), tr("Create Dot"), this);
QAction* createSvgImageAction = new QAction(QIcon(":/pdfplugins/editorplugin/create-svg-image.svg"), tr("Create SVG Image"), this);
QAction* clearAction = new QAction(QIcon(":/pdfplugins/editorplugin/clear.svg"), tr("Clear All Graphics"), this);
QAction* certificatesAction = new QAction(QIcon(":/pdfplugins/editorplugin/certificates.svg"), tr("Certificates Manager"), this);
activateAction->setObjectName("editortool_activateAction");
createTextAction->setObjectName("editortool_createTextAction");
createFreehandCurveAction->setObjectName("editortool_createFreehandCurveAction");
createAcceptMarkAction->setObjectName("editortool_createAcceptMarkAction");
createRejectMarkAction->setObjectName("editortool_createRejectMarkAction");
createRectangleAction->setObjectName("editortool_createRectangleAction");
createRoundedRectangleAction->setObjectName("editortool_createRoundedRectangleAction");
createHorizontalLineAction->setObjectName("editortool_createHorizontalLineAction");
createVerticalLineAction->setObjectName("editortool_createVerticalLineAction");
createLineAction->setObjectName("editortool_createLineAction");
createDotAction->setObjectName("editortool_createDotAction");
createSvgImageAction->setObjectName("editortool_createSvgImageAction");
clearAction->setObjectName("editortool_clearAction");
certificatesAction->setObjectName("editortool_certificatesAction");
activateAction->setCheckable(true);
createTextAction->setCheckable(true);
createFreehandCurveAction->setCheckable(true);
createAcceptMarkAction->setCheckable(true);
createRejectMarkAction->setCheckable(true);
createRectangleAction->setCheckable(true);
createRoundedRectangleAction->setCheckable(true);
createHorizontalLineAction->setCheckable(true);
createVerticalLineAction->setCheckable(true);
createLineAction->setCheckable(true);
createDotAction->setCheckable(true);
createSvgImageAction->setCheckable(true);
m_actions[Activate] = activateAction;
m_actions[Text] = createTextAction;
m_actions[FreehandCurve] = createFreehandCurveAction;
m_actions[AcceptMark] = createAcceptMarkAction;
m_actions[RejectMark] = createRejectMarkAction;
m_actions[Rectangle] = createRectangleAction;
m_actions[RoundedRectangle] = createRoundedRectangleAction;
m_actions[HorizontalLine] = createHorizontalLineAction;
m_actions[VerticalLine] = createVerticalLineAction;
m_actions[Line] = createLineAction;
m_actions[Dot] = createDotAction;
m_actions[SvgImage] = createSvgImageAction;
m_actions[Clear] = clearAction;
QFile acceptMarkFile(":/pdfplugins/editorplugin/accept-mark.svg");
QByteArray acceptMarkContent;
if (acceptMarkFile.open(QFile::ReadOnly))
{
acceptMarkContent = acceptMarkFile.readAll();
acceptMarkFile.close();
}
QFile rejectMarkFile(":/pdfplugins/editorplugin/reject-mark.svg");
QByteArray rejectMarkContent;
if (rejectMarkFile.open(QFile::ReadOnly))
{
rejectMarkContent = rejectMarkFile.readAll();
rejectMarkFile.close();
}
m_tools[TextTool] = new pdf::PDFCreatePCElementTextTool(widget->getDrawWidgetProxy(), &m_scene, createTextAction, this);
m_tools[FreehandCurveTool] = new pdf::PDFCreatePCElementFreehandCurveTool(widget->getDrawWidgetProxy(), &m_scene, createFreehandCurveAction, this);
m_tools[AcceptMarkTool] = new pdf::PDFCreatePCElementImageTool(widget->getDrawWidgetProxy(), &m_scene, createAcceptMarkAction, acceptMarkContent, false, this);
m_tools[RejectMarkTool] = new pdf::PDFCreatePCElementImageTool(widget->getDrawWidgetProxy(), &m_scene, createRejectMarkAction, rejectMarkContent, false, this);
m_tools[RectangleTool] = new pdf::PDFCreatePCElementRectangleTool(widget->getDrawWidgetProxy(), &m_scene, createRectangleAction, false, this);
m_tools[RoundedRectangleTool] = new pdf::PDFCreatePCElementRectangleTool(widget->getDrawWidgetProxy(), &m_scene, createRoundedRectangleAction, true, this);
m_tools[HorizontalLineTool] = new pdf::PDFCreatePCElementLineTool(widget->getDrawWidgetProxy(), &m_scene, createHorizontalLineAction, true, false, this);
m_tools[VerticalLineTool] = new pdf::PDFCreatePCElementLineTool(widget->getDrawWidgetProxy(), &m_scene, createVerticalLineAction, false, true, this);
m_tools[LineTool] = new pdf::PDFCreatePCElementLineTool(widget->getDrawWidgetProxy(), &m_scene, createLineAction, false, false, this);
m_tools[DotTool] = new pdf::PDFCreatePCElementDotTool(widget->getDrawWidgetProxy(), &m_scene, createDotAction, this);
m_tools[ImageTool] = new pdf::PDFCreatePCElementImageTool(widget->getDrawWidgetProxy(), &m_scene, createSvgImageAction, QByteArray(), true, this);
pdf::PDFToolManager* toolManager = widget->getToolManager();
for (pdf::PDFWidgetTool* tool : m_tools)
{
toolManager->addTool(tool);
connect(tool, &pdf::PDFWidgetTool::toolActivityChanged, this, &EditorPlugin::onToolActivityChanged);
}
m_widget->addInputInterface(&m_scene);
m_widget->getDrawWidgetProxy()->registerDrawInterface(&m_scene);
m_scene.setWidget(m_widget);
connect(&m_scene, &pdf::PDFPageContentScene::sceneChanged, this, &EditorPlugin::onSceneChanged);
connect(&m_scene, &pdf::PDFPageContentScene::selectionChanged, this, &EditorPlugin::onSceneSelectionChanged);
connect(&m_scene, &pdf::PDFPageContentScene::editElementRequest, this, &EditorPlugin::onSceneEditElement);
connect(clearAction, &QAction::triggered, &m_scene, &pdf::PDFPageContentScene::clear);
connect(activateAction, &QAction::triggered, this, &EditorPlugin::setActive);
connect(m_widget->getDrawWidgetProxy(), &pdf::PDFDrawWidgetProxy::drawSpaceChanged, this, &EditorPlugin::onDrawSpaceChanged);
updateActions();
}
void EditorPlugin::setDocument(const pdf::PDFModifiedDocument& document)
{
BaseClass::setDocument(document);
if (document.hasReset())
{
setActive(false);
updateActions();
}
}
std::vector<QAction*> EditorPlugin::getActions() const
{
std::vector<QAction*> result;
result.push_back(m_actions[Activate]);
return result;
}
void EditorPlugin::onSceneChanged(bool graphicsOnly)
{
if (!graphicsOnly)
{
updateActions();
}
if (m_editorWidget)
{
m_editorWidget->updateItemsInListWidget();
}
updateGraphics();
}
void EditorPlugin::onSceneSelectionChanged()
{
if (m_editorWidget && m_sceneSelectionChangeEnabled)
{
m_editorWidget->setSelection(m_scene.getSelectedElementIds());
}
}
void EditorPlugin::onWidgetSelectionChanged()
{
Q_ASSERT(m_editorWidget);
pdf::PDFTemporaryValueChange guard(&m_sceneSelectionChangeEnabled, false);
m_scene.setSelectedElementIds(m_editorWidget->getSelection());
}
pdf::PDFWidgetTool* EditorPlugin::getActiveTool()
{
for (pdf::PDFWidgetTool* currentTool : m_tools)
{
if (currentTool->isActive())
{
return currentTool;
}
}
return nullptr;
}
void EditorPlugin::onToolActivityChanged()
{
if (m_editorWidget)
{
pdf::PDFWidgetTool* activeTool = getActiveTool();
const pdf::PDFPageContentElement* element = nullptr;
pdf::PDFCreatePCElementTool* tool = qobject_cast<pdf::PDFCreatePCElementTool*>(activeTool);
if (tool)
{
element = tool->getElement();
}
m_editorWidget->loadStyleFromElement(element);
}
}
void EditorPlugin::onSceneEditElement(const std::set<pdf::PDFInteger>& elements)
{
if (elements.empty())
{
return;
}
pdf::PDFPageContentElement* element = nullptr;
for (pdf::PDFInteger id : elements)
{
element = m_scene.getElementById(id);
if (element)
{
break;
}
}
if (!element)
{
return;
}
if (pdf::PDFPageContentEditorStyleSettings::showEditElementStyleDialog(m_dataExchangeInterface->getMainWindow(), element))
{
updateGraphics();
}
}
void EditorPlugin::onPenChanged(const QPen& pen)
{
if (pdf::PDFCreatePCElementTool* activeTool = qobject_cast<pdf::PDFCreatePCElementTool*>(getActiveTool()))
{
activeTool->setPen(pen);
}
}
void EditorPlugin::onBrushChanged(const QBrush& brush)
{
if (pdf::PDFCreatePCElementTool* activeTool = qobject_cast<pdf::PDFCreatePCElementTool*>(getActiveTool()))
{
activeTool->setBrush(brush);
}
}
void EditorPlugin::onFontChanged(const QFont& font)
{
if (pdf::PDFCreatePCElementTool* activeTool = qobject_cast<pdf::PDFCreatePCElementTool*>(getActiveTool()))
{
activeTool->setFont(font);
}
}
void EditorPlugin::onAlignmentChanged(Qt::Alignment alignment)
{
if (pdf::PDFCreatePCElementTool* activeTool = qobject_cast<pdf::PDFCreatePCElementTool*>(getActiveTool()))
{
activeTool->setAlignment(alignment);
}
}
void EditorPlugin::onTextAngleChanged(pdf::PDFReal angle)
{
if (pdf::PDFCreatePCElementTool* activeTool = qobject_cast<pdf::PDFCreatePCElementTool*>(getActiveTool()))
{
activeTool->setTextAngle(angle);
}
}
void EditorPlugin::setActive(bool active)
{
if (m_scene.isActive() != active)
{
// Abort active tool, if we are deactivating the plugin
if (!active)
{
if (pdf::PDFWidgetTool* tool = m_widget->getToolManager()->getActiveTool())
{
auto it = std::find(m_tools.cbegin(), m_tools.cend(), tool);
if (it != m_tools.cend())
{
m_widget->getToolManager()->setActiveTool(nullptr);
}
}
}
m_scene.setActive(active);
if (!active)
{
m_scene.clear();
m_editedPageContent.clear();
}
else
{
updateDockWidget();
updateEditedPages();
}
m_actions[Activate]->setChecked(active);
updateActions();
}
}
void EditorPlugin::updateActions()
{
m_actions[Activate]->setEnabled(m_document);
if (!m_scene.isActive() || !m_document)
{
// Inactive scene - disable all except activate action
for (QAction* action : m_actions)
{
if (action == m_actions[Activate])
{
continue;
}
action->setEnabled(false);
}
return;
}
const bool isSceneNonempty = !m_scene.isEmpty();
// Tool actions
for (auto actionId : { Text, FreehandCurve, AcceptMark, RejectMark,
Rectangle, RoundedRectangle, HorizontalLine,
VerticalLine, Line, Dot, SvgImage })
{
m_actions[actionId]->setEnabled(true);
}
// Clear action
QAction* clearAction = m_actions[Clear];
clearAction->setEnabled(isSceneNonempty);
}
void EditorPlugin::updateGraphics()
{
if (m_widget)
{
m_widget->getDrawWidget()->getWidget()->update();
}
}
void EditorPlugin::updateDockWidget()
{
if (m_editorWidget)
{
return;
}
m_editorWidget = new pdf::PDFPageContentEditorWidget(m_dataExchangeInterface->getMainWindow());
m_editorWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_dataExchangeInterface->getMainWindow()->addDockWidget(Qt::RightDockWidgetArea, m_editorWidget, Qt::Vertical);
m_editorWidget->setFloating(false);
m_editorWidget->setWindowTitle(tr("Editor Toolbox"));
m_editorWidget->setScene(&m_scene);
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::operationTriggered, &m_scene, &pdf::PDFPageContentScene::performOperation);
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::itemSelectionChangedByUser, this, &EditorPlugin::onWidgetSelectionChanged);
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignTop))->setIcon(QIcon(":/resources/pce-align-top.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignCenterVertically))->setIcon(QIcon(":/resources/pce-align-v-center.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignBottom))->setIcon(QIcon(":/resources/pce-align-bottom.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignLeft))->setIcon(QIcon(":/resources/pce-align-left.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignCenterHorizontally))->setIcon(QIcon(":/resources/pce-align-h-center.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::AlignRight))->setIcon(QIcon(":/resources/pce-align-right.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::SetSameHeight))->setIcon(QIcon(":/resources/pce-same-height.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::SetSameWidth))->setIcon(QIcon(":/resources/pce-same-width.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::SetSameSize))->setIcon(QIcon(":/resources/pce-same-size.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::CenterHorizontally))->setIcon(QIcon(":/resources/pce-center-h.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::CenterVertically))->setIcon(QIcon(":/resources/pce-center-v.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::CenterHorAndVert))->setIcon(QIcon(":/resources/pce-center-vh.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::LayoutVertically))->setIcon(QIcon(":/resources/pce-layout-v.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::LayoutHorizontally))->setIcon(QIcon(":/resources/pce-layout-h.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::LayoutForm))->setIcon(QIcon(":/resources/pce-layout-form.svg"));
m_editorWidget->getToolButtonForOperation(static_cast<int>(pdf::PDFPageContentElementManipulator::Operation::LayoutGrid))->setIcon(QIcon(":/resources/pce-layout-grid.svg"));
for (QAction* action : m_actions)
{
m_editorWidget->addAction(action);
}
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::penChanged, this, &EditorPlugin::onPenChanged);
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::brushChanged, this, &EditorPlugin::onBrushChanged);
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::fontChanged, this, &EditorPlugin::onFontChanged);
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::alignmentChanged, this, &EditorPlugin::onAlignmentChanged);
connect(m_editorWidget, &pdf::PDFPageContentEditorWidget::textAngleChanged, this, &EditorPlugin::onTextAngleChanged);
}
void EditorPlugin::updateEditedPages()
{
if (!m_scene.isActive())
{
// Editor is not active
return;
}
std::vector<pdf::PDFInteger> currentPages = m_widget->getDrawWidget()->getCurrentPages();
for (pdf::PDFInteger pageIndex : currentPages)
{
if (m_editedPageContent.count(pageIndex))
{
continue;
}
const pdf::PDFPage* page = m_document->getCatalog()->getPage(pageIndex);
auto cms = m_widget->getDrawWidgetProxy()->getCMSManager()->getCurrentCMS();
pdf::PDFPageContentEditorProcessor processor(page,
m_document,
m_widget->getDrawWidgetProxy()->getFontCache(),
cms.data(),
m_widget->getDrawWidgetProxy()->getOptionalContentActivity(),
QTransform(),
pdf::PDFMeshQualitySettings());
QList<pdf::PDFRenderError> errors = processor.processContents();
Q_UNUSED(errors);
m_editedPageContent[pageIndex] = processor.takeEditedPageContent();
size_t elementCount = m_editedPageContent[pageIndex].getElementCount();
for (size_t i = 0; i <elementCount; ++i)
{
pdf::PDFEditedPageContentElement* element = m_editedPageContent[pageIndex].getElement(i);
}
/*
std::vector<pdf::PDFEditedPageContent::ContentTextInfo> textInfos = m_editedPageContent[pageIndex].getTextInfos();
for (const pdf::PDFEditedPageContent::ContentTextInfo& textInfo : textInfos)
{
if (textInfo.boundingRectangle.isEmpty())
{
continue;
}
pdf::PDFPageContentElementEditedContentTextBox* textBox = new pdf::PDFPageContentElementEditedContentTextBox();
textBox->setPageIndex(pageIndex);
textBox->setRectangle(textInfo.boundingRectangle);
textBox->setContentId(textInfo.id);
m_scene.addElement(textBox);
}*/
}
}
void EditorPlugin::onDrawSpaceChanged()
{
updateEditedPages();
}
}

View File

@ -0,0 +1,124 @@
// Copyright (C) 2023 Jakub Melka
//
// This file is part of PDF4QT.
//
// PDF4QT is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// with the written consent of the copyright owner, any later version.
//
// PDF4QT is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
#ifndef EDITORSPLUGIN_H
#define EDITORSPLUGIN_H
#include "pdfplugin.h"
#include "pdfpagecontentelements.h"
#include "pdfpagecontenteditortools.h"
#include "pdfpagecontenteditorprocessor.h"
#include <QObject>
namespace pdf
{
class PDFPageContentEditorWidget;
}
namespace pdfplugin
{
class EditorPlugin : public pdf::PDFPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "PDF4QT.EditorPlugin" FILE "EditorPlugin.json")
private:
using BaseClass = pdf::PDFPlugin;
public:
EditorPlugin();
virtual void setWidget(pdf::PDFWidget* widget) override;
virtual void setDocument(const pdf::PDFModifiedDocument& document) override;
virtual std::vector<QAction*> getActions() const override;
private:
void onSceneChanged(bool graphicsOnly);
void onSceneSelectionChanged();
void onWidgetSelectionChanged();
void onToolActivityChanged();
void onSceneEditElement(const std::set<pdf::PDFInteger>& elements);
void onPenChanged(const QPen& pen);
void onBrushChanged(const QBrush& brush);
void onFontChanged(const QFont& font);
void onAlignmentChanged(Qt::Alignment alignment);
void onTextAngleChanged(pdf::PDFReal angle);
enum Action
{
// Activate action
Activate,
// Create graphics actions
Text,
FreehandCurve,
AcceptMark,
RejectMark,
Rectangle,
RoundedRectangle,
HorizontalLine,
VerticalLine,
Line,
Dot,
SvgImage,
Clear,
LastAction
};
enum Tools
{
TextTool,
FreehandCurveTool,
AcceptMarkTool,
RejectMarkTool,
RectangleTool,
RoundedRectangleTool,
HorizontalLineTool,
VerticalLineTool,
LineTool,
DotTool,
ImageTool,
LastTool
};
void setActive(bool active);
void updateActions();
void updateGraphics();
void updateDockWidget();
void updateEditedPages();
void onDrawSpaceChanged();
pdf::PDFWidgetTool* getActiveTool();
std::array<QAction*, LastAction> m_actions;
std::array<pdf::PDFWidgetTool*, LastTool> m_tools;
pdf::PDFPageContentEditorWidget* m_editorWidget;
pdf::PDFPageContentScene m_scene;
std::map<pdf::PDFInteger, pdf::PDFEditedPageContent> m_editedPageContent;
bool m_sceneSelectionChangeEnabled;
};
} // namespace pdfplugin
#endif // EDITORSPLUGIN_H

View File

@ -0,0 +1,19 @@
<RCC>
<qresource prefix="/pdfplugins/editorplugin">
<file>accept-mark.svg</file>
<file>reject-mark.svg</file>
<file>activate.svg</file>
<file>clear.svg</file>
<file>create-dot.svg</file>
<file>create-freehand-curve.svg</file>
<file>create-horizontal-line.svg</file>
<file>create-line.svg</file>
<file>create-no-mark.svg</file>
<file>create-rectangle.svg</file>
<file>create-rounded-rectangle.svg</file>
<file>create-svg-image.svg</file>
<file>create-text.svg</file>
<file>create-vertical-line.svg</file>
<file>create-yes-mark.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Vrstva_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#C80000" cx="12" cy="12" r="11.098"/>
<g>
<g>
<path fill="#FFFFFF" d="M13.713,12l5.063-4.201c0.46-0.381,0.524-1.07,0.143-1.539c-0.394-0.466-1.077-0.531-1.54-0.141
l-5.382,4.466L6.622,6.119C6.157,5.733,5.469,5.796,5.084,6.26C4.699,6.728,4.763,7.417,5.227,7.798L10.289,12l-5.062,4.204
c-0.464,0.389-0.528,1.074-0.143,1.54c0.216,0.258,0.527,0.394,0.84,0.394c0.246,0,0.491-0.079,0.697-0.253l5.377-4.462
l5.38,4.462c0.207,0.174,0.458,0.253,0.698,0.253c0.31,0,0.625-0.133,0.842-0.394c0.382-0.466,0.317-1.151-0.143-1.54L13.713,12z"
/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB