Merge pull request 'fix/Tensor-luminosity-gradient' (#326) from fix/Tensor-luminosity-gradient into release/v9.0.0

Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/326
This commit is contained in:
Oleg Korshul
2025-05-27 18:38:41 +00:00
10 changed files with 479 additions and 102 deletions

View File

@ -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);
}
};

View File

@ -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;
}
}
}

View File

@ -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<double> 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;
}

View File

@ -863,20 +863,22 @@ namespace Aggplus
double CGraphicsPath::GetArea(unsigned idx, bool isCurve) const noexcept
{
float area;
double area;
if (isCurve)
{
std::vector<PointD> 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<PointD> points = GetPoints(idx, 2);
area = 4.0 * (points[1].Y * points[0].X - points[1].X * points[0].Y) / 3.0;
}
std::vector<PointD> points = GetPoints(idx, 2);
area = (points[1].Y * points[0].X - points[1].X * points[0].Y) / 20;
return area;
}

View File

@ -371,6 +371,7 @@ namespace NSStructures
*
* Наверное напишу адаптор который переводит порядок точек из 6 типа в общий.
*/
agg::rgba8 fill_color;
std::vector<std::vector<Point>> patch;
std::vector<std::vector<agg::rgba8>> patch_colors; // 2 на 2 цвета по углам
std::vector<std::vector<float>> 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<std::vector<float>> &curve_parametrs,
const std::vector<std::vector<agg::rgba8>> &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<agg::rgba8>(256, t0, t1);
ginfo.luminocity = luminosity;
ginfo.continue_shading_f = false;
ginfo.continue_shading_b = false;

View File

@ -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<long>(shape->m_dWidth * c_dMMToPix);
long height_pix = static_cast<long>(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<CBgraFrame> 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<unsigned int*>(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"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\" w:header=\"0\" w:footer=\"0\" w:gutter=\"0\"/></w:sectPr>");
}
void CPage::DrawImage(shape_ptr_t pShape, std::shared_ptr<CImageInfo> 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<long>(pShape->m_dWidth * c_dMMToPix);
long height_pix = static_cast<long>(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<CBgraFrame> 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<unsigned int*>(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();
}
}
}

View File

@ -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<CImageInfo> 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<item_ptr_t> m_arOutputObjects;
std::vector<std::wstring> m_arCompleteObjectsXml;
// save the luminosity shapes for later filling
std::vector<shape_ptr_t> m_arLuminosityShapes;
std::vector<shape_ptr_t> m_arOneColorGradientShape;
size_t m_nShapeOrder = 0;
};
}

View File

@ -12,6 +12,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
listOfCheckBox = ui->centralwidget->findChildren<QCheckBox*>();
listOfColorLabels = ui->centralwidget->findChildren<CustomColorLabel*>();
listOfParametricLines = ui->centralwidget->findChildren<CustomParametrLineEdit*>();
listOfAlphas = ui->centralwidget->findChildren<CustomAlphaLineEdit*>();
connect(ui->label_test, SIGNAL(mousePressed()), this, SLOT(on_label_test_clicked()));
@ -61,6 +62,9 @@ QImage GenerateImg(std::vector<NSStructures::Point> &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<unsigned int>(label->getColor().red()),
@ -230,6 +247,24 @@ std::vector<std::vector<agg::rgba8>> MainWindow::qColor2rgbaMatrix()
return colors;
}
std::vector<std::vector<agg::rgba8>> MainWindow::setAlphas()
{
std::vector<std::vector<agg::rgba8>> colors;
size_t size = listOfAlphas.size() / 2;
for (int i = 0; i < size; i++)
{
std::vector<agg::rgba8> 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<NSStructures::Point> 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);
}

View File

@ -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<agg::rgba8> qColor2rgba(bool triangle);
std::vector<std::vector<agg::rgba8>> qColor2rgbaMatrix();
std::vector<std::vector<agg::rgba8>> 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<CustomLineEdit *> listOfLines;
QList<CustomColorLabel *> listOfColorLabels;
QList<CustomParametrLineEdit *> listOfParametricLines;
QList<CustomAlphaLineEdit *> listOfAlphas;
Ui::MainWindow *ui;
};

View File

@ -55,7 +55,7 @@
</rect>
</property>
<property name="currentIndex">
<number>0</number>
<number>4</number>
</property>
<widget class="QWidget" name="Linear_Page">
<widget class="QGroupBox" name="groupBox">
@ -2468,7 +2468,7 @@
</rect>
</property>
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="page_11">
<widget class="QGroupBox" name="groupBox_Linear">
@ -2607,6 +2607,111 @@
</widget>
</widget>
</widget>
<widget class="QWidget" name="page_9">
<widget class="QGroupBox" name="groupBox_26">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>201</width>
<height>101</height>
</rect>
</property>
<property name="title">
<string>Set alphas and fill color</string>
</property>
<widget class="CustomColorLabel" name="label_125">
<property name="geometry">
<rect>
<x>70</x>
<y>70</y>
<width>30</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="CustomAlphaLineEdit" name="lineEdit_88">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>0</string>
</property>
<property name="placeholderText">
<string>0</string>
</property>
</widget>
<widget class="CustomAlphaLineEdit" name="lineEdit_89">
<property name="geometry">
<rect>
<x>60</x>
<y>30</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>150</string>
</property>
<property name="placeholderText">
<string>150</string>
</property>
</widget>
<widget class="CustomAlphaLineEdit" name="lineEdit_90">
<property name="geometry">
<rect>
<x>100</x>
<y>30</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>150</string>
</property>
<property name="placeholderText">
<string>150</string>
</property>
</widget>
<widget class="CustomAlphaLineEdit" name="lineEdit_91">
<property name="geometry">
<rect>
<x>140</x>
<y>30</y>
<width>31</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>255</string>
</property>
<property name="placeholderText">
<string>255</string>
</property>
</widget>
<widget class="QLabel" name="label_35">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Fill color</string>
</property>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget class="QStackedWidget" name="stackedWidget_2">
@ -3360,7 +3465,7 @@
<x>0</x>
<y>0</y>
<width>1126</width>
<height>25</height>
<height>21</height>
</rect>
</property>
</widget>
@ -3383,6 +3488,7 @@
<addaction name="actionCoons_Patch_Parametric"/>
<addaction name="actionTensor_Coons_Patch_Gradient"/>
<addaction name="actionTensor_Coons_Patch_Parametric"/>
<addaction name="actionactionLuminocity_Gradient"/>
</widget>
<action name="actionLinear_Gradient">
<property name="text">
@ -3442,6 +3548,17 @@
<enum>QAction::TextHeuristicRole</enum>
</property>
</action>
<action name="actionactionLuminocity_Gradient">
<property name="text">
<string>Luminocity Gradient</string>
</property>
<property name="toolTip">
<string>TensorPatchLuminosity</string>
</property>
<property name="menuRole">
<enum>QAction::TextHeuristicRole</enum>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
@ -3467,6 +3584,11 @@
<slot>onMouseClicked()</slot>
</slots>
</customwidget>
<customwidget>
<class>CustomAlphaLineEdit</class>
<extends>QLineEdit</extends>
<header>mainwindow.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>