From 1fc98b70c6db92c05181743f7fbb2226ca92c5c1 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sat, 21 Nov 2015 16:09:14 +0100 Subject: [PATCH] [DEV] color integration might be correct ... need test opacity (not coded) and multiple boject addition --- esvg/Renderer.cpp | 66 +++++++++++++++++++++---------------- esvg/Renderer.h | 8 +++-- esvg/render/SegmentList.cpp | 12 +++---- test/testRectangle.cpp | 9 +++++ 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/esvg/Renderer.cpp b/esvg/Renderer.cpp index f70afd1..285ae7b 100644 --- a/esvg/Renderer.cpp +++ b/esvg/Renderer.cpp @@ -34,10 +34,26 @@ esvg::Renderer::~Renderer() { m_size = ivec2(0,0); } +etk::Color esvg::Renderer::mergeColor(etk::Color _base, const etk::Color& _integration) { + if (_integration.a() == 0.0f) { + return _base; + } + etk::Color tmpColor(_integration.r()*_integration.a(), + _integration.g()*_integration.a(), + _integration.b()*_integration.a(), + _integration.a()); + // Blend over + float tmpA = std::min(1.0f, (_base.a() + _integration.a())); + _base *= (1.0f - _integration.a()); + _base += tmpColor; + _base.setA(tmpA); + return _base; +} + void esvg::Renderer::print(const esvg::render::Weight& _weightFill, - const etk::Color& _colorFill, + const etk::Color& _colorFill, const esvg::render::Weight& _weightStroke, - const etk::Color& _colorStroke) { + const etk::Color& _colorStroke) { int32_t sizeX = m_size.x(); int32_t sizeY = m_size.y(); #if DEBUG @@ -56,10 +72,10 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill, #endif float valueStroke = _weightStroke.get(pos); if (valueStroke != 0.0f) { - m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r()); - m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g()); - m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b()); - m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a()); + // set a ratio of the merging value + etk::Color tmpColor = _colorStroke * valueStroke; + // integrate the value at the previous color + m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor); } } } @@ -76,10 +92,10 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill, #endif float valueFill = _weightFill.get(pos); if (valueFill != 0.0f) { - m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r()); - m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g()); - m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b()); - m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a()); + // set a ratio of the merging value + etk::Color tmpColor = _colorFill * valueFill; + // integrate the value at the previous color + m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor); } } } @@ -94,17 +110,11 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill, #endif float valueFill = _weightFill.get(pos); float valueStroke = _weightStroke.get(pos); - if (valueStroke != 0.0f) { - m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r()); - m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g()); - m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b()); - m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a()); - } else { - m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r()); - m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g()); - m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b()); - m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a()); - } + // calculate merge of stroke and fill value: + etk::Color intermediateColorFill = _colorFill*valueFill; + etk::Color intermediateColorStroke = _colorStroke*valueStroke; + etk::Color intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke); + m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], intermediateColor); } } } @@ -145,10 +155,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill, float coefficient = delta.x()/delta.y(); float bbb = it.p0.x() * m_factor - coefficient*it.p0.y() * m_factor; float xpos = coefficient * subSamplingCenterPos + bbb; - m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 ] = 0x00; - m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 + 1] = 0x00; - m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 + 2] = 0xFF; - m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 + 3] = 0xFF; + m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))] = etk::color::blue; } } } @@ -173,7 +180,8 @@ void esvg::Renderer::writePpm(std::string fileName) { SVG_DEBUG("Generate ppm : " << m_size << " debug size=" << ivec2(sizeX,sizeY)); fprintf(fd, "P6 %d %d 255 ", sizeX, sizeY); for (int32_t iii=0 ; iii tmp = m_buffer[iii]; + fwrite(&tmp, 1, 3, fd); } fclose(fd); } @@ -186,17 +194,19 @@ void esvg::Renderer::setSize(const ivec2& _size) { #if DEBUG * m_factor * m_factor #endif - * DATA_ALLOCATION_ELEMENT, 0); + , etk::color::none); } const ivec2& esvg::Renderer::getSize() const { return m_size; } + uint8_t* esvg::Renderer::getDataPointer() { - return &m_buffer[0]; + return nullptr; //&m_buffer[0]; }; + uint32_t esvg::Renderer::getDataSize() const { return m_buffer.size(); }; diff --git a/esvg/Renderer.h b/esvg/Renderer.h index d75deab..761d8f2 100644 --- a/esvg/Renderer.h +++ b/esvg/Renderer.h @@ -30,7 +30,7 @@ namespace esvg { void setSize(const ivec2& _size); const ivec2& getSize() const; protected: - std::vector m_buffer; + std::vector> m_buffer; public: uint8_t* getDataPointer(); uint32_t getDataSize() const; @@ -51,11 +51,13 @@ namespace esvg { int32_t getNumberSubScanLine() const; public: void writePpm(std::string fileName); + protected: + etk::Color mergeColor(etk::Color _base, const etk::Color& _integration); public: void print(const esvg::render::Weight& _weightFill, - const etk::Color& _colorFill, + const etk::Color& _colorFill, const esvg::render::Weight& _weightStroke, - const etk::Color& _colorStroke); + const etk::Color& _colorStroke); #ifdef DEBUG void addDebugSegment(const esvg::render::SegmentList& _listSegment); #endif diff --git a/esvg/render/SegmentList.cpp b/esvg/render/SegmentList.cpp index 2be5492..2809b5c 100644 --- a/esvg/render/SegmentList.cpp +++ b/esvg/render/SegmentList.cpp @@ -76,16 +76,16 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& SVG_ERROR("an error occure a next ID is >= nbPoint len .... "); continue; } - SVG_DEBUG("JOIN : id : prev/curr/next : " << idPevious << "/" << idCurrent << "/" << idNext); - SVG_DEBUG("JOIN : val : prev/curr/next : " << itListPoint[idPevious].m_pos << "/" << itListPoint[idCurrent].m_pos << "/" << itListPoint[idNext].m_pos); + //SVG_DEBUG("JOIN : id : prev/curr/next : " << idPevious << "/" << idCurrent << "/" << idNext); + //SVG_DEBUG("JOIN : val : prev/curr/next : " << itListPoint[idPevious].m_pos << "/" << itListPoint[idCurrent].m_pos << "/" << itListPoint[idNext].m_pos); vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos; - SVG_DEBUG("JOIN : vecA : " << vecA); + //SVG_DEBUG("JOIN : vecA : " << vecA); vecA.safeNormalize(); vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos; - SVG_DEBUG("JOIN : vecB : " << vecB); + //SVG_DEBUG("JOIN : vecB : " << vecB); vecB.safeNormalize(); vec2 vecC = vecA - vecB; - SVG_DEBUG("JOIN : vecC : " << vecC); + //SVG_DEBUG("JOIN : vecC : " << vecC); if (vecC == vec2(0.0f, 0.0f)) { // special case: 1 line ... itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x()); @@ -93,7 +93,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList& vecC.safeNormalize(); itListPoint[idCurrent].m_miterAxe = vecC; } - SVG_DEBUG("JOIN : miterAxe " << itListPoint[idCurrent].m_miterAxe); + //SVG_DEBUG("JOIN : miterAxe " << itListPoint[idCurrent].m_miterAxe); } else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_start) { vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos; vecB.safeNormalize(); diff --git a/test/testRectangle.cpp b/test/testRectangle.cpp index 88f32ab..9a5ffe6 100644 --- a/test/testRectangle.cpp +++ b/test/testRectangle.cpp @@ -40,6 +40,15 @@ TEST(TestRectangle, fill_and_stroke) { doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke.ppm", g_visualDebug); } +TEST(TestRectangle, fill_and_stroke_blend) { + esvg::Document doc; + doc.parse( "" + "" + " " + ""); + doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke_blend.ppm", g_visualDebug); +} + TEST(TestRectangle, corned_fill) { esvg::Document doc; doc.parse( ""