[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"
|
#define __class__ "PaintState"
|
||||||
|
|
||||||
esvg::PaintState::PaintState() :
|
esvg::PaintState::PaintState() :
|
||||||
fill(etk::color::black),
|
fill(std::pair<etk::Color<float,4>, std::string>(etk::color::black, "")),
|
||||||
stroke(etk::color::none),
|
stroke(std::pair<etk::Color<float,4>, std::string>(etk::color::none, "")),
|
||||||
strokeWidth(1.0f),
|
strokeWidth(1.0f),
|
||||||
flagEvenOdd(false),
|
flagEvenOdd(false),
|
||||||
lineCap(esvg::cap_butt),
|
lineCap(esvg::cap_butt),
|
||||||
@ -30,8 +30,8 @@ esvg::PaintState::PaintState() :
|
|||||||
}
|
}
|
||||||
|
|
||||||
void esvg::PaintState::clear() {
|
void esvg::PaintState::clear() {
|
||||||
fill = etk::color::black;
|
fill = std::pair<etk::Color<float,4>, std::string>(etk::color::black, "");
|
||||||
stroke = etk::color::none;
|
stroke = std::pair<etk::Color<float,4>, std::string>(etk::color::none, "");
|
||||||
strokeWidth = 1.0;
|
strokeWidth = 1.0;
|
||||||
viewPort.setValue(255,255);
|
viewPort.setValue(255,255);
|
||||||
flagEvenOdd = false;
|
flagEvenOdd = false;
|
||||||
@ -151,10 +151,9 @@ std::pair<float, enum esvg::distance> esvg::Base::parseLength2(const std::string
|
|||||||
}
|
}
|
||||||
SVG_VERBOSE(" lenght : '" << n << "' => unit=" << unit);
|
SVG_VERBOSE(" lenght : '" << n << "' => unit=" << unit);
|
||||||
// note : ";" is for the parsing of the style elements ...
|
// note : ";" is for the parsing of the style elements ...
|
||||||
if( unit.size() == 0
|
if(unit.size() == 0) {
|
||||||
|| unit[0] == ';' ) {
|
|
||||||
return std::make_pair(n, esvg::distance_pixel);
|
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);
|
return std::make_pair(n, esvg::distance_pourcent);
|
||||||
} else if ( unit[0] == 'e'
|
} else if ( unit[0] == 'e'
|
||||||
&& unit[1] == 'm') { // xxx em
|
&& unit[1] == 'm') { // xxx em
|
||||||
@ -212,43 +211,14 @@ float esvg::Base::parseLength(const std::string& _dataInput) {
|
|||||||
return 0.0f;
|
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) {
|
void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _element) {
|
||||||
if (_element == nullptr) {
|
if (_element == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
bool fillNone = false;
|
bool fillNone = false;
|
||||||
bool strokeNone = false;
|
bool strokeNone = false;
|
||||||
|
*/
|
||||||
std::string content;
|
std::string content;
|
||||||
// ---------------- get unique ID ----------------
|
// ---------------- get unique ID ----------------
|
||||||
m_id = _element->getAttribute("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");
|
content = _element->getAttribute("stroke");
|
||||||
if (content.size()!=0) {
|
if (content.size()!=0) {
|
||||||
m_paint.stroke = parseColor(content);
|
m_paint.stroke = parseColor(content);
|
||||||
if (m_paint.stroke.a() == 0) {
|
/*
|
||||||
|
if (m_paint.stroke.first.a() == 0) {
|
||||||
strokeNone = true;
|
strokeNone = true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
content = _element->getAttribute("stroke-width");
|
content = _element->getAttribute("stroke-width");
|
||||||
if (content.size()!=0) {
|
if (content.size()!=0) {
|
||||||
@ -268,7 +240,7 @@ void esvg::Base::parsePaintAttr(const std::shared_ptr<const exml::Element>& _ele
|
|||||||
if (content.size()!=0) {
|
if (content.size()!=0) {
|
||||||
float opacity = parseLength(content);
|
float opacity = parseLength(content);
|
||||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||||
m_paint.stroke.setA(opacity);
|
m_paint.stroke.first.setA(opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
content = _element->getAttribute("stroke-dasharray");
|
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");
|
content = _element->getAttribute("fill");
|
||||||
if (content.size()!=0) {
|
if (content.size()!=0) {
|
||||||
m_paint.fill = parseColor(content);
|
m_paint.fill = parseColor(content);
|
||||||
|
/*
|
||||||
if (m_paint.fill.a() == 0) {
|
if (m_paint.fill.a() == 0) {
|
||||||
fillNone = true;
|
fillNone = true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
content = _element->getAttribute("fill-opacity");
|
content = _element->getAttribute("fill-opacity");
|
||||||
if (content.size()!=0) {
|
if (content.size()!=0) {
|
||||||
float opacity = parseLength(content);
|
float opacity = parseLength(content);
|
||||||
opacity = std::avg(0.0f, opacity, 1.0f);
|
opacity = std::avg(0.0f, opacity, 1.0f);
|
||||||
m_paint.fill.setA(opacity);
|
m_paint.fill.first.setA(opacity);
|
||||||
}
|
}
|
||||||
content = _element->getAttribute("fill-rule");
|
content = _element->getAttribute("fill-rule");
|
||||||
if (content.size()!=0) {
|
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 = parseLength(content);
|
||||||
m_paint.opacity = std::avg(0.0f, m_paint.opacity, 1.0f);
|
m_paint.opacity = std::avg(0.0f, m_paint.opacity, 1.0f);
|
||||||
}
|
}
|
||||||
// ---------------- STYLE ----------------
|
// Note : No parsing of 'style' it is already converted in attribute before...
|
||||||
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 << "\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check if somewere none is set to the filling:
|
// check if somewere none is set to the filling:
|
||||||
|
/*
|
||||||
if (fillNone == true) {
|
if (fillNone == true) {
|
||||||
m_paint.fill.setA(0.0f);
|
m_paint.fill.setA(0.0f);
|
||||||
}
|
}
|
||||||
if (strokeNone == true) {
|
if (strokeNone == true) {
|
||||||
m_paint.stroke.setA(0.0f);
|
m_paint.stroke.setA(0.0f);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::Color<uint8_t,4> esvg::Base::parseColor(const std::string& _inputData) {
|
std::pair<etk::Color<float,4>, std::string> esvg::Base::parseColor(const std::string& _inputData) {
|
||||||
etk::Color<uint8_t,4> localColor = etk::color::white;
|
std::pair<etk::Color<float,4>, std::string> localColor(etk::color::white, "");
|
||||||
|
|
||||||
if( _inputData.size() > 4
|
if( _inputData.size() > 4
|
||||||
&& _inputData[0] == 'u'
|
&& _inputData[0] == 'u'
|
||||||
@ -443,13 +335,14 @@ etk::Color<uint8_t,4> esvg::Base::parseColor(const std::string& _inputData) {
|
|||||||
&& _inputData[2] == 'l'
|
&& _inputData[2] == 'l'
|
||||||
&& _inputData[3] == '(') {
|
&& _inputData[3] == '(') {
|
||||||
if (_inputData[4] == '#') {
|
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 {
|
} 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;
|
return localColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
esvg/Base.h
10
esvg/Base.h
@ -40,8 +40,8 @@ namespace esvg {
|
|||||||
PaintState();
|
PaintState();
|
||||||
void clear();
|
void clear();
|
||||||
public:
|
public:
|
||||||
etk::Color<float,4> fill;
|
std::pair<etk::Color<float,4>, std::string> fill;
|
||||||
etk::Color<float,4> stroke;
|
std::pair<etk::Color<float,4>, std::string> stroke;
|
||||||
float strokeWidth;
|
float strokeWidth;
|
||||||
bool flagEvenOdd; //!< Fill rules
|
bool flagEvenOdd; //!< Fill rules
|
||||||
enum esvg::cap lineCap;
|
enum esvg::cap lineCap;
|
||||||
@ -51,8 +51,6 @@ namespace esvg {
|
|||||||
float opacity;
|
float opacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t extractPartOfStyle(const std::string& _data, std::string& _outputType, std::string& _outputData, int32_t _pos);
|
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
protected:
|
protected:
|
||||||
PaintState m_paint;
|
PaintState m_paint;
|
||||||
@ -95,9 +93,9 @@ namespace esvg {
|
|||||||
/**
|
/**
|
||||||
* @brief parse a color specification from the svg file
|
* @brief parse a color specification from the svg file
|
||||||
* @param[in] _inputData Data C String with the xml definition
|
* @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:
|
protected:
|
||||||
std::string m_id; //!< unique ID of the element.
|
std::string m_id; //!< unique ID of the element.
|
||||||
public:
|
public:
|
||||||
|
@ -102,8 +102,13 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
esvg::render::SegmentList listSegmentStroke;
|
esvg::render::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
if (m_paint.fill.a() != 0x00) {
|
if (colorFill != nullptr) {
|
||||||
listSegmentFill.createSegmentList(listPoints);
|
listSegmentFill.createSegmentList(listPoints);
|
||||||
listSegmentFill.applyMatrix(mtx);
|
listSegmentFill.applyMatrix(mtx);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// 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);
|
listSegmentFill);
|
||||||
}
|
}
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -127,9 +131,9 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_myRenderer.addDebugSegment(listSegmentFill);
|
||||||
|
@ -75,8 +75,8 @@ void esvg::Dimension::set(std::string _config) {
|
|||||||
SVG_VERBOSE(" config dimention : \"" << _config << "\" == > " << *this );
|
SVG_VERBOSE(" config dimention : \"" << _config << "\" == > " << *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum distance parseType(std::string& _config) {
|
static enum esvg::distance parseType(std::string& _config) {
|
||||||
enum distance type = esvg::distance_pixel;
|
enum esvg::distance type = esvg::distance_pixel;
|
||||||
if (etk::end_with(_config, "%", false) == true) {
|
if (etk::end_with(_config, "%", false) == true) {
|
||||||
type = esvg::distance_pourcent;
|
type = esvg::distance_pourcent;
|
||||||
_config.erase(_config.size()-1, 1);
|
_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);
|
float valueY = etk::string_to_float(_configY);
|
||||||
// TODO : Check difference ...
|
// TODO : Check difference ...
|
||||||
set(vec2(valueX, valueY), typeX);
|
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);
|
void set(const vec2& _size, enum distance _type);
|
||||||
|
|
||||||
private:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief set the current dimention in requested type
|
* @brief set the current dimention in requested type
|
||||||
* @param[in] _config dimension configuration.
|
* @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::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
if (m_paint.fill.a() != 0x00) {
|
if (colorFill != nullptr) {
|
||||||
listSegmentFill.createSegmentList(listPoints);
|
listSegmentFill.createSegmentList(listPoints);
|
||||||
listSegmentFill.applyMatrix(mtx);
|
listSegmentFill.applyMatrix(mtx);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// 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);
|
listSegmentFill);
|
||||||
}
|
}
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -132,9 +136,9 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_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) {
|
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) {
|
for (size_t iii=0; iii<m_subElementList.size(); ++iii) {
|
||||||
if (m_subElementList[iii] != nullptr) {
|
if (m_subElementList[iii] != nullptr) {
|
||||||
m_subElementList[iii]->display(_spacing+1);
|
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::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
// No background ...
|
// No background ...
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -99,9 +103,9 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_myRenderer.addDebugSegment(listSegmentFill);
|
||||||
|
@ -15,14 +15,15 @@
|
|||||||
#define __class__ "LinearGradient"
|
#define __class__ "LinearGradient"
|
||||||
|
|
||||||
esvg::LinearGradient::LinearGradient(PaintState _parentPaintState) : esvg::Base(_parentPaintState) {
|
esvg::LinearGradient::LinearGradient(PaintState _parentPaintState) : esvg::Base(_parentPaintState) {
|
||||||
m_pos1.setValue(0,0);
|
m_pos1.set(vec2(0,0), esvg::distance_pixel);
|
||||||
m_pos2.setValue(0,0);
|
m_pos2.set(vec2(0,0), esvg::distance_pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
esvg::LinearGradient::~LinearGradient() {
|
esvg::LinearGradient::~LinearGradient() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _element, mat2& _parentTrans, vec2& _sizeMax) {
|
bool esvg::LinearGradient::parseXML(const std::shared_ptr<exml::Element>& _element, mat2& _parentTrans, vec2& _sizeMax) {
|
||||||
// line must have a minimum size...
|
// line must have a minimum size...
|
||||||
//m_paint.strokeWidth = 1;
|
//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 ...
|
// add the property of the parrent modifications ...
|
||||||
m_transformMatrix *= _parentTrans;
|
m_transformMatrix *= _parentTrans;
|
||||||
|
|
||||||
std::string content = _element->getAttribute("x1");
|
std::string contentX = _element->getAttribute("x1");
|
||||||
if (content.size()!=0) {
|
std::string contentY = _element->getAttribute("y1");
|
||||||
m_pos1.setX(parseLength(content));
|
m_pos1.set(contentX, contentY);
|
||||||
}
|
contentX = _element->getAttribute("x2");
|
||||||
content = _element->getAttribute("y1");
|
contentY = _element->getAttribute("y2");
|
||||||
if (content.size()!=0) {
|
m_pos2.set(contentX, contentY);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse all sub node :
|
// parse all sub node :
|
||||||
for(int32_t iii=0; iii<_element->size() ; iii++) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
if (child->getValue() == "stop") {
|
if (child->getValue() == "stop") {
|
||||||
float offset = 0;
|
float offset = 100;
|
||||||
etk::Color<float,4> stopColor = etk::color::none;
|
etk::Color<float,4> stopColor = etk::color::none;
|
||||||
// ---------------- offset ----------------
|
std::string content = child->getAttribute("offset");
|
||||||
content = child->getAttribute("offset");
|
|
||||||
if (content.size()!=0) {
|
if (content.size()!=0) {
|
||||||
offset = parseLength(content);
|
std::pair<float, enum esvg::distance> tmp = parseLength2(content);
|
||||||
offset = std::avg(0.0f, offset, 100.0f);
|
if (tmp.second != esvg::distance_pourcent) {
|
||||||
}
|
SVG_ERROR("offset : " << content << " res=" << tmp.first << "," << tmp.second << " Not support other than pourcent %");
|
||||||
// ---------------- STYLE ----------------
|
} else {
|
||||||
content = _element->getAttribute("style");
|
offset = tmp.first;
|
||||||
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 << "\"");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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));
|
m_data.push_back(std::pair<float, etk::Color<float,4>>(offset, stopColor));
|
||||||
} else {
|
} else {
|
||||||
SVG_ERROR("(l " << child->getPos() << ") node not suported : \"" << child->getValue() << "\" must be [stop]");
|
SVG_ERROR("(l " << child->getPos() << ") node not suported : \"" << child->getValue() << "\" must be [stop]");
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
namespace esvg {
|
namespace esvg {
|
||||||
class LinearGradient : public esvg::Base {
|
class LinearGradient : public esvg::Base {
|
||||||
private:
|
private:
|
||||||
vec2 m_pos1; //!< gradient position x1 y1
|
esvg::Dimension m_pos1; //!< gradient position x1 y1
|
||||||
vec2 m_pos2; //!< gradient position x2 y2
|
esvg::Dimension m_pos2; //!< gradient position x2 y2
|
||||||
std::vector<std::pair<float, etk::Color<float,4>>> m_data;
|
std::vector<std::pair<float, etk::Color<float,4>>> m_data;
|
||||||
public:
|
public:
|
||||||
LinearGradient(PaintState _parentPaintState);
|
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::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
if (m_paint.fill.a() != 0x00) {
|
if (colorFill != nullptr) {
|
||||||
listSegmentFill.createSegmentList(listPoints);
|
listSegmentFill.createSegmentList(listPoints);
|
||||||
listSegmentFill.applyMatrix(mtx);
|
listSegmentFill.applyMatrix(mtx);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
||||||
tmpFill.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentFill);
|
tmpFill.generate(_myRenderer.getSize(), _myRenderer.getNumberSubScanLine(), listSegmentFill);
|
||||||
}
|
}
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -292,9 +296,9 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t _l
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_myRenderer.addDebugSegment(listSegmentFill);
|
||||||
|
@ -88,8 +88,13 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
esvg::render::SegmentList listSegmentStroke;
|
esvg::render::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
if (m_paint.fill.a() != 0x00) {
|
if (colorFill != nullptr) {
|
||||||
listSegmentFill.createSegmentList(listPoints);
|
listSegmentFill.createSegmentList(listPoints);
|
||||||
listSegmentFill.applyMatrix(mtx);
|
listSegmentFill.applyMatrix(mtx);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// 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);
|
listSegmentFill);
|
||||||
}
|
}
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -113,9 +117,9 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_t
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_myRenderer.addDebugSegment(listSegmentFill);
|
||||||
|
@ -85,8 +85,13 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
|
|||||||
esvg::render::SegmentList listSegmentStroke;
|
esvg::render::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
if (m_paint.fill.a() != 0x00) {
|
if (colorFill != nullptr) {
|
||||||
listSegmentFill.createSegmentList(listPoints);
|
listSegmentFill.createSegmentList(listPoints);
|
||||||
listSegmentFill.applyMatrix(mtx);
|
listSegmentFill.applyMatrix(mtx);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// 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);
|
listSegmentFill);
|
||||||
}
|
}
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -110,9 +114,9 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32_
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_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) {
|
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;
|
esvg::render::Path listElement;
|
||||||
listElement.clear();
|
listElement.clear();
|
||||||
if ( m_roundedCorner.x() == 0.0f
|
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::SegmentList listSegmentStroke;
|
||||||
esvg::render::Weight tmpFill;
|
esvg::render::Weight tmpFill;
|
||||||
esvg::render::Weight tmpStroke;
|
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
|
// Check if we need to display background
|
||||||
if (m_paint.fill.a() != 0x00) {
|
if (colorFill != nullptr) {
|
||||||
listSegmentFill.createSegmentList(listPoints);
|
listSegmentFill.createSegmentList(listPoints);
|
||||||
listSegmentFill.applyMatrix(mtx);
|
listSegmentFill.applyMatrix(mtx);
|
||||||
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
|
// 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);
|
listSegmentFill);
|
||||||
}
|
}
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
if ( m_paint.strokeWidth > 0
|
if (colorStroke != nullptr) {
|
||||||
&& m_paint.stroke.a() != 0x00) {
|
|
||||||
listSegmentStroke.createSegmentListStroke(listPoints,
|
listSegmentStroke.createSegmentListStroke(listPoints,
|
||||||
m_paint.strokeWidth,
|
m_paint.strokeWidth,
|
||||||
m_paint.lineCap,
|
m_paint.lineCap,
|
||||||
@ -127,9 +132,9 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2& _basicTrans, int32
|
|||||||
}
|
}
|
||||||
// add on images:
|
// add on images:
|
||||||
_myRenderer.print(tmpFill,
|
_myRenderer.print(tmpFill,
|
||||||
m_paint.fill,
|
colorFill,
|
||||||
tmpStroke,
|
tmpStroke,
|
||||||
m_paint.stroke,
|
colorStroke,
|
||||||
m_paint.opacity);
|
m_paint.opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_myRenderer.addDebugSegment(listSegmentFill);
|
_myRenderer.addDebugSegment(listSegmentFill);
|
||||||
|
@ -13,14 +13,15 @@
|
|||||||
#undef __class__
|
#undef __class__
|
||||||
#define __class__ "Renderer"
|
#define __class__ "Renderer"
|
||||||
|
|
||||||
esvg::Renderer::Renderer(const ivec2& _size, bool _visualDebug) :
|
esvg::Renderer::Renderer(const ivec2& _size, esvg::Document* _document, bool _visualDebug) :
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
m_visualDebug(_visualDebug),
|
m_visualDebug(_visualDebug),
|
||||||
m_factor(1),
|
m_factor(1),
|
||||||
#endif
|
#endif
|
||||||
m_interpolationRecurtionMax(10),
|
m_interpolationRecurtionMax(10),
|
||||||
m_interpolationThreshold(0.25f),
|
m_interpolationThreshold(0.25f),
|
||||||
m_nbSubScanLine(8) {
|
m_nbSubScanLine(8),
|
||||||
|
m_document(_document) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (m_visualDebug == true) {
|
if (m_visualDebug == true) {
|
||||||
m_factor = 20;
|
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,
|
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 esvg::render::Weight& _weightStroke,
|
||||||
const etk::Color<float,4>& _colorStroke,
|
const std::shared_ptr<esvg::render::DynamicColor>& _colorStroke,
|
||||||
float _opacity) {
|
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();
|
||||||
@ -67,68 +68,25 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
|
|||||||
sizeX *= m_factor;
|
sizeX *= m_factor;
|
||||||
sizeY *= m_factor;
|
sizeY *= m_factor;
|
||||||
#endif
|
#endif
|
||||||
if (_colorFill.a() == 0x00) {
|
|
||||||
if (_colorStroke.a() != 0x00) {
|
// all together
|
||||||
// only stroke
|
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
|
||||||
for (int32_t yyy=0; yyy<sizeY; ++yyy) {
|
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
|
||||||
for (int32_t xxx=0; xxx<sizeX; ++xxx) {
|
#if DEBUG
|
||||||
#if DEBUG
|
ivec2 pos(xxx/m_factor, yyy/m_factor);
|
||||||
ivec2 pos(xxx/m_factor, yyy/m_factor);
|
#else
|
||||||
#else
|
ivec2 pos(xxx, yyy);
|
||||||
ivec2 pos(xxx, yyy);
|
#endif
|
||||||
#endif
|
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:
|
||||||
// set a ratio of the merging value
|
etk::Color<float,4> intermediateColorFill = _colorFill->getColor(pos);
|
||||||
etk::Color<float,4> tmpColor = _colorStroke * valueStroke;
|
intermediateColorFill.setA(intermediateColorFill.a()*valueFill);
|
||||||
tmpColor.setA(tmpColor.a() * _opacity);
|
etk::Color<float,4> intermediateColorStroke = _colorStroke->getColor(pos);
|
||||||
// integrate the value at the previous color
|
intermediateColorStroke.setA(intermediateColorStroke.a()*valueStroke);
|
||||||
m_buffer[sizeX*yyy + xxx] = mergeColor(m_buffer[sizeX*yyy + xxx], tmpColor);
|
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);
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,10 @@
|
|||||||
#include <etk/math/Vector2D.h>
|
#include <etk/math/Vector2D.h>
|
||||||
#include <etk/Color.h>
|
#include <etk/Color.h>
|
||||||
#include <esvg/render/Weight.h>
|
#include <esvg/render/Weight.h>
|
||||||
|
#include <esvg/render/DynamicColor.h>
|
||||||
|
|
||||||
namespace esvg {
|
namespace esvg {
|
||||||
|
class Document;
|
||||||
class Renderer {
|
class Renderer {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
private:
|
private:
|
||||||
@ -22,7 +24,7 @@ namespace esvg {
|
|||||||
int32_t m_factor;
|
int32_t m_factor;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
Renderer(const ivec2& _size, bool _visualDebug=false);
|
Renderer(const ivec2& _size, esvg::Document* _document, bool _visualDebug=false);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
protected:
|
protected:
|
||||||
ivec2 m_size;
|
ivec2 m_size;
|
||||||
@ -55,13 +57,19 @@ namespace esvg {
|
|||||||
etk::Color<float,4> mergeColor(etk::Color<float,4> _base, etk::Color<float,4> _integration);
|
etk::Color<float,4> mergeColor(etk::Color<float,4> _base, etk::Color<float,4> _integration);
|
||||||
public:
|
public:
|
||||||
void print(const esvg::render::Weight& _weightFill,
|
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 esvg::render::Weight& _weightStroke,
|
||||||
const etk::Color<float,4>& _colorStroke,
|
const std::shared_ptr<esvg::render::DynamicColor>& _colorStroke,
|
||||||
float _opacity);
|
float _opacity);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
|
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
|
||||||
#endif
|
#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);
|
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 ...
|
// create the first element matrix modification ...
|
||||||
mat2 basicTrans;
|
mat2 basicTrans;
|
||||||
basicTrans *= etk::mat2Scale(vec2(sizeRender.x()/m_size.x(), sizeRender.y()/m_size.y()));
|
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());
|
_size.setY(m_size.y());
|
||||||
}
|
}
|
||||||
SVG_DEBUG("Generate size " << _size);
|
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 ...
|
// create the first element matrix modification ...
|
||||||
mat2 basicTrans;
|
mat2 basicTrans;
|
||||||
basicTrans *= etk::mat2Scale(vec2(_size.x()/m_size.x(), _size.y()/m_size.y()));
|
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;
|
m_loadOK = false;
|
||||||
return m_loadOK;
|
return m_loadOK;
|
||||||
}
|
}
|
||||||
|
cleanStyleProperty(root);
|
||||||
m_loadOK = parseXMLData(root);
|
m_loadOK = parseXMLData(root);
|
||||||
return m_loadOK;
|
return m_loadOK;
|
||||||
}
|
}
|
||||||
@ -198,6 +199,7 @@ bool esvg::Document::load(const std::string& _file) {
|
|||||||
m_loadOK = false;
|
m_loadOK = false;
|
||||||
return m_loadOK;
|
return m_loadOK;
|
||||||
}
|
}
|
||||||
|
cleanStyleProperty(root);
|
||||||
m_loadOK = parseXMLData(root);
|
m_loadOK = parseXMLData(root);
|
||||||
return m_loadOK;
|
return m_loadOK;
|
||||||
}
|
}
|
||||||
@ -206,7 +208,36 @@ bool esvg::Document::store(const std::string& _file) {
|
|||||||
return false;
|
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) {
|
bool esvg::Document::parseXMLData(const std::shared_ptr<exml::Element>& _root, bool _isReference) {
|
||||||
// get the svg version :
|
// 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 maxSize(0,0);
|
||||||
vec2 size(0,0);
|
vec2 size(0,0);
|
||||||
// parse all sub node :
|
// parse all sub node:
|
||||||
for(int32_t iii=0; iii< _root->size(); iii++) {
|
for(int32_t iii=0; iii< _root->size(); iii++) {
|
||||||
std::shared_ptr<exml::Element> child = _root->getElement(iii);
|
std::shared_ptr<exml::Element> child = _root->getElement(iii);
|
||||||
if (child == nullptr) {
|
if (child == nullptr) {
|
||||||
|
@ -59,6 +59,10 @@ namespace esvg {
|
|||||||
*/
|
*/
|
||||||
bool store(const std::string& _file);
|
bool store(const std::string& _file);
|
||||||
protected:
|
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);
|
virtual bool parseXMLData(const std::shared_ptr<exml::Element>& _root, bool _isReference = false);
|
||||||
public:
|
public:
|
||||||
bool isLoadOk() {
|
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/Segment.cpp',
|
||||||
'esvg/render/SegmentList.cpp',
|
'esvg/render/SegmentList.cpp',
|
||||||
'esvg/render/Weight.cpp',
|
'esvg/render/Weight.cpp',
|
||||||
|
'esvg/render/DynamicColor.cpp',
|
||||||
'esvg/LinearGradient.cpp',
|
'esvg/LinearGradient.cpp',
|
||||||
'esvg/RadialGradient.cpp'
|
'esvg/RadialGradient.cpp'
|
||||||
])
|
])
|
||||||
@ -102,6 +103,7 @@ def create(target, module_name):
|
|||||||
'esvg/render/Segment.h',
|
'esvg/render/Segment.h',
|
||||||
'esvg/render/SegmentList.h',
|
'esvg/render/SegmentList.h',
|
||||||
'esvg/render/Weight.h',
|
'esvg/render/Weight.h',
|
||||||
|
'esvg/render/DynamicColor.h',
|
||||||
'esvg/LinearGradient.h',
|
'esvg/LinearGradient.h',
|
||||||
'esvg/RadialGradient.h'
|
'esvg/RadialGradient.h'
|
||||||
])
|
])
|
||||||
|
@ -27,7 +27,7 @@ TEST(TestGradientLinear, horizontal) {
|
|||||||
esvg::Document doc;
|
esvg::Document doc;
|
||||||
doc.parse(data);
|
doc.parse(data);
|
||||||
etk::FSNodeWriteAllData("TestGradientLinear_horizontal.svg", 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