[DEV] set Opacity working corectly and corect old bug of opacity

This commit is contained in:
Edouard DUPIN 2015-11-21 16:34:58 +01:00
parent 1fc98b70c6
commit f5d5391884
8 changed files with 58 additions and 32 deletions

View File

@ -12,9 +12,37 @@
#include <math.h> #include <math.h>
#undef __class__
#define __class__ "PaintState"
esvg::PaintState::PaintState() :
fill(etk::color::none),
stroke(etk::color::none),
strokeWidth(1.0f),
flagEvenOdd(false),
lineCap(esvg::cap_butt),
lineJoin(esvg::join_miter),
viewPort(255,255),
opacity(1.0) {
}
void esvg::PaintState::clear() {
fill = etk::color::none;
stroke = etk::color::none;
strokeWidth = 1.0;
viewPort.setValue(255,255);
flagEvenOdd = false;
lineJoin = esvg::join_miter;
lineCap = esvg::cap_butt;
opacity = 1.0;
}
#undef __class__ #undef __class__
#define __class__ "Base" #define __class__ "Base"
esvg::Base::Base(PaintState _parentPaintState) { esvg::Base::Base(PaintState _parentPaintState) {
// copy the parent painting properties ... // copy the parent painting properties ...
m_paint = _parentPaintState; m_paint = _parentPaintState;
@ -220,10 +248,8 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
} }
content = _element->getAttribute("opacity"); content = _element->getAttribute("opacity");
if (content.size()!=0) { if (content.size()!=0) {
float opacity = parseLength(content); m_paint.opacity = parseLength(content);
opacity = std::avg(0.0f, opacity, 1.0f); m_paint.opacity = std::avg(0.0f, m_paint.opacity, 1.0f);
m_paint.fill.setA(opacity*0xFF);
m_paint.stroke.setA(opacity*0xFF);
} }
content = _element->getAttribute("fill-opacity"); content = _element->getAttribute("fill-opacity");
if (content.size()!=0) { if (content.size()!=0) {
@ -298,11 +324,9 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
m_paint.strokeWidth = parseLength(outputValue); m_paint.strokeWidth = parseLength(outputValue);
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.strokeWidth); SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.strokeWidth);
} else if (outputType == "opacity" ) { } else if (outputType == "opacity" ) {
float opacity = parseLength(outputValue); m_paint.opacity = parseLength(content);
opacity = std::avg(0.0f, opacity, 1.0f); m_paint.opacity = std::avg(0.0f, m_paint.opacity, 1.0f);
m_paint.fill.setA(opacity*0xFF); SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.opacity);
m_paint.stroke.setA(opacity*0xFF);
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.fill);
} else if (outputType == "fill-opacity") { } else if (outputType == "fill-opacity") {
float opacity = parseLength(outputValue); float opacity = parseLength(outputValue);
opacity = std::avg(0.0f, opacity, 1.0f); opacity = std::avg(0.0f, opacity, 1.0f);

View File

@ -50,6 +50,9 @@ namespace esvg {
}; };
class PaintState { class PaintState {
public:
PaintState();
void clear();
public: public:
etk::Color<uint8_t,4> fill; etk::Color<uint8_t,4> fill;
etk::Color<uint8_t,4> stroke; etk::Color<uint8_t,4> stroke;
@ -58,6 +61,7 @@ namespace esvg {
enum esvg::cap lineCap; enum esvg::cap lineCap;
enum esvg::join lineJoin; enum esvg::join lineJoin;
vec2 viewPort; vec2 viewPort;
float opacity;
}; };
class Base { class Base {

View File

@ -285,7 +285,8 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
_myRenderer.print(tmpFill, _myRenderer.print(tmpFill,
m_paint.fill, m_paint.fill,
tmpStroke, tmpStroke,
m_paint.stroke); m_paint.stroke,
m_paint.opacity);
#ifdef DEBUG #ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill); _myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke); _myRenderer.addDebugSegment(listSegmentStroke);

View File

@ -101,7 +101,8 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
_myRenderer.print(tmpFill, _myRenderer.print(tmpFill,
m_paint.fill, m_paint.fill,
tmpStroke, tmpStroke,
m_paint.stroke); m_paint.stroke,
m_paint.opacity);
#ifdef DEBUG #ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill); _myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke); _myRenderer.addDebugSegment(listSegmentStroke);

View File

@ -53,7 +53,8 @@ etk::Color<float,4> esvg::Renderer::mergeColor(etk::Color<float,4> _base, const
void esvg::Renderer::print(const esvg::render::Weight& _weightFill, void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
const etk::Color<float,4>& _colorFill, const etk::Color<float,4>& _colorFill,
const esvg::render::Weight& _weightStroke, const esvg::render::Weight& _weightStroke,
const etk::Color<float,4>& _colorStroke) { const etk::Color<float,4>& _colorStroke,
float _opacity) {
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
@ -73,7 +74,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
float valueStroke = _weightStroke.get(pos); float valueStroke = _weightStroke.get(pos);
if (valueStroke != 0.0f) { if (valueStroke != 0.0f) {
// set a ratio of the merging value // set a ratio of the merging value
etk::Color<float,4> tmpColor = _colorStroke * valueStroke; etk::Color<float,4> tmpColor = _colorStroke * valueStroke * _opacity;
// integrate the value at the previous color // integrate the value at the previous color
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor); m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor);
} }
@ -93,7 +94,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
float valueFill = _weightFill.get(pos); float valueFill = _weightFill.get(pos);
if (valueFill != 0.0f) { if (valueFill != 0.0f) {
// set a ratio of the merging value // set a ratio of the merging value
etk::Color<float,4> tmpColor = _colorFill * valueFill; etk::Color<float,4> tmpColor = _colorFill * valueFill * _opacity;
// integrate the value at the previous color // integrate the value at the previous color
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor); m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor);
} }
@ -113,7 +114,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
// calculate merge of stroke and fill value: // calculate merge of stroke and fill value:
etk::Color<float,4> intermediateColorFill = _colorFill*valueFill; etk::Color<float,4> intermediateColorFill = _colorFill*valueFill;
etk::Color<float,4> intermediateColorStroke = _colorStroke*valueStroke; etk::Color<float,4> intermediateColorStroke = _colorStroke*valueStroke;
etk::Color<float,4> intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke); etk::Color<float,4> intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke) * _opacity;
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], intermediateColor); m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], intermediateColor);
} }
} }

View File

@ -57,7 +57,8 @@ namespace esvg {
void print(const esvg::render::Weight& _weightFill, void print(const esvg::render::Weight& _weightFill,
const etk::Color<float,4>& _colorFill, const etk::Color<float,4>& _colorFill,
const esvg::render::Weight& _weightStroke, const esvg::render::Weight& _weightStroke,
const etk::Color<float,4>& _colorStroke); const etk::Color<float,4>& _colorStroke,
float _opacity);
#ifdef DEBUG #ifdef DEBUG
void addDebugSegment(const esvg::render::SegmentList& _listSegment); void addDebugSegment(const esvg::render::SegmentList& _listSegment);
#endif #endif

View File

@ -28,14 +28,6 @@ esvg::Document::Document() :
m_fileName = ""; m_fileName = "";
m_version = "0.0"; m_version = "0.0";
m_loadOK = false; m_loadOK = false;
m_paint.fill = etk::color::none;
m_paint.stroke = etk::color::none;
m_paint.strokeWidth = 1.0;
m_paint.viewPort.setValue(255,255);
m_paint.flagEvenOdd = false;
m_paint.lineJoin = esvg::join_miter;
m_paint.lineCap = esvg::cap_butt;
m_size.setValue(0,0); m_size.setValue(0,0);
} }
@ -164,14 +156,7 @@ void esvg::Document::clear() {
m_fileName = ""; m_fileName = "";
m_version = "0.0"; m_version = "0.0";
m_loadOK = true; m_loadOK = true;
m_paint.fill = etk::color::none; m_paint.clear();
m_paint.stroke = etk::color::none;
m_paint.strokeWidth = 1.0;
m_paint.viewPort.setValue(255,255);
m_paint.flagEvenOdd = false;
m_paint.lineJoin = esvg::join_miter;
m_paint.lineCap = esvg::cap_butt;
m_size.setValue(0,0); m_size.setValue(0,0);
} }

View File

@ -49,6 +49,15 @@ TEST(TestRectangle, fill_and_stroke_blend) {
doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke_blend.ppm", g_visualDebug); doc.generateAnImage(ivec2(100, 100), "TestRectangle_fill_and_stroke_blend.ppm", g_visualDebug);
} }
TEST(TestRectangle, fill_and_stroke_opacity) {
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='#0F0F' stroke-width='3' fill='#F00F' opacity='0.5' />"
"</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'?>"