From 870531a0bec46361abbfb86ad576e61ad3d1ba9a Mon Sep 17 00:00:00 2001 From: karlis <2995621482@qq.com> Date: Wed, 8 Feb 2023 15:38:03 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8PixelPath=E6=9B=B4=E6=8D=A2=E4=BA=86QP?= =?UTF-8?q?ainterPath=EF=BC=8C=E4=B8=80=E7=B3=BB=E5=88=97=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .../ArchitectureColoredPainting.vcxproj | 2 + ...rchitectureColoredPainting.vcxproj.filters | 6 ++ .../src/Editor/EditorWidget.cpp | 3 +- .../src/Editor/EditorWidget.h | 1 + .../src/Editor/ElementManager.cpp | 4 +- .../src/Editor/ElementManager.h | 4 +- .../src/Editor/GraphicElement.cpp | 51 +++++++++--- .../src/Editor/GraphicElement.h | 79 ++++++++----------- .../src/Editor/LayerManager.cpp | 3 +- .../src/Editor/LayerWrapper.cpp | 17 ++-- .../src/Editor/LayerWrapper.h | 10 +-- .../src/Editor/PixelPath.cpp | 70 ++++++++++++++++ .../src/Editor/PixelPath.h | 25 ++++++ .../src/Editor/PreviewWindow.cpp | 32 +++++--- .../src/Editor/PreviewWindow.h | 4 + UnitTest/Qt.x64.runsettings | 8 -- 17 files changed, 225 insertions(+), 97 deletions(-) create mode 100644 ArchitectureColoredPainting/src/Editor/PixelPath.cpp create mode 100644 ArchitectureColoredPainting/src/Editor/PixelPath.h delete mode 100644 UnitTest/Qt.x64.runsettings diff --git a/.gitignore b/.gitignore index 9491a2f..59dddc1 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,5 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd +/UnitTest/Qt.x64.runsettings diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index 20f28b2..94fa401 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -105,6 +105,7 @@ + @@ -181,6 +182,7 @@ + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index 12795b5..bc091f9 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -204,6 +204,9 @@ Source Files\Renderer\Preview + + Source Files + @@ -408,6 +411,9 @@ Header Files\Renderer\Preview + + Header Files + diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp index 69527c7..fe71bc7 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp @@ -2,6 +2,7 @@ EditorWidget::EditorWidget(QWidget *parent) : QWidget(parent) { + QImage x; displayLayer = nullptr; displayElement = nullptr; ui.setupUi(this); @@ -25,7 +26,7 @@ EditorWidget::EditorWidget(QWidget *parent) : QWidget(parent) qDebug() << jError.errorString(); // end test QJsonObject source = jsonDoc.object(); - elementManager = new ElementManager(source); + elementManager = new ElementManager(source,previewWindow->getRenderer()); layerManager = new LayerManager(source, elementManager); previewWindow->initialize(layerManager); if (layerManager->getRoot() != nullptr) diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidget.h b/ArchitectureColoredPainting/src/Editor/EditorWidget.h index 3e7a3f5..6c56ded 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidget.h +++ b/ArchitectureColoredPainting/src/Editor/EditorWidget.h @@ -9,6 +9,7 @@ #include #include #include + class EditorWidget : public QWidget { Q_OBJECT diff --git a/ArchitectureColoredPainting/src/Editor/ElementManager.cpp b/ArchitectureColoredPainting/src/Editor/ElementManager.cpp index 63008cd..78b03b6 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementManager.cpp +++ b/ArchitectureColoredPainting/src/Editor/ElementManager.cpp @@ -1,5 +1,5 @@ #include "ElementManager.h" -ElementManager::ElementManager(QJsonObject source) +ElementManager::ElementManager(QJsonObject source,Renderer::ElementRenderer* renderer) { auto elementsJson = source.value("elements").toArray(); qDebug() << elementsJson.size(); @@ -9,6 +9,8 @@ ElementManager::ElementManager(QJsonObject source) elements.push_back(new GroupElement()); else elements.push_back(new SimpleElement(elementJson.toObject())); + + (*elements.rbegin())->renderer = renderer; } } diff --git a/ArchitectureColoredPainting/src/Editor/ElementManager.h b/ArchitectureColoredPainting/src/Editor/ElementManager.h index 952cb1d..3c26f9b 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementManager.h +++ b/ArchitectureColoredPainting/src/Editor/ElementManager.h @@ -2,10 +2,12 @@ #include "GraphicElement.h" #include "LayerManager.h" #include +#include "../Renderer/Preview/ElementRenderer.h" #include using std::vector; class LayerManager; class GraphicElement; +class Renderer::ElementRenderer; class ElementManager { @@ -13,7 +15,7 @@ class ElementManager vector elements; public: - ElementManager(QJsonObject source); + ElementManager(QJsonObject source,Renderer::ElementRenderer *renderer); ~ElementManager(); void addElement(GraphicElement *element); void removeElement(GraphicElement *pElement); diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 012a306..ac3e2a5 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -1,9 +1,12 @@ #include "GraphicElement.h" #include "util/SvgFileLoader.h" using namespace std; -QPainterPath SimpleElement::getPaintObject() const + +PixelPath SimpleElement::getPaintObject() const { - return painterPath; + PixelPath result; + result.addPath(painterPath); + return result; } void SimpleElement::loadSvgFile(const QString& filePath) @@ -29,26 +32,48 @@ void GroupElement::setSourceLayer(FolderLayerWrapper *sourceLayer) { this->sourceLayer = sourceLayer; } -QPainterPath GroupElement::getPaintObject() const +PixelPath GroupElement::getPaintObject() const { if (sourceLayer != nullptr) { sourceLayer->refresh(); return sourceLayer->getCache(); } else - return QPainterPath(); + return PixelPath(); } -void BitmapPath::applyTransformation(QTransform& transformation) -{ +//TODO: apply styles and send back +PixelPath SimpleElement::getPaintObject(std::vector styles) const { + PixelPath result; + Renderer::ElementStyleStrokeDemo demo; + qDebug() << (renderer==nullptr)<<"------------"; + //auto [img, mov] = renderer->drawElement(painterPath,demo,1.0,false); + //qDebug() << img << " ------"; + //result.addImage(img, mov); + result.addPath(painterPath); + // QImage img(80,80,QImage::Format_ARGB32); + // QPainter pt(&img); + //pt.setPen(QPen(Qt::red, 2)); + //pt.drawLine(0, 0, 80, 80); + //pt.end(); + //result.addImage(img, QPoint(0, 0)); + return result; } -QImage FolderBitmapPath::getStylesAppliedCache() const -{ - return QImage(); +PixelPath GroupElement::getPaintObject(std::vector styles) const { + return getPaintObject(); } -QImage ComposedPainterPath::getStylesAppliedCache() const -{ - return QImage(); -} +//BitmapPath::BitmapPath() { +// pathCount = 0u; +//} +// +//void BitmapPath::initialize(vector& paths) { +// cache.clear(); +// rawPath.clear(); +// pathCount = 1u; +// bound +// for (auto& path : paths) { +// rawPath.addPath(path); +// } +//} diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index edd0caf..a34d56f 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -1,12 +1,16 @@ #pragma once + #include "LayerWrapper.h" #include #include #include #include +#include #include - +#include "../Renderer/Preview/ElementRenderer.h" #include "../Renderer/Painting/ElementStyle.h" +#include "PixelPath.h" +#include class LayerWrapper; class LeafLayerWrapper; @@ -16,9 +20,11 @@ class ComposedPainterPath; class GraphicElement { public: + Renderer::ElementRenderer *renderer; QString name = ""; // TODO: 改为BitmapPath - virtual QPainterPath getPaintObject() const = 0; + virtual PixelPath getPaintObject() const = 0; + virtual PixelPath getPaintObject(std::vector) const = 0; }; class SimpleElement : public GraphicElement @@ -32,7 +38,8 @@ private: public: SimpleElement(QJsonObject jsonSource); ~SimpleElement() = default; - QPainterPath getPaintObject() const override; + PixelPath getPaintObject() const override; + PixelPath getPaintObject(std::vector) const override; }; class GroupElement : public GraphicElement @@ -44,51 +51,31 @@ public: GroupElement() = default; GroupElement(FolderLayerWrapper* mSourceLayer); ~GroupElement() = default; - QPainterPath getPaintObject() const override; + PixelPath getPaintObject() const override; + PixelPath getPaintObject(std::vector) const override; void setSourceLayer(FolderLayerWrapper* sourceLayer); }; //******************************** BitmapPath ********************************// -using std::vector; -using std::shared_ptr; - -class BitmapPath -{ -protected: - QRectF boundingRect; - QImage stylesAppliedCache; - void applyTransformation(QTransform &transformation); - -public: - /** - * 用painter的引用将它的QImage画到画布上 - */ - virtual void paint(QPainter* painter) const = 0; - virtual QImage getStylesAppliedCache() const = 0; -}; - -class FolderBitmapPath : public BitmapPath -{ -public: - const vector children; - virtual QImage getStylesAppliedCache() const override; -}; - -/** - * 当获取cache的时候应该调用Render的接口 - */ -class ComposedPainterPath : public BitmapPath -{ -public: - /** - * 因为ElementStyle应该被应用至整个叶子图层节点,所以它应该只用zealed来确定某些Style是否应该被作用于该Path - */ - struct SinglePath { - shared_ptr path; - bool zealed; - }; - - const vector paths; - virtual QImage getStylesAppliedCache() const override; -}; \ No newline at end of file +//using std::vector; +//using std::shared_ptr; +// +//class BitmapPath +//{ +//private: +// QRectF *boundingRect; +// QPainterPath cache; +// QPainterPath rawPath; +// size_t pathCount; +// +//public: +// BitmapPath(); +// void initialize(std::vector& paths); +// void styles(Renderer::ElementStyle* style); +// void trans(QTransform& transform); +// QPainterPath getPainterPath() const; +// void addBitmapPath(BitmapPath& path); +// QRectF boundingRect()const; +// void clear(); +//}; diff --git a/ArchitectureColoredPainting/src/Editor/LayerManager.cpp b/ArchitectureColoredPainting/src/Editor/LayerManager.cpp index 3a9a60f..13de1bc 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerManager.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerManager.cpp @@ -13,7 +13,8 @@ LayerWrapper *LayerManager::getRoot() const } void LayerManager::paint(QPainter *painter) const { - painter->drawPath(root->getCache()); + auto p = root->getCache().getPixmap(); + painter->drawPixmap(0, 0, p); } bool LayerManager::singleSelectedCheck() const { diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index e06bc7a..efd5de6 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -23,11 +23,12 @@ LayerWrapper *LayerWrapper::getParent() const return this == nullptr ? nullptr : this->parent.get(); } -QPainterPath LayerWrapper::getCache() +PixelPath LayerWrapper::getCache() { this->refresh(); return cache; } + // TODO: undone LayerWrapper::LayerWrapper(QJsonObject json, LayerWrapper *parent) { @@ -76,19 +77,19 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana int elementIndex = json.value("element").toInt(); wrappedElement = elementManager->getElementById(elementIndex); } -void LayerWrapper::SimpleProperty::apply(QPainterPath &cache) const +void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const { QTransform trans; - double centerX = cache.boundingRect().center().x(); - double centerY = cache.boundingRect().center().y(); - qDebug() << name << " " << cache.boundingRect().center(); - qDebug() << name << " " << cache.boundingRect(); + double centerX = cache.getBoundingRect().center().x(); + double centerY = cache.getBoundingRect().center().y(); + //qDebug() << name << " " << cache.boundingRect().center(); + //qDebug() << name << " " << cache.boundingRect(); trans.translate(centerX, centerY); trans.scale(scale.x(), scale.y()); trans.rotate(rotation); trans.translate(-centerX, -centerY); trans.translate(offset.x(), offset.y()); - cache = trans.map(cache); + cache = cache.trans(trans); } void LayerWrapper::refresh() { @@ -108,7 +109,7 @@ void LeafLayerWrapper::refresh() cache.clear(); if (wrappedElement != nullptr) { - cache.addPath(wrappedElement->getPaintObject()); + cache.addPath(wrappedElement->getPaintObject(this->styles)); } LayerWrapper::refresh(); } diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index d063db9..ea90dd8 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -12,7 +12,7 @@ #include #include #include - +#include "PixelPath.h" #include "../Renderer/Painting/ElementStyle.h" using std::shared_ptr; using std::vector; @@ -29,7 +29,7 @@ class LayerWrapper QPointF referencePoint; // vector styles; // TODO: 将cache移到子类,对Leaf用ComposedPainterPath,对Folder用FolderBitmapPath - QPainterPath cache; + PixelPath cache; public: QTreeWidgetItem *qTreeItem; @@ -42,12 +42,12 @@ class LayerWrapper bool flipHorizontally = 0; bool flipVertically = 0; // TODO: 将QPainterPath改为BitmapPath - void apply(QPainterPath &cache) const; + void apply(PixelPath&cache) const; } property; void setParent(LayerWrapper *newParent); virtual void refresh(); // TODO: 将QPainterPath改为BitmapPath/QImage,或者直接将其删除,绘制时直接使用BitmapPath的paint方法 - QPainterPath getCache(); + virtual PixelPath getCache(); LayerWrapper *getParent() const; // invoke by manager, then invoke parent's applyStyles LayerWrapper(QJsonObject json, LayerWrapper *parent); LayerWrapper() = default; @@ -76,7 +76,7 @@ class LeafLayerWrapper : public LayerWrapper { public: GraphicElement *wrappedElement; - const vector styles; + const vector styles; public: void refresh() override; diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp new file mode 100644 index 0000000..b729882 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp @@ -0,0 +1,70 @@ +#include "PixelPath.h" +#include +using namespace std; + +PixelPath::PixelPath(int w, int h) :w(w), h(h) +{ + pixmap = QPixmap(w, h); + pixmap.fill(Qt::transparent); + boundingRect = QRectF(0, 0, 0, 0); +} + +PixelPath::PixelPath(QPainterPath painterPath, int w, int h) :w(w), h(h) +{ + pixmap = QPixmap(w, h); + pixmap.fill(Qt::transparent); + boundingRect = QRectF(0, 0, 0, 0); + addPath(painterPath); +} + +QRectF PixelPath::getBoundingRect() const +{ + return boundingRect; +} + +QPixmap PixelPath::getPixmap() const +{ + return pixmap; +} + +void PixelPath::addPath(const PixelPath& path) +{ + QPainter painter(&pixmap); + painter.drawPixmap(0, 0, path.getPixmap()); + boundingRect = boundingRect.united(path.getBoundingRect()); +} + +void PixelPath::addPath(const QPainterPath& path) +{ + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::HighQualityAntialiasing); + painter.setPen(QPen(Qt::black,1)); + painter.drawPath(path); + boundingRect = boundingRect.united(path.boundingRect()); +} + +void PixelPath::addImage(const QImage& image,const QPointF& pos) +{ + QPainter painter(&pixmap); + painter.drawImage(pos, image); + boundingRect = boundingRect.united(QRectF(pos, image.size())); +} + +void PixelPath::clear() +{ + pixmap.fill(Qt::transparent); + boundingRect = QRectF(0, 0, 0, 0); +} + +PixelPath PixelPath::trans(QTransform& mat)const +{ + PixelPath result(w, h); + QPainter painter(&result.pixmap); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::HighQualityAntialiasing); + painter.setTransform(mat); + painter.drawPixmap(0, 0, pixmap); + result.boundingRect = mat.mapRect(boundingRect); + return result; +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.h b/ArchitectureColoredPainting/src/Editor/PixelPath.h new file mode 100644 index 0000000..204b74f --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include + +class PixelPath +{ +private: + QRectF boundingRect; + QPixmap pixmap; + int w,h; +public: + PixelPath(int w=1280, int h=720); + PixelPath(QPainterPath painterPath,int w = 1280, int h = 720); + ~PixelPath() = default; + QRectF getBoundingRect() const; + QPixmap getPixmap() const; + void addPath(const PixelPath& path); + void addPath(const QPainterPath& path); + void addImage(const QImage& image,const QPointF& pos); + void clear(); + PixelPath trans(QTransform& mat)const; +}; \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp b/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp index 3b30cff..2c7767c 100644 --- a/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp +++ b/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp @@ -2,10 +2,13 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent) { + this->renderer = new Renderer::ElementRenderer(this); QSurfaceFormat surfaceFormat; surfaceFormat.setSamples(16); setFormat(surfaceFormat); painter = new QPainter(this); + painter->setRenderHint(QPainter::SmoothPixmapTransform); + painter->setRenderHint(QPainter::HighQualityAntialiasing); layerManager = nullptr; } @@ -16,28 +19,29 @@ void PreviewWindow::initialize(LayerManager *layerManager) void PreviewWindow::show() { - QFile settingFile; - settingFile.setFileName("../data.json"); - settingFile.open(QFile::ReadOnly); - QByteArray setting = settingFile.readAll().trimmed(); - QJsonDocument jsonDoc(QJsonDocument::fromJson(setting)); - auto jElements = jsonDoc.object().value("elements").toArray(); + //QFile settingFile; + //settingFile.setFileName("../data.json"); + //settingFile.open(QFile::ReadOnly); + //QByteArray setting = settingFile.readAll().trimmed(); + //QJsonDocument jsonDoc(QJsonDocument::fromJson(setting)); + //auto jElements = jsonDoc.object().value("elements").toArray(); - for (auto &&ele : jElements) - { - SimpleElement element(ele.toObject()); - painter->drawPath(element.getPaintObject()); - } + //for (auto &&ele : jElements) + //{ + // SimpleElement element(ele.toObject()); + // painter->drawPath(element.getPaintObject()); + //} } void PreviewWindow::initializeGL() { + this->renderer->initialize(); initializeOpenGLFunctions(); - glClearColor(1.0, 1.0, 1.0, 1.0); } void PreviewWindow::paintGL() { + glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); painter->begin(this); painter->setRenderHint(QPainter::Antialiasing); @@ -49,3 +53,7 @@ void PreviewWindow::paintGL() void PreviewWindow::resizeGL(int w, int h) { } + +Renderer::ElementRenderer* const PreviewWindow::getRenderer()const { + return this->renderer; +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/PreviewWindow.h b/ArchitectureColoredPainting/src/Editor/PreviewWindow.h index 3f040ef..0dea51b 100644 --- a/ArchitectureColoredPainting/src/Editor/PreviewWindow.h +++ b/ArchitectureColoredPainting/src/Editor/PreviewWindow.h @@ -8,6 +8,8 @@ #include #include #include +#include "../Renderer/Preview/ElementRenderer.h" + class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT @@ -15,6 +17,7 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions private: QPainter *painter; LayerManager *layerManager; + Renderer::ElementRenderer* renderer; public: PreviewWindow(QWidget *parent = nullptr); @@ -23,4 +26,5 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions void initializeGL() override; void paintGL() override; void resizeGL(int w, int h) override; + Renderer::ElementRenderer* const getRenderer()const; }; diff --git a/UnitTest/Qt.x64.runsettings b/UnitTest/Qt.x64.runsettings deleted file mode 100644 index 13451a6..0000000 --- a/UnitTest/Qt.x64.runsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - %PATH%;E:/Qt/5.15.2/msvc2019_64/bin - - - \ No newline at end of file