From f6e2e91a4d00d15088d60a14b67d5efa1bd10ea7 Mon Sep 17 00:00:00 2001 From: danya Date: Sat, 3 Apr 2021 17:40:56 +0300 Subject: [PATCH] Radial fix, PDF gradinet implementation Fixed radial shading cone display Started working on coons shading, it can convert pdfreader colors to graphics colors(rgb only) and drow similar (in math sense) shape, however size is still wrong, figuring out how to diplay shape with corect size and offset. Todo: Other gradients Size and offset Alpha Channel --- .../include/test_grads/custom_gradients.h | 33 ++++++++---- DesktopEditor/graphics/IRenderer.h | 2 + PdfReader/Src/Graphics.cpp | 18 ++++++- PdfReader/Src/OutputDevice.cpp | 2 + PdfReader/Src/OutputDevice.h | 5 +- PdfReader/Src/RendererOutputDev.cpp | 50 ++++++++++++++++++ PdfReader/Src/RendererOutputDev.h | 5 ++ .../gradient/Gradient/Gradient.pro | 5 ++ Test/Applications/gradient/Gradient/main.cpp | 2 +- .../gradient/Gradient/mainwindow.cpp | 46 ++++++++++++++-- .../gradient/Gradient/mainwindow.h | 4 ++ .../gradient/Gradient/mainwindow.ui | 52 +++++++++++++++++++ 12 files changed, 206 insertions(+), 18 deletions(-) diff --git a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h index 002b457815..1ca90d4825 100644 --- a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h +++ b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h @@ -79,18 +79,22 @@ namespace agg p0 = _gi.p0; p1 = _gi.p1; ginfo = _gi; + + } virtual float eval(float x, float y) override { - if (r0 * r0 > (x - p0.x)*(x - p0.x) + (y - p0.y)*(y - p0.y)) - { - return ginfo.shading.function.get_x_min() - 1; - } - if (r1 * r1 < (x - p1.x)*(x - p1.x) + (y - p1.y)*(y - p1.y)) - { - return ginfo.shading.function.get_x_max() + 1; - } + // if (r0 * r0 > (x - p0.x)*(x - p0.x) + (y - p0.y)*(y - p0.y)) + // { + // //return ginfo.shading.function.get_x_min() - 1; + // } + // if (r1 * r1 < (x - p1.x)*(x - p1.x) + (y - p1.y)*(y - p1.y)) + // { + // //return ginfo.shading.function.get_x_max() + 1; + // } + + float a = (r1 - r0) * (r1 - r0) - (p1.x - p0.x) * (p1.x - p0.x) - (p1.y - p0.y) * (p1.y - p0.y); @@ -103,9 +107,12 @@ namespace agg { return NAN_FLOAT; } - float x1 = (-b + sqrtf(D)) / 2 / a; + float x1 = (-b + sqrtf(D)) / 2 / a; float x2 = (-b - sqrtf(D)) / 2 / a; + if (abs(a) < FLT_EPSILON) + x1 = -c / b; + if (0 <= x1 && x1 <= 1) { return ginfo.shading.function.get_x_min() + @@ -116,6 +123,12 @@ namespace agg return ginfo.shading.function.get_x_min() + (ginfo.shading.function.get_x_max() - ginfo.shading.function.get_x_min()) * x2; } + if (ginfo.continue_shading_b) + { + if (x1 < 0 || x2 < 0) + return ginfo.shading.function.get_x_min(); + + } return NAN_FLOAT; } virtual ~calcRadial() {} @@ -887,4 +900,4 @@ namespace agg }; } -#endif \ No newline at end of file +#endif diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 4a4df4f802..6ec5652ba1 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -36,6 +36,7 @@ #include #include "../common/IGrObject.h" +#include "structures.h" #include "Matrix.h" // тип в DrawPath @@ -189,6 +190,7 @@ public: virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height) = 0; virtual HRESULT put_BrushGradientColors(LONG* lColors, double* pPositions, LONG nCount) = 0; + //virtual void put_BrushGradInfo(const NSStructures::GradientInfo &_ginfo) {}; // font ------------------------------------------------------------------------------------- virtual HRESULT get_FontName(std::wstring* bsName) = 0; diff --git a/PdfReader/Src/Graphics.cpp b/PdfReader/Src/Graphics.cpp index 0f391144cb..1472a676ee 100644 --- a/PdfReader/Src/Graphics.cpp +++ b/PdfReader/Src/Graphics.cpp @@ -1935,7 +1935,7 @@ namespace PdfReader } void Graphics::DoTilingPatternFill(GrTilingPattern *pPattern, bool bStroke, bool bEOFill) - { + { // Color space GrPatternColorSpace *pPatternCS = (GrPatternColorSpace *)(bStroke ? m_pGState->GetStrokeColorSpace() : m_pGState->GetFillColorSpace()); @@ -3287,6 +3287,22 @@ namespace PdfReader if (m_pOut->IsStopped()) return; + m_pGState->SetFillColor(&pPatch->arrColor[0][0]); + m_pGState->SetStrokeColor(&pPatch->arrColor[0][0]); + //m_pOut->UpdateFillColor(m_pGState); + //m_pOut->UpdateStrokeColor(m_pGState); + m_pGState->MoveTo(pPatch->arrX[0][0], pPatch->arrY[0][0]); + m_pGState->CurveTo(pPatch->arrX[0][1], pPatch->arrY[0][1], pPatch->arrX[0][2], pPatch->arrY[0][2], pPatch->arrX[0][3], pPatch->arrY[0][3]); + m_pGState->CurveTo(pPatch->arrX[1][3], pPatch->arrY[1][3], pPatch->arrX[2][3], pPatch->arrY[2][3], pPatch->arrX[3][3], pPatch->arrY[3][3]); + m_pGState->CurveTo(pPatch->arrX[3][2], pPatch->arrY[3][2], pPatch->arrX[3][1], pPatch->arrY[3][1], pPatch->arrX[3][0], pPatch->arrY[3][0]); + m_pGState->CurveTo(pPatch->arrX[2][0], pPatch->arrY[2][0], pPatch->arrX[1][0], pPatch->arrY[1][0], pPatch->arrX[0][0], pPatch->arrY[0][0]); + m_pGState->ClosePath(); + + m_pOut->FillStrokeGradient(m_pGState, pPatch); + + m_pGState->ClearPath(); + return; + GrPatch oPatch00, oPatch01, oPatch10, oPatch11; double arrX[4][8], arrY[4][8]; double dMidX, dMidY; diff --git a/PdfReader/Src/OutputDevice.cpp b/PdfReader/Src/OutputDevice.cpp index 08cd7c9f24..c30a4a1151 100644 --- a/PdfReader/Src/OutputDevice.cpp +++ b/PdfReader/Src/OutputDevice.cpp @@ -34,6 +34,8 @@ #include "Stream.h" #include "GState.h" #include "OutputDevice.h" +#include "Graphics.h" +#include "../PdfReader.h" namespace PdfReader { diff --git a/PdfReader/Src/OutputDevice.h b/PdfReader/Src/OutputDevice.h index ea6cef37bf..e135a79548 100644 --- a/PdfReader/Src/OutputDevice.h +++ b/PdfReader/Src/OutputDevice.h @@ -34,7 +34,8 @@ #include "CharTypes.h" #include "GlobalParams.h" - +#include "Graphics.h" +#include "../PdfReader.h" namespace PdfReader { class StringExt; @@ -221,6 +222,8 @@ namespace PdfReader virtual void UpdateTextShift(GrState *pGState, double dShift) {} //----- Рисование Path + virtual void FillStrokeGradient(GrState *pGState, GrPatch *patch) {} + virtual void Stroke(GrState *pGState) {} virtual void Fill(GrState *pGState) {} virtual void EoFill(GrState *pGState) {} diff --git a/PdfReader/Src/RendererOutputDev.cpp b/PdfReader/Src/RendererOutputDev.cpp index 30f41e4d44..f34e63b0f0 100644 --- a/PdfReader/Src/RendererOutputDev.cpp +++ b/PdfReader/Src/RendererOutputDev.cpp @@ -3913,4 +3913,54 @@ namespace PdfReader } return; } + + void RendererOutputDev::FillStrokeGradient(GrState *pGState, PdfReader::GrPatch *patch) + { + if (m_bDrawOnlyText) + return; + + if (m_bTransparentGroupSoftMask) + return; + + DoPath(pGState, pGState->GetPath(), pGState->GetPageHeight(), pGState->GetCTM()); + + long brush; + double xpi, ypi; + double xmin, ymin, xmax, ymax; + pGState->GetClipBBox(&xmin, &ymin, &xmax, &ymax); + patch->arrColor[0]; + m_pRenderer->get_DpiX(&xpi); + m_pRenderer->get_DpiY(&ypi); + m_pRenderer->get_BrushType(&brush); + m_pRenderer->put_BrushType(c_BrushTypeMyTestGradient); + std::vector> points(4, std::vector(4)); + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + points[i][j].x = patch->arrX[i][j] + 520; + points[i][j].y = (patch->arrY[i][j]) + 400; + } + } + std::vector> colors(2, std::vector(2)); + GrDeviceRGBColorSpace ColorSpace; + for (int i = 0; i < 2; i ++) + { + for (int j = 0; j < 2; j++) + { + DWORD dcolor = ColorSpace.GetDwordColor(&patch->arrColor[i][j]); + colors[i][j] = {dcolor % 0x100, (dcolor >> 8) % 0x100, (dcolor >> 16) % 0x100}; + } + } + auto info = NSStructures::GInfoConstructor::get_tensor_curve(points, + {{0, 1}, {1 , 0.5}}, + colors, + false + ); + ((NSGraphics::IGraphicsRenderer*)m_pRenderer)->put_BrushGradInfo(info); + m_pRenderer->DrawPath(c_nWindingFillMode); + + m_pRenderer->EndCommand(c_nPathType); + m_pRenderer->put_BrushType(brush); + } } diff --git a/PdfReader/Src/RendererOutputDev.h b/PdfReader/Src/RendererOutputDev.h index 4dc9875119..4d37d50dbd 100644 --- a/PdfReader/Src/RendererOutputDev.h +++ b/PdfReader/Src/RendererOutputDev.h @@ -34,7 +34,11 @@ #include "../../DesktopEditor/graphics/IRenderer.h" #include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/graphics/pro/Graphics.h" #include "../../DesktopEditor/graphics/TemporaryCS.h" +#include "../../DesktopEditor/graphics/structures.h" +#include "../PdfReader.h" +#include "./Graphics.h" #include "OutputDevice.h" #include "XmlUtils.h" @@ -117,6 +121,7 @@ namespace PdfReader class RendererOutputDev : public OutputDev { public: + virtual void FillStrokeGradient(GrState *pGState, GrPatch *patch); RendererOutputDev(GlobalParams *pGlobalParams, IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList = NULL); virtual ~RendererOutputDev(); diff --git a/Test/Applications/gradient/Gradient/Gradient.pro b/Test/Applications/gradient/Gradient/Gradient.pro index ed4edc8088..f341289848 100644 --- a/Test/Applications/gradient/Gradient/Gradient.pro +++ b/Test/Applications/gradient/Gradient/Gradient.pro @@ -15,4 +15,9 @@ CORE_ROOT_DIR = $$PWD/../../../../../core include($$CORE_ROOT_DIR/Common/base.pri) ADD_DEPENDENCY(kernel, graphics, UnicodeConverter) +ADD_DEPENDENCY(PdfReader) +ADD_DEPENDENCY(HtmlRenderer) core_linux:include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) + +LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lkernel -lgraphics + diff --git a/Test/Applications/gradient/Gradient/main.cpp b/Test/Applications/gradient/Gradient/main.cpp index 44fa88c768..7c9d4c93b5 100644 --- a/Test/Applications/gradient/Gradient/main.cpp +++ b/Test/Applications/gradient/Gradient/main.cpp @@ -4,7 +4,7 @@ #include "../../../../DesktopEditor/graphics/pro/Graphics.h" int main(int argc, char *argv[]) { - QApplication a(argc, argv); + QApplication a(argc, argv ); MainWindow w; w.show(); return a.exec(); diff --git a/Test/Applications/gradient/Gradient/mainwindow.cpp b/Test/Applications/gradient/Gradient/mainwindow.cpp index 102ea99a42..4bf34be000 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.cpp +++ b/Test/Applications/gradient/Gradient/mainwindow.cpp @@ -3,6 +3,9 @@ #include #include #include "../../../../DesktopEditor/graphics/pro/Graphics.h" +#include "../../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../PdfReader/PdfReader.h" std::vector drawCircle1(int n, double cx, double cy, double r) { std::vector res; @@ -34,8 +37,10 @@ MainWindow::~MainWindow() void GenerateImg(QImage &img, std::vector &points, Info &info) { + NSGraphics::IGraphicsRenderer* pRasterRenderer = NSGraphics::Create(); - pRasterRenderer->SetFontManager(NULL); + NSFonts::IFontManager *fmp = NSFonts::NSFontManager::Create(); + pRasterRenderer->SetFontManager(fmp); int nRasterW = img.size().width(); int nRasterH = img.size().height(); BYTE* pData = new BYTE[4 * nRasterW * nRasterH]; @@ -70,6 +75,7 @@ void GenerateImg(QImage &img, std::vector &points, Info &info) { auto b = info.p; LONG *c = a.data(); double *p = b.data(); + pRasterRenderer->CommandDrawText(L"Test", 10, 10, 345, 345); pRasterRenderer->put_BrushType(info.gradient_type); pRasterRenderer->put_BrushGradientColors(c, p, info.n_colors); pRasterRenderer->PathCommandStart(); @@ -92,17 +98,33 @@ void GenerateImg(QImage &img, std::vector &points, Info &info) { } } + + void MainWindow::on_RenderPic_clicked() { - QImage pm(400, 400, QImage::Format_RGB888); - GenerateImg(pm, points, info); + CApplicationFontsWorker oWorker; + oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; + oWorker.m_bIsNeedThumbnails = false; + if (!NSDirectory::Exists(oWorker.m_sDirectory)) + NSDirectory::CreateDirectory(oWorker.m_sDirectory); + + NSFonts::IApplicationFonts* pFonts = oWorker.Check(); + PdfReader::CPdfReader PDFREADER(pFonts); + PDFREADER.LoadFromFile(L"test.pdf"); + int page = ui->lineEdit->text().toInt(); + PDFREADER.ConvertToRaster(page + 1, L"testpdf.bmp", 1); + QImage pm("testpdf.bmp"); + // QImage pm(400, 400, QImage::Format_RGB888); + // GenerateImg(pm, points, info); //setColor2(pm, 0x0000FF); //pm.invertPixels(); ui->lable_test->setPixmap(QPixmap::fromImage(pm)) ; ui->lable_test->setScaledContents(true); - ui->lable_test->resize(pm.size()); - pm.save("test.bmp"); + // ui->lable_test->resize(pm.size()); + //pm.save("test.bmp"); + + // pFonts->Release(); } @@ -590,3 +612,17 @@ void MainWindow::on_TrianglePoint3Y_sliderMoved(int position) on_RenderPic_clicked(); } } + +void MainWindow::on_LeftButton_clicked() +{ + int page = ui->lineEdit->text().toInt(); + ui->lineEdit->setText(QString::number(page - 1)); + on_RenderPic_clicked(); +} + +void MainWindow::on_RightButton_clicked() +{ + int page = ui->lineEdit->text().toInt(); + ui->lineEdit->setText(QString::number(page + 1)); + on_RenderPic_clicked(); +} diff --git a/Test/Applications/gradient/Gradient/mainwindow.h b/Test/Applications/gradient/Gradient/mainwindow.h index fbef279b7f..9c2dedfcf7 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.h +++ b/Test/Applications/gradient/Gradient/mainwindow.h @@ -124,6 +124,10 @@ private slots: void on_TrianglePoint3Y_sliderMoved(int position); + void on_LeftButton_clicked(); + + void on_RightButton_clicked(); + private: Ui::MainWindow *ui; }; diff --git a/Test/Applications/gradient/Gradient/mainwindow.ui b/Test/Applications/gradient/Gradient/mainwindow.ui index fdd490c716..e743183e25 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.ui +++ b/Test/Applications/gradient/Gradient/mainwindow.ui @@ -549,6 +549,58 @@ XY triangle + + + + 770 + 320 + 54 + 17 + + + + PDF + + + + + + 680 + 400 + 80 + 25 + + + + Left + + + + + + 790 + 400 + 80 + 25 + + + + Right + + + + + + 730 + 360 + 113 + 25 + + + + 746 + +