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 222de87c28..3ea3b2a64e 100644 --- a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h +++ b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h @@ -1,5 +1,15 @@ namespace agg { + /** + * Основной смысл в том, что есть два этапа обсчета, это параметризация и вычисление цвета. + * + * В частности радиальный и линейный градиенты, требуют параметризацию, (x,y)-> t, + * чтобы затем перевести параметр в цвет. + * + * У шейдеров параметризация опциональная, поэтому для них отдельно есть способ с параметризацией и без нее + * + * */ + class calcBase { public: @@ -156,6 +166,35 @@ namespace agg NSStructures::GradientInfo ginfo; }; + class calcTriangle : public calcBase + { + public: + calcTriangle(const NSStructures::GradientInfo &_g) + { + ginfo = _g; + } + virtual float eval(float x, float y) override + { + // тут можно любую интерполяцию сделать, там не написано какая должна быть + // пока просто по проекциям берет среднее todo refactor + float t1 = relative_project_len(x, y, ginfo.shading.triangle[0], ginfo.shading.triangle[1]); + float t2 = relative_project_len(x, y, ginfo.shading.triangle[1], ginfo.shading.triangle[2]); + float t3 = relative_project_len(x, y, ginfo.shading.triangle[2], ginfo.shading.triangle[0]); + return 0.333333333 * (ginfo.shading.triangle_parametrs[0] * (t2 + 1 - t1) + + ginfo.shading.triangle_parametrs[1] * (t3 + 1 - t2) + + ginfo.shading.triangle_parametrs[2] * (t1 + 1 - t3)); + } + // x first, наверное это стоит немного отрефакторить пока просто пробую чтобы работало + //todo + static float relative_project_len(float x, float y, std::pair start, std::pair finish) + { + return ((x - start.first) * (finish.first - start.first) + (y - start.second) * (finish.second - start.second)) + / ((finish.first - start.first) * (finish.first - start.first) + + (finish.second - start.second) * (finish.second - start.second)); //(a, b) / b^2 + } + NSStructures::GradientInfo ginfo; + }; + template class gradient_base { @@ -265,6 +304,9 @@ namespace agg case Aggplus::BrushTypeNewLinearGradient: calculate = new calcNewLinear(m_oGradientInfo, xmin, ymin, xmax, ymax); break; + case Aggplus::BrushTypeMyTestGradient: + calculate = new calcTriangle(m_oGradientInfo); + break; default: fprintf(stderr, "WRONG BRUSH TYPE"); calculate = new calcRandom(); @@ -296,15 +338,48 @@ namespace agg double _y = y; m_trans.transform(&_x, &_y); float t = calculate_param((float)_x, (float)_y); - - int index = int(t * MaxColorIndex + 0.5); - if (!m_valid_table[index]) - CalcColor(index); - - *span++ = m_color_table[index]; + if (m_oGradientInfo.shading.parametrised_triangle_shading) { + *span++ = this->triangle(x, y); + } + else if (m_oGradientInfo.shading.f_type == NSStructures::ShadingInfo::UseXY2Color) + { + _x = (_x - xmin) / (xmax - xmin); + _y = (_y - ymin) / (ymax - xmin); + *span++ = m_oGradientInfo.shading.function.get_color(_x, _y); //m_color_table[index]; + } + else if (m_oGradientInfo.shading.f_type == NSStructures::ShadingInfo::UseT2Color) + { + *span++ = m_oGradientInfo.shading.function.get_color(t); + } + else + { + int index = int(t * MaxColorIndex + 0.5); + if (!m_valid_table[index]) + CalcColor(index); + *span++ = m_color_table[index]; + } } } + //todo refactor + ColorT mul(ColorT c1, float t) + { + return ColorT(c1.r * t, c1.g * t, c1.b * t, c1.a * t); + } + ColorT sum(ColorT c1, ColorT c2) + { + return ColorT(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b, c1.a + c2.a); + } + ColorT triangle(float x, float y) + { + float t1 = calcTriangle::relative_project_len(x, y, m_oGradientInfo.shading.triangle[0], m_oGradientInfo.shading.triangle[1]); + float t2 = calcTriangle::relative_project_len(x, y, m_oGradientInfo.shading.triangle[1], m_oGradientInfo.shading.triangle[2]); + float t3 = calcTriangle::relative_project_len(x, y, m_oGradientInfo.shading.triangle[2], m_oGradientInfo.shading.triangle[0]); + ColorT c1 = mul(m_oGradientInfo.shading.triangle_colors[0], (t2 + 1 - t1)/3); + ColorT c2 = mul(m_oGradientInfo.shading.triangle_colors[1], (t3 + 1 - t2)/3); + ColorT c3 = mul(m_oGradientInfo.shading.triangle_colors[2], (t2 + 1 - t1)/3); + return sum(c1, sum(c2,c3)); + } void SetDirection(const agg::rect_d &bounds, const agg::trans_affine &trans) { m_trans = trans; diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 63bbe2decd..3b40ecd15f 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -33,6 +33,9 @@ #include #include "../fontengine/FontFile.h" +namespace Aggplus { + #include "test/shading.h" +} namespace Aggplus { CGraphics::CGraphics() diff --git a/DesktopEditor/graphics/shading_info.h b/DesktopEditor/graphics/shading_info.h new file mode 100644 index 0000000000..454bda52aa --- /dev/null +++ b/DesktopEditor/graphics/shading_info.h @@ -0,0 +1,319 @@ +#include +namespace NSStructures +{ + /** + * PDF Gradients is not so comparable with this graphics lib + * so my realisation of gradients use quite different interface. + * + * First of all we have to be able to use different (x, y) -> color / t -> color + * functions in runtime. I think the most natural way is to use vector. + * + * + * Потом приведу комменты в порядок, после ревью. + * + * + * */ + // TODO div optimise + template + class ColorFuction + /** + * Реализацию произвольной функции в рантайме я решил сделать как массив, тк так проще всего + * я еще не совсем понял как точно передается в пдфе функция, но такая реализация, позволяет пользователю + * выбрать любой способ. + * + * Пока все копируется, т.к. в большинсве случаев вектор 2кБ по размеру и проблем нету + * только если использовать двумерную функцию размер возрастает до МБ, но не хочется возится с укузателями + * ради этого, т.к. судя по всему случай исключительный(только 1 шейдинг требует такую функцию). + * Если надо будет, наверно можно будет переписать на юникптр. + * + * Есть возможность выставить обычную линейную интерполяцию, просто для тестирования + * + так реализуется градиент стандартный. + * + * Пока у меня конструкторы по умолчанию, чтото заполняют, для тестирования опятьже + * потом стоит все убрать, чтобы в кисти не таскать это все, когда оно не нужно, + * если не выделять память то там в сумме будет <100B гдето, не думаю, что это будет так много, + * чтобы писать отдельный интерфейс для кисти + * + * Плюс я вообще не знаю как обрабатывать, внештатные ситуации, в целом, можно вообще просто + * эксепшены кидать если что или ничего не делать. + */ + { + public: + // Default constructor works only with one parameter functions + ColorFuction() : RESOLUTION(512), x_domain_min(0.0f), x_domain_max(1.0f), + values(std::vector>(1, std::vector(RESOLUTION))) + { + for (int i = 0; i < RESOLUTION; i++) + { + uint value = 255 - (255 * ((float)i / RESOLUTION)); + values[0][i] = ColorT(value, value, value); + } + } + + ColorFuction(size_t res, float xmin, float xmax) : RESOLUTION(res), x_domain_min(xmin), x_domain_max(xmax), + values(std::vector>(1, std::vector(RESOLUTION))) + { + for (int i = 0; i < RESOLUTION; i++) + { + uint value = 255 - (255 * ((float)i / RESOLUTION)); + values[0][i] = ColorT(value, value, value); + } + } + + ColorFuction(size_t res, float xmin, float xmax, float ymin, float ymax) : RESOLUTION(res), x_domain_min(xmin), x_domain_max(xmax), y_domain_min(ymin), y_domain_max(ymax), + values(std::vector>(RESOLUTION, std::vector(RESOLUTION))) + { + + for (int i = 0; i < RESOLUTION; i++) + { + for (int j = 0; j < RESOLUTION; j++) + { + uint value = 255 - (255 * ((float)(i + j) / RESOLUTION / 2)); + values[j][i] = ColorT(value, value, value); + } + } + } + + ColorT get_color(float x) + { + int index = get_x_index(x); + return values[0][index]; + } + + //used only in shading type 1 + ColorT get_color(float x, float y) + { + int xi = get_x_index(x); + int yi = get_y_index(y); + + return values[yi][xi]; + } + + int set_color(float x, int r, int g, int b, int a) + { + int index = get_x_index(x); // pls dont set color out of bounds, it wont crush, but will work not as you max expected + values[0][index].r = r; + values[0][index].g = g; + values[0][index].b = b; + values[0][index].a = a; + } + int set_color(float x, float y, int r, int g, int b, int a) + { + int xindex = get_x_index(x); + int yindex = get_y_index(y); + values[yindex][xindex].r = r; + values[yindex][xindex].g = g; + values[yindex][xindex].b = b; + values[yindex][xindex].a = a; + } + int set_color(size_t xindex, int r, int g, int b, int a) + { + values[0][xindex].r = r; + values[0][xindex].g = g; + values[0][xindex].b = b; + values[0][xindex].a = a; + } + int set_color(size_t xindex, size_t yindex, int r, int g, int b, int a) + { + values[yindex][xindex].r = r; + values[yindex][xindex].g = g; + values[yindex][xindex].b = b; + values[yindex][xindex].a = a; + } + // position must be sorted by incr ub otherwise + // only for 1 in function + int set_linear_interpolation(const std::vector &colors, const std::vector &positions) + { + if (colors.size() != positions.size()) + { + return -1; // error + } + std::vector indexes; + for (float x : positions) + { + indexes.push_back(get_x_index(x)); + } + for (int i = 0; i < colors.size(); i++) + { + values[0][indexes[i]].r = hex2r(colors[i]); + values[0][indexes[i]].g = hex2g(colors[i]); + values[0][indexes[i]].b = hex2b(colors[i]); + values[0][indexes[i]].a = hex2a(colors[i]); + + std::cout << colors[i] << ' ' << std::endl; + std::cout << hex2r(colors[i]) << ' ' << hex2g(colors[i]) << ' ' + << hex2b(colors[i]) << ' ' << hex2a(colors[i]) << std::endl; + } + for (int i = 0; i < positions.size() - 1; i++) + { + interpolate_indexes(indexes[i], indexes[i + 1]); + } + return 0; + } + size_t get_resolution() const + { + return RESOLUTION; + } + private: + size_t RESOLUTION; + std::vector> values; + float x_domain_min, x_domain_max; + float y_domain_min, y_domain_max; + int get_x_index(float x) + { + int x_index = (int)(RESOLUTION - 1) * (x - x_domain_min) / (x_domain_max - x_domain_min); + if (x_index < 0) + return 0; + if (x_index > RESOLUTION - 1) + return RESOLUTION - 1; + return x_index; + } + int get_y_index(float y) + { + int y_index = (int)(RESOLUTION - 1) * (y - y_domain_min) / (y_domain_max - y_domain_min); + if (values.size() < RESOLUTION) + { + return 0; + } + if (y_index < 0) + return 0; + if (y_index > RESOLUTION - 1) + return RESOLUTION - 1; + return y_index; + } + + int interpolate_indexes(size_t first, size_t second, size_t line = 0) + { + size_t len = second - first; + ColorT f = values[line][first]; + ColorT s = values[line][second]; + for(int i = first + 1; i < second; i++) { + values[line][i].r = f.r * (1 - (float)(i - first) / len ) + s.r * ((float)(i - first) / len ); + values[line][i].g = f.g * (1 - (float)(i - first) / len ) + s.g * ((float)(i - first) / len ); ; + values[line][i].b = f.b * (1 - (float)(i - first) / len ) + s.b * ((float)(i - first) / len ); ; + values[line][i].a = f.a * (1 - (float)(i - first) / len ) + s.a * ((float)(i - first) / len ); ; + } + } + + uint hex2a(uint32_t c) + { + return (c / 256 / 256 / 256) % 256; + } + + uint hex2r(uint32_t c) + { + return (c / 256 / 256) % 256; + } + uint hex2g(uint32_t c) + { + return (c / 256) % 256; + } + uint hex2b(uint32_t c) + { + return c % 256; + } + }; + + // Contains PDF render info + /** + * Тут хранится информация спецефичная для рендера ПДФ. + * + * Взял новую реализацию преобразований, т.к. готовая была на даблах, + * а в такой точности смысла нету особо. + * + * Для шейдеров требуется поддерживать два способа вычисления (с параметром и без), + * поэтому требуется много дополнительной инфы. + * + * Так же шейдер будет получать, в качетве параметров, границы, тут я пока не решил, вообще + * можно оставить соблюдение границ, на откуп пользователю, т.к. все равно заполенение в конечном итоге будет + * выполняться с помощью рисования замкнутого пути и команды Fill + * + * + * */ + + struct float_affine { + float sx, shy, shx, sy, tx, ty; + void transform(float &x, float &y) + { + double tmp = x; + x = tmp * sx + y * shx + tx; + y = tmp * shy + y * sy + ty; + } + }; + + struct ShadingInfo + { + public: + ShadingInfo() : function(), + f_type(UseT2Color) + { + } + enum ShadingType { + Triangle, SimpleCubic, TensorCubic + }; + enum ColorFunctionType + { + UseOld, + UseT2Color, + UseXY2Color + }; // if UseOld old function is called, look for IChaphicsRender.put_BrushGradientColors + ColorFunctionType f_type; + ColorFuction function; + + + bool default_mapping; // boundaries to domain of color function + float_affine mapping; // пока не готово, если дефолтный то выстввляется специальным методом, если нет то пользователь сам выставляет. + + + // triangle shading + bool parametrised_triangle_shading; + std::vector> triangle; + std::vector triangle_colors; + std::vector triangle_parametrs; + + // non linear (NOT ready) пока не написал, как кривую переводить в нормальные координаты + bool parametrised_curve_shading; + std::vector> patch; // 12 точкек характеризующих фигуру + std::vector patch_colors; // 4 цвета по углам + }; + + // Containing additional info about gradient + struct GradientInfo + { + GradientInfo() : littleRadius(0.0f), largeRadius(1.0f), + centerX(0.0f), centerY(0.0f), + angle(0.0f), + discrete_step(0.0f), + reflected(false), + periods(0.5f), periodic(false), + xsize(1.0f), ysize(1.0f), + linstretch(1.0f), linoffset(0.0f) + + { + } + void setAngleDegrees(float deg) + { + angle = deg / 180.f * (float)M_PI; + } + float getAngleDegrees() const + { + return angle / (float)M_PI * 180.f; + } + void setStepByNum(int n) // recomended to use + { + discrete_step = 1.0f / n; + } + + float littleRadius, largeRadius; // used in radial gradient - [0, 1] + float centerX, centerY; // used in radial, diamond and conical gradient - offset relative to figure center + float angle; // used in linear and conical gradient (rad) + float discrete_step; // used to make discrete gradient. <= 0 to make continious + float xsize, ysize; // stretch image; can be negative to reflect relative to other axis; cannot be zero + bool reflected; // 1234567 -> 1357531 works kind of like this + bool periodic; + float periods; // number of perionds (best with to colours, works as saw fuction in color space) + float linstretch; // stretch linear gradient, can be negative (eq angle = 180) can not be zero + float linoffset; // offset relative to image size + ShadingInfo shading; + }; +} diff --git a/DesktopEditor/graphics/structures.h b/DesktopEditor/graphics/structures.h index 48e4be3f68..78eb89196b 100644 --- a/DesktopEditor/graphics/structures.h +++ b/DesktopEditor/graphics/structures.h @@ -34,123 +34,92 @@ #include "../common/Array.h" #include "../graphics/aggplustypes.h" - +#include "../agg-2.4/include/agg_color_rgba.h" +#include "./test/shading.h" +#include "shading_info.h" #include #include #include #include +#include // pen ----------------------------------------------------------- -const long c_ag_LineCapFlat = 0; -const long c_ag_LineCapSquare = 1; -const long c_ag_LineCapTriangle = 3; -const long c_ag_LineCapNoAnchor = 16; -const long c_ag_LineCapSquareAnchor = 17; -const long c_ag_LineCapRoundAnchor = 18; -const long c_ag_LineCapDiamondAnchor = 19; -const long c_ag_LineCapArrowAnchor = 20; -const long c_ag_LineCapAnchorMask = 240; -const long c_ag_LineCapCustom = 255; +const long c_ag_LineCapFlat = 0; +const long c_ag_LineCapSquare = 1; +const long c_ag_LineCapTriangle = 3; +const long c_ag_LineCapNoAnchor = 16; +const long c_ag_LineCapSquareAnchor = 17; +const long c_ag_LineCapRoundAnchor = 18; +const long c_ag_LineCapDiamondAnchor = 19; +const long c_ag_LineCapArrowAnchor = 20; +const long c_ag_LineCapAnchorMask = 240; +const long c_ag_LineCapCustom = 255; -const long c_ag_DashCapFlat = 0; -const long c_ag_DashCapRound = 2; -const long c_ag_DashCapTriangle = 3; +const long c_ag_DashCapFlat = 0; +const long c_ag_DashCapRound = 2; +const long c_ag_DashCapTriangle = 3; -const long c_ag_LineJoinMiter = 0; -const long c_ag_LineJoinBevel = 1; -const long c_ag_LineJoinRound = 2; -const long c_ag_LineJoinMiterClipped = 3; +const long c_ag_LineJoinMiter = 0; +const long c_ag_LineJoinBevel = 1; +const long c_ag_LineJoinRound = 2; +const long c_ag_LineJoinMiterClipped = 3; -const long c_ag_PenAlignmentCenter = 0; -const long c_ag_PenAlignmentInset = 1; -const long c_ag_PenAlignmentOutset = 2; -const long c_ag_PenAlignmentLeft = 3; -const long c_ag_PenAlignmentRight = 4; +const long c_ag_PenAlignmentCenter = 0; +const long c_ag_PenAlignmentInset = 1; +const long c_ag_PenAlignmentOutset = 2; +const long c_ag_PenAlignmentLeft = 3; +const long c_ag_PenAlignmentRight = 4; // -------------------------------------------------------------- // brush -------------------------------------------------------- // old constants for brush type -const long c_BrushTypeSolid_ = 0; -const long c_BrushTypeHorizontal_ = 1; -const long c_BrushTypeVertical_ = 2; -const long c_BrushTypeDiagonal1_ = 3; -const long c_BrushTypeDiagonal2_ = 4; -const long c_BrushTypeCenter_ = 5; -const long c_BrushTypePathGradient1_ = 6; -const long c_BrushTypePathGradient2_ = 7; -const long c_BrushTypeTexture_ = 8; -const long c_BrushTypeHatch1_ = 9; -const long c_BrushTypeHatch53_ = 61; -const long c_BrushTypeGradient1_ = 62; -const long c_BrushTypeGradient6_ = 70; +const long c_BrushTypeSolid_ = 0; +const long c_BrushTypeHorizontal_ = 1; +const long c_BrushTypeVertical_ = 2; +const long c_BrushTypeDiagonal1_ = 3; +const long c_BrushTypeDiagonal2_ = 4; +const long c_BrushTypeCenter_ = 5; +const long c_BrushTypePathGradient1_ = 6; +const long c_BrushTypePathGradient2_ = 7; +const long c_BrushTypeTexture_ = 8; +const long c_BrushTypeHatch1_ = 9; +const long c_BrushTypeHatch53_ = 61; +const long c_BrushTypeGradient1_ = 62; +const long c_BrushTypeGradient6_ = 70; -const long c_BrushTypeSolid = 1000; -const long c_BrushTypeHorizontal = 2001; -const long c_BrushTypeVertical = 2002; -const long c_BrushTypeDiagonal1 = 2003; -const long c_BrushTypeDiagonal2 = 2004; -const long c_BrushTypeCenter = 2005; -const long c_BrushTypePathGradient1 = 2006; // left for comparability -const long c_BrushTypePathGradient2 = 2007; // left for comparability -const long c_BrushTypeCylinderHor = 2008; -const long c_BrushTypeCylinderVer = 2009; -const long c_BrushTypeTexture = 3008; -const long c_BrushTypePattern = 3009; -const long c_BrushTypeHatch1 = 4009; -const long c_BrushTypeHatch53 = 4061; -const long c_BrushTypeNoFill = 5000; -const long c_BrushTypeNotSet = 5001; +const long c_BrushTypeSolid = 1000; +const long c_BrushTypeHorizontal = 2001; +const long c_BrushTypeVertical = 2002; +const long c_BrushTypeDiagonal1 = 2003; +const long c_BrushTypeDiagonal2 = 2004; +const long c_BrushTypeCenter = 2005; +const long c_BrushTypePathGradient1 = 2006; // left for comparability +const long c_BrushTypePathGradient2 = 2007; // left for comparability +const long c_BrushTypeCylinderHor = 2008; +const long c_BrushTypeCylinderVer = 2009; +const long c_BrushTypeTexture = 3008; +const long c_BrushTypePattern = 3009; +const long c_BrushTypeHatch1 = 4009; +const long c_BrushTypeHatch53 = 4061; +const long c_BrushTypeNoFill = 5000; +const long c_BrushTypeNotSet = 5001; -const long c_BrushTypeMyTestGradient = 6000; -const long c_BrushTypePathRadialGradient = 6001; -const long c_BrushTypePathConicalGradient = 6002; -const long c_BrushTypePathDiamondGradient = 6003; -const long c_BrushTypePathNewLinearGradient = 6004; +const long c_BrushTypeMyTestGradient = 6000; +const long c_BrushTypePathRadialGradient = 6001; +const long c_BrushTypePathConicalGradient = 6002; +const long c_BrushTypePathDiamondGradient = 6003; +const long c_BrushTypePathNewLinearGradient = 6004; -const long c_BrushTextureModeStretch = 0; -const long c_BrushTextureModeTile = 1; -const long c_BrushTextureModeTileCenter = 2; +const long c_BrushTypeShading = 7000; + +const long c_BrushTextureModeStretch = 0; +const long c_BrushTextureModeTile = 1; +const long c_BrushTextureModeTileCenter = 2; // -------------------------------------------------------------- namespace NSStructures { - // Containing additional info about gradient - struct GradientInfo { - GradientInfo() : - littleRadius(0.0f), largeRadius(1.0f), - centerX(0.0f), centerY(0.0f), - angle(0.0f), - discrete_step(0.0f), - reflected(false), - periods(0.5f), periodic(false), - xsize(1.0f), ysize(1.0f), - linstretch(1.0f), linoffset(0.0f) - {} - void setAngleDegrees(float deg) - { - angle = deg / 180.f * (float)M_PI; - } - float getAngleDegrees() - { - return angle / (float)M_PI * 180.f; - } - void setStepByNum(int n) // recomended to use - { - discrete_step = 1.0f / n; - } - float littleRadius, largeRadius; // used in radial gradient - [0, 1] - float centerX, centerY; // used in radial, diamond and conical gradient - offset relative to figure center - float angle; // used in linear and conical gradient (rad) - float discrete_step; // used to make discrete gradient. <= 0 to make continious - float xsize, ysize; // stretch image; can be negative to reflect relative to other axis; cannot be zero - bool reflected; // 1234567 -> 1357531 works kind of like this - bool periodic; - float periods; // number of perionds (best with to colours, works as saw fuction in color space) - float linstretch; // stretch linear gradient, can be negative (eq angle = 180) can not be zero - float linoffset; // offset relative to image size - }; - class CPen { public: @@ -163,16 +132,16 @@ namespace NSStructures unsigned char LineEndCap; unsigned char LineJoin; - double* DashPattern; + double *DashPattern; long Count; double DashOffset; - + long Align; double MiterLimit; - - public: - void GetDashPattern(double* arrDashPattern, long& nCount) const + + public: + void GetDashPattern(double *arrDashPattern, long &nCount) const { if (nCount == Count) { @@ -182,7 +151,7 @@ namespace NSStructures } } } - void SetDashPattern(double* arrDashPattern, long nCount) + void SetDashPattern(double *arrDashPattern, long nCount) { if ((arrDashPattern == NULL) || (nCount == 0)) { @@ -204,61 +173,62 @@ namespace NSStructures } } } - - void ScaleAlpha( double dScale ) + + void ScaleAlpha(double dScale) { long dNewAlpha = long(Alpha * dScale + 0.5); - - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; - + + if (dNewAlpha > 255) + dNewAlpha = 255; + else if (dNewAlpha < 0) + dNewAlpha = 0; + Alpha = dNewAlpha; } - INT IsEqual(CPen* pPen) + INT IsEqual(CPen *pPen) { if (NULL == pPen) return FALSE; return ((Color == pPen->Color) && (Alpha == pPen->Alpha) && (Size == pPen->Size) && - (DashStyle == pPen->DashStyle) && (LineStartCap == pPen->LineStartCap) && - (LineEndCap == pPen->LineEndCap) && (LineJoin == pPen->LineJoin)); - } + (DashStyle == pPen->DashStyle) && (LineStartCap == pPen->LineStartCap) && + (LineEndCap == pPen->LineEndCap) && (LineJoin == pPen->LineJoin)); + } void SetDefaultParams() { Color = 0; Alpha = 255; - Size = 1; + Size = 1; - DashStyle = 0; + DashStyle = 0; LineStartCap = 0; - LineEndCap = 0; - LineJoin = 0; + LineEndCap = 0; + LineJoin = 0; DashPattern = NULL; - Count = 0; + Count = 0; DashOffset = 0; Align = Aggplus::PenAlignmentCenter; MiterLimit = 0.5; } - - public: + public: CPen() { SetDefaultParams(); } - CPen( const CPen& other ) + CPen(const CPen &other) { SetDefaultParams(); *this = other; } - CPen& operator=(const CPen& other) + CPen &operator=(const CPen &other) { Color = other.Color; Alpha = other.Alpha; - Size = other.Size; + Size = other.Size; DashStyle = other.DashStyle; LineStartCap = other.LineStartCap; @@ -289,7 +259,7 @@ namespace NSStructures class CBrush { public: - int test; + int test; struct TSubColor { long color; @@ -298,60 +268,60 @@ namespace NSStructures public: long Type; - + long Color1; long Color2; long Alpha1; long Alpha2; - + std::wstring TexturePath; long TextureAlpha; long TextureMode; - + int Rectable; - Aggplus::RectF Rect; - Aggplus::CDoubleRect Bounds; + Aggplus::RectF Rect; + Aggplus::CDoubleRect Bounds; double LinearAngle; - std::vector m_arrSubColors; - NSStructures::GradientInfo m_oGradientInfo; + std::vector m_arrSubColors; + NSStructures::GradientInfo m_oGradientInfo; public: - void LoadSubColors( const std::string& str ) + void LoadSubColors(const std::string &str) { - m_arrSubColors.clear(); + m_arrSubColors.clear(); - if( str.empty() ) + if (str.empty()) return; TSubColor subcolor; - int start = 0; - - for(;;) + int start = 0; + + for (;;) { - int pos = (int)str.find( (wchar_t)',', start ); - if( pos < 0 ) + int pos = (int)str.find((wchar_t)',', start); + if (pos < 0) break; - subcolor.color = ::atoi( str.substr( start, pos - start ).c_str() ); + subcolor.color = ::atoi(str.substr(start, pos - start).c_str()); start = pos + 1; - pos = (int)str.find( (wchar_t)';', start ); - if( pos < 0 ) + pos = (int)str.find((wchar_t)';', start); + if (pos < 0) break; - subcolor.position = ::atoi( str.substr( start, pos - start ).c_str() ); + subcolor.position = ::atoi(str.substr(start, pos - start).c_str()); start = pos + 1; - m_arrSubColors.push_back(subcolor ); + m_arrSubColors.push_back(subcolor); } } inline long ConstantCompatible(long nConstant) { - if( c_BrushTypeDiagonal1_ == nConstant ) + if (c_BrushTypeDiagonal1_ == nConstant) nConstant = c_BrushTypeDiagonal2_; - else if( c_BrushTypeDiagonal2_ == nConstant ) + else if (c_BrushTypeDiagonal2_ == nConstant) nConstant = c_BrushTypeDiagonal1_; if (1000 <= nConstant) @@ -369,47 +339,52 @@ namespace NSStructures return 1000; } - - void ScaleAlpha1( double dScale ) + + void ScaleAlpha1(double dScale) { long dNewAlpha = long(Alpha1 * dScale + 0.5); - - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; - + + if (dNewAlpha > 255) + dNewAlpha = 255; + else if (dNewAlpha < 0) + dNewAlpha = 0; + Alpha1 = dNewAlpha; } - void ScaleAlpha2( double dScale ) + void ScaleAlpha2(double dScale) { long dNewAlpha = long(Alpha2 * dScale + 0.5); - - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; - + + if (dNewAlpha > 255) + dNewAlpha = 255; + else if (dNewAlpha < 0) + dNewAlpha = 0; + Alpha2 = dNewAlpha; } - void ScaleTextureAlpha( double dScale ) + void ScaleTextureAlpha(double dScale) { long dNewAlpha = long(TextureAlpha * dScale + 0.5); - - if( dNewAlpha > 255 ) dNewAlpha = 255; - else if( dNewAlpha < 0 ) dNewAlpha = 0; - + + if (dNewAlpha > 255) + dNewAlpha = 255; + else if (dNewAlpha < 0) + dNewAlpha = 0; + TextureAlpha = dNewAlpha; } - - INT IsEqual(CBrush* pBrush) + INT IsEqual(CBrush *pBrush) { if (NULL == pBrush) return FALSE; - return ((Type == pBrush->Type) && - (Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) && - (Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2) && (LinearAngle == pBrush->LinearAngle) && - (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && - (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); + return ((Type == pBrush->Type) && + (Color1 == pBrush->Color1) && (Color2 == pBrush->Color2) && + (Alpha1 == pBrush->Alpha1) && (Alpha2 == pBrush->Alpha2) && (LinearAngle == pBrush->LinearAngle) && + (TexturePath == pBrush->TexturePath) && (TextureAlpha == pBrush->TextureAlpha) && (TextureMode == pBrush->TextureMode) && + (Rectable == pBrush->Rectable) && (Rect.Equals(pBrush->Rect))); } void SetDefaultParams() @@ -422,7 +397,7 @@ namespace NSStructures Alpha2 = 255; TextureAlpha = 255; - TextureMode = c_BrushTextureModeStretch; + TextureMode = c_BrushTextureModeStretch; LinearAngle = 0; @@ -430,62 +405,61 @@ namespace NSStructures Rectable = FALSE; - Rect.X = 0.0F; - Rect.Y = 0.0F; - Rect.Width = 0.0F; + Rect.X = 0.0F; + Rect.Y = 0.0F; + Rect.Width = 0.0F; Rect.Height = 0.0F; - Bounds.left = 0; - Bounds.top = 0; - Bounds.right = 0; - Bounds.bottom = 0; + Bounds.left = 0; + Bounds.top = 0; + Bounds.right = 0; + Bounds.bottom = 0; - m_arrSubColors.clear(); + m_arrSubColors.clear(); } - + public: - CBrush() { SetDefaultParams(); } - CBrush( const CBrush& other ) + CBrush(const CBrush &other) { - Type = other.Type; - - Color1 = other.Color1; - Alpha1 = other.Alpha1; - Color2 = other.Color2; - Alpha2 = other.Alpha2; + Type = other.Type; - TexturePath = other.TexturePath; + Color1 = other.Color1; + Alpha1 = other.Alpha1; + Color2 = other.Color2; + Alpha2 = other.Alpha2; + + TexturePath = other.TexturePath; TextureAlpha = other.TextureAlpha; - TextureMode = other.TextureMode; + TextureMode = other.TextureMode; Rectable = other.Rectable; - Rect = other.Rect; + Rect = other.Rect; - Bounds = other.Bounds; + Bounds = other.Bounds; LinearAngle = other.LinearAngle; m_arrSubColors = other.m_arrSubColors; } - CBrush& operator=(const CBrush& other) + CBrush &operator=(const CBrush &other) { - Type = other.Type; - - Color1 = other.Color1; - Alpha1 = other.Alpha1; - Color2 = other.Color2; - Alpha2 = other.Alpha2; + Type = other.Type; - TexturePath = other.TexturePath; + Color1 = other.Color1; + Alpha1 = other.Alpha1; + Color2 = other.Color2; + Alpha2 = other.Alpha2; + + TexturePath = other.TexturePath; TextureAlpha = other.TextureAlpha; - TextureMode = other.TextureMode; + TextureMode = other.TextureMode; Rectable = other.Rectable; - Rect = other.Rect; - Bounds = other.Bounds; + Rect = other.Rect; + Bounds = other.Bounds; LinearAngle = other.LinearAngle; m_arrSubColors = other.m_arrSubColors; @@ -509,7 +483,6 @@ namespace NSStructures return ((c_BrushTypeHorizontal <= Type && c_BrushTypeCylinderVer >= Type) || (c_BrushTypeHatch1 <= Type && c_BrushTypeHatch53 >= Type)); } - }; class CFont { @@ -526,18 +499,18 @@ namespace NSStructures double CharSpace; int FaceIndex; - - int IsEqual(CFont* pFont) + + int IsEqual(CFont *pFont) { if (NULL == pFont) return FALSE; return ((Name == pFont->Name) && (Path == pFont->Path) && (FaceIndex == pFont->FaceIndex) && (StringGID == pFont->StringGID) && (Size == pFont->Size) && - (Bold == pFont->Bold) && (Italic == pFont->Italic) && - (Underline == pFont->Underline) && (Strikeout == pFont->Strikeout)); + (Bold == pFont->Bold) && (Italic == pFont->Italic) && + (Underline == pFont->Underline) && (Strikeout == pFont->Strikeout)); } - long GetStyle() const + long GetStyle() const { long lStyle = 0; if (Bold) @@ -557,10 +530,10 @@ namespace NSStructures lStyle |= 0x02; return lStyle; } - void SetStyle(long const& lStyle) + void SetStyle(long const &lStyle) { - Bold = (0x01 == (0x01 & lStyle)); - Italic = (0x02 == (0x02 & lStyle)); + Bold = (0x01 == (0x01 & lStyle)); + Italic = (0x02 == (0x02 & lStyle)); Underline = (unsigned char)(0x7C & lStyle) >> 2; Strikeout = (unsigned char)(0x0180 & lStyle) >> 7; } @@ -568,10 +541,10 @@ namespace NSStructures { Name = L"Arial"; Path = L""; - - Size = 0; - Bold = FALSE; - Italic = FALSE; + + Size = 0; + Bold = FALSE; + Italic = FALSE; Underline = 0; Strikeout = 0; @@ -579,34 +552,34 @@ namespace NSStructures CharSpace = 0.0; FaceIndex = 0; } - LONG GetTextDecorationStyle() - { - if ((0 == Underline) && (0 == Strikeout)) - return 0; - if ((1 == Underline) && (0 == Strikeout)) - return 1; - if ((0 == Underline) && (1 == Strikeout)) - return 2; - if ((1 == Underline) && (1 == Strikeout)) - return 3; - return 4; - } + LONG GetTextDecorationStyle() + { + if ((0 == Underline) && (0 == Strikeout)) + return 0; + if ((1 == Underline) && (0 == Strikeout)) + return 1; + if ((0 == Underline) && (1 == Strikeout)) + return 2; + if ((1 == Underline) && (1 == Strikeout)) + return 3; + return 4; + } CFont() { SetDefaultParams(); } - CFont( const CFont& other ) + CFont(const CFont &other) { *this = other; } - CFont& operator=(const CFont& other) + CFont &operator=(const CFont &other) { - Name = other.Name; - Path = other.Path; - Size = other.Size; - Bold = other.Bold; - Italic = other.Italic; + Name = other.Name; + Path = other.Path; + Size = other.Size; + Bold = other.Bold; + Italic = other.Italic; Underline = other.Underline; Strikeout = other.Strikeout; @@ -624,50 +597,46 @@ namespace NSStructures class CShadow { public: - INT Visible; double DistanceX; double DistanceY; double BlurSize; long Color; long Alpha; - - public: + public: void SetDefaultParams() { - Visible = FALSE; + Visible = FALSE; DistanceX = 15; DistanceY = 15; - BlurSize = 0; - Color = 0; - Alpha = 120; + BlurSize = 0; + Color = 0; + Alpha = 120; } - + public: - CShadow() { SetDefaultParams(); } - CShadow( const CShadow& other ) + CShadow(const CShadow &other) { - Visible = other.Visible; + Visible = other.Visible; DistanceX = other.DistanceX; DistanceY = other.DistanceY; - BlurSize = other.BlurSize; - Color = other.Color; - Alpha = other.Alpha; - + BlurSize = other.BlurSize; + Color = other.Color; + Alpha = other.Alpha; } - CShadow& operator=(const CShadow& other) + CShadow &operator=(const CShadow &other) { - Visible = other.Visible; + Visible = other.Visible; DistanceX = other.DistanceX; DistanceY = other.DistanceY; - BlurSize = other.BlurSize; - Color = other.Color; - Alpha = other.Alpha; + BlurSize = other.BlurSize; + Color = other.Color; + Alpha = other.Alpha; return *this; } @@ -679,41 +648,38 @@ namespace NSStructures class CEdgeText { public: - long Visible; double Dist; long Color; long Alpha; - + public: - void SetDefaultParams() { Visible = 0; - Dist = 5; - Color = 0; - Alpha = 255; + Dist = 5; + Color = 0; + Alpha = 255; } - + public: - CEdgeText() { SetDefaultParams(); } - CEdgeText( const CEdgeText& other ) + CEdgeText(const CEdgeText &other) { Visible = other.Visible; - Dist = other.Dist; - Color = other.Color; - Alpha = other.Alpha; + Dist = other.Dist; + Color = other.Color; + Alpha = other.Alpha; } - CEdgeText& operator=(const CEdgeText& other) + CEdgeText &operator=(const CEdgeText &other) { Visible = other.Visible; - Dist = other.Dist; - Color = other.Color; - Alpha = other.Alpha; + Dist = other.Dist; + Color = other.Color; + Alpha = other.Alpha; return *this; } diff --git a/Test/Applications/gradient/Gradient/mainwindow.cpp b/Test/Applications/gradient/Gradient/mainwindow.cpp index 238ee7d9b9..4fd5798989 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.cpp +++ b/Test/Applications/gradient/Gradient/mainwindow.cpp @@ -8,7 +8,7 @@ std::vector drawCircle1(int n, double cx, double cy, double r) { std::vector res; for (int i = 0; i < n; i++) { double x = cx + r * cos(i * 8 * atan(1) / n); - double y = cy + r * sin(i * 8 * atan(1) / n); + double y = cy + r * sin(i * 8 * atan(1) / n); res.push_back({x, y}); } return res; @@ -22,7 +22,7 @@ MainWindow::MainWindow(QWidget *parent) { ui->setupUi(this); ui->lable_test->setStyleSheet("QLabel { background-color : white;}"); - points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; + points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; } @@ -33,7 +33,7 @@ MainWindow::~MainWindow() } -void GenerateImg(QImage &img, std::vector &points, const Info &info) { +void GenerateImg(QImage &img, std::vector &points, Info &info) { NSGraphics::IGraphicsRenderer* pRasterRenderer = NSGraphics::Create(); pRasterRenderer->SetFontManager(NULL); int nRasterW = img.size().width(); @@ -64,6 +64,7 @@ void GenerateImg(QImage &img, std::vector &points, const Info &info) { NSStructures::GradientInfo ginfo = info.ginfo; //ginfo.reflected = true; + ginfo.shading.f_type = NSStructures::ShadingInfo::UseT2Color; pRasterRenderer->put_BrushGradInfo(ginfo); auto a = info.c; auto b = info.p; @@ -145,8 +146,10 @@ void MainWindow::on_DiscreteStepSlider_sliderMoved(int position) void MainWindow::on_PathType_itemDoubleClicked(QListWidgetItem *item) { + int tmp = info.gradient_type; on_PathType_itemClicked(item); this->on_RenderPic_clicked(); + //info.gradient_type = tmp; } void MainWindow::on_PathType_itemClicked(QListWidgetItem *item) @@ -159,6 +162,11 @@ void MainWindow::on_PathType_itemClicked(QListWidgetItem *item) } else if (item->text() == "Triangle") { points = {{5, 10}, {40, 100}, {100, 1}}; + info.gradient_type = c_BrushTypeMyTestGradient; + info.ginfo.shading.triangle = {{5 * 3.84, 10 * 3.84}, {40 * 3.84, 100 * 3.84}, {100 * 3.84, 1 * 3.84}}; + info.ginfo.shading.triangle_parametrs = {0, 0.1, 1}; + info.ginfo.shading.parametrised_triangle_shading = false; + info.ginfo.shading.triangle_colors = {{255,0,0, 255}, {0,255,0,255 }, {0,0,255,255}}; } } @@ -240,21 +248,26 @@ void MainWindow::on_ColorSpaces_itemClicked(QListWidgetItem *item) info.c = {0xFFff0000, 0xFFffa500, 0xFFffff00, 0xFF008000, 0xFF0000ff, 0xFFFF00FF}; info.p = {0.0,0.2,0.4,0.6,0.8,1}; info.n_colors = 6; + info.ginfo.shading.function.set_linear_interpolation({0xFFff0000, 0xFFffa500, 0xFFffff00, 0xFF008000, 0xFF0000ff, 0xFFFF00FF} + , {0.0,0.2,0.4,0.6,0.8,1}); } else if (item->text() == "Black and white") { info.c = {0xFFFFFFFF, 0xFF000000}; info.p = {0.0, 1}; info.n_colors = 2; + info.ginfo.shading.function.set_linear_interpolation({0xFFFFFFFF, 0xFF000000}, {0.0, 1}); } else if (item->text() == "Red Blue") { info.c = {0xFFFF0000, 0xFF0000FF}; info.p = {0.0, 1}; info.n_colors = 2; + info.ginfo.shading.function.set_linear_interpolation({0xFFFF0000, 0xFF0000FF}, {0.0, 1}); } else if (item->text() == "Pastel") { info.c = {0xfff39189, 0xff046582}; info.p = {0.0, 1}; info.n_colors = 2; + info.ginfo.shading.function.set_linear_interpolation({0xfff39189, 0xff046582}, {0.0, 1}); } } diff --git a/Test/Applications/gradient/Gradient/mainwindow.h b/Test/Applications/gradient/Gradient/mainwindow.h index 54d385b09c..1ec0237dfb 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.h +++ b/Test/Applications/gradient/Gradient/mainwindow.h @@ -55,8 +55,8 @@ public: ~MainWindow(); QImage img; QLabel *lable; - Info info; std::vector points; + Info info; private slots: void on_RenderPic_clicked();