[DEV] start think of the gradient rendering ==> very complicated ...
This commit is contained in:
parent
effc33ef14
commit
7e67a54e32
157
esvg/Base.cpp
157
esvg/Base.cpp
@ -17,8 +17,8 @@ const float esvg::kappa90(0.5522847493f);
|
||||
#define __class__ "PaintState"
|
||||
|
||||
esvg::PaintState::PaintState() :
|
||||
fill(etk::color::black),
|
||||
stroke(etk::color::none),
|
||||
fill(std::pair<etk::Color<float,4>, std::string>(etk::color::black, "")),
|
||||
stroke(std::pair<etk::Color<float,4>, std::string>(etk::color::none, "")),
|
||||
strokeWidth(1.0f),
|
||||
flagEvenOdd(false),
|
||||
lineCap(esvg::cap_butt),
|
||||
@ -30,8 +30,8 @@ esvg::PaintState::PaintState() :
|
||||
}
|
||||
|
||||
void esvg::PaintState::clear() {
|
||||
fill = etk::color::black;
|
||||
stroke = etk::color::none;
|
||||
fill = std::pair<etk::Color<float,4>, std::string>(etk::color::black, "");
|
||||
stroke = std::pair<etk::Color<float,4>, std::string>(etk::color::none, "");
|
||||
strokeWidth = 1.0;
|
||||
viewPort.setValue(255,255);
|
||||
flagEvenOdd = false;
|
||||
@ -151,10 +151,9 @@ std::pair<float, enum esvg::distance> esvg::Base::parseLength2(const std::string
|
||||
}
|
||||
SVG_VERBOSE(" lenght : '" << n << "' => unit=" << unit);
|
||||
// note : ";" is for the parsing of the style elements ...
|
||||
if( unit.size() == 0
|
||||
|| unit[0] == ';' ) {
|
||||
if(unit.size() == 0) {
|
||||
return std::make_pair(n, esvg::distance_pixel);
|
||||
} else if (unit[0] == '%') { // xxx %
|
||||
} else if (unit[0] == '%') { // xxx %
|
||||
return std::make_pair(n, esvg::distance_pourcent);
|
||||
} else if ( unit[0] == 'e'
|
||||
&& unit[1] == 'm') { // xxx em
|
||||
@ -212,43 +211,14 @@ float esvg::Base::parseLength(const std::string& _dataInput) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// return the next char position ... (after ';' or NULL)
|
||||
int32_t esvg::extractPartOfStyle(const std::string& _data, std::string& _outputType, std::string& _outputData, int32_t _pos) {
|
||||
_outputType = "";
|
||||
_outputData = "";
|
||||
if (_pos == -1) {
|
||||
return -2;
|
||||
}
|
||||
bool processFirst=true;
|
||||
//SVG_DEBUG("parse : '" << _data.Extract(_pos) << "'");
|
||||
for( int32_t iii=_pos; iii<_data.size(); iii++) {
|
||||
//SVG_DEBUG(" ? '" << _data[iii] << "'");
|
||||
if (_data[iii] == ';') {
|
||||
// end of the element
|
||||
return iii+1;
|
||||
}
|
||||
if (_data[iii] == ' ') {
|
||||
// nothing to do ... we do not copy espaces ...
|
||||
} else if (_data[iii] == ':') {
|
||||
processFirst = false;
|
||||
} else {
|
||||
if (processFirst) {
|
||||
_outputType += _data[iii];
|
||||
} else {
|
||||
_outputData += _data[iii];
|
||||
}
|
||||
}
|
||||
}
|
||||
SVG_VERBOSE(" extract : '" << _outputType << "':'" << _outputData << "'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _element) {
|
||||
if (_element == nullptr) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
bool fillNone = false;
|
||||
bool strokeNone = false;
|
||||
*/
|
||||
std::string content;
|
||||
// ---------------- get unique ID ----------------
|
||||
m_id = _element->getAttribute("id");
|
||||
@ -256,9 +226,11 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
|
||||
content = _element->getAttribute("stroke");
|
||||
if (content.size()!=0) {
|
||||
m_paint.stroke = parseColor(content);
|
||||
if (m_paint.stroke.a() == 0) {
|
||||
/*
|
||||
if (m_paint.stroke.first.a() == 0) {
|
||||
strokeNone = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
content = _element->getAttribute("stroke-width");
|
||||
if (content.size()!=0) {
|
||||
@ -268,7 +240,7 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
|
||||
if (content.size()!=0) {
|
||||
float opacity = parseLength(content);
|
||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||
m_paint.stroke.setA(opacity);
|
||||
m_paint.stroke.first.setA(opacity);
|
||||
}
|
||||
|
||||
content = _element->getAttribute("stroke-dasharray");
|
||||
@ -314,15 +286,17 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
|
||||
content = _element->getAttribute("fill");
|
||||
if (content.size()!=0) {
|
||||
m_paint.fill = parseColor(content);
|
||||
/*
|
||||
if (m_paint.fill.a() == 0) {
|
||||
fillNone = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
content = _element->getAttribute("fill-opacity");
|
||||
if (content.size()!=0) {
|
||||
float opacity = parseLength(content);
|
||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||
m_paint.fill.setA(opacity);
|
||||
m_paint.fill.first.setA(opacity);
|
||||
}
|
||||
content = _element->getAttribute("fill-rule");
|
||||
if (content.size()!=0) {
|
||||
@ -340,102 +314,20 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
|
||||
m_paint.opacity = parseLength(content);
|
||||
m_paint.opacity = std::avg(0.0f, m_paint.opacity, 1.0f);
|
||||
}
|
||||
// ---------------- STYLE ----------------
|
||||
content = _element->getAttribute("style");
|
||||
if (content.size()!=0) {
|
||||
std::string outputType;
|
||||
std::string outputValue;
|
||||
|
||||
for( int32_t sss=extractPartOfStyle(content, outputType, outputValue, 0);
|
||||
-2 != sss;
|
||||
sss=extractPartOfStyle(content, outputType, outputValue, sss) ) {
|
||||
SVG_VERBOSE(" style parse : \"" << outputType << "\" with value : \"" << outputValue << "\"");
|
||||
if (outputType == "fill") {
|
||||
m_paint.fill = parseColor(outputValue);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.fill);
|
||||
if (m_paint.fill.a() == 0) {
|
||||
fillNone = true;
|
||||
}
|
||||
} else if (outputType == "stroke") {
|
||||
m_paint.stroke = parseColor(outputValue);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.stroke);
|
||||
if (m_paint.stroke.a() == 0) {
|
||||
strokeNone = true;
|
||||
}
|
||||
} else if (outputType == "stroke-width" ) {
|
||||
m_paint.strokeWidth = parseLength(outputValue);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.strokeWidth);
|
||||
} else if (outputType == "opacity" ) {
|
||||
m_paint.opacity = parseLength(content);
|
||||
m_paint.opacity = std::avg(0.0f, m_paint.opacity, 1.0f);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.opacity);
|
||||
} else if (outputType == "fill-opacity") {
|
||||
float opacity = parseLength(outputValue);
|
||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||
m_paint.fill.setA(opacity);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.fill);
|
||||
} else if (outputType == "stroke-opacity") {
|
||||
float opacity = parseLength(outputValue);
|
||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||
m_paint.stroke.setA(opacity);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << m_paint.stroke);
|
||||
} else if (outputType == "fill-rule" ) {
|
||||
if (outputValue == "nonzero" ) {
|
||||
m_paint.flagEvenOdd = false;
|
||||
} else if (outputValue == "evenodd") {
|
||||
m_paint.flagEvenOdd = true;
|
||||
} else {
|
||||
SVG_ERROR("not know " << outputType << " value : \"" << outputValue << "\", not in [nonzero,evenodd]");
|
||||
}
|
||||
} else if (outputType == "stroke-linecap") {
|
||||
if (outputValue == "butt") {
|
||||
m_paint.lineCap = esvg::cap_butt;
|
||||
} else if (outputValue == "round") {
|
||||
m_paint.lineCap = esvg::cap_round;
|
||||
} else if (outputValue == "square") {
|
||||
m_paint.lineCap = esvg::cap_square;
|
||||
} else {
|
||||
m_paint.lineCap = esvg::cap_butt;
|
||||
SVG_ERROR("not know " << outputType << " value : \"" << outputValue << "\", not in [butt,round,square]");
|
||||
}
|
||||
} else if (outputType == "stroke-linejoin") {
|
||||
if (outputValue == "miter") {
|
||||
m_paint.lineJoin = esvg::join_miter;
|
||||
} else if (outputValue == "round") {
|
||||
m_paint.lineJoin = esvg::join_round;
|
||||
} else if (outputValue == "bevel") {
|
||||
m_paint.lineJoin = esvg::join_bevel;
|
||||
} else {
|
||||
m_paint.lineJoin = esvg::join_miter;
|
||||
SVG_ERROR("not know " << outputType << " value : \"" << outputValue << "\", not in [miter,round,bevel]");
|
||||
}
|
||||
} else if (outputType == "stroke-dasharray") {
|
||||
if (outputValue == "none") {
|
||||
// OK, Nothing to do ...
|
||||
} else {
|
||||
SVG_TODO(" 'stroke-dasharray' not implemented ...");
|
||||
}
|
||||
} else if (outputType == "stroke-miterlimit") {
|
||||
float tmp = parseLength(outputValue);
|
||||
m_paint.miterLimit = std::max(0.0f, tmp);
|
||||
} else if (outputType == "marker-start") {
|
||||
// TODO : ...
|
||||
} else {
|
||||
SVG_ERROR("not know painting element in style balise : \"" << outputType << "\" with value : \"" << outputValue << "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note : No parsing of 'style' it is already converted in attribute before...
|
||||
// check if somewere none is set to the filling:
|
||||
/*
|
||||
if (fillNone == true) {
|
||||
m_paint.fill.setA(0.0f);
|
||||
}
|
||||
if (strokeNone == true) {
|
||||
m_paint.stroke.setA(0.0f);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
etk::Color<uint8_t,4> esvg::Base::parseColor(const std::string& _inputData) {
|
||||
etk::Color<uint8_t,4> localColor = etk::color::white;
|
||||
std::pair<etk::Color<float,4>, std::string> esvg::Base::parseColor(const std::string& _inputData) {
|
||||
std::pair<etk::Color<float,4>, std::string> localColor(etk::color::white, "");
|
||||
|
||||
if( _inputData.size() > 4
|
||||
&& _inputData[0] == 'u'
|
||||
@ -443,13 +335,14 @@ etk::Color<uint8_t,4> esvg::Base::parseColor(const std::string& _inputData) {
|
||||
&& _inputData[2] == 'l'
|
||||
&& _inputData[3] == '(') {
|
||||
if (_inputData[4] == '#') {
|
||||
// TODO : parse gradient ...
|
||||
localColor = std::pair<etk::Color<float,4>, std::string>(etk::color::none, &(_inputData[5]));
|
||||
} else {
|
||||
SVG_ERROR(" pb in parsing the color : \"" << _inputData << "\" == > url(XXX) is not supported now ...");
|
||||
}
|
||||
SVG_ERROR(" pb in parsing the color : \"" << _inputData << "\" == > url(XXX) is not supported now ...");
|
||||
} else {
|
||||
localColor = etk::Color<uint8_t,4>(_inputData);
|
||||
localColor = std::pair<etk::Color<float,4>, std::string>(_inputData, "");
|
||||
}
|
||||
SVG_VERBOSE("Parse color : \"" << _inputData << "\" == > " << localColor);
|
||||
SVG_VERBOSE("Parse color : \"" << _inputData << "\" == > " << localColor.first << " " << localColor.second);
|
||||
return localColor;
|
||||
}
|
||||
|
||||
|
10
esvg/Base.h
10
esvg/Base.h
@ -40,8 +40,8 @@ namespace esvg {
|
||||
PaintState();
|
||||
void clear();
|
||||
public:
|
||||
etk::Color<float,4> fill;
|
||||
etk::Color<float,4> stroke;
|
||||
std::pair<etk::Color<float,4>, std::string> fill;
|
||||
std::pair<etk::Color<float,4>, std::string> stroke;
|
||||
float strokeWidth;
|
||||
bool flagEvenOdd; //!< Fill rules
|
||||
enum esvg::cap lineCap;
|
||||
@ -51,8 +51,6 @@ namespace esvg {
|
||||
float opacity;
|
||||
};
|
||||
|
||||
int32_t extractPartOfStyle(const std::string& _data, std::string& _outputType, std::string& _outputData, int32_t _pos);
|
||||
|
||||
class Base {
|
||||
protected:
|
||||
PaintState m_paint;
|
||||
@ -95,9 +93,9 @@ namespace esvg {
|
||||
/**
|
||||
* @brief parse a color specification from the svg file
|
||||
* @param[in] _inputData Data C String with the xml definition
|
||||
* @return the parsed color
|
||||
* @return The parsed color (color used and the link if needed)
|
||||
*/
|
||||
etk::Color<uint8_t,4> parseColor(const std::string& _inputData);
|
||||
std::pair<etk::Color<float,4>, std::string> parseColor(const std::string& _inputData);
|
||||
protected:
|
||||
std::string m_id; //!< unique ID of the element.
|
||||
public:
|
||||
|
@ -102,8 +102,13 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
if (m_paint.fill.a() != 0x00) {
|
||||
if (colorFill != nullptr) {
|
||||
listSegmentFill.createSegmentList(listPoints);
|
||||
listSegmentFill.applyMatrix(mtx);
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
@ -112,8 +117,7 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
listSegmentFill);
|
||||
}
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -127,9 +131,9 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -75,8 +75,8 @@ void esvg::Dimension::set(std::string _config) {
|
||||
SVG_VERBOSE(" config dimention : \"" << _config << "\" == > " << *this );
|
||||
}
|
||||
|
||||
static enum distance parseType(std::string& _config) {
|
||||
enum distance type = esvg::distance_pixel;
|
||||
static enum esvg::distance parseType(std::string& _config) {
|
||||
enum esvg::distance type = esvg::distance_pixel;
|
||||
if (etk::end_with(_config, "%", false) == true) {
|
||||
type = esvg::distance_pourcent;
|
||||
_config.erase(_config.size()-1, 1);
|
||||
@ -120,7 +120,7 @@ void esvg::Dimension::set(std::string _configX, std::string _configY) {
|
||||
float valueY = etk::string_to_float(_configY);
|
||||
// TODO : Check difference ...
|
||||
set(vec2(valueX, valueY), typeX);
|
||||
SVG_VERBOSE(" config dimention : \"" << _config << "\" == > " << *this );
|
||||
SVG_VERBOSE(" config dimention : '" << _configX << "' '" << _configY << "' == > " << *this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ namespace esvg {
|
||||
*/
|
||||
void set(const vec2& _size, enum distance _type);
|
||||
|
||||
private:
|
||||
public:
|
||||
/**
|
||||
* @brief set the current dimention in requested type
|
||||
* @param[in] _config dimension configuration.
|
||||
|
@ -107,8 +107,13 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
if (m_paint.fill.a() != 0x00) {
|
||||
if (colorFill != nullptr) {
|
||||
listSegmentFill.createSegmentList(listPoints);
|
||||
listSegmentFill.applyMatrix(mtx);
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
@ -117,8 +122,7 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
listSegmentFill);
|
||||
}
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -132,9 +136,9 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -99,7 +99,9 @@ bool esvg::Group::parseXML(const std::shared_ptr<exml::Element>& _element, mat2&
|
||||
}
|
||||
|
||||
void esvg::Group::display(int32_t _spacing) {
|
||||
SVG_DEBUG(spacingDist(_spacing) << "Group (START) fill=" << m_paint.fill << " stroke=" << m_paint.stroke << " stroke-width=" << m_paint.strokeWidth );
|
||||
SVG_DEBUG(spacingDist(_spacing) << "Group (START) fill=" << m_paint.fill.first << "/" << m_paint.fill.second
|
||||
<< " stroke=" << m_paint.stroke.first << "/" << m_paint.stroke.second
|
||||
<< " stroke-width=" << m_paint.strokeWidth );
|
||||
for (size_t iii=0; iii<m_subElementList.size(); ++iii) {
|
||||
if (m_subElementList[iii] != nullptr) {
|
||||
m_subElementList[iii]->display(_spacing+1);
|
||||
|
@ -81,11 +81,15 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
// No background ...
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -99,9 +103,9 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -15,14 +15,15 @@
|
||||
#define __class__ "LinearGradient"
|
||||
|
||||
esvg::LinearGradient::LinearGradient(PaintState _parentPaintState) : esvg::Base(_parentPaintState) {
|
||||
m_pos1.setValue(0,0);
|
||||
m_pos2.setValue(0,0);
|
||||
m_pos1.set(vec2(0,0), esvg::distance_pixel);
|
||||
m_pos2.set(vec2(0,0), esvg::distance_pixel);
|
||||
}
|
||||
|
||||
esvg::LinearGradient::~LinearGradient() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _element, mat2& _parentTrans, vec2& _sizeMax) {
|
||||
// line must have a minimum size...
|
||||
//m_paint.strokeWidth = 1;
|
||||
@ -39,22 +40,12 @@ bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _eleme
|
||||
// add the property of the parrent modifications ...
|
||||
m_transformMatrix *= _parentTrans;
|
||||
|
||||
std::string content = _element->getAttribute("x1");
|
||||
if (content.size()!=0) {
|
||||
m_pos1.setX(parseLength(content));
|
||||
}
|
||||
content = _element->getAttribute("y1");
|
||||
if (content.size()!=0) {
|
||||
m_pos1.setY(parseLength(content));
|
||||
}
|
||||
content = _element->getAttribute("x2");
|
||||
if (content.size()!=0) {
|
||||
m_pos2.setX(parseLength(content));
|
||||
}
|
||||
content = _element->getAttribute("y2");
|
||||
if (content.size()!=0) {
|
||||
m_pos2.setY(parseLength(content));
|
||||
}
|
||||
std::string contentX = _element->getAttribute("x1");
|
||||
std::string contentY = _element->getAttribute("y1");
|
||||
m_pos1.set(contentX, contentY);
|
||||
contentX = _element->getAttribute("x2");
|
||||
contentY = _element->getAttribute("y2");
|
||||
m_pos2.set(contentX, contentY);
|
||||
|
||||
// parse all sub node :
|
||||
for(int32_t iii=0; iii<_element->size() ; iii++) {
|
||||
@ -64,36 +55,29 @@ bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _eleme
|
||||
continue;
|
||||
}
|
||||
if (child->getValue() == "stop") {
|
||||
float offset = 0;
|
||||
float offset = 100;
|
||||
etk::Color<float,4> stopColor = etk::color::none;
|
||||
// ---------------- offset ----------------
|
||||
content = child->getAttribute("offset");
|
||||
std::string content = child->getAttribute("offset");
|
||||
if (content.size()!=0) {
|
||||
offset = parseLength(content);
|
||||
offset = std::avg(0.0f, offset, 100.0f);
|
||||
}
|
||||
// ---------------- STYLE ----------------
|
||||
content = _element->getAttribute("style");
|
||||
if (content.size()!=0) {
|
||||
std::string outputType;
|
||||
std::string outputValue;
|
||||
for( int32_t sss=extractPartOfStyle(content, outputType, outputValue, 0);
|
||||
-2 != sss;
|
||||
sss=extractPartOfStyle(content, outputType, outputValue, sss) ) {
|
||||
SVG_VERBOSE(" style parse : \"" << outputType << "\" with value : \"" << outputValue << "\"");
|
||||
if (outputType == "stop-color") {
|
||||
stopColor = parseColor(outputValue);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << stopColor);
|
||||
} else if (outputType == "stop-opacity") {
|
||||
float opacity = parseLength(outputValue);
|
||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||
stopColor.setA(opacity);
|
||||
SVG_VERBOSE(" input : \"" << outputValue << "\" == > " << stopColor);
|
||||
} else {
|
||||
SVG_ERROR("not know painting element in style balise : \"" << outputType << "\" with value : \"" << outputValue << "\"");
|
||||
}
|
||||
std::pair<float, enum esvg::distance> tmp = parseLength2(content);
|
||||
if (tmp.second != esvg::distance_pourcent) {
|
||||
SVG_ERROR("offset : " << content << " res=" << tmp.first << "," << tmp.second << " Not support other than pourcent %");
|
||||
} else {
|
||||
offset = tmp.first;
|
||||
}
|
||||
}
|
||||
content = child->getAttribute("stop-color");
|
||||
if (content.size()!=0) {
|
||||
stopColor = parseColor(content).first;
|
||||
SVG_VERBOSE(" color : \"" << content << "\" == > " << stopColor);
|
||||
}
|
||||
content = child->getAttribute("stop-opacity");
|
||||
if (content.size()!=0) {
|
||||
float opacity = parseLength(content);
|
||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||
stopColor.setA(opacity);
|
||||
SVG_VERBOSE(" opacity : \"" << content << "\" == > " << stopColor);
|
||||
}
|
||||
m_data.push_back(std::pair<float, etk::Color<float,4>>(offset, stopColor));
|
||||
} else {
|
||||
SVG_ERROR("(l " << child->getPos() << ") node not suported : \"" << child->getValue() << "\" must be [stop]");
|
||||
|
@ -14,8 +14,8 @@
|
||||
namespace esvg {
|
||||
class LinearGradient : public esvg::Base {
|
||||
private:
|
||||
vec2 m_pos1; //!< gradient position x1 y1
|
||||
vec2 m_pos2; //!< gradient position x2 y2
|
||||
esvg::Dimension m_pos1; //!< gradient position x1 y1
|
||||
esvg::Dimension m_pos2; //!< gradient position x2 y2
|
||||
std::vector<std::pair<float, etk::Color<float,4>>> m_data;
|
||||
public:
|
||||
LinearGradient(PaintState _parentPaintState);
|
||||
|
@ -271,16 +271,20 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
if (m_paint.fill.a() != 0x00) {
|
||||
if (colorFill != nullptr) {
|
||||
listSegmentFill.createSegmentList(listPoints);
|
||||
listSegmentFill.applyMatrix(mtx);
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
tmpFill.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentFill);
|
||||
}
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -292,9 +296,9 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -88,8 +88,13 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
if (m_paint.fill.a() != 0x00) {
|
||||
if (colorFill != nullptr) {
|
||||
listSegmentFill.createSegmentList(listPoints);
|
||||
listSegmentFill.applyMatrix(mtx);
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
@ -98,8 +103,7 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
listSegmentFill);
|
||||
}
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -113,9 +117,9 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -85,8 +85,13 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
if (m_paint.fill.a() != 0x00) {
|
||||
if (colorFill != nullptr) {
|
||||
listSegmentFill.createSegmentList(listPoints);
|
||||
listSegmentFill.applyMatrix(mtx);
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
@ -95,8 +100,7 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
|
||||
listSegmentFill);
|
||||
}
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -110,9 +114,9 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -59,7 +59,8 @@ void esvg::Rectangle::display(int32_t _spacing) {
|
||||
}
|
||||
|
||||
void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _level) {
|
||||
SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Rectangle : fill=" << m_paint.fill << " stroke=" << m_paint.stroke);
|
||||
SVG_VERBOSE(spacingDist(_level) << "DRAW esvg::Rectangle: fill=" << m_paint.fill.first << "/" << m_paint.fill.second
|
||||
<< " stroke=" << m_paint.stroke.first << "/" << m_paint.stroke.second);
|
||||
esvg::render::Path listElement;
|
||||
listElement.clear();
|
||||
if ( m_roundedCorner.x() == 0.0f
|
||||
@ -102,8 +103,13 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
|
||||
esvg::render::SegmentList listSegmentStroke;
|
||||
esvg::render::Weight tmpFill;
|
||||
esvg::render::Weight tmpStroke;
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx, m_paint.viewPort);
|
||||
std::shared_ptr<esvg::render::DynamicColor> colorStroke;
|
||||
if (m_paint.strokeWidth > 0.0f) {
|
||||
colorStroke = esvg::render::createColor(m_paint.stroke, mtx, m_paint.viewPort);
|
||||
}
|
||||
// Check if we need to display background
|
||||
if (m_paint.fill.a() != 0x00) {
|
||||
if (colorFill != nullptr) {
|
||||
listSegmentFill.createSegmentList(listPoints);
|
||||
listSegmentFill.applyMatrix(mtx);
|
||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||
@ -112,8 +118,7 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
|
||||
listSegmentFill);
|
||||
}
|
||||
// check if we need to display stroke:
|
||||
if ( m_paint.strokeWidth > 0
|
||||
&& m_paint.stroke.a() != 0x00) {
|
||||
if (colorStroke != nullptr) {
|
||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||
m_paint.strokeWidth,
|
||||
m_paint.lineCap,
|
||||
@ -127,9 +132,9 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
|
||||
}
|
||||
// add on images:
|
||||
_myRenderer.print(tmpFill,
|
||||
m_paint.fill,
|
||||
colorFill,
|
||||
tmpStroke,
|
||||
m_paint.stroke,
|
||||
colorStroke,
|
||||
m_paint.opacity);
|
||||
#ifdef DEBUG
|
||||
_myRenderer.addDebugSegment(listSegmentFill);
|
||||
|
@ -13,14 +13,15 @@
|
||||
#undef __class__
|
||||
#define __class__ "Renderer"
|
||||
|
||||
esvg::Renderer::Renderer(const ivec2& _size, bool _visualDebug) :
|
||||
esvg::Renderer::Renderer(const ivec2& _size, esvg::Document* _document, bool _visualDebug) :
|
||||
#ifdef DEBUG
|
||||
m_visualDebug(_visualDebug),
|
||||
m_factor(1),
|
||||
#endif
|
||||
m_interpolationRecurtionMax(10),
|
||||
m_interpolationThreshold(0.25f),
|
||||
m_nbSubScanLine(8) {
|
||||
m_nbSubScanLine(8),
|
||||
m_document(_document) {
|
||||
#ifdef DEBUG
|
||||
if (m_visualDebug == true) {
|
||||
m_factor = 20;
|
||||
@ -57,9 +58,9 @@ etk::Color<float,4> esvg::Renderer::mergeColor(etk::Color<float,4> _base, etk::C
|
||||
}
|
||||
|
||||
void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
||||
const etk::Color<float,4>& _colorFill,
|
||||
const std::shared_ptr<esvg::render::DynamicColor>& _colorFill,
|
||||
const esvg::render::Weight& _weightStroke,
|
||||
const etk::Color<float,4>& _colorStroke,
|
||||
const std::shared_ptr<esvg::render::DynamicColor>& _colorStroke,
|
||||
float _opacity) {
|
||||
int32_t sizeX = m_size.x();
|
||||
int32_t sizeY = m_size.y();
|
||||
@ -67,68 +68,25 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
||||
sizeX *= m_factor;
|
||||
sizeY *= m_factor;
|
||||
#endif
|
||||
if (_colorFill.a() == 0x00) {
|
||||
if (_colorStroke.a() != 0x00) {
|
||||
// only stroke
|
||||
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
|
||||
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
|
||||
#if DEBUG
|
||||
ivec2 pos(xxx/m_factor, yyy/m_factor);
|
||||
#else
|
||||
ivec2 pos(xxx, yyy);
|
||||
#endif
|
||||
float valueStroke = _weightStroke.get(pos);
|
||||
if (valueStroke != 0.0f) {
|
||||
// set a ratio of the merging value
|
||||
etk::Color<float,4> tmpColor = _colorStroke * valueStroke;
|
||||
tmpColor.setA(tmpColor.a() * _opacity);
|
||||
// integrate the value at the previous color
|
||||
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_colorStroke.a() == 0x00) {
|
||||
// only Fill
|
||||
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
|
||||
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
|
||||
#if DEBUG
|
||||
ivec2 pos(xxx/m_factor, yyy/m_factor);
|
||||
#else
|
||||
ivec2 pos(xxx, yyy);
|
||||
#endif
|
||||
float valueFill = _weightFill.get(pos);
|
||||
if (valueFill != 0.0f) {
|
||||
// set a ratio of the merging value
|
||||
etk::Color<float,4> tmpColor = _colorFill * valueFill;
|
||||
tmpColor.setA(tmpColor.a() * _opacity);
|
||||
// integrate the value at the previous color
|
||||
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// all together
|
||||
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
|
||||
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
|
||||
#if DEBUG
|
||||
ivec2 pos(xxx/m_factor, yyy/m_factor);
|
||||
#else
|
||||
ivec2 pos(xxx, yyy);
|
||||
#endif
|
||||
float valueFill = _weightFill.get(pos);
|
||||
float valueStroke = _weightStroke.get(pos);
|
||||
// calculate merge of stroke and fill value:
|
||||
etk::Color<float,4> intermediateColorFill = _colorFill;
|
||||
intermediateColorFill.setA(intermediateColorFill.a()*valueFill);
|
||||
etk::Color<float,4> intermediateColorStroke = _colorStroke;
|
||||
intermediateColorStroke.setA(intermediateColorStroke.a()*valueStroke);
|
||||
etk::Color<float,4> intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
|
||||
intermediateColor.setA(intermediateColor.a() * _opacity);
|
||||
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], intermediateColor);
|
||||
}
|
||||
}
|
||||
|
||||
// all together
|
||||
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
|
||||
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
|
||||
#if DEBUG
|
||||
ivec2 pos(xxx/m_factor, yyy/m_factor);
|
||||
#else
|
||||
ivec2 pos(xxx, yyy);
|
||||
#endif
|
||||
float valueFill = _weightFill.get(pos);
|
||||
float valueStroke = _weightStroke.get(pos);
|
||||
// calculate merge of stroke and fill value:
|
||||
etk::Color<float,4> intermediateColorFill = _colorFill->getColor(pos);
|
||||
intermediateColorFill.setA(intermediateColorFill.a()*valueFill);
|
||||
etk::Color<float,4> intermediateColorStroke = _colorStroke->getColor(pos);
|
||||
intermediateColorStroke.setA(intermediateColorStroke.a()*valueStroke);
|
||||
etk::Color<float,4> intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
|
||||
intermediateColor.setA(intermediateColor.a() * _opacity);
|
||||
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], intermediateColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,10 @@
|
||||
#include <etk/math/Vector2D.h>
|
||||
#include <etk/Color.h>
|
||||
#include <esvg/render/Weight.h>
|
||||
#include <esvg/render/DynamicColor.h>
|
||||
|
||||
namespace esvg {
|
||||
class Document;
|
||||
class Renderer {
|
||||
#ifdef DEBUG
|
||||
private:
|
||||
@ -22,7 +24,7 @@ namespace esvg {
|
||||
int32_t m_factor;
|
||||
#endif
|
||||
public:
|
||||
Renderer(const ivec2& _size, bool _visualDebug=false);
|
||||
Renderer(const ivec2& _size, esvg::Document* _document, bool _visualDebug=false);
|
||||
~Renderer();
|
||||
protected:
|
||||
ivec2 m_size;
|
||||
@ -55,13 +57,19 @@ namespace esvg {
|
||||
etk::Color<float,4> mergeColor(etk::Color<float,4> _base, etk::Color<float,4> _integration);
|
||||
public:
|
||||
void print(const esvg::render::Weight& _weightFill,
|
||||
const etk::Color<float,4>& _colorFill,
|
||||
const std::shared_ptr<esvg::render::DynamicColor>& _colorFill,
|
||||
const esvg::render::Weight& _weightStroke,
|
||||
const etk::Color<float,4>& _colorStroke,
|
||||
const std::shared_ptr<esvg::render::DynamicColor>& _colorStroke,
|
||||
float _opacity);
|
||||
#ifdef DEBUG
|
||||
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
|
||||
#endif
|
||||
protected:
|
||||
esvg::Document* m_document;
|
||||
public:
|
||||
esvg::Document* getMainDocument() {
|
||||
return m_document;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ void esvg::Document::generateAnImage(const ivec2& _size, const std::string& _fil
|
||||
}
|
||||
SVG_DEBUG("Generate size " << sizeRender);
|
||||
|
||||
std::shared_ptr<esvg::Renderer> renderedElement = std::make_shared<esvg::Renderer>(sizeRender, _visualDebug);
|
||||
std::shared_ptr<esvg::Renderer> renderedElement = std::make_shared<esvg::Renderer>(sizeRender, this, _visualDebug);
|
||||
// create the first element matrix modification ...
|
||||
mat2 basicTrans;
|
||||
basicTrans *= etk::mat2Scale(vec2(sizeRender.x()/m_size.x(), sizeRender.y()/m_size.y()));
|
||||
@ -99,7 +99,7 @@ std::vector<etk::Color<float,4>> esvg::Document::renderImageFloatRGBA(ivec2& _si
|
||||
_size.setY(m_size.y());
|
||||
}
|
||||
SVG_DEBUG("Generate size " << _size);
|
||||
std::shared_ptr<esvg::Renderer> renderedElement = std::make_shared<esvg::Renderer>(_size);
|
||||
std::shared_ptr<esvg::Renderer> renderedElement = std::make_shared<esvg::Renderer>(_size, this);
|
||||
// create the first element matrix modification ...
|
||||
mat2 basicTrans;
|
||||
basicTrans *= etk::mat2Scale(vec2(_size.x()/m_size.x(), _size.y()/m_size.y()));
|
||||
@ -170,6 +170,7 @@ bool esvg::Document::parse(const std::string& _data) {
|
||||
m_loadOK = false;
|
||||
return m_loadOK;
|
||||
}
|
||||
cleanStyleProperty(root);
|
||||
m_loadOK = parseXMLData(root);
|
||||
return m_loadOK;
|
||||
}
|
||||
@ -198,6 +199,7 @@ bool esvg::Document::load(const std::string& _file) {
|
||||
m_loadOK = false;
|
||||
return m_loadOK;
|
||||
}
|
||||
cleanStyleProperty(root);
|
||||
m_loadOK = parseXMLData(root);
|
||||
return m_loadOK;
|
||||
}
|
||||
@ -206,7 +208,36 @@ bool esvg::Document::store(const std::string& _file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool esvg::Document::cleanStyleProperty(const std::shared_ptr<exml::Element>& _root) {
|
||||
// for each nodes:
|
||||
for(int32_t iii=0; iii< _root->size(); iii++) {
|
||||
std::shared_ptr<exml::Element> child = _root->getElement(iii);
|
||||
if (child == nullptr) {
|
||||
continue;
|
||||
}
|
||||
// get attribute style:
|
||||
if (child->existAttribute("style") == true) {
|
||||
std::string content = child->getAttribute("style");
|
||||
if (content.size() != 0) {
|
||||
std::vector<std::string> listStyle = etk::split(content, ';');
|
||||
for (auto &it : listStyle) {
|
||||
std::vector<std::string> value = etk::split(it, ':');
|
||||
if (value.size() != 2) {
|
||||
SVG_ERROR("parsing style with a wrong patern : " << it << " missing ':'");
|
||||
continue;
|
||||
}
|
||||
// TODO : Check if the attibute already exist ...
|
||||
child->setAttribute(value[0], value[1]);
|
||||
}
|
||||
}
|
||||
// remove attribute style:
|
||||
child->removeAttribute("style");
|
||||
}
|
||||
// sub-parsing ...
|
||||
cleanStyleProperty(child);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool esvg::Document::parseXMLData(const std::shared_ptr<exml::Element>& _root, bool _isReference) {
|
||||
// get the svg version :
|
||||
@ -223,7 +254,7 @@ bool esvg::Document::parseXMLData(const std::shared_ptr<exml::Element>& _root, b
|
||||
}
|
||||
vec2 maxSize(0,0);
|
||||
vec2 size(0,0);
|
||||
// parse all sub node :
|
||||
// parse all sub node:
|
||||
for(int32_t iii=0; iii< _root->size(); iii++) {
|
||||
std::shared_ptr<exml::Element> child = _root->getElement(iii);
|
||||
if (child == nullptr) {
|
||||
|
@ -59,6 +59,10 @@ namespace esvg {
|
||||
*/
|
||||
bool store(const std::string& _file);
|
||||
protected:
|
||||
/**
|
||||
* @brief change all style in a xml atribute
|
||||
*/
|
||||
virtual bool cleanStyleProperty(const std::shared_ptr<exml::Element>& _root);
|
||||
virtual bool parseXMLData(const std::shared_ptr<exml::Element>& _root, bool _isReference = false);
|
||||
public:
|
||||
bool isLoadOk() {
|
||||
|
33
esvg/render/DynamicColor.cpp
Normal file
33
esvg/render/DynamicColor.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <esvg/debug.h>
|
||||
#include <esvg/render/DynamicColor.h>
|
||||
|
||||
esvg::render::DynamicColorLinear::DynamicColorLinear(const std::string& _link, const mat2& _mtx, const vec2 _objectSize, const vec2 _objectPos)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
etk::Color<float,4> esvg::render::DynamicColorLinear::getColor(const ivec2& _pos) {
|
||||
return etk::color::purple;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<esvg::render::DynamicColor> esvg::render::createColor(std::pair<etk::Color<float,4>, std::string> _color, const mat2& _mtx, const vec2 _size) {
|
||||
// Check if need to create a color:
|
||||
if ( _color.first.a() == 0x00
|
||||
&& _color.second == "") {
|
||||
return nullptr;
|
||||
}
|
||||
if (_color.second != "") {
|
||||
return std::make_shared<esvg::render::DynamicColorLinear>(_color.second, _mtx, _size);
|
||||
}
|
||||
return std::make_shared<esvg::render::DynamicColorUni>(_color.first);
|
||||
}
|
52
esvg/render/DynamicColor.h
Normal file
52
esvg/render/DynamicColor.h
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ESVG_RENDER_DYNAMIC_COLOR_H__
|
||||
#define __ESVG_RENDER_DYNAMIC_COLOR_H__
|
||||
|
||||
#include <etk/types.h>
|
||||
#include <etk/Color.h>
|
||||
#include <etk/math/Vector2D.h>
|
||||
#include <etk/math/Matrix2.h>
|
||||
|
||||
namespace esvg {
|
||||
namespace render {
|
||||
class DynamicColor {
|
||||
public:
|
||||
DynamicColor() {
|
||||
// nothing to do ...
|
||||
}
|
||||
virtual ~DynamicColor() {};
|
||||
virtual etk::Color<float,4> getColor(const ivec2& _pos) = 0;
|
||||
};
|
||||
class DynamicColorUni : public esvg::render::DynamicColor {
|
||||
public:
|
||||
etk::Color<float,4> m_color;
|
||||
public:
|
||||
DynamicColorUni(const etk::Color<float,4>& _color) :
|
||||
m_color(_color) {
|
||||
|
||||
}
|
||||
etk::Color<float,4> getColor(const ivec2& _pos) {
|
||||
return m_color;
|
||||
}
|
||||
};
|
||||
class DynamicColorLinear : public esvg::render::DynamicColor {
|
||||
public:
|
||||
etk::Color<float,4> m_color;
|
||||
public:
|
||||
DynamicColorLinear(const std::string& _link, const mat2& _mtx, const vec2 _objectSize, const vec2 _objectPos);
|
||||
etk::Color<float,4> getColor(const ivec2& _pos);
|
||||
};
|
||||
|
||||
std::shared_ptr<DynamicColor> createColor(std::pair<etk::Color<float,4>, std::string> _color, const mat2& _mtx, const vec2 _size);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -62,6 +62,7 @@ def create(target, module_name):
|
||||
'esvg/render/Segment.cpp',
|
||||
'esvg/render/SegmentList.cpp',
|
||||
'esvg/render/Weight.cpp',
|
||||
'esvg/render/DynamicColor.cpp',
|
||||
'esvg/LinearGradient.cpp',
|
||||
'esvg/RadialGradient.cpp'
|
||||
])
|
||||
@ -102,6 +103,7 @@ def create(target, module_name):
|
||||
'esvg/render/Segment.h',
|
||||
'esvg/render/SegmentList.h',
|
||||
'esvg/render/Weight.h',
|
||||
'esvg/render/DynamicColor.h',
|
||||
'esvg/LinearGradient.h',
|
||||
'esvg/RadialGradient.h'
|
||||
])
|
||||
|
@ -27,7 +27,7 @@ TEST(TestGradientLinear, horizontal) {
|
||||
esvg::Document doc;
|
||||
doc.parse(data);
|
||||
etk::FSNodeWriteAllData("TestGradientLinear_horizontal.svg", data);
|
||||
//doc.generateAnImage(ivec2(100, 100), "TestGradientLinear_horizontal.bmp", g_visualDebug);
|
||||
doc.generateAnImage(ivec2(100, 100), "TestGradientLinear_horizontal.bmp", g_visualDebug);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user