[DEV] color integration might be correct ... need test opacity (not coded) and multiple boject addition
This commit is contained in:
parent
5ab659858e
commit
1fc98b70c6
@ -34,10 +34,26 @@ esvg::Renderer::~Renderer() {
|
|||||||
m_size = ivec2(0,0);
|
m_size = ivec2(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etk::Color<float,4> esvg::Renderer::mergeColor(etk::Color<float,4> _base, const etk::Color<float,4>& _integration) {
|
||||||
|
if (_integration.a() == 0.0f) {
|
||||||
|
return _base;
|
||||||
|
}
|
||||||
|
etk::Color<float,4> 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,
|
void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
||||||
const etk::Color<uint8_t,4>& _colorFill,
|
const etk::Color<float,4>& _colorFill,
|
||||||
const esvg::render::Weight& _weightStroke,
|
const esvg::render::Weight& _weightStroke,
|
||||||
const etk::Color<uint8_t,4>& _colorStroke) {
|
const etk::Color<float,4>& _colorStroke) {
|
||||||
int32_t sizeX = m_size.x();
|
int32_t sizeX = m_size.x();
|
||||||
int32_t sizeY = m_size.y();
|
int32_t sizeY = m_size.y();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -56,10 +72,10 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
|||||||
#endif
|
#endif
|
||||||
float valueStroke = _weightStroke.get(pos);
|
float valueStroke = _weightStroke.get(pos);
|
||||||
if (valueStroke != 0.0f) {
|
if (valueStroke != 0.0f) {
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
|
// set a ratio of the merging value
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g());
|
etk::Color<float,4> tmpColor = _colorStroke * valueStroke;
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b());
|
// integrate the value at the previous color
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
|
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
|
#endif
|
||||||
float valueFill = _weightFill.get(pos);
|
float valueFill = _weightFill.get(pos);
|
||||||
if (valueFill != 0.0f) {
|
if (valueFill != 0.0f) {
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueFill*_colorFill.r());
|
// set a ratio of the merging value
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueFill*_colorFill.g());
|
etk::Color<float,4> tmpColor = _colorFill * valueFill;
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueFill*_colorFill.b());
|
// integrate the value at the previous color
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueFill*_colorFill.a());
|
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
|
#endif
|
||||||
float valueFill = _weightFill.get(pos);
|
float valueFill = _weightFill.get(pos);
|
||||||
float valueStroke = _weightStroke.get(pos);
|
float valueStroke = _weightStroke.get(pos);
|
||||||
if (valueStroke != 0.0f) {
|
// calculate merge of stroke and fill value:
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 ] = uint8_t(valueStroke*_colorStroke.r());
|
etk::Color<float,4> intermediateColorFill = _colorFill*valueFill;
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 1] = uint8_t(valueStroke*_colorStroke.g());
|
etk::Color<float,4> intermediateColorStroke = _colorStroke*valueStroke;
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 2] = uint8_t(valueStroke*_colorStroke.b());
|
etk::Color<float,4> intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
|
||||||
m_buffer[(sizeX*yyy + xxx)*4 + 3] = uint8_t(valueStroke*_colorStroke.a());
|
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], intermediateColor);
|
||||||
} 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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,10 +155,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
|||||||
float coefficient = delta.x()/delta.y();
|
float coefficient = delta.x()/delta.y();
|
||||||
float bbb = it.p0.x() * m_factor - coefficient*it.p0.y() * m_factor;
|
float bbb = it.p0.x() * m_factor - coefficient*it.p0.y() * m_factor;
|
||||||
float xpos = coefficient * subSamplingCenterPos + bbb;
|
float xpos = coefficient * subSamplingCenterPos + bbb;
|
||||||
m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))*4 ] = 0x00;
|
m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))] = etk::color::blue;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +180,8 @@ void esvg::Renderer::writePpm(std::string fileName) {
|
|||||||
SVG_DEBUG("Generate ppm : " << m_size << " debug size=" << ivec2(sizeX,sizeY));
|
SVG_DEBUG("Generate ppm : " << m_size << " debug size=" << ivec2(sizeX,sizeY));
|
||||||
fprintf(fd, "P6 %d %d 255 ", sizeX, sizeY);
|
fprintf(fd, "P6 %d %d 255 ", sizeX, sizeY);
|
||||||
for (int32_t iii=0 ; iii<sizeX*sizeY; iii++) {
|
for (int32_t iii=0 ; iii<sizeX*sizeY; iii++) {
|
||||||
fwrite(&m_buffer[iii*DATA_ALLOCATION_ELEMENT], 1, 3, fd);
|
etk::Color<uint8_t,3> tmp = m_buffer[iii];
|
||||||
|
fwrite(&tmp, 1, 3, fd);
|
||||||
}
|
}
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
}
|
}
|
||||||
@ -186,17 +194,19 @@ void esvg::Renderer::setSize(const ivec2& _size) {
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
* m_factor * m_factor
|
* m_factor * m_factor
|
||||||
#endif
|
#endif
|
||||||
* DATA_ALLOCATION_ELEMENT, 0);
|
, etk::color::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ivec2& esvg::Renderer::getSize() const {
|
const ivec2& esvg::Renderer::getSize() const {
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t* esvg::Renderer::getDataPointer() {
|
uint8_t* esvg::Renderer::getDataPointer() {
|
||||||
return &m_buffer[0];
|
return nullptr; //&m_buffer[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
uint32_t esvg::Renderer::getDataSize() const {
|
uint32_t esvg::Renderer::getDataSize() const {
|
||||||
return m_buffer.size();
|
return m_buffer.size();
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@ namespace esvg {
|
|||||||
void setSize(const ivec2& _size);
|
void setSize(const ivec2& _size);
|
||||||
const ivec2& getSize() const;
|
const ivec2& getSize() const;
|
||||||
protected:
|
protected:
|
||||||
std::vector<uint8_t> m_buffer;
|
std::vector<etk::Color<float,4>> m_buffer;
|
||||||
public:
|
public:
|
||||||
uint8_t* getDataPointer();
|
uint8_t* getDataPointer();
|
||||||
uint32_t getDataSize() const;
|
uint32_t getDataSize() const;
|
||||||
@ -51,11 +51,13 @@ namespace esvg {
|
|||||||
int32_t getNumberSubScanLine() const;
|
int32_t getNumberSubScanLine() const;
|
||||||
public:
|
public:
|
||||||
void writePpm(std::string fileName);
|
void writePpm(std::string fileName);
|
||||||
|
protected:
|
||||||
|
etk::Color<float,4> mergeColor(etk::Color<float,4> _base, const etk::Color<float,4>& _integration);
|
||||||
public:
|
public:
|
||||||
void print(const esvg::render::Weight& _weightFill,
|
void print(const esvg::render::Weight& _weightFill,
|
||||||
const etk::Color<uint8_t,4>& _colorFill,
|
const etk::Color<float,4>& _colorFill,
|
||||||
const esvg::render::Weight& _weightStroke,
|
const esvg::render::Weight& _weightStroke,
|
||||||
const etk::Color<uint8_t,4>& _colorStroke);
|
const etk::Color<float,4>& _colorStroke);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
|
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
|
||||||
#endif
|
#endif
|
||||||
|
@ -76,16 +76,16 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
SVG_ERROR("an error occure a next ID is >= nbPoint len .... ");
|
SVG_ERROR("an error occure a next ID is >= nbPoint len .... ");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SVG_DEBUG("JOIN : id : prev/curr/next : " << idPevious << "/" << idCurrent << "/" << idNext);
|
//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 : 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;
|
vec2 vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
|
||||||
SVG_DEBUG("JOIN : vecA : " << vecA);
|
//SVG_DEBUG("JOIN : vecA : " << vecA);
|
||||||
vecA.safeNormalize();
|
vecA.safeNormalize();
|
||||||
vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
||||||
SVG_DEBUG("JOIN : vecB : " << vecB);
|
//SVG_DEBUG("JOIN : vecB : " << vecB);
|
||||||
vecB.safeNormalize();
|
vecB.safeNormalize();
|
||||||
vec2 vecC = vecA - vecB;
|
vec2 vecC = vecA - vecB;
|
||||||
SVG_DEBUG("JOIN : vecC : " << vecC);
|
//SVG_DEBUG("JOIN : vecC : " << vecC);
|
||||||
if (vecC == vec2(0.0f, 0.0f)) {
|
if (vecC == vec2(0.0f, 0.0f)) {
|
||||||
// special case: 1 line ...
|
// special case: 1 line ...
|
||||||
itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x());
|
itListPoint[idCurrent].m_miterAxe = vec2(vecA.y(), vecA.x());
|
||||||
@ -93,7 +93,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
|
|||||||
vecC.safeNormalize();
|
vecC.safeNormalize();
|
||||||
itListPoint[idCurrent].m_miterAxe = vecC;
|
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) {
|
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type_start) {
|
||||||
vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
vec2 vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
|
||||||
vecB.safeNormalize();
|
vecB.safeNormalize();
|
||||||
|
@ -40,6 +40,15 @@ TEST(TestRectangle, fill_and_stroke) {
|
|||||||
doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke.ppm", g_visualDebug);
|
doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke.ppm", g_visualDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestRectangle, fill_and_stroke_blend) {
|
||||||
|
esvg::Document doc;
|
||||||
|
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
|
||||||
|
"<svg height='100' width='100'>"
|
||||||
|
" <rect x='12.5' y='12.5' width='75' height='50' stroke='#0F08' stroke-width='3' fill='#F008' />"
|
||||||
|
"</svg>");
|
||||||
|
doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke_blend.ppm", g_visualDebug);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(TestRectangle, corned_fill) {
|
TEST(TestRectangle, corned_fill) {
|
||||||
esvg::Document doc;
|
esvg::Document doc;
|
||||||
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
|
doc.parse( "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user