diff --git a/DesktopEditor/agg-2.4/include/agg_color_rgba.h b/DesktopEditor/agg-2.4/include/agg_color_rgba.h index db1cb4f666..5baa97399e 100644 --- a/DesktopEditor/agg-2.4/include/agg_color_rgba.h +++ b/DesktopEditor/agg-2.4/include/agg_color_rgba.h @@ -416,6 +416,16 @@ namespace agg { return self_type(rgba::from_wavelength(wl, gamma)); } + + bool operator==(const self_type& other) + { + return a == other.a && r == other.r && g == other.g && b == other.b; + } + + bool operator!=(const self_type& other) + { + return !operator==(other); + } }; 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 46314feb5c..98e9fc5dea 100644 --- a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h +++ b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h @@ -1000,7 +1000,17 @@ namespace agg { if (i < RES && j < RES) { - precalc[i][j] = c; + if (m_oGradientInfo.luminocity) + { + ColorT fillC; + fillC.r = m_oGradientInfo.shading.fill_color.r * c.r / 255 + 255 - c.r; + fillC.g = m_oGradientInfo.shading.fill_color.g * c.g / 255 + 255 - c.g; + fillC.b = m_oGradientInfo.shading.fill_color.b * c.b / 255 + 255 - c.b; + fillC.a = 255; + precalc[i][j] = fillC; + } + else + precalc[i][j] = c; } } } diff --git a/DesktopEditor/graphics/BooleanOperations.cpp b/DesktopEditor/graphics/BooleanOperations.cpp index 05d7a991d3..7d88d4ae11 100644 --- a/DesktopEditor/graphics/BooleanOperations.cpp +++ b/DesktopEditor/graphics/BooleanOperations.cpp @@ -1020,22 +1020,39 @@ void CBooleanOperations::TracePaths() { size_t length = Segments1.size(); Result.StartFigure(); + bool first_start = true; for (size_t i = 0; i < length + Segments2.size(); i++) { Segment s = i >= length ? Segments2[i - length] : Segments1[i]; bool valid = s.IsValid(Op), - start = true; + start = true; + PointD start_point; while (valid) { if (!start || (Op == Intersection && s.Inters && !GetNextSegment(s).Inters)) SetVisited(s); - if (start) + if (first_start) + { Result.MoveTo(s.P.X, s.P.Y); + start_point = s.P; + } + else if (start) + { + double x, y; + Result.GetLastPoint(x, y); + if (isZero(start_point.X - x) && isZero(start_point.Y - y)) + { + Result.MoveTo(s.P.X, s.P.Y); + start_point = s.P; + } + else + Result.LineTo(s.P.X, s.P.Y); + } else if (s.IsCurve) Result.CurveTo(s.HI.X + s.P.X, s.HI.Y + s.P.Y, - s.HO.X + s.P.X, s.HO.Y + s.P.Y, - s.P.X, s.P.Y); + s.HO.X + s.P.X, s.HO.Y + s.P.Y, + s.P.X, s.P.Y); else Result.LineTo(s.P.X, s.P.Y); @@ -1065,6 +1082,9 @@ void CBooleanOperations::TracePaths() if (start) start = false; + + if (first_start) + first_start = false; } if (!start && AllOverlap()) break; @@ -1645,12 +1665,14 @@ int CBooleanOperations::CheckInters(const PointD& point, const Segment& segment, std::vector roots = curve.GetCurveLineIntersection(segment.P.X,segment.P.Y, point.X - segment.P.X, point.Y - segment.P.Y); Curve line(segment, Segment(point)); - int count = 0; - for (const auto& r : roots) - if (line.GetTimeOf(curve.GetPoint(r)) != -1) - count++; + return roots.size() % 2; - return count; + // int count = 0; + // for (const auto& r : roots) + // if (line.GetTimeOf(curve.GetPoint(r)) != -1) + // count++; + + // return count; } return 0; } diff --git a/DesktopEditor/graphics/GraphicsPath.cpp b/DesktopEditor/graphics/GraphicsPath.cpp index ec259ff452..4f15063441 100644 --- a/DesktopEditor/graphics/GraphicsPath.cpp +++ b/DesktopEditor/graphics/GraphicsPath.cpp @@ -863,20 +863,22 @@ namespace Aggplus double CGraphicsPath::GetArea(unsigned idx, bool isCurve) const noexcept { - float area; + double area; if (isCurve) { std::vector points = GetPoints(idx, 4); - area = 3 * ((points[3].Y - points[0].Y) * (points[1].X + points[2].X) - - (points[3].X - points[0].X) * (points[1].Y * points[2].Y) - + points[1].Y * (points[0].X - points[2].X) - - points[1].X * (points[0].Y - points[2].Y) - + points[3].Y * (points[2].X + points[0].X / 3) - - points[3].X * (points[2].Y - points[0].Y / 3)) / 20; + area = (points[3].Y - points[0].Y) * (points[1].X + points[2].X) + - (points[3].X - points[0].X) * (points[1].Y + points[2].Y) + + points[1].Y * (points[0].X - points[2].X) + - points[1].X * (points[0].Y - points[2].Y) + + points[3].Y * (points[2].X + points[0].X / 3.0) + - points[3].X * (points[2].Y + points[0].Y / 3.0); + } + else + { + std::vector points = GetPoints(idx, 2); + area = 4.0 * (points[1].Y * points[0].X - points[1].X * points[0].Y) / 3.0; } - - std::vector points = GetPoints(idx, 2); - area = (points[1].Y * points[0].X - points[1].X * points[0].Y) / 20; return area; } diff --git a/DesktopEditor/graphics/shading_info.h b/DesktopEditor/graphics/shading_info.h index 6ab27759f1..0c763942d4 100644 --- a/DesktopEditor/graphics/shading_info.h +++ b/DesktopEditor/graphics/shading_info.h @@ -371,6 +371,7 @@ namespace NSStructures * * Наверное напишу адаптор который переводит порядок точек из 6 типа в общий. */ + agg::rgba8 fill_color; std::vector> patch; std::vector> patch_colors; // 2 на 2 цвета по углам std::vector> patch_parameters; // 2 на 2 параметра @@ -388,8 +389,8 @@ namespace NSStructures xsize(1.0f), ysize(1.0f), linstretch(1.0f), linoffset(0.0f), continue_shading_f(false), - continue_shading_b(false) - + continue_shading_b(false), + luminocity(false) { } void setAngleDegrees(float deg) @@ -404,6 +405,57 @@ namespace NSStructures { discrete_step = 1.0f / n; } + bool checkLuminosity() const + { + if (shading.patch_colors.empty()) + return false; + + for (const auto& ar : shading.patch_colors) + for (const auto& c : ar) + if (c.r != c.g || c.g != c.b) + return false; + + return true; + } + bool colorEqual(const agg::rgba8& c1, const agg::rgba8& c2) const + { + return c1.r == c2.r && + c1.g == c2.g && + c1.b == c2.b && + c1.a == c2.a; + } + bool isOneColor() const + { + switch (shading.shading_type) + { + case ShadingInfo::FunctionOnly: + case ShadingInfo::Parametric: + return false; + case ShadingInfo::TriangleInterpolation: + return colorEqual(shading.triangle_colors[0], shading.triangle_colors[1]) && + colorEqual(shading.triangle_colors[1], shading.triangle_colors[2]); + case ShadingInfo::CurveInterpolation: + case ShadingInfo::TensorCurveInterpolation: + return colorEqual(shading.patch_colors[0][0], shading.patch_colors[0][1]) && + colorEqual(shading.patch_colors[0][1], shading.patch_colors[1][0]) && + colorEqual(shading.patch_colors[1][0], shading.patch_colors[1][1]); + default: + return false; + } + } + agg::rgba8 getFillColor() const + { + if (!shading.triangle_colors.empty()) + return shading.triangle_colors[0]; + if (!shading.patch_colors.empty()) + return shading.patch_colors[0][0]; + return agg::rgba8(0, 0, 0); + } + void setFillColor(const agg::rgba8& color) + { + shading.fill_color = color; + luminocity = true; + } void transform(const Aggplus::CMatrix& matrix) { // shading transform @@ -502,6 +554,7 @@ namespace NSStructures float linstretch; // stretch linear gradient, can be negative (eq angle = 180) can not be zero float linoffset; // offset relative to image size float continue_shading_b, continue_shading_f; + bool luminocity; ShadingInfo shading; }; @@ -643,6 +696,7 @@ namespace NSStructures const std::vector> &curve_parametrs, const std::vector> &curve_colors, bool parametric, + bool luminosity = false, float t0 = 0.0f, float t1 = 1.0f) { GradientInfo ginfo; @@ -651,6 +705,7 @@ namespace NSStructures ginfo.shading.f_type = ShadingInfo::UseNew; ginfo.shading.function = ColorFunction(256, t0, t1); + ginfo.luminocity = luminosity; ginfo.continue_shading_f = false; ginfo.continue_shading_b = false; diff --git a/DocxRenderer/src/logic/Page.cpp b/DocxRenderer/src/logic/Page.cpp index c7525f5bc1..1d10c6e6c6 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -32,7 +32,7 @@ namespace NSDocxRenderer } else if (lType == c_nClipType) { - // closing clip path if non-closed + //closing clip path if non-closed if (!m_oCurrVectorGraphics.IsEmpty() && m_oCurrVectorGraphics.GetData().back().type != CVectorGraphics::ePathCommandType::pctClose) m_oCurrVectorGraphics.Add({CVectorGraphics::ePathCommandType::pctClose, {}}); @@ -44,6 +44,9 @@ namespace NSDocxRenderer else m_oClipVectorGraphics = std::move(m_oCurrVectorGraphics); } + + if (!m_arLuminosityShapes.empty() && !m_arOneColorGradientShape.empty()) + FillLuminosityShapes(); } void CPage::Clear() @@ -66,6 +69,7 @@ namespace NSDocxRenderer m_oCurrVectorGraphics.Clear(); m_oClipVectorGraphics.Clear(); m_arCompleteObjectsXml.clear(); + m_arLuminosityShapes.clear(); } CPage::~CPage() @@ -227,84 +231,31 @@ namespace NSDocxRenderer } shape->SetVector(std::move(m_oCurrVectorGraphics)); + bool skip_shape = false; auto info = pInfo; if (!info && m_bIsGradient) { - // image with gradient must be closed - if (!shape->m_oVector.IsEmpty() && shape->m_oVector.GetData().back().type != CVectorGraphics::ePathCommandType::pctClose) - shape->m_oVector.Add({CVectorGraphics::ePathCommandType::pctClose, {}}); - - long width_pix = static_cast(shape->m_dWidth * c_dMMToPix); - long height_pix = static_cast(shape->m_dHeight * c_dMMToPix); - - if (width_pix == 0) width_pix = 1; - if (height_pix == 0) height_pix = 1; - - const long step = 4; - const long stride = -step * width_pix; - - std::unique_ptr frame(new CBgraFrame()); - size_t data_size = width_pix * height_pix * step; - BYTE* data = new BYTE[data_size]; - - // white and alpha is min (full transparent) - for (size_t i = 0; i < width_pix * height_pix; ++i) - reinterpret_cast(data)[i] = 0x00ffffff; - - frame->put_Data(data); - frame->put_Height(height_pix); - frame->put_Width(width_pix); - frame->put_Stride(stride); - - auto shifted_vector = shape->m_oVector; - Aggplus::CMatrix transform_matrix; - transform_matrix.Translate(-shifted_vector.GetLeft(), -shifted_vector.GetTop()); - shifted_vector.Transform(transform_matrix); - - NSStructures::CBrush shifted_brush = m_oBrush; - shifted_brush.Bounds.left = shifted_vector.GetLeft(); - shifted_brush.Bounds.right = shifted_vector.GetRight(); - shifted_brush.Bounds.bottom = shifted_vector.GetBottom(); - shifted_brush.Bounds.top = shifted_vector.GetTop(); - shifted_brush.m_oGradientInfo.transform(transform_matrix); - - NSGraphics::IGraphicsRenderer* g_renderer = NSGraphics::Create(); - g_renderer->CreateFromBgraFrame(frame.get()); - g_renderer->SetSwapRGB(false); - g_renderer->put_Width(shape->m_dWidth); - g_renderer->put_Height(shape->m_dHeight); - g_renderer->RestoreBrush(shifted_brush); - g_renderer->RestorePen(m_oPen); - g_renderer->BeginCommand(c_nPathType); - shifted_vector.DrawOnRenderer(g_renderer); - g_renderer->DrawPath(c_nWindingFillMode); - g_renderer->EndCommand(c_nPathType); - - Aggplus::CImage img; - img.Create(data, width_pix, height_pix, stride, true); - info = m_oManagers.pImageManager->WriteImage(&img, shape->m_dTop, shape->m_dBaselinePos, shape->m_dWidth, shape->m_dHeight); - rotation = 0; - image_vector = shape->m_oVector; + if (m_oBrush.m_oGradientInfo.checkLuminosity()) + m_arLuminosityShapes.push_back(shape); + else if (m_oBrush.m_oGradientInfo.isOneColor()) + { + m_arOneColorGradientShape.push_back(shape); + skip_shape = true; + } + else + DrawGradient(shape); m_bIsGradient = false; - RELEASEINTERFACE(g_renderer) } - shape->m_dRotation = rotation; - - if (info) + else if (info) { - shape->m_pImageInfo = info; - shape->m_eType = CShape::eShapeType::stVectorTexture; - image_vector.RotateAt(-shape->m_dRotation, shape->m_oVector.GetCenter()); - - shape->m_dImageBot = image_vector.GetBottom(); - shape->m_dImageTop = image_vector.GetTop(); - shape->m_dImageLeft = image_vector.GetLeft(); - shape->m_dImageRight = image_vector.GetRight(); + shape->m_dRotation = rotation; + DrawImage(shape, info, image_vector); } else shape->m_eType = CShape::eShapeType::stVectorGraphics; + if (!shape->IsOoxmlValid()) return; @@ -314,8 +265,11 @@ namespace NSDocxRenderer shape->m_oBrush.Color1 == c_iWhiteColor) return; - shape->m_nOrder = ++m_nShapeOrder; - m_arShapes.push_back(shape); + if (!skip_shape) + { + shape->m_nOrder = ++m_nShapeOrder; + m_arShapes.push_back(shape); + } } void CPage::AddText( @@ -2155,4 +2109,127 @@ namespace NSDocxRenderer else oWriter.WriteString(L""); } + + void CPage::DrawImage(shape_ptr_t pShape, std::shared_ptr oImgInfo, CVectorGraphics& imageVector) + { + pShape->m_pImageInfo = oImgInfo; + pShape->m_eType = CShape::eShapeType::stVectorTexture; + imageVector.RotateAt(-pShape->m_dRotation, pShape->m_oVector.GetCenter()); + + pShape->m_dImageBot = imageVector.GetBottom(); + pShape->m_dImageTop = imageVector.GetTop(); + pShape->m_dImageLeft = imageVector.GetLeft(); + pShape->m_dImageRight = imageVector.GetRight(); + } + + void CPage::DrawGradient(shape_ptr_t pShape) + { + // image with gradient must be closed + if (!pShape->m_oVector.IsEmpty() && pShape->m_oVector.GetData().back().type != CVectorGraphics::ePathCommandType::pctClose) + pShape->m_oVector.Add({CVectorGraphics::ePathCommandType::pctClose, {}}); + + long width_pix = static_cast(pShape->m_dWidth * c_dMMToPix); + long height_pix = static_cast(pShape->m_dHeight * c_dMMToPix); + + if (width_pix == 0) width_pix = 1; + if (height_pix == 0) height_pix = 1; + + const long step = 4; + const long stride = -step * width_pix; + + std::unique_ptr frame(new CBgraFrame()); + size_t data_size = width_pix * height_pix * step; + BYTE* data = new BYTE[data_size]; + + // white and alpha is min (full transparent) + for (size_t i = 0; i < width_pix * height_pix; ++i) + reinterpret_cast(data)[i] = 0x00ffffff; + + frame->put_Data(data); + frame->put_Height(height_pix); + frame->put_Width(width_pix); + frame->put_Stride(stride); + + auto shifted_vector = pShape->m_oVector; + Aggplus::CMatrix transform_matrix; + transform_matrix.Translate(-shifted_vector.GetLeft(), -shifted_vector.GetTop()); + shifted_vector.Transform(transform_matrix); + + NSStructures::CBrush shifted_brush = pShape->m_oBrush; + shifted_brush.Bounds.left = shifted_vector.GetLeft(); + shifted_brush.Bounds.right = shifted_vector.GetRight(); + shifted_brush.Bounds.bottom = shifted_vector.GetBottom(); + shifted_brush.Bounds.top = shifted_vector.GetTop(); + shifted_brush.m_oGradientInfo.transform(transform_matrix); + + NSGraphics::IGraphicsRenderer* g_renderer = NSGraphics::Create(); + g_renderer->CreateFromBgraFrame(frame.get()); + g_renderer->SetSwapRGB(false); + g_renderer->put_Width(pShape->m_dWidth); + g_renderer->put_Height(pShape->m_dHeight); + g_renderer->RestoreBrush(shifted_brush); + g_renderer->RestorePen(m_oPen); + g_renderer->BeginCommand(c_nPathType); + shifted_vector.DrawOnRenderer(g_renderer); + g_renderer->DrawPath(c_nWindingFillMode); + g_renderer->EndCommand(c_nPathType); + + Aggplus::CImage img; + img.Create(data, width_pix, height_pix, stride, true); + auto info = m_oManagers.pImageManager->WriteImage(&img, pShape->m_dTop, pShape->m_dBaselinePos, pShape->m_dWidth, pShape->m_dHeight); + pShape->m_dRotation = 0; + + DrawImage(pShape, info, pShape->m_oVector); + + RELEASEINTERFACE(g_renderer) + } + + agg::rgba8 CPage::GetFillColor() + { + bool is_one = true; + agg::rgba8 color = m_arOneColorGradientShape[0]->m_oBrush.m_oGradientInfo.getFillColor(); + for (const auto& s : m_arOneColorGradientShape) + if (s->m_oBrush.m_oGradientInfo.getFillColor() != color) + is_one = false; + + if (is_one) + return color; + else + return agg::rgba8(); + } + + void CPage::FillLuminosityShapes() + { + if (GetFillColor() == agg::rgba8::no_color()) + { + for (auto itt = m_arOneColorGradientShape.begin(); itt != m_arOneColorGradientShape.end();) + { + for (auto it = m_arLuminosityShapes.begin(); it != m_arLuminosityShapes.end();) + { + if ((*it)->m_oVector.GetRight() > (*itt)->m_oVector.GetLeft() && (*it)->m_oVector.GetBottom() > (*itt)->m_oVector.GetTop() && + (*it)->m_oVector.GetLeft() < (*itt)->m_oVector.GetRight() && (*it)->m_oVector.GetTop() < (*itt)->m_oVector.GetBottom()) + { + (*it)->m_oBrush.m_oGradientInfo.setFillColor((*itt)->m_oBrush.m_oGradientInfo.getFillColor()); + DrawGradient((*it)); + it = m_arLuminosityShapes.erase(it); + } + else + ++it; + } + itt = m_arOneColorGradientShape.erase(itt); + } + } + else + { + auto fill_color = GetFillColor(); + for (auto& s : m_arLuminosityShapes) + { + s->m_oBrush.m_oGradientInfo.setFillColor(fill_color); + DrawGradient(s); + } + + m_arLuminosityShapes.clear(); + m_arOneColorGradientShape.clear(); + } + } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index e17e9fcb19..0b2567de24 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -41,12 +41,13 @@ namespace NSDocxRenderer NSStructures::CEdgeText m_oEdgeText{}; Aggplus::CMatrix m_oTransform{}; - bool m_bIsDeleteTextClipPage{true}; - bool m_bIsRecalcFontSize {true}; - bool m_bIsGradient {false}; - bool m_bUseDefaultFont {false}; - bool m_bWriteStyleRaw {false}; - bool m_bIsBuildTables {false}; + bool m_bIsDeleteTextClipPage {true}; + bool m_bIsRecalcFontSize {true}; + bool m_bIsGradient {false}; + bool m_bUseDefaultFont {false}; + bool m_bWriteStyleRaw {false}; + bool m_bIsBuildTables {false}; + bool m_bIsLuminosityShapesFiled{false}; CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers); ~CPage(); @@ -189,6 +190,12 @@ namespace NSDocxRenderer static shape_ptr_t CreateSingleLineShape(line_ptr_t& pLine); static shape_ptr_t CreateSingleParagraphShape(paragraph_ptr_t& pParagraph); + void DrawImage(shape_ptr_t pShape, std::shared_ptr oImg, CVectorGraphics& imageVector); + void DrawGradient(shape_ptr_t pShape); + + agg::rgba8 GetFillColor(); + void FillLuminosityShapes(); + CManagers m_oManagers; CVectorGraphics m_oCurrVectorGraphics; @@ -207,6 +214,10 @@ namespace NSDocxRenderer std::vector m_arOutputObjects; std::vector m_arCompleteObjectsXml; + // save the luminosity shapes for later filling + std::vector m_arLuminosityShapes; + std::vector m_arOneColorGradientShape; + size_t m_nShapeOrder = 0; }; } diff --git a/Test/Applications/gradient/Gradient/mainwindow.cpp b/Test/Applications/gradient/Gradient/mainwindow.cpp index d01fd8ab22..70917d1c21 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.cpp +++ b/Test/Applications/gradient/Gradient/mainwindow.cpp @@ -12,6 +12,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi listOfCheckBox = ui->centralwidget->findChildren(); listOfColorLabels = ui->centralwidget->findChildren(); listOfParametricLines = ui->centralwidget->findChildren(); + listOfAlphas = ui->centralwidget->findChildren(); connect(ui->label_test, SIGNAL(mousePressed()), this, SLOT(on_label_test_clicked())); @@ -61,6 +62,9 @@ QImage GenerateImg(std::vector &points, Info &info, const i NSStructures::GradientInfo ginfo = info.ginfo; ginfo.shading.f_type = NSStructures::ShadingInfo::UseNew; + NSStructures::CBrush brush; + brush.m_oGradientInfo = ginfo; + //pRasterRenderer->RestoreBrush(brush); pRasterRenderer->put_BrushGradInfo(&ginfo); auto a = info.c; auto b = info.p; @@ -96,6 +100,7 @@ void MainWindow::initializeColors(bool Triangle) { listOfColorLabels[3]->setColor(QColor(Qt::yellow)); } + listOfColorLabels[4]->setColor(QColor(Qt::black)); } void MainWindow::on_actionLinear_Gradient_triggered() @@ -189,6 +194,18 @@ void MainWindow::on_actionTensor_Coons_Patch_Parametric_triggered() ui->statusbar->showMessage("Tensor Coons Patch Parametric"); } +void MainWindow::on_actionactionLuminocity_Gradient_triggered() +{ + ui->stackedWidget_1->setCurrentIndex(4); + ui->stackedWidget_2->setCurrentIndex(6); + ui->stackedWidget_3->setCurrentIndex(2); + info.gradient = Luminosity; + info.offset = TensorCoonsPatchOffset; + info.gradient_type = c_BrushTypeTensorCurveGradient; + initializeColors(false); + ui->statusbar->showMessage("Tensor Coons Patch"); +} + inline agg::rgba8 getRGB(CustomColorLabel *label) { return {static_cast(label->getColor().red()), @@ -230,6 +247,24 @@ std::vector> MainWindow::qColor2rgbaMatrix() return colors; } +std::vector> MainWindow::setAlphas() +{ + std::vector> colors; + size_t size = listOfAlphas.size() / 2; + + for (int i = 0; i < size; i++) + { + std::vector sub_colors; + for (int j = 0; j < size; j++) + { + sub_colors.push_back({0, 0, 0, listOfAlphas[2 * i + j]->text().toUInt()}); + } + colors.push_back(sub_colors); + } + + return colors; +} + NSStructures::Point MainWindow::scaleCoord(NSStructures::Point p) { return {p.x * MM_TO_COORD(ui->label_test->width()), p.y * MM_TO_COORD(ui->label_test->height())}; @@ -279,6 +314,7 @@ void MainWindow::setPoints(QImage *image) break; case TensorCoonsPatch: case TensorCoonsPatchParametric: + case Luminosity: for (std::vector v : info.tensorcurve) { for (NSStructures::Point p : v) @@ -440,6 +476,11 @@ void MainWindow::on_pushButton_clicked() info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve(info.tensorcurve, info.tensor_curve_parametrs, qColor2rgbaMatrix(), info.gradient == TensorCoonsPatchParametric); break; + case Luminosity: + info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve(info.tensorcurve, info.tensor_curve_parametrs, + setAlphas(), false, true); + info.ginfo.setFillColor(getRGB(listOfColorLabels[4])); + break; default: break; } @@ -479,3 +520,6 @@ void MainWindow::on_pushButton_clicked() ui->label_test->setPixmap(QPixmap::fromImage(pm)); ui->label_test->setScaledContents(true); } + + + diff --git a/Test/Applications/gradient/Gradient/mainwindow.h b/Test/Applications/gradient/Gradient/mainwindow.h index 2a78c1a472..4d07017804 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.h +++ b/Test/Applications/gradient/Gradient/mainwindow.h @@ -64,6 +64,25 @@ public slots: } }; +class CustomAlphaLineEdit : public QLineEdit +{ + Q_OBJECT +public: + CustomAlphaLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) + { + connect(this, &QLineEdit::editingFinished, this, &CustomAlphaLineEdit::onEditingFinished); + } + ~CustomAlphaLineEdit() {} +public slots: + void onEditingFinished() + { + if (this->text() == "") + this->setText(this->placeholderText()); + if (this->text().toUInt() > 255) + this->setText("255"); + } +}; + class CustomLabel : public QLabel { Q_OBJECT @@ -198,7 +217,8 @@ typedef enum CoonsPatch, CoonsPatchParametric, TensorCoonsPatch, - TensorCoonsPatchParametric + TensorCoonsPatchParametric, + Luminosity } GradientType; typedef enum @@ -246,6 +266,7 @@ public: void initializeColors(bool triangle); std::vector qColor2rgba(bool triangle); std::vector> qColor2rgbaMatrix(); + std::vector> setAlphas(); void setPoints(QImage *image); NSStructures::Point scaleCoord(NSStructures::Point p); @@ -278,6 +299,8 @@ private slots: void on_actionTensor_Coons_Patch_Parametric_triggered(); + void on_actionactionLuminocity_Gradient_triggered(); + private: QImage img; Info info; @@ -287,6 +310,7 @@ private: QList listOfLines; QList listOfColorLabels; QList listOfParametricLines; + QList listOfAlphas; Ui::MainWindow *ui; }; diff --git a/Test/Applications/gradient/Gradient/mainwindow.ui b/Test/Applications/gradient/Gradient/mainwindow.ui index f64b558c70..f41c9ad2fa 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.ui +++ b/Test/Applications/gradient/Gradient/mainwindow.ui @@ -55,7 +55,7 @@ - 0 + 4 @@ -2468,7 +2468,7 @@ - 0 + 2 @@ -2607,6 +2607,111 @@ + + + + + 10 + 20 + 201 + 101 + + + + Set alphas and fill color + + + + + 70 + 70 + 30 + 20 + + + + + + + + + + 20 + 30 + 31 + 28 + + + + 0 + + + 0 + + + + + + 60 + 30 + 31 + 28 + + + + 150 + + + 150 + + + + + + 100 + 30 + 31 + 28 + + + + 150 + + + 150 + + + + + + 140 + 30 + 31 + 28 + + + + 255 + + + 255 + + + + + + 20 + 70 + 49 + 16 + + + + Fill color + + + + @@ -3360,7 +3465,7 @@ 0 0 1126 - 25 + 21 @@ -3383,6 +3488,7 @@ + @@ -3442,6 +3548,17 @@ QAction::TextHeuristicRole + + + Luminocity Gradient + + + TensorPatchLuminosity + + + QAction::TextHeuristicRole + + @@ -3467,6 +3584,11 @@ onMouseClicked() + + CustomAlphaLineEdit + QLineEdit +
mainwindow.h
+