[DEV] start transform

This commit is contained in:
Edouard DUPIN 2021-03-29 00:14:17 +02:00
parent ad5b11151e
commit aa7a62bae3
83 changed files with 2222 additions and 2167 deletions

View File

@ -21,7 +21,12 @@
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/scenarium-logger">
<classpathentry combineaccessrules="false" kind="src" path="/scenarium-logger">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/atriasoft-etk">
<attributes>
<attribute name="module" value="true"/>
</attributes>

View File

@ -2,19 +2,19 @@
<profiles version="20">
<profile kind="CodeFormatterProfile" name="EWOL" version="20">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enuthis.declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enuthis.constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enuthis.constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
@ -22,12 +22,12 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enuthis.constant" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_frothis.starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
@ -43,7 +43,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enuthis.constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
@ -53,7 +53,7 @@
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enuthis.constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
@ -86,7 +86,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enuthis.constant" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
@ -96,7 +96,7 @@
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enuthis.constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
@ -141,15 +141,15 @@
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enuthis.constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enuthis.declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enuthis.declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
@ -168,14 +168,14 @@
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enuthis.declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enuthis.constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
@ -218,7 +218,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enuthis.constants" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
@ -245,7 +245,7 @@
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enuthis.constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
@ -289,7 +289,7 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enuthis.declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
@ -317,7 +317,7 @@
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="33"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enuthis.declaration" value="33"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
@ -358,22 +358,22 @@
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enuthis.constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enuthis.declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enuthis.constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enuthis.constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enuthis.constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>

11
esvg.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -7,4 +7,5 @@ open module org.atriasoft.esvg {
exports org.atriasoft.esvg.render;
requires transitive io.scenarium.logger;
requires transitive org.atriasoft.etk;
}

View File

@ -11,36 +11,10 @@
const float esvg::kappa90(0.5522847493f);
esvg::PaintState::PaintState() :
fill(etk::Pair<etk::Color<float,4>, etk::String>(etk::color::black, "")),
stroke(etk::Pair<etk::Color<float,4>, etk::String>(etk::color::none, "")),
strokeWidth(1.0f),
flagEvenOdd(false),
lineCap(esvg::cap_butt),
lineJoin(esvg::join_miter),
miterLimit(4.0f),
viewPort(Vector2f(0.0f,0.0f), Vector2f(0.0f,0.0f)),
opacity(1.0) {
}
void esvg::PaintState::clear() {
fill = etk::Pair<etk::Color<float,4>, etk::String>(etk::color::black, "");
stroke = etk::Pair<etk::Color<float,4>, etk::String>(etk::color::none, "");
strokeWidth = 1.0;
viewPort.first.setValue(0.0f,0.0f);
viewPort.first.setValue(0.0f,0.0f);
flagEvenOdd = false;
lineJoin = esvg::join_miter;
lineCap = esvg::cap_butt;
miterLimit = 4.0f;
opacity = 1.0;
}
esvg::Base::Base(PaintState _parentPaintState) {
// copy the parent painting properties ...
m_paint = _parentPaintState;
this.paint = _parentPaintState;
}
etk::String extractTransformData(const etk::String& _value, const etk::String& _base) {
@ -97,7 +71,7 @@ void esvg::Base::parseTransform(const exml::Element& _element) {
if (data.size() != 0) {
double matrix[6];
if (sscanf(data.c_str(), "%lf %lf %lf %lf %lf %lf", &matrix[0], &matrix[1], &matrix[2], &matrix[3], &matrix[4], &matrix[5]) == 6) {
m_transformMatrix = mat2x3(matrix);
this.transformMatrix = mat2x3(matrix);
// find a matrix : simply exit ...
return;
} else {
@ -108,10 +82,10 @@ void esvg::Base::parseTransform(const exml::Element& _element) {
if (data.size() != 0) {
float xxx, yyy;
if (sscanf(data.c_str(), "%f %f", &xxx, &yyy) == 2) {
m_transformMatrix *= etk::mat2x3Translate(Vector2f(xxx, yyy));
this.transformMatrix *= etk::mat2x3Translate(Vector2f(xxx, yyy));
Log.verbose("Translate : " << xxx << ", " << yyy);
} else if (sscanf(data.c_str(), "%f", &xxx) == 1) {
m_transformMatrix *= etk::mat2x3Translate(Vector2f(xxx, 0));
this.transformMatrix *= etk::mat2x3Translate(Vector2f(xxx, 0));
Log.verbose("Translate : " << xxx << ", " << 0);
} else {
Log.error("Parsing translate() with wrong data ... '" << data << "'");
@ -121,10 +95,10 @@ void esvg::Base::parseTransform(const exml::Element& _element) {
if (data.size() != 0) {
float xxx, yyy;
if (sscanf(data.c_str(), "%f %f", &xxx, &yyy) == 2) {
m_transformMatrix *= etk::mat2x3Scale(Vector2f(xxx, yyy));
this.transformMatrix *= etk::mat2x3Scale(Vector2f(xxx, yyy));
Log.verbose("Scale : " << xxx << ", " << yyy);
} else if (sscanf(data.c_str(), "%f", &xxx) == 1) {
m_transformMatrix *= etk::mat2x3Scale(xxx);
this.transformMatrix *= etk::mat2x3Scale(xxx);
Log.verbose("Scale : " << xxx << ", " << xxx);
} else {
Log.error("Parsing scale() with wrong data ... '" << data << "'");
@ -135,13 +109,13 @@ void esvg::Base::parseTransform(const exml::Element& _element) {
float angle, xxx, yyy;
if (sscanf(data.c_str(), "%f %f %f", &angle, &xxx, &yyy) == 3) {
angle = angle / 180 * M_PI;
m_transformMatrix *= etk::mat2x3Translate(Vector2f(-xxx, -yyy));
m_transformMatrix *= etk::mat2x3Rotate(angle);
m_transformMatrix *= etk::mat2x3Translate(Vector2f(xxx, yyy));
this.transformMatrix *= etk::mat2x3Translate(Vector2f(-xxx, -yyy));
this.transformMatrix *= etk::mat2x3Rotate(angle);
this.transformMatrix *= etk::mat2x3Translate(Vector2f(xxx, yyy));
} else if (sscanf(data.c_str(), "%f", &angle) == 1) {
angle = angle / 180 * M_PI;
Log.verbose("rotate : " << angle << "rad, " << (angle/M_PI*180) << "°");
m_transformMatrix *= etk::mat2x3Rotate(angle);
this.transformMatrix *= etk::mat2x3Rotate(angle);
} else {
Log.error("Parsing rotate() with wrong data ... '" << data << "'");
}
@ -152,7 +126,7 @@ void esvg::Base::parseTransform(const exml::Element& _element) {
if (sscanf(data.c_str(), "%f", &angle) == 1) {
angle = angle / 180 * M_PI;
Log.verbose("skewX : " << angle << "rad, " << (angle/M_PI*180) << "°");
m_transformMatrix *= etk::mat2x3Skew(Vector2f(angle, 0.0f));
this.transformMatrix *= etk::mat2x3Skew(Vector2f(angle, 0.0f));
} else {
Log.error("Parsing skewX() with wrong data ... '" << data << "'");
}
@ -163,7 +137,7 @@ void esvg::Base::parseTransform(const exml::Element& _element) {
if (sscanf(data.c_str(), "%f", &angle) == 1) {
angle = angle / 180 * M_PI;
Log.verbose("skewY : " << angle << "rad, " << (angle/M_PI*180) << "°");
m_transformMatrix *= etk::mat2x3Skew(Vector2f(0.0f, angle));
this.transformMatrix *= etk::mat2x3Skew(Vector2f(0.0f, angle));
} else {
Log.error("Parsing skewY() with wrong data ... '" << data << "'");
}
@ -196,7 +170,7 @@ void esvg::Base::parsePosition(const exml::Element& _element, Vector2f &_pos, Ve
}
etk::Pair<float, enum esvg::distance> esvg::Base::parseLength2(const etk::String& _dataInput) {
Pair<float, enum esvg::distance> esvg::Base::parseLength2(const etk::String& _dataInput) {
Log.verbose(" lenght : '" << _dataInput << "'");
float n = _dataInput.to<float>();
etk::String unit;
@ -246,12 +220,12 @@ etk::Pair<float, enum esvg::distance> esvg::Base::parseLength2(const etk::String
float esvg::Base::parseLength(const etk::String& _dataInput) {
etk::Pair<float, enum esvg::distance> value = parseLength2(_dataInput);
Pair<float, enum esvg::distance> value = parseLength2(_dataInput);
Log.verbose(" lenght : '" << value.first << "' => unit=" << value.second);
float font_size = 20.0f;
switch (value.second) {
case esvg::distance_pourcent:
return value.first;// / 100.0 * m_paint.viewPort.x();
return value.first;// / 100.0 * this.paint.viewPort.x();
case esvg::distance_element:
return value.first * font_size;
case esvg::distance_ex:
@ -277,29 +251,29 @@ void esvg::Base::parsePaintAttr(const exml::Element& _element) {
return;
}
/*
bool fillNone = false;
bool strokeNone = false;
boolean fillNone = false;
boolean strokeNone = false;
*/
etk::String content;
// ---------------- get unique ID ----------------
m_id = _element.attributes["id"];
this.id = _element.attributes["id"];
// ---------------- stroke ----------------
content = _element.attributes["stroke"];
if (content == "none") {
m_paint.stroke = etk::Pair<etk::Color<float,4>, etk::String>(etk::color::none, "");
this.paint.stroke = Pair<etk::Color<float,4>, etk::String>(etk::color::none, "");
} else {
if (content.size()!=0) {
m_paint.stroke = parseColor(content);
this.paint.stroke = parseColor(content);
}
content = _element.attributes["stroke-width"];
if (content.size()!=0) {
m_paint.strokeWidth = parseLength(content);
this.paint.strokeWidth = parseLength(content);
}
content = _element.attributes["stroke-opacity"];
if (content.size()!=0) {
float opacity = parseLength(content);
opacity = etk::avg(0.0f, opacity, 1.0f);
m_paint.stroke.first.setA(opacity);
this.paint.stroke.first.setA(opacity);
}
content = _element.attributes["stroke-dasharray"];
@ -313,55 +287,55 @@ void esvg::Base::parsePaintAttr(const exml::Element& _element) {
content = _element.attributes["stroke-linecap"];
if (content.size()!=0) {
if (content == "butt" ) {
m_paint.lineCap = esvg::cap_butt;
this.paint.lineCap = esvg::cap_butt;
} else if (content == "round" ) {
m_paint.lineCap = esvg::cap_round;
this.paint.lineCap = esvg::cap_round;
} else if (content == "square" ) {
m_paint.lineCap = esvg::cap_square;
this.paint.lineCap = esvg::cap_square;
} else {
m_paint.lineCap = esvg::cap_butt;
this.paint.lineCap = esvg::cap_butt;
Log.error("not know stroke-linecap value : \"" << content << "\", not in [butt,round,square]");
}
}
content = _element.attributes["stroke-linejoin"];
if (content.size()!=0) {
if (content == "miter" ) {
m_paint.lineJoin = esvg::join_miter;
this.paint.lineJoin = esvg::join_miter;
} else if (content == "round" ) {
m_paint.lineJoin = esvg::join_round;
this.paint.lineJoin = esvg::join_round;
} else if (content == "bevel" ) {
m_paint.lineJoin = esvg::join_bevel;
this.paint.lineJoin = esvg::join_bevel;
} else {
m_paint.lineJoin = esvg::join_miter;
this.paint.lineJoin = esvg::join_miter;
Log.error("not know stroke-linejoin value : \"" << content << "\", not in [miter,round,bevel]");
}
}
content = _element.attributes["stroke-miterlimit"];
if (content.size()!=0) {
float tmp = parseLength(content);
m_paint.miterLimit = etk::max(0.0f, tmp);
this.paint.miterLimit = etk::max(0.0f, tmp);
}
}
// ---------------- FILL ----------------
content = _element.attributes["fill"];
if (content == "none") {
m_paint.fill = etk::Pair<etk::Color<float,4>, etk::String>(etk::color::none, "");
this.paint.fill = Pair<etk::Color<float,4>, etk::String>(etk::color::none, "");
} else {
if (content.size()!=0) {
m_paint.fill = parseColor(content);
this.paint.fill = parseColor(content);
}
content = _element.attributes["fill-opacity"];
if (content.size()!=0) {
float opacity = parseLength(content);
opacity = etk::avg(0.0f, opacity, 1.0f);
m_paint.fill.first.setA(opacity);
this.paint.fill.first.setA(opacity);
}
content = _element.attributes["fill-rule"];
if (content.size()!=0) {
if (content == "nonzero") {
m_paint.flagEvenOdd = false;
this.paint.flagEvenOdd = false;
} else if (content == "evenodd" ) {
m_paint.flagEvenOdd = true;
this.paint.flagEvenOdd = true;
} else {
Log.error("not know fill-rule value : \"" << content << "\", not in [nonzero,evenodd]");
}
@ -369,14 +343,14 @@ void esvg::Base::parsePaintAttr(const exml::Element& _element) {
// ---------------- opacity ----------------
content = _element.attributes["opacity"];
if (content.size()!=0) {
m_paint.opacity = parseLength(content);
m_paint.opacity = etk::avg(0.0f, m_paint.opacity, 1.0f);
this.paint.opacity = parseLength(content);
this.paint.opacity = etk::avg(0.0f, this.paint.opacity, 1.0f);
}
}
}
etk::Pair<etk::Color<float,4>, etk::String> esvg::Base::parseColor(const etk::String& _inputData) {
etk::Pair<etk::Color<float,4>, etk::String> localColor(etk::color::white, "");
Pair<etk::Color<float,4>, etk::String> esvg::Base::parseColor(const etk::String& _inputData) {
Pair<etk::Color<float,4>, etk::String> localColor(etk::color::white, "");
if( _inputData.size() > 4
&& _inputData[0] == 'u'
@ -385,27 +359,27 @@ etk::Pair<etk::Color<float,4>, etk::String> esvg::Base::parseColor(const etk::St
&& _inputData[3] == '(') {
if (_inputData[4] == '#') {
etk::String color(_inputData.begin() + 5, _inputData.end()-1);
localColor = etk::Pair<etk::Color<float,4>, etk::String>(etk::color::none, color);
localColor = Pair<etk::Color<float,4>, etk::String>(etk::color::none, color);
} else {
Log.error("Problem in parsing the color : \"" << _inputData << "\" == > url(XXX) is not supported now ...");
}
} else {
localColor = etk::Pair<etk::Color<float,4>, etk::String>(_inputData, "");
localColor = Pair<etk::Color<float,4>, etk::String>(_inputData, "");
}
Log.verbose("Parse color : \"" << _inputData << "\" == > " << localColor.first << " " << localColor.second);
return localColor;
}
bool esvg::Base::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Base::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
// TODO : UNDERSTAND why nothing is done here ...
// Parse basic elements (ID...):
m_id = _element.attributes["id"];
this.id = _element.attributes["id"];
_sizeMax = Vector2f(0.0f, 0.0f);
return false;
}
const char * esvg::Base::spacingDist(int32_t _spacing) {
const char * esvg::Base::spacingDist(int _spacing) {
static const char *tmpValue = " ";
if (_spacing>20) {
_spacing = 20;
@ -413,27 +387,27 @@ const char * esvg::Base::spacingDist(int32_t _spacing) {
return tmpValue + 20*4 - _spacing*4;
}
void esvg::Base::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Base::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.warning(spacingDist(_level) << "DRAW esvg::Base ... ==> No drawing availlable");
}
const etk::String& esvg::Base::getId() const {
return m_id;
return this.id;
}
void esvg::Base::setId(const etk::String& _newId) {
// TODO : Check if it is UNIQUE ...
m_id = _newId;
this.id = _newId;
}
void esvg::Base::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
}

View File

@ -1,129 +1,95 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <esvg/join.hpp>
#include <esvg/cap.hpp>
#pragma once
#include <etk/types.hpp>
#include <etk/Vector.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/math/Matrix2x3.hpp>
#include <etk/Color.hpp>
#include <esvg/render/Path.hpp>
#include <exml/exml.hpp>
#include <esvg/Renderer.hpp>
#include <esvg/Dimension.hpp>
namespace esvg {
extern const float kappa90; //!< proportional lenght to the radius of a bezier handle for 90° arcs.
class Base {
public static float kappa90; //!< proportional lenght to the radius of a bezier handle for 90° arcs.
protected PaintState paint;
protected mat2x3 transformMatrix; //!< specific render of the curent element
protected String spacingDist(int _spacing);
public Base() {};
Base(PaintState _parentPaintState);
/**
* @brief Painting mode of the Object:
* parse all the element needed in the basic node
* @param _element standart XML node
* @return true if no problem arrived
*/
enum paint {
paint_none, //!< No painting.
paint_color, //!< Painting a color.
paint_gradientLinear, //!< Painting a linear gradient.
paint_gradientRadial //!< Painting a radial gradient.
};
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
class PaintState {
public:
PaintState();
void clear();
public:
etk::Pair<etk::Color<float,4>, etk::String> fill;
etk::Pair<etk::Color<float,4>, etk::String> stroke;
float strokeWidth;
bool flagEvenOdd; //!< Fill rules
enum esvg::cap lineCap;
enum esvg::join lineJoin;
float miterLimit;
etk::Pair<Vector2f, Vector2f> viewPort; //!< min pos, max pos
float opacity;
};
/**
* Draw the form in the renderer
* @param _myRenderer Renderer engine
* @param _basicTrans Parant transformation of the environement
* @param _level Level of the tree
*/
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level=1);
class Base {
protected:
PaintState m_paint;
mat2x3 m_transformMatrix; //!< specific render of the curent element
const char * spacingDist(int32_t _spacing);
public:
Base() {};
Base(PaintState _parentPaintState);
virtual ~Base() { };
/**
* @brief parse all the element needed in the basic node
* @param[in] _element standart XML node
* @return true if no problem arrived
*/
virtual bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
/**
* @brief Draw the form in the renderer
* @param[in] _myRenderer Renderer engine
* @param[in] _basicTrans Parant transformation of the environement
* @param[in] _level Level of the tree
*/
virtual void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level=1);
/**
* @brief Draw rhe shape with all points
* @param[in] _out where the lines are added
* @param[in] _recurtionMax interpolation recurtion max
* @param[in] _threshold threshold to stop recurtion
* @param[in] _basicTrans Parant transformation of the environement
* @param[in] _level Level of the tree
*/
virtual void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1);
virtual void display(int32_t _spacing) { };
void parseTransform(const exml::Element& _element);
/**
* @brief parse x, y, width, height attribute of the xml node
* @param[in] _element XML node
* @param[out] _pos parsed position
* @param[out] _size parsed dimention
*/
void parsePosition(const exml::Element& _element, Vector2f &_pos, Vector2f &_size);
/**
* @brief parse a lenght of the xml element
* @param[in] _dataInput Data C String with the printed lenght
* @return standard number of pixels
*/
float parseLength(const etk::String& _dataInput);
etk::Pair<float, enum esvg::distance> parseLength2(const etk::String& _dataInput);
/**
* @brief parse a Painting attribute of a specific node
* @param[in] _element Basic node of the XML that might be parsed
*/
void parsePaintAttr(const exml::Element& _element);
/**
* @brief parse a color specification from the svg file
* @param[in] _inputData Data C String with the xml definition
* @return The parsed color (color used and the link if needed)
*/
etk::Pair<etk::Color<float,4>, etk::String> parseColor(const etk::String& _inputData);
protected:
etk::String m_id; //!< unique ID of the element.
public:
/**
* @brief Get the ID of the Element
* @return UniqueId in the svg file
*/
const etk::String& getId() const;
/**
* @brief Set the ID of the Element
* @param[in] _newId New Id of the element
*/
void setId(const etk::String& _newId);
};
};
/**
* Draw rhe shape with all points
* @param _out where the lines are added
* @param _recurtionMax interpolation recurtion max
* @param _threshold threshold to stop recurtion
* @param _basicTrans Parant transformation of the environement
* @param _level Level of the tree
*/
void drawShapePoints(final List<List<Vector2f>> _out,
final int _recurtionMax,
final float _threshold,
final mat2x3 _basicTrans,
final int _level=1);
void display(final int _spacing) {};
void parseTransform(const exml::Element& _element);
/**
* parse x, y, width, height attribute of the xml node
* @param _element XML node
* @param _pos parsed position
* @param _size parsed dimention
*/
void parsePosition(const exml::Element& _element, Vector2f &_pos, Vector2f &_size);
/**
* parse a lenght of the xml element
* @param _dataInput Data C String with the printed lenght
* @return standard number of pixels
*/
float parseLength(const etk::String& _dataInput);
Pair<float, enum esvg::distance> parseLength2(const etk::String& _dataInput);
/**
* parse a Painting attribute of a specific node
* @param _element Basic node of the XML that might be parsed
*/
void parsePaintAttr(exml::Element _element);
/**
* parse a color specification from the svg file
* @param _inputData Data C String with the xml definition
* @return The parsed color (color used and the link if needed)
*/
Pair<Color, String> parseColor(String _inputData);
protected String id; //!< unique ID of the element.
/**
* Get the ID of the Element
* @return UniqueId in the svg file
*/
public String getId() {
return this.id;
}
/**
* Set the ID of the Element
* @param _newId New Id of the element
*/
public void setId(String _newId) {
this.id = _newId;
}
}

View File

@ -0,0 +1,13 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
public enum CapMode {
BUTT,
ROUND,
SQUARE
}

View File

@ -17,9 +17,9 @@ esvg::Circle::~Circle() {
}
bool esvg::Circle::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
m_radius = 0.0;
m_position.setValue(0,0);
boolean esvg::Circle::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
this.radius = 0.0;
this.position.setValue(0,0);
if (_element.exist() == false) {
return false;
}
@ -27,70 +27,70 @@ bool esvg::Circle::parseXML(const exml::Element& _element, mat2x3& _parentTrans,
parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
etk::String content = _element.attributes["cx"];
if (content.size()!=0) {
m_position.setX(parseLength(content));
this.position.setX(parseLength(content));
}
content = _element.attributes["cy"];
if (content.size()!=0) {
m_position.setY(parseLength(content));
this.position.setY(parseLength(content));
}
content = _element.attributes["r"];
if (content.size()!=0) {
m_radius = parseLength(content);
this.radius = parseLength(content);
} else {
Log.error("(l "<<_element.getPos()<<") Circle \"r\" is not present");
return false;
}
if (0 > m_radius) {
m_radius = 0;
if (0 > this.radius) {
this.radius = 0;
Log.error("(l "<<_element.getPos()<<") Circle \"r\" is negative");
return false;
}
_sizeMax.setValue(m_position.x() + m_radius, m_position.y() + m_radius);
_sizeMax.setValue(this.position.x() + this.radius, this.position.y() + this.radius);
return true;
}
void esvg::Circle::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Circle " << m_position << " radius=" << m_radius);
void esvg::Circle::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Circle " << this.position << " radius=" << this.radius);
}
esvg::render::Path esvg::Circle::createPath() {
esvg::render::Path out;
out.clear();
out.moveTo(false, m_position + Vector2f(m_radius, 0.0f));
out.moveTo(false, this.position + Vector2f(this.radius, 0.0f));
out.curveTo(false,
m_position + Vector2f(m_radius, m_radius*esvg::kappa90),
m_position + Vector2f(m_radius*esvg::kappa90, m_radius),
m_position + Vector2f(0.0f, m_radius));
this.position + Vector2f(this.radius, this.radius*esvg::kappa90),
this.position + Vector2f(this.radius*esvg::kappa90, this.radius),
this.position + Vector2f(0.0f, this.radius));
out.curveTo(false,
m_position + Vector2f(-m_radius*esvg::kappa90, m_radius),
m_position + Vector2f(-m_radius, m_radius*esvg::kappa90),
m_position + Vector2f(-m_radius, 0.0f));
this.position + Vector2f(-this.radius*esvg::kappa90, this.radius),
this.position + Vector2f(-this.radius, this.radius*esvg::kappa90),
this.position + Vector2f(-this.radius, 0.0f));
out.curveTo(false,
m_position + Vector2f(-m_radius, -m_radius*esvg::kappa90),
m_position + Vector2f(-m_radius*esvg::kappa90, -m_radius),
m_position + Vector2f(0.0f, -m_radius));
this.position + Vector2f(-this.radius, -this.radius*esvg::kappa90),
this.position + Vector2f(-this.radius*esvg::kappa90, -this.radius),
this.position + Vector2f(0.0f, -this.radius));
out.curveTo(false,
m_position + Vector2f(m_radius*esvg::kappa90, -m_radius),
m_position + Vector2f(m_radius, -m_radius*esvg::kappa90),
m_position + Vector2f(m_radius, 0.0f));
this.position + Vector2f(this.radius*esvg::kappa90, -this.radius),
this.position + Vector2f(this.radius, -this.radius*esvg::kappa90),
this.position + Vector2f(this.radius, 0.0f));
out.close();
return out;
}
void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Circle");
if (m_radius <= 0.0f) {
Log.verbose(spacingDist(_level+1) << "Too small radius" << m_radius);
if (this.radius <= 0.0f) {
Log.verbose(spacingDist(_level+1) << "Too small radius" << this.radius);
return;
}
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
@ -102,10 +102,10 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
if (colorFill != null) {
@ -120,10 +120,10 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -136,7 +136,7 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
@ -144,21 +144,21 @@ void esvg::Circle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_
}
void esvg::Circle::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Circle");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,27 +6,33 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include<esvg/Base.hpp>
namespace esvg {
class Circle : public esvg::Base {
namespace esvg{
class Circle extends esvg::Base
{
private:
Vector2f m_position; //!< Position of the Circle
float m_radius; //!< Radius of the Circle
Vector2f this.position; //!< Position of the Circle
float this.radius; //!< Radius of the Circle
public:
Circle(PaintState _parentPaintState);
~Circle();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Circle(PaintState _parentPaintState);~
Circle();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
private:
esvg::render::Path createPath();
};
}
esvg::render::
Path createPath();
};}

View File

@ -22,20 +22,20 @@ static const float millimeterToKilometer = 1000000.0f;
static const float basicRatio = 72.0f / 25.4f;
esvg::Dimension::Dimension() :
m_data(0,0),
m_type(esvg::distance_pixel) {
this.data(0,0),
this.type(esvg::distance_pixel) {
// notinh to do ...
}
esvg::Dimension::Dimension(const Vector2f& _size, enum esvg::distance _type) :
m_data(0,0),
m_type(esvg::distance_pixel) {
this.data(0,0),
this.type(esvg::distance_pixel) {
set(_size, _type);
}
void esvg::Dimension::set(etk::String _config) {
m_data.setValue(0,0);
m_type = esvg::distance_pixel;
this.data.setValue(0,0);
this.type = esvg::distance_pixel;
enum distance type = esvg::distance_pixel;
if (etk::end_with(_config, "%", false) == true) {
type = esvg::distance_pourcent;
@ -106,8 +106,8 @@ static enum esvg::distance parseType(etk::String& _config) {
void esvg::Dimension::set(etk::String _configX, etk::String _configY) {
m_data.setValue(0,0);
m_type = esvg::distance_pixel;
this.data.setValue(0,0);
this.type = esvg::distance_pixel;
enum distance type = esvg::distance_pixel;
// First Parse X
enum distance typeX = parseType(_configX);
@ -170,8 +170,8 @@ esvg::Dimension::operator etk::String() const {
}
void esvg::Dimension::set(const Vector2f& _size, enum esvg::distance _type) {
m_data = _size;
m_type = _type;
this.data = _size;
this.type = _type;
switch(_type) {
case esvg::distance_pourcent:
case esvg::distance_pixel:
@ -193,23 +193,23 @@ void esvg::Dimension::set(const Vector2f& _size, enum esvg::distance _type) {
}
Vector2f esvg::Dimension::getPixel(const Vector2f& _upperSize) const {
switch(m_type) {
switch(this.type) {
case esvg::distance_pourcent:
return Vector2f(_upperSize.x()*m_data.x()*0.01f, _upperSize.y()*m_data.y()*0.01f);
return Vector2f(_upperSize.x()*this.data.x()*0.01f, _upperSize.y()*this.data.y()*0.01f);
case esvg::distance_pixel:
return m_data;
return this.data;
case esvg::distance_meter:
return Vector2f(m_data.x()*meterToMillimeter*basicRatio, m_data.y()*meterToMillimeter*basicRatio);
return Vector2f(this.data.x()*meterToMillimeter*basicRatio, this.data.y()*meterToMillimeter*basicRatio);
case esvg::distance_centimeter:
return Vector2f(m_data.x()*centimeterToMillimeter*basicRatio, m_data.y()*centimeterToMillimeter*basicRatio);
return Vector2f(this.data.x()*centimeterToMillimeter*basicRatio, this.data.y()*centimeterToMillimeter*basicRatio);
case esvg::distance_millimeter:
return Vector2f(m_data.x()*basicRatio, m_data.y()*basicRatio);
return Vector2f(this.data.x()*basicRatio, this.data.y()*basicRatio);
case esvg::distance_kilometer:
return Vector2f(m_data.x()*kilometerToMillimeter*basicRatio, m_data.y()*kilometerToMillimeter*basicRatio);
return Vector2f(this.data.x()*kilometerToMillimeter*basicRatio, this.data.y()*kilometerToMillimeter*basicRatio);
case esvg::distance_inch:
return Vector2f(m_data.x()*inchToMillimeter*basicRatio, m_data.y()*inchToMillimeter*basicRatio);
return Vector2f(this.data.x()*inchToMillimeter*basicRatio, this.data.y()*inchToMillimeter*basicRatio);
case esvg::distance_foot:
return Vector2f(m_data.x()*footToMillimeter*basicRatio, m_data.y()*footToMillimeter*basicRatio);
return Vector2f(this.data.x()*footToMillimeter*basicRatio, this.data.y()*footToMillimeter*basicRatio);
}
return Vector2f(128.0f, 128.0f);
}
@ -268,30 +268,30 @@ namespace etk {
template<> etk::UString toUString<esvg::Dimension>(const esvg::Dimension& _obj) {
return etk::toUString(etk::toString(_obj));
}
template<> bool from_string<esvg::Dimension>(esvg::Dimension& _variableRet, const etk::String& _value) {
template<> boolean frothis.string<esvg::Dimension>(esvg::Dimension& _variableRet, const etk::String& _value) {
_variableRet = esvg::Dimension(_value);
return true;
}
template<> bool from_string<esvg::Dimension>(esvg::Dimension& _variableRet, const etk::UString& _value) {
return from_string(_variableRet, etk::toString(_value));
template<> boolean frothis.string<esvg::Dimension>(esvg::Dimension& _variableRet, const etk::UString& _value) {
return frothis.string(_variableRet, etk::toString(_value));
}
};
esvg::Dimension1D::Dimension1D() :
m_data(0.0f),
m_type(esvg::distance_pixel) {
this.data(0.0f),
this.type(esvg::distance_pixel) {
// notinh to do ...
}
esvg::Dimension1D::Dimension1D(float _size, enum esvg::distance _type) :
m_data(0.0f),
m_type(esvg::distance_pixel) {
this.data(0.0f),
this.type(esvg::distance_pixel) {
set(_size, _type);
}
void esvg::Dimension1D::set(etk::String _config) {
m_data = 0;
m_type = esvg::distance_pixel;
this.data = 0;
this.type = esvg::distance_pixel;
enum distance type = esvg::distance_pixel;
if (etk::end_with(_config, "%", false) == true) {
type = esvg::distance_pourcent;
@ -375,8 +375,8 @@ esvg::Dimension1D::operator etk::String() const {
}
void esvg::Dimension1D::set(float _size, enum esvg::distance _type) {
m_data = _size;
m_type = _type;
this.data = _size;
this.type = _type;
switch(_type) {
case esvg::distance_pourcent:
case esvg::distance_pixel:
@ -398,23 +398,23 @@ void esvg::Dimension1D::set(float _size, enum esvg::distance _type) {
}
float esvg::Dimension1D::getPixel(float _upperSize) const {
switch(m_type) {
switch(this.type) {
case esvg::distance_pourcent:
return _upperSize*m_data*0.01f;
return _upperSize*this.data*0.01f;
case esvg::distance_pixel:
return m_data;
return this.data;
case esvg::distance_meter:
return m_data*meterToMillimeter*basicRatio;
return this.data*meterToMillimeter*basicRatio;
case esvg::distance_centimeter:
return m_data*centimeterToMillimeter*basicRatio;
return this.data*centimeterToMillimeter*basicRatio;
case esvg::distance_millimeter:
return m_data*basicRatio;
return this.data*basicRatio;
case esvg::distance_kilometer:
return m_data*kilometerToMillimeter*basicRatio;
return this.data*kilometerToMillimeter*basicRatio;
case esvg::distance_inch:
return m_data*inchToMillimeter*basicRatio;
return this.data*inchToMillimeter*basicRatio;
case esvg::distance_foot:
return m_data*footToMillimeter*basicRatio;
return this.data*footToMillimeter*basicRatio;
}
return 128.0f;
}
@ -431,12 +431,12 @@ namespace etk {
template<> etk::UString toUString<esvg::Dimension1D>(const esvg::Dimension1D& _obj) {
return etk::toUString(etk::toString(_obj));
}
template<> bool from_string<esvg::Dimension1D>(esvg::Dimension1D& _variableRet, const etk::String& _value) {
template<> boolean frothis.string<esvg::Dimension1D>(esvg::Dimension1D& _variableRet, const etk::String& _value) {
_variableRet = esvg::Dimension1D(_value);
return true;
}
template<> bool from_string<esvg::Dimension1D>(esvg::Dimension1D& _variableRet, const etk::UString& _value) {
return from_string(_variableRet, etk::toString(_value));
template<> boolean frothis.string<esvg::Dimension1D>(esvg::Dimension1D& _variableRet, const etk::UString& _value) {
return frothis.string(_variableRet, etk::toString(_value));
}
};

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,10 +6,237 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>
namespace esvg {
namespace esvg{
/**
* in the dimention class we store the data as the more usefull unit (pixel)
* but one case need to be dynamic the %, then when requested in % the register the % value
*/
class Dimension {
private:Vector2f this.data;
enum distance this.type;
public:
/**
* Constructor (default :0,0 mode pixel)
*/
Dimension();
/**
* Constructor
* @param _size Requested dimention
* @param _type Unit of the Dimention
*/
Dimension(const Vector2f& _size, enum esvg::distance _type=esvg::distance_pixel);
/**
* Constructor
* @param _config dimension configuration.
*/
Dimension(const etk::String& _config) :
this.data(0,0),
this.type(esvg::distance_pixel) {
set(_config);
};
/**
* Constructor
* @param _configX dimension X configuration.
* @param _configY dimension Y configuration.
*/
Dimension(const etk::String& _configX, const etk::String& _configY) :
this.data(0,0),
this.type(esvg::distance_pixel) {
set(_configX, _configY);
};
/**
* Destructor
*/
~Dimension();
/**
* string cast :
*/
operator etk::String() const;
/**
* get the current dimention.
* @return dimention requested.
*/
const Vector2f& getValue() const {
return this.data;
}
/**
* @breif get the dimension type
* @return the type
*/
enum distance getType() const {
return this.type;
};
/**
* set the current dimention in requested type
* @param _size Dimention to set
* @param _type Type of unit requested.
*/
void set(const Vector2f& _size, enum distance _type);
public:
/**
* set the current dimention in requested type
* @param _config dimension configuration.
*/
void set(etk::String _config);
/**
* set the current dimention in requested type
* @param _configX dimension X configuration.
* @param _configY dimension Y configuration.
*/
void set(etk::String _configX, etk::String _configY);
public:
/**
* get the current dimention in pixel
* @param _upperSize Size in pixel of the upper value
* @return dimention in Pixel
*/
Vector2f getPixel(const Vector2f& _upperSize) const;
/*****************************************************
* = assigment
*****************************************************/
const Dimension& operator= (const Dimension& _obj ) {
if (this!=&_obj) {
this.data = _obj.this.data;
this.type = _obj.this.type;
}
return *this;
}
/*****************************************************
* == operator
*****************************************************/
boolean operator == (const Dimension& _obj) const {
if( this.data == _obj.this.data
&& this.type == _obj.this.type) {
return true;
}
return false;
}
/*****************************************************
* != operator
*****************************************************/
boolean operator!= (const Dimension& _obj) const {
if( this.data != _obj.this.data
|| this.type != _obj.this.type) {
return true;
}
return false;
}
};
etk::Stream& operator <<(etk::Stream& _os, enum esvg::distance _obj);
etk::Stream& operator <<(etk::Stream& _os, const esvg::Dimension& _obj);
/**
* in the dimention class we store the data as the more usefull unit (pixel)
* but one case need to be dynamic the %, then when requested in % the register the % value
*/
class Dimension1D {
private:
float this.data;
enum distance this.type;
public:
/**
* Constructor (default :0,0 mode pixel)
*/
Dimension1D();
/**
* Constructor
* @param _size Requested dimention
* @param _type Unit of the Dimention
*/
Dimension1D(float _size, enum esvg::distance _type=esvg::distance_pixel);
/**
* Constructor
* @param _config dimension configuration.
*/
Dimension1D(const etk::String& _config) :
this.data(0.0f),
this.type(esvg::distance_pixel) {
set(_config);
};
/**
* Destructor
*/
~Dimension1D();
/**
* string cast :
*/
operator etk::String() const;
/**
* get the current dimention.
* @return dimention requested.
*/
const float& getValue() const {
return this.data;
}
/**
* @breif get the dimension type
* @return the type
*/
enum distance getType() const {
return this.type;
};
/**
* set the current dimention in requested type
* @param _size Dimention to set
* @param _type Type of unit requested.
*/
void set(float _size, enum distance _type);
public:
/**
* set the current dimention in requested type
* @param _config dimension configuration.
*/
void set(etk::String _config);
public:
/**
* get the current dimention in pixel
* @param _upperSize Size in pixel of the upper value
* @return dimention in Pixel
*/
float getPixel(float _upperSize) const;
/*****************************************************
* = assigment
*****************************************************/
const Dimension1D& operator= (const Dimension1D& _obj ) {
if (this!=&_obj) {
this.data = _obj.this.data;
this.type = _obj.this.type;
}
return *this;
}
/*****************************************************
* == operator
*****************************************************/
boolean operator == (const Dimension1D& _obj) const {
if( this.data == _obj.this.data
&& this.type == _obj.this.type) {
return true;
}
return false;
}
/*****************************************************
* != operator
*****************************************************/
boolean operator!= (const Dimension1D& _obj) const {
if( this.data != _obj.this.data
|| this.type != _obj.this.type) {
return true;
}
return false;
}
};
etk::Stream& operator <<(etk::Stream& _os, const esvg::Dimension1D& _obj);
}
;
enum distance {
distance_pourcent=0, //!< "%"
distance_pixel, //!< "px"
@ -22,231 +250,4 @@ namespace esvg {
distance_ex, //!< "ex"
distance_point, //!< "pt"
distance_pc //!< "pc"
};
/**
* @brief in the dimention class we store the data as the more usefull unit (pixel)
* but one case need to be dynamic the %, then when requested in % the register the % value
*/
class Dimension {
private:
Vector2f m_data;
enum distance m_type;
public:
/**
* @brief Constructor (default :0,0 mode pixel)
*/
Dimension();
/**
* @brief Constructor
* @param[in] _size Requested dimention
* @param[in] _type Unit of the Dimention
*/
Dimension(const Vector2f& _size, enum esvg::distance _type=esvg::distance_pixel);
/**
* @brief Constructor
* @param[in] _config dimension configuration.
*/
Dimension(const etk::String& _config) :
m_data(0,0),
m_type(esvg::distance_pixel) {
set(_config);
};
/**
* @brief Constructor
* @param[in] _configX dimension X configuration.
* @param[in] _configY dimension Y configuration.
*/
Dimension(const etk::String& _configX, const etk::String& _configY) :
m_data(0,0),
m_type(esvg::distance_pixel) {
set(_configX, _configY);
};
/**
* @brief Destructor
*/
~Dimension();
/**
* @brief string cast :
*/
operator etk::String() const;
/**
* @brief get the current dimention.
* @return dimention requested.
*/
const Vector2f& getValue() const {
return m_data;
}
/**
* @breif get the dimension type
* @return the type
*/
enum distance getType() const {
return m_type;
};
/**
* @brief set the current dimention in requested type
* @param[in] _size Dimention to set
* @param[in] _type Type of unit requested.
*/
void set(const Vector2f& _size, enum distance _type);
public:
/**
* @brief set the current dimention in requested type
* @param[in] _config dimension configuration.
*/
void set(etk::String _config);
/**
* @brief set the current dimention in requested type
* @param[in] _configX dimension X configuration.
* @param[in] _configY dimension Y configuration.
*/
void set(etk::String _configX, etk::String _configY);
public:
/**
* @brief get the current dimention in pixel
* @param[in] _upperSize Size in pixel of the upper value
* @return dimention in Pixel
*/
Vector2f getPixel(const Vector2f& _upperSize) const;
/*****************************************************
* = assigment
*****************************************************/
const Dimension& operator= (const Dimension& _obj ) {
if (this!=&_obj) {
m_data = _obj.m_data;
m_type = _obj.m_type;
}
return *this;
}
/*****************************************************
* == operator
*****************************************************/
bool operator == (const Dimension& _obj) const {
if( m_data == _obj.m_data
&& m_type == _obj.m_type) {
return true;
}
return false;
}
/*****************************************************
* != operator
*****************************************************/
bool operator!= (const Dimension& _obj) const {
if( m_data != _obj.m_data
|| m_type != _obj.m_type) {
return true;
}
return false;
}
};
etk::Stream& operator <<(etk::Stream& _os, enum esvg::distance _obj);
etk::Stream& operator <<(etk::Stream& _os, const esvg::Dimension& _obj);
/**
* @brief in the dimention class we store the data as the more usefull unit (pixel)
* but one case need to be dynamic the %, then when requested in % the register the % value
*/
class Dimension1D {
private:
float m_data;
enum distance m_type;
public:
/**
* @brief Constructor (default :0,0 mode pixel)
*/
Dimension1D();
/**
* @brief Constructor
* @param[in] _size Requested dimention
* @param[in] _type Unit of the Dimention
*/
Dimension1D(float _size, enum esvg::distance _type=esvg::distance_pixel);
/**
* @brief Constructor
* @param[in] _config dimension configuration.
*/
Dimension1D(const etk::String& _config) :
m_data(0.0f),
m_type(esvg::distance_pixel) {
set(_config);
};
/**
* @brief Destructor
*/
~Dimension1D();
/**
* @brief string cast :
*/
operator etk::String() const;
/**
* @brief get the current dimention.
* @return dimention requested.
*/
const float& getValue() const {
return m_data;
}
/**
* @breif get the dimension type
* @return the type
*/
enum distance getType() const {
return m_type;
};
/**
* @brief set the current dimention in requested type
* @param[in] _size Dimention to set
* @param[in] _type Type of unit requested.
*/
void set(float _size, enum distance _type);
public:
/**
* @brief set the current dimention in requested type
* @param[in] _config dimension configuration.
*/
void set(etk::String _config);
public:
/**
* @brief get the current dimention in pixel
* @param[in] _upperSize Size in pixel of the upper value
* @return dimention in Pixel
*/
float getPixel(float _upperSize) const;
/*****************************************************
* = assigment
*****************************************************/
const Dimension1D& operator= (const Dimension1D& _obj ) {
if (this!=&_obj) {
m_data = _obj.m_data;
m_type = _obj.m_type;
}
return *this;
}
/*****************************************************
* == operator
*****************************************************/
bool operator == (const Dimension1D& _obj) const {
if( m_data == _obj.m_data
&& m_type == _obj.m_type) {
return true;
}
return false;
}
/*****************************************************
* != operator
*****************************************************/
bool operator!= (const Dimension1D& _obj) const {
if( m_data != _obj.m_data
|| m_type != _obj.m_type) {
return true;
}
return false;
}
};
etk::Stream& operator <<(etk::Stream& _os, const esvg::Dimension1D& _obj);
}
}

View File

@ -17,7 +17,7 @@ esvg::Ellipse::~Ellipse() {
}
bool esvg::Ellipse::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Ellipse::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
if (_element.exist() == false) {
return false;
}
@ -25,77 +25,77 @@ bool esvg::Ellipse::parseXML(const exml::Element& _element, mat2x3& _parentTrans
parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
m_c.setValue(0,0);
m_r.setValue(0,0);
this.c.setValue(0,0);
this.r.setValue(0,0);
etk::String content = _element.attributes["cx"];
if (content.size()!=0) {
m_c.setX(parseLength(content));
this.c.setX(parseLength(content));
}
content = _element.attributes["cy"];
if (content.size()!=0) {
m_c.setY(parseLength(content));
this.c.setY(parseLength(content));
}
content = _element.attributes["rx"];
if (content.size()!=0) {
m_r.setX(parseLength(content));
this.r.setX(parseLength(content));
} else {
Log.error("(l "<<_element.getPos()<<") Ellipse \"rx\" is not present");
return false;
}
content = _element.attributes["ry"];
if (content.size()!=0) {
m_r.setY(parseLength(content));
this.r.setY(parseLength(content));
} else {
Log.error("(l "<<_element.getPos()<<") Ellipse \"ry\" is not present");
return false;
}
_sizeMax.setValue(m_c.x() + m_r.x(), m_c.y() + m_r.y());
_sizeMax.setValue(this.c.x() + this.r.x(), this.c.y() + this.r.y());
return true;
}
void esvg::Ellipse::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Ellipse c=" << m_c << " r=" << m_r);
void esvg::Ellipse::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Ellipse c=" << this.c << " r=" << this.r);
}
esvg::render::Path esvg::Ellipse::createPath() {
esvg::render::Path out;
out.clear();
out.moveTo(false, m_c + Vector2f(m_r.x(), 0.0f));
out.moveTo(false, this.c + Vector2f(this.r.x(), 0.0f));
out.curveTo(false,
m_c + Vector2f(m_r.x(), m_r.y()*esvg::kappa90),
m_c + Vector2f(m_r.x()*esvg::kappa90, m_r.y()),
m_c + Vector2f(0.0f, m_r.y()));
this.c + Vector2f(this.r.x(), this.r.y()*esvg::kappa90),
this.c + Vector2f(this.r.x()*esvg::kappa90, this.r.y()),
this.c + Vector2f(0.0f, this.r.y()));
out.curveTo(false,
m_c + Vector2f(-m_r.x()*esvg::kappa90, m_r.y()),
m_c + Vector2f(-m_r.x(), m_r.y()*esvg::kappa90),
m_c + Vector2f(-m_r.x(), 0.0f));
this.c + Vector2f(-this.r.x()*esvg::kappa90, this.r.y()),
this.c + Vector2f(-this.r.x(), this.r.y()*esvg::kappa90),
this.c + Vector2f(-this.r.x(), 0.0f));
out.curveTo(false,
m_c + Vector2f(-m_r.x(), -m_r.y()*esvg::kappa90),
m_c + Vector2f(-m_r.x()*esvg::kappa90, -m_r.y()),
m_c + Vector2f(0.0f, -m_r.y()));
this.c + Vector2f(-this.r.x(), -this.r.y()*esvg::kappa90),
this.c + Vector2f(-this.r.x()*esvg::kappa90, -this.r.y()),
this.c + Vector2f(0.0f, -this.r.y()));
out.curveTo(false,
m_c + Vector2f(m_r.x()*esvg::kappa90, -m_r.y()),
m_c + Vector2f(m_r.x(), -m_r.y()*esvg::kappa90),
m_c + Vector2f(m_r.x(), 0.0f));
this.c + Vector2f(this.r.x()*esvg::kappa90, -this.r.y()),
this.c + Vector2f(this.r.x(), -this.r.y()*esvg::kappa90),
this.c + Vector2f(this.r.x(), 0.0f));
out.close();
return out;
}
void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Ellipse");
if ( m_r.x()<=0.0f
|| m_r.y()<=0.0f) {
Log.verbose(spacingDist(_level+1) << "Too small radius" << m_r);
if ( this.r.x()<=0.0f
|| this.r.y()<=0.0f) {
Log.verbose(spacingDist(_level+1) << "Too small radius" << this.r);
return;
}
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
@ -107,10 +107,10 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
if (colorFill != null) {
@ -125,10 +125,10 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -141,7 +141,7 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
@ -150,21 +150,21 @@ void esvg::Ellipse::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
void esvg::Ellipse::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Ellipse");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,26 +6,30 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include<esvg/Base.hpp>
namespace esvg {
class Ellipse : public esvg::Base {
private:
Vector2f m_c; //!< Center property of the ellipse
Vector2f m_r; //!< Radius property of the ellipse
public:
Ellipse(PaintState _parentPaintState);
~Ellipse();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
float _threshold,
namespace esvg{
class Ellipse extends esvg::Base
{
private Vector2f c; //!< Center property of the ellipse
private Vector2f r; //!< Radius property of the ellipse
public Ellipse(final PaintState _parentPaintState) {
super(_parentPaintState);
}
public boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
public void display(final int _spacing) override;
public void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
public void drawShapePoints(final List<List<Vector2f>> _out,
final int _recurtionMax,
final float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
private:
esvg::render::Path createPath();
};
}
int _level=1) override;
private esvg::render::
Path createPath();
};}

View File

@ -26,7 +26,7 @@ esvg::Group::~Group() {
}
bool esvg::Group::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Group::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
if (_element.exist() == false) {
return false;
}
@ -36,12 +36,12 @@ bool esvg::Group::parseXML(const exml::Element& _element, mat2x3& _parentTrans,
parseTransform(_element);
parsePosition(_element, pos, size);
parsePaintAttr(_element);
Log.verbose("parsed G1. trans : " << m_transformMatrix);
Log.verbose("parsed G1. trans : " << this.transformMatrix);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
Log.verbose("parsed G2. trans : " << m_transformMatrix);
Log.verbose("parsed G2. trans : " << this.transformMatrix);
_sizeMax.setValue(0,0);
Vector2f tmpPos(0,0);
@ -54,25 +54,25 @@ bool esvg::Group::parseXML(const exml::Element& _element, mat2x3& _parentTrans,
}
ememory::SharedPtr<esvg::Base> elementParser;
if (child.getValue() == "g") {
elementParser = ememory::makeShared<esvg::Group>(m_paint);
elementParser = ememory::makeShared<esvg::Group>(this.paint);
} else if (child.getValue() == "a") {
// TODO ...
} else if (child.getValue() == "path") {
elementParser = ememory::makeShared<esvg::Path>(m_paint);
elementParser = ememory::makeShared<esvg::Path>(this.paint);
} else if (child.getValue() == "rect") {
elementParser = ememory::makeShared<esvg::Rectangle>(m_paint);
elementParser = ememory::makeShared<esvg::Rectangle>(this.paint);
} else if (child.getValue() == "circle") {
elementParser = ememory::makeShared<esvg::Circle>(m_paint);
elementParser = ememory::makeShared<esvg::Circle>(this.paint);
} else if (child.getValue() == "ellipse") {
elementParser = ememory::makeShared<esvg::Ellipse>(m_paint);
elementParser = ememory::makeShared<esvg::Ellipse>(this.paint);
} else if (child.getValue() == "line") {
elementParser = ememory::makeShared<esvg::Line>(m_paint);
elementParser = ememory::makeShared<esvg::Line>(this.paint);
} else if (child.getValue() == "polyline") {
elementParser = ememory::makeShared<esvg::Polyline>(m_paint);
elementParser = ememory::makeShared<esvg::Polyline>(this.paint);
} else if (child.getValue() == "polygon") {
elementParser = ememory::makeShared<esvg::Polygon>(m_paint);
elementParser = ememory::makeShared<esvg::Polygon>(this.paint);
} else if (child.getValue() == "text") {
elementParser = ememory::makeShared<esvg::Text>(m_paint);
elementParser = ememory::makeShared<esvg::Text>(this.paint);
} else {
Log.error("(l " << child.getPos() << ") node not suported : '" << child.getValue() << "' must be [g,a,path,rect,circle,ellipse,line,polyline,polygon,text]");
}
@ -80,7 +80,7 @@ bool esvg::Group::parseXML(const exml::Element& _element, mat2x3& _parentTrans,
Log.error("(l " << child.getPos() << ") error on node: '" << child.getValue() << "' allocation error or not supported ...");
continue;
}
if (elementParser->parseXML(child, m_transformMatrix, tmpPos) == false) {
if (elementParser->parseXML(child, this.transformMatrix, tmpPos) == false) {
Log.error("(l " << child.getPos() << ") error on node: '" << child.getValue() << "' Sub Parsing ERROR");
elementParser.reset();
continue;
@ -88,16 +88,16 @@ bool esvg::Group::parseXML(const exml::Element& _element, mat2x3& _parentTrans,
_sizeMax.setValue(etk::max(_sizeMax.x(), tmpPos.x()),
etk::max(_sizeMax.y(), tmpPos.y()));
// add element in the system
m_subElementList.pushBack(elementParser);
this.subElementList.pushBack(elementParser);
}
return true;
}
void esvg::Group::display(int32_t _spacing) {
Log.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 (auto &it : m_subElementList) {
void esvg::Group::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Group (START) fill=" << this.paint.fill.first << "/" << this.paint.fill.second
<< " stroke=" << this.paint.stroke.first << "/" << this.paint.stroke.second
<< " stroke-width=" << this.paint.strokeWidth );
for (auto &it : this.subElementList) {
if (it != null) {
it->display(_spacing+1);
}
@ -105,9 +105,9 @@ void esvg::Group::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Group (STOP)");
}
void esvg::Group::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Group::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::group");
for (auto &it : m_subElementList) {
for (auto &it : this.subElementList) {
if (it != null) {
it->draw(_myRenderer, _basicTrans, _level+1);
}
@ -115,12 +115,12 @@ void esvg::Group::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t
}
void esvg::Group::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW shape esvg::group");
for (auto &it : m_subElementList) {
for (auto &it : this.subElementList) {
if (it != null) {
it->drawShapePoints(_out, _recurtionMax, _threshold, _basicTrans, _level+1);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,24 +6,29 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include <etk/Vector.hpp>
#include<esvg/Base.hpp>#include<etk/Vector.hpp>
namespace esvg {
class Group : public esvg::Base {
namespace esvg{
class Group extends esvg::Base
{
private:
List<ememory::SharedPtr<esvg::Base>> m_subElementList; //!< sub elements ...
List<ememory::SharedPtr<esvg::Base>> this.subElementList; //!< sub elements ...
public:
Group(PaintState _parentPaintState);
~Group();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Group(PaintState _parentPaintState);~
Group();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(final List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
};
}

View File

@ -0,0 +1,13 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
public enum JoinMode {
MITER,
ROUND,
BEVEL
}

View File

@ -10,17 +10,17 @@
#include <esvg/render/Weight.hpp>
esvg::Line::Line(PaintState _parentPaintState) : esvg::Base(_parentPaintState) {
m_startPos.setValue(0,0);
m_stopPos.setValue(0,0);
this.startPos.setValue(0,0);
this.stopPos.setValue(0,0);
}
esvg::Line::~Line() {
}
bool esvg::Line::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Line::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
// line must have a minimum size...
m_paint.strokeWidth = 1;
this.paint.strokeWidth = 1;
if (_element.exist() == false) {
return false;
}
@ -28,48 +28,48 @@ bool esvg::Line::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
etk::String content = _element.attributes["x1"];
if (content.size() != 0) {
m_startPos.setX(parseLength(content));
this.startPos.setX(parseLength(content));
}
content = _element.attributes["y1"];
if (content.size() != 0) {
m_startPos.setY(parseLength(content));
this.startPos.setY(parseLength(content));
}
content = _element.attributes["x2"];
if (content.size() != 0) {
m_stopPos.setX(parseLength(content));
this.stopPos.setX(parseLength(content));
}
content = _element.attributes["y2"];
if (content.size() != 0) {
m_stopPos.setY(parseLength(content));
this.stopPos.setY(parseLength(content));
}
_sizeMax.setValue(etk::max(m_startPos.x(), m_stopPos.x()),
etk::max(m_startPos.y(), m_stopPos.y()));
_sizeMax.setValue(etk::max(this.startPos.x(), this.stopPos.x()),
etk::max(this.startPos.y(), this.stopPos.y()));
return true;
}
void esvg::Line::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Line " << m_startPos << " to " << m_stopPos);
void esvg::Line::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Line " << this.startPos << " to " << this.stopPos);
}
esvg::render::Path esvg::Line::createPath() {
esvg::render::Path out;
out.clear();
out.moveTo(false, m_startPos);
out.lineTo(false, m_stopPos);
out.moveTo(false, this.startPos);
out.lineTo(false, this.stopPos);
out.stop();
return out;
}
void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Line");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
@ -81,20 +81,20 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
// No background ...
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -107,31 +107,31 @@ void esvg::Line::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
_myRenderer.addDebugSegment(listElement.m_debugInformation);
_myRenderer.addDebugSegment(listElement.this.debugInformation);
#endif
}
void esvg::Line::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Line");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,26 +6,32 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include<esvg/Base.hpp>
namespace esvg {
class Line : public esvg::Base {
private:
Vector2f m_startPos; //!< Start line position
Vector2f m_stopPos; //!< Stop line position
namespace esvg{
class Line extends Base {
private:
Vector2f this.startPos; //!< Start line position
Vector2f this.stopPos; //!< Stop line position
public:
Line(PaintState _parentPaintState);
~Line();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Line(PaintState _parentPaintState);~
Line();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
private:
esvg::render::Path createPath();
};
}
esvg::render::
Path createPath();
};}

View File

@ -13,10 +13,10 @@
esvg::LinearGradient::LinearGradient(PaintState _parentPaintState) :
esvg::Base(_parentPaintState),
m_pos1(Vector2f(50,50), esvg::distance_pourcent),
m_pos2(Vector2f(50,50), esvg::distance_pourcent),
m_unit(gradientUnits_objectBoundingBox),
m_spread(spreadMethod_pad) {
this.pos1(Vector2f(50,50), esvg::distance_pourcent),
this.pos2(Vector2f(50,50), esvg::distance_pourcent),
this.unit(gradientUnits_objectBoundingBox),
this.spread(spreadMethod_pad) {
}
@ -25,39 +25,39 @@ esvg::LinearGradient::~LinearGradient() {
}
bool esvg::LinearGradient::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::LinearGradient::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
// line must have a minimum size...
//m_paint.strokeWidth = 1;
//this.paint.strokeWidth = 1;
if (_element.exist() == false) {
return false;
}
// ---------------- get unique ID ----------------
m_id = _element.attributes["id"];
this.id = _element.attributes["id"];
//parseTransform(_element);
//parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
etk::String contentX = _element.attributes["x1"];
etk::String contentY = _element.attributes["y1"];
if ( contentX != ""
&& contentY != "") {
m_pos1.set(contentX, contentY);
this.pos1.set(contentX, contentY);
}
contentX = _element.attributes["x2"];
contentY = _element.attributes["y2"];
if ( contentX != ""
&& contentY != "") {
m_pos2.set(contentX, contentY);
this.pos2.set(contentX, contentY);
}
contentX = _element.attributes["gradientUnits"];
if (contentX == "userSpaceOnUse") {
m_unit = gradientUnits_userSpaceOnUse;
this.unit = gradientUnits_userSpaceOnUse;
} else {
m_unit = gradientUnits_objectBoundingBox;
this.unit = gradientUnits_objectBoundingBox;
if ( contentX.size() != 0
&& contentX != "objectBoundingBox") {
Log.error("Parsing error of 'gradientUnits' ==> not suported value: '" << contentX << "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox");
@ -65,20 +65,20 @@ bool esvg::LinearGradient::parseXML(const exml::Element& _element, mat2x3& _pare
}
contentX = _element.attributes["spreadMethod"];
if (contentX == "reflect") {
m_spread = spreadMethod_reflect;
this.spread = spreadMethod_reflect;
} else if (contentX == "repeat") {
m_spread = spreadMethod_repeat;
this.spread = spreadMethod_repeat;
} else {
m_spread = spreadMethod_pad;
this.spread = spreadMethod_pad;
if ( contentX.size() != 0
&& contentX != "pad") {
Log.error("Parsing error of 'spreadMethod' ==> not suported value: '" << contentX << "' not in : {reflect/repeate/pad} use pad");
}
}
// note: xlink:href is incompatible with subNode "stop"
m_href = _element.attributes["xlink:href"];
if (m_href.size() != 0) {
m_href = etk::String(m_href.begin()+1, m_href.end());
this.href = _element.attributes["xlink:href"];
if (this.href.size() != 0) {
this.href = etk::String(this.href.begin()+1, this.href.end());
}
// parse all sub node :
for(const auto it : _element.nodes) {
@ -92,7 +92,7 @@ bool esvg::LinearGradient::parseXML(const exml::Element& _element, mat2x3& _pare
etk::Color<float,4> stopColor = etk::color::none;
etk::String content = child.attributes["offset"];
if (content.size()!=0) {
etk::Pair<float, enum esvg::distance> tmp = parseLength2(content);
Pair<float, enum esvg::distance> tmp = parseLength2(content);
if (tmp.second == esvg::distance_pixel) {
// special case ==> all time % then no type define ==> % in [0.0 .. 1.0]
offset = tmp.first*100.0f;
@ -114,58 +114,58 @@ bool esvg::LinearGradient::parseXML(const exml::Element& _element, mat2x3& _pare
stopColor.setA(opacity);
Log.verbose(" opacity : '" << content << "' == > " << stopColor);
}
m_data.pushBack(etk::Pair<float, etk::Color<float,4>>(offset, stopColor));
this.data.pushBack(Pair<float, etk::Color<float,4>>(offset, stopColor));
} else {
Log.error("(l " << child.getPos() << ") node not suported : '" << child.getValue() << "' must be [stop]");
}
}
if (m_data.size() != 0) {
if (m_href != "") {
if (this.data.size() != 0) {
if (this.href != "") {
Log.error("(l " << _element.getPos() << ") node can not have an xlink:href element with sub node named: stop ==> removing href");
m_href = "";
this.href = "";
}
}
return true;
}
void esvg::LinearGradient::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "LinearGradient " << m_pos1 << " to " << m_pos2);
for (auto &it : m_data) {
void esvg::LinearGradient::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "LinearGradient " << this.pos1 << " to " << this.pos2);
for (auto &it : this.data) {
Log.debug(spacingDist(_spacing+1) << "STOP: offset=" << it.first << " color=" << it.second);
}
}
void esvg::LinearGradient::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::LinearGradient::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::LinearGradient");
}
const esvg::Dimension& esvg::LinearGradient::getPosition1() {
return m_pos1;
return this.pos1;
}
const esvg::Dimension& esvg::LinearGradient::getPosition2() {
return m_pos2;
return this.pos2;
}
const List<etk::Pair<float, etk::Color<float,4>>>& esvg::LinearGradient::getColors(esvg::Document* _document) {
if (m_href == "") {
return m_data;
const List<Pair<float, etk::Color<float,4>>>& esvg::LinearGradient::getColors(esvg::Document* _document) {
if (this.href == "") {
return this.data;
}
if (_document == null) {
Log.error("Get null input for document");
return m_data;
return this.data;
}
ememory::SharedPtr<esvg::Base> base = _document->getReference(m_href);
ememory::SharedPtr<esvg::Base> base = _document->getReference(this.href);
if (base == null) {
Log.error("Can not get base : '" << m_href << "'");
return m_data;
Log.error("Can not get base : '" << this.href << "'");
return this.data;
}
ememory::SharedPtr<esvg::RadialGradient> gradientR = ememory::dynamicPointerCast<esvg::RadialGradient>(base);
if (gradientR == null) {
ememory::SharedPtr<esvg::LinearGradient> gradientL = ememory::dynamicPointerCast<esvg::LinearGradient>(base);
if (gradientL == null) {
Log.error("Can not cast in a linear/radial gradient: '" << m_href << "' ==> wrong type");
return m_data;
Log.error("Can not cast in a linear/radial gradient: '" << this.href << "' ==> wrong type");
return this.data;
}
return gradientL->getColors(_document);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,32 +6,30 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include <esvg/gradientUnits.hpp>
#include <esvg/spreadMethod.hpp>
#include<esvg/Base.hpp>#include<esvg/gradientUnits.hpp>#include<esvg/spreadMethod.hpp>
namespace esvg {
class Document;
class LinearGradient : public esvg::Base {
namespace esvg{
class Document;
class LinearGradient extends esvg::Base
{
private:
esvg::Dimension m_pos1; //!< gradient position x1 y1
esvg::Dimension m_pos2; //!< gradient position x2 y2
esvg::Dimension this.pos1; //!< gradient position x1 y1
esvg::Dimension this.pos2; //!< gradient position x2 y2
public:
enum gradientUnits m_unit;
enum spreadMethod m_spread;
enum gradientUnits this.unit;
enum spreadMethod this.spread;
private:
etk::String m_href; //!< in case of using a single gradient in multiple gradient, the gradient is store in an other element...
List<etk::Pair<float, etk::Color<float,4>>> m_data; //!< incompatible with href
etk::String this.href; //!< in case of using a single gradient in multiple gradient, the gradient is store in an other element...
List<Pair<float, etk::Color<float,4>>> this.data; //!< incompatible with href
public:
LinearGradient(PaintState _parentPaintState);
~LinearGradient();
virtual bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
virtual void display(int32_t _spacing);
virtual void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level);
virtual boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
virtual void display(int _spacing);
virtual void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level);
public:
const esvg::Dimension& getPosition1();
const esvg::Dimension& getPosition2();
const List<etk::Pair<float, etk::Color<float,4>>>& getColors(esvg::Document* _document);
const List<Pair<float, etk::Color<float,4>>>& getColors(esvg::Document* _document);
};
}

View File

@ -0,0 +1,12 @@
package org.atriasoft.esvg;
/**
* Painting mode of the Object:
*/
public enum PaintMode {
NONE, //!< No painting.
COLOR, //!< Painting a color.
GRADIENT_LINEAR, //!< Painting a linear gradient.
GRADIENT_RADIAL; //!< Painting a radial gradient.
}

View File

@ -0,0 +1,44 @@
package org.atriasoft.esvg;
import org.atriasoft.etk.Color;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.util.Pair;
public class PaintState {
public Pair<Color, String> fill;
public Pair<Color, String> stroke;
public float strokeWidth;
public boolean flagEvenOdd;
public CapMode lineCap;
public JoinMode lineJoin; //!< Fill rules
public float miterLimit;
public Pair<Vector2f, Vector2f> viewPort;
public float opacity;
public PaintState() {
this.fill = new Pair<Color, String>(new Color(0, 0, 0, 1), "");
this.stroke = new Pair<Color, String>(new Color(0, 0, 0, 0), "");
this.strokeWidth = 1.0f;
this.viewPort.first.setValue(0.0f, 0.0f);
this.viewPort.first.setValue(0.0f, 0.0f);
this.flagEvenOdd = false;
this.lineJoin = JoinMode.MITER;
this.lineCap = CapMode.BUTT;
this.miterLimit = 4.0f;
this.opacity = 1.0f;
}
public void clear() {
this.fill = new Pair<Color, String>(new Color(0, 0, 0, 1), "");
this.stroke = new Pair<Color, String>(new Color(0, 0, 0, 0), "");
this.strokeWidth = 1.0f;
this.viewPort.first.setValue(0.0f, 0.0f);
this.viewPort.first.setValue(0.0f, 0.0f);
this.flagEvenOdd = false;
this.lineJoin = JoinMode.MITER;
this.lineCap = CapMode.BUTT;
this.miterLimit = 4.0f;
this.opacity = 1.0f;
}
}

View File

@ -38,11 +38,11 @@ const char * extractCmd(const char* _input, char& _cmd, List<float>& _outputList
if (_input[1] == '\0') {
return &_input[1];
}
int32_t iii=1;
int iii=1;
// extract every float separated by a ' ' or a ','
float element;
char spacer[10];
int32_t nbElementRead;
int nbElementRead;
while( sscanf(&_input[iii], "%1[, ]%f%n", spacer, &element, &nbElementRead) == 2
|| sscanf(&_input[iii], "%f%n", &element, &nbElementRead) == 1) {
Log.verbose("Find element : " << element);
@ -58,7 +58,7 @@ const char * extractCmd(const char* _input, char& _cmd, List<float>& _outputList
}
etk::String cleanBadSpaces(const etk::String& _input) {
etk::String out;
bool haveSpace = false;
boolean haveSpace = false;
for (auto &it : _input) {
if ( it == ' '
|| it == '\t'
@ -76,7 +76,7 @@ etk::String cleanBadSpaces(const etk::String& _input) {
return out;
}
bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
if (_element.exist() == false) {
return false;
}
@ -84,7 +84,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
etk::String elementXML1 = _element.attributes["d"];
@ -102,7 +102,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
for( const char *sss=extractCmd(elementXML, command, listDot);
sss != null;
sss=extractCmd(sss, command, listDot) ) {
bool relative = false;
boolean relative = false;
switch(command) {
case 'm': // Move to (relative)
relative = true;
@ -113,11 +113,11 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
if (listDot.size() >= 2) {
m_listElement.moveTo(relative,
this.listElement.moveTo(relative,
Vector2f(listDot[0], listDot[1]));
}
for (size_t iii=2; iii<listDot.size(); iii+=2) {
m_listElement.lineTo(relative,
this.listElement.lineTo(relative,
Vector2f(listDot[iii], listDot[iii+1]));
}
break;
@ -130,7 +130,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=2) {
m_listElement.lineTo(relative,
this.listElement.lineTo(relative,
Vector2f(listDot[iii], listDot[iii+1]));
}
break;
@ -144,7 +144,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=1) {
m_listElement.lineToV(relative,
this.listElement.lineToV(relative,
listDot[iii]);
}
break;
@ -158,7 +158,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=1) {
m_listElement.lineToH(relative,
this.listElement.lineToH(relative,
listDot[iii]);
}
break;
@ -172,7 +172,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=4) {
m_listElement.bezierCurveTo(relative,
this.listElement.bezierCurveTo(relative,
Vector2f(listDot[iii],listDot[iii+1]),
Vector2f(listDot[iii+2],listDot[iii+3]));
}
@ -187,7 +187,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=2) {
m_listElement.bezierSmoothCurveTo(relative,
this.listElement.bezierSmoothCurveTo(relative,
Vector2f(listDot[iii],listDot[iii+1]));
}
break;
@ -201,7 +201,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=6) {
m_listElement.curveTo(relative,
this.listElement.curveTo(relative,
Vector2f(listDot[iii],listDot[iii+1]),
Vector2f(listDot[iii+2],listDot[iii+3]),
Vector2f(listDot[iii+4],listDot[iii+5]));
@ -217,7 +217,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=4) {
m_listElement.smoothCurveTo(relative,
this.listElement.smoothCurveTo(relative,
Vector2f(listDot[iii],listDot[iii+1]),
Vector2f(listDot[iii+2],listDot[iii+3]));
}
@ -232,15 +232,15 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
break;
}
for (size_t iii=0; iii<listDot.size(); iii+=7) {
bool largeArcFlag = true;
bool sweepFlag = true;
boolean largeArcFlag = true;
boolean sweepFlag = true;
if (listDot[iii+3] == 0.0f) {
largeArcFlag = false;
}
if (listDot[iii+4] == 0.0f) {
sweepFlag = false;
}
m_listElement.ellipticTo(relative,
this.listElement.ellipticTo(relative,
Vector2f(listDot[iii], listDot[iii+1]),
listDot[iii+2],
largeArcFlag,
@ -256,7 +256,7 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
Log.warning("the PATH command "<< command << " has not the good number of element = " << listDot.size() );
break;
}
m_listElement.close(relative);
this.listElement.close(relative);
break;
default:
ESVG_ERROR ("Unknow error : \"" << command << "\"");
@ -266,18 +266,18 @@ bool esvg::Path::parseXML(const exml::Element& _element, mat2x3& _parentTrans, V
return true;
}
void esvg::Path::display(int32_t _spacing) {
m_listElement.display(_spacing);
void esvg::Path::display(int _spacing) {
this.listElement.display(_spacing);
}
void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Path");
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = m_listElement.generateListPoints(_level,
listPoints = this.listElement.generateListPoints(_level,
_myRenderer.getInterpolationRecurtionMax(),
_myRenderer.getInterpolationThreshold());
//listPoints.applyMatrix(mtx);
@ -285,10 +285,10 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
if (colorFill != null) {
@ -301,10 +301,10 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -315,33 +315,33 @@ void esvg::Path::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
m_listElement.m_debugInformation.applyMatrix(mtx);
_myRenderer.addDebugSegment(m_listElement.m_debugInformation);
this.listElement.this.debugInformation.applyMatrix(mtx);
_myRenderer.addDebugSegment(this.listElement.this.debugInformation);
#endif
}
void esvg::Path::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Path");
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = m_listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints = this.listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,24 +6,29 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include <esvg/render/Path.hpp>
#include<esvg/Base.hpp>#include<esvg/render/Path.hpp>
namespace esvg {
class Path : public esvg::Base {
namespace esvg{
class Path extends esvg::Base
{
public:
esvg::render::Path m_listElement;
esvg::render::Path this.listElement;
public:
Path(PaintState _parentPaintState);
~Path();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Path(PaintState _parentPaintState);~
Path();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(final List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
};
}

View File

@ -17,19 +17,19 @@ esvg::Polygon::~Polygon() {
}
bool esvg::Polygon::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Polygon::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
if (_element.exist() == false) {
return false;
}
parseTransform(_element);
parsePaintAttr(_element);
Log.verbose("parsed P1. trans: " << m_transformMatrix);
Log.verbose("parsed P1. trans: " << this.transformMatrix);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
Log.verbose("parsed P2. trans: " << m_transformMatrix);
Log.verbose("parsed P2. trans: " << this.transformMatrix);
const etk::String sss1 = _element.attributes["points"];
if (sss1.size() == 0) {
@ -41,9 +41,9 @@ bool esvg::Polygon::parseXML(const exml::Element& _element, mat2x3& _parentTrans
Log.verbose("Parse polygon : \"" << sss << "\"");
while ('\0' != sss[0]) {
Vector2f pos(0,0);
int32_t n;
if (sscanf(sss, "%f,%f%n", &pos.m_floats[0], &pos.m_floats[1], &n) == 2) {
m_listPoint.pushBack(pos);
int n;
if (sscanf(sss, "%f,%f%n", &pos.this.floats[0], &pos.this.floats[1], &n) == 2) {
this.listPoint.pushBack(pos);
sss += n;
_sizeMax.setValue(etk::max(_sizeMax.x(), pos.x()),
etk::max(_sizeMax.y(), pos.y()));
@ -57,26 +57,26 @@ bool esvg::Polygon::parseXML(const exml::Element& _element, mat2x3& _parentTrans
return true;
}
void esvg::Polygon::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Polygon nbPoint=" << m_listPoint.size());
void esvg::Polygon::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Polygon nbPoint=" << this.listPoint.size());
}
esvg::render::Path esvg::Polygon::createPath() {
esvg::render::Path out;
out.moveTo(false, m_listPoint[0]);
for(size_t iii=1; iii< m_listPoint.size(); iii++) {
out.lineTo(false, m_listPoint[iii]);
out.moveTo(false, this.listPoint[0]);
for(size_t iii=1; iii< this.listPoint.size(); iii++) {
out.lineTo(false, this.listPoint[iii]);
}
out.close();
return out;
}
void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Polygon");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
@ -88,10 +88,10 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
if (colorFill != null) {
@ -106,10 +106,10 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -122,7 +122,7 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
@ -131,21 +131,21 @@ void esvg::Polygon::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32
void esvg::Polygon::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Polygon");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,33 +6,39 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include <etk/Vector.hpp>
#include<esvg/Base.hpp>#include<etk/Vector.hpp>
namespace esvg {
/*
enum polygonMode {
polygoneModeNonZero,
polygoneModeEvenOdd
};
*/
class Polygon : public esvg::Base {
namespace esvg{
/*
enum polygonMode {
polygoneModeNonZero,
polygoneModeEvenOdd
};
*/
class Polygon extends esvg::Base
{
private:
List<Vector2f > m_listPoint; //!< list of all point of the polygone
//enum esvg::polygonMode m_diplayMode; //!< polygone specific display mode
List<Vector2f > this.listPoint; //!< list of all point of the polygone
//enum esvg::polygonMode this.diplayMode; //!< polygone specific display mode
public:
Polygon(PaintState parentPaintState);
~Polygon();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Polygon(PaintState parentPaintState);~
Polygon();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
private:
esvg::render::Path createPath();
};
}
esvg::render::
Path createPath();
};}

View File

@ -17,9 +17,9 @@ esvg::Polyline::~Polyline() {
}
bool esvg::Polyline::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Polyline::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
// line must have a minimum size...
m_paint.strokeWidth = 1;
this.paint.strokeWidth = 1;
if (_element.exist() == false) {
return false;
}
@ -27,7 +27,7 @@ bool esvg::Polyline::parseXML(const exml::Element& _element, mat2x3& _parentTran
parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
etk::String sss1 = _element.attributes["points"];
if (sss1.size() == 0) {
@ -39,9 +39,9 @@ bool esvg::Polyline::parseXML(const exml::Element& _element, mat2x3& _parentTran
const char* sss = sss1.c_str();
while ('\0' != sss[0]) {
Vector2f pos;
int32_t n;
if (sscanf(sss, "%f,%f %n", &pos.m_floats[0], &pos.m_floats[1], &n) == 2) {
m_listPoint.pushBack(pos);
int n;
if (sscanf(sss, "%f,%f %n", &pos.this.floats[0], &pos.this.floats[1], &n) == 2) {
this.listPoint.pushBack(pos);
_sizeMax.setValue(etk::max(_sizeMax.x(), pos.x()),
etk::max(_sizeMax.y(), pos.y()));
sss += n;
@ -52,28 +52,28 @@ bool esvg::Polyline::parseXML(const exml::Element& _element, mat2x3& _parentTran
return true;
}
void esvg::Polyline::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Polyline nbPoint=" << m_listPoint.size());
void esvg::Polyline::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Polyline nbPoint=" << this.listPoint.size());
}
esvg::render::Path esvg::Polyline::createPath() {
esvg::render::Path out;
out.clear();
out.moveTo(false, m_listPoint[0]);
for(size_t iii=1; iii< m_listPoint.size(); iii++) {
out.lineTo(false, m_listPoint[iii]);
out.moveTo(false, this.listPoint[0]);
for(size_t iii=1; iii< this.listPoint.size(); iii++) {
out.lineTo(false, this.listPoint[iii]);
}
out.stop();
return out;
}
void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Polyline");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
@ -85,10 +85,10 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int3
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
if (colorFill != null) {
@ -103,10 +103,10 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int3
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -119,7 +119,7 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int3
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
@ -128,21 +128,21 @@ void esvg::Polyline::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int3
void esvg::Polyline::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Polyline");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,26 +6,32 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include <etk/Vector.hpp>
#include<esvg/Base.hpp>#include<etk/Vector.hpp>
namespace esvg {
class Polyline : public esvg::Base {
namespace esvg{
class Polyline extends esvg::Base
{
private:
List<Vector2f > m_listPoint; //!< list of all point of the polyline
List<Vector2f > this.listPoint; //!< list of all point of the polyline
public:
Polyline(PaintState _parentPaintState);
~Polyline();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Polyline(PaintState _parentPaintState);~
Polyline();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
private:
esvg::render::Path createPath();
};
}
esvg::render::
Path createPath();
};}

View File

@ -13,11 +13,11 @@
esvg::RadialGradient::RadialGradient(PaintState _parentPaintState) :
esvg::Base(_parentPaintState),
m_center(Vector2f(50,50), esvg::distance_pourcent),
m_radius(50, esvg::distance_pourcent),
m_focal(Vector2f(50,50), esvg::distance_pourcent),
m_unit(gradientUnits_objectBoundingBox),
m_spread(spreadMethod_pad) {
this.center(Vector2f(50,50), esvg::distance_pourcent),
this.radius(50, esvg::distance_pourcent),
this.focal(Vector2f(50,50), esvg::distance_pourcent),
this.unit(gradientUnits_objectBoundingBox),
this.spread(spreadMethod_pad) {
}
@ -26,43 +26,43 @@ esvg::RadialGradient::~RadialGradient() {
}
bool esvg::RadialGradient::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::RadialGradient::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
// line must have a minimum size...
//m_paint.strokeWidth = 1;
//this.paint.strokeWidth = 1;
if (_element.exist() == false) {
return false;
}
// ---------------- get unique ID ----------------
m_id = _element.attributes["id"];
this.id = _element.attributes["id"];
//parseTransform(_element);
//parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
etk::String contentX = _element.attributes["cx"];
etk::String contentY = _element.attributes["cy"];
if ( contentX != ""
&& contentY != "") {
m_center.set(contentX, contentY);
this.center.set(contentX, contentY);
}
contentX = _element.attributes["r"];
if (contentX != "") {
m_radius.set(contentX);
this.radius.set(contentX);
}
contentX = _element.attributes["fx"];
contentY = _element.attributes["fy"];
if ( contentX != ""
&& contentY != "") {
m_focal.set(contentX, contentY);
this.focal.set(contentX, contentY);
}
contentX = _element.attributes["gradientUnits"];
if (contentX == "userSpaceOnUse") {
m_unit = gradientUnits_userSpaceOnUse;
this.unit = gradientUnits_userSpaceOnUse;
} else {
m_unit = gradientUnits_objectBoundingBox;
this.unit = gradientUnits_objectBoundingBox;
if ( contentX.size() != 0
&& contentX != "objectBoundingBox") {
Log.error("Parsing error of 'gradientUnits' ==> not suported value: '" << contentX << "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox");
@ -70,20 +70,20 @@ bool esvg::RadialGradient::parseXML(const exml::Element& _element, mat2x3& _pare
}
contentX = _element.attributes["spreadMethod"];
if (contentX == "reflect") {
m_spread = spreadMethod_reflect;
this.spread = spreadMethod_reflect;
} else if (contentX == "repeat") {
m_spread = spreadMethod_repeat;
this.spread = spreadMethod_repeat;
} else {
m_spread = spreadMethod_pad;
this.spread = spreadMethod_pad;
if ( contentX.size() != 0
&& contentX != "pad") {
Log.error("Parsing error of 'spreadMethod' ==> not suported value: '" << contentX << "' not in : {reflect/repeate/pad} use pad");
}
}
// note: xlink:href is incompatible with subNode "stop"
m_href = _element.attributes["xlink:href"];
if (m_href.size() != 0) {
m_href = etk::String(m_href.begin()+1, m_href.end());
this.href = _element.attributes["xlink:href"];
if (this.href.size() != 0) {
this.href = etk::String(this.href.begin()+1, this.href.end());
}
// parse all sub node :
for(auto it : _element.nodes) {
@ -97,7 +97,7 @@ bool esvg::RadialGradient::parseXML(const exml::Element& _element, mat2x3& _pare
etk::Color<float,4> stopColor = etk::color::none;
etk::String content = child.attributes["offset"];
if (content.size()!=0) {
etk::Pair<float, enum esvg::distance> tmp = parseLength2(content);
Pair<float, enum esvg::distance> tmp = parseLength2(content);
if (tmp.second == esvg::distance_pixel) {
// special case ==> all time % then no type define ==> % in [0.0 .. 1.0]
offset = tmp.first*100.0f;
@ -119,62 +119,62 @@ bool esvg::RadialGradient::parseXML(const exml::Element& _element, mat2x3& _pare
stopColor.setA(opacity);
Log.verbose(" opacity : '" << content << "' == > " << stopColor);
}
m_data.pushBack(etk::Pair<float, etk::Color<float,4>>(offset, stopColor));
this.data.pushBack(Pair<float, etk::Color<float,4>>(offset, stopColor));
} else {
Log.error("(l " << child.getPos() << ") node not suported : '" << child.getValue() << "' must be [stop]");
}
}
if (m_data.size() != 0) {
if (m_href != "") {
if (this.data.size() != 0) {
if (this.href != "") {
Log.error("(l " << _element.getPos() << ") node can not have an xlink:href element with sub node named: stop ==> removing href");
m_href = "";
this.href = "";
}
}
return true;
}
void esvg::RadialGradient::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "RadialGradient center=" << m_center << " focal=" << m_focal << " radius=" << m_radius);
for (auto &it : m_data) {
void esvg::RadialGradient::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "RadialGradient center=" << this.center << " focal=" << this.focal << " radius=" << this.radius);
for (auto &it : this.data) {
Log.debug(spacingDist(_spacing+1) << "STOP: offset=" << it.first << " color=" << it.second);
}
}
void esvg::RadialGradient::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
void esvg::RadialGradient::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::RadialGradient");
}
const esvg::Dimension& esvg::RadialGradient::getCenter() {
return m_center;
return this.center;
}
const esvg::Dimension& esvg::RadialGradient::getFocal() {
return m_focal;
return this.focal;
}
const esvg::Dimension1D& esvg::RadialGradient::getRadius() {
return m_radius;
return this.radius;
}
const List<etk::Pair<float, etk::Color<float,4>>>& esvg::RadialGradient::getColors(esvg::Document* _document) {
if (m_href == "") {
return m_data;
const List<Pair<float, etk::Color<float,4>>>& esvg::RadialGradient::getColors(esvg::Document* _document) {
if (this.href == "") {
return this.data;
}
if (_document == null) {
Log.error("Get null input for document");
return m_data;
return this.data;
}
ememory::SharedPtr<esvg::Base> base = _document->getReference(m_href);
ememory::SharedPtr<esvg::Base> base = _document->getReference(this.href);
if (base == null) {
Log.error("Can not get base : '" << m_href << "'");
return m_data;
Log.error("Can not get base : '" << this.href << "'");
return this.data;
}
ememory::SharedPtr<esvg::RadialGradient> gradientR = ememory::dynamicPointerCast<esvg::RadialGradient>(base);
if (gradientR == null) {
ememory::SharedPtr<esvg::LinearGradient> gradientL = ememory::dynamicPointerCast<esvg::LinearGradient>(base);
if (gradientL == null) {
Log.error("Can not cast in a linear/radial gradient: '" << m_href << "' ==> wrong type");
return m_data;
Log.error("Can not cast in a linear/radial gradient: '" << this.href << "' ==> wrong type");
return this.data;
}
return gradientL->getColors(_document);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,34 +6,32 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include <esvg/gradientUnits.hpp>
#include <esvg/spreadMethod.hpp>
#include<esvg/Base.hpp>#include<esvg/gradientUnits.hpp>#include<esvg/spreadMethod.hpp>
namespace esvg {
class Document;
class RadialGradient : public esvg::Base {
namespace esvg{
class Document;
class RadialGradient extends esvg::Base
{
private:
esvg::Dimension m_center; //!< gradient position cx cy
esvg::Dimension1D m_radius; //!< Radius of the gradient
esvg::Dimension m_focal; //!< gradient Focal fx fy
esvg::Dimension this.center; //!< gradient position cx cy
esvg::Dimension1D this.radius; //!< Radius of the gradient
esvg::Dimension this.focal; //!< gradient Focal fx fy
public:
enum gradientUnits m_unit;
enum spreadMethod m_spread;
enum gradientUnits this.unit;
enum spreadMethod this.spread;
private:
etk::String m_href; //!< in case of using a single gradient in multiple gradient, the gradient is store in an other element...
List<etk::Pair<float, etk::Color<float,4>>> m_data; //!< incompatible with href
etk::String this.href; //!< in case of using a single gradient in multiple gradient, the gradient is store in an other element...
List<Pair<float, etk::Color<float,4>>> this.data; //!< incompatible with href
public:
RadialGradient(PaintState _parentPaintState);
~RadialGradient();
virtual bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
virtual void display(int32_t _spacing);
virtual void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level);
virtual boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
virtual void display(int _spacing);
virtual void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level);
public:
const esvg::Dimension& getCenter();
const esvg::Dimension& getFocal();
const esvg::Dimension1D& getRadius();
const List<etk::Pair<float, etk::Color<float,4>>>& getColors(esvg::Document* _document);
const List<Pair<float, etk::Color<float,4>>>& getColors(esvg::Document* _document);
};
}

View File

@ -10,87 +10,87 @@
#include <esvg/render/Weight.hpp>
esvg::Rectangle::Rectangle(PaintState _parentPaintState) : esvg::Base(_parentPaintState) {
m_position.setValue(0,0);
m_size.setValue(0,0);
m_roundedCorner.setValue(0,0);
this.position.setValue(0,0);
this.size.setValue(0,0);
this.roundedCorner.setValue(0,0);
}
esvg::Rectangle::~Rectangle() {
}
bool esvg::Rectangle::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Rectangle::parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
if (_element.exist() == false) {
return false;
}
m_position.setValue(0.0f, 0.0f);
m_size.setValue(0.0f, 0.0f);
m_roundedCorner.setValue(0.0f, 0.0f);
this.position.setValue(0.0f, 0.0f);
this.size.setValue(0.0f, 0.0f);
this.roundedCorner.setValue(0.0f, 0.0f);
parseTransform(_element);
parsePaintAttr(_element);
// add the property of the parrent modifications ...
m_transformMatrix *= _parentTrans;
this.transformMatrix *= _parentTrans;
parsePosition(_element, m_position, m_size);
parsePosition(_element, this.position, this.size);
etk::String content = _element.attributes["rx"];
if (content.size()!=0) {
m_roundedCorner.setX(parseLength(content));
this.roundedCorner.setX(parseLength(content));
}
content = _element.attributes["ry"];
if (content.size()!=0) {
m_roundedCorner.setY(parseLength(content));
this.roundedCorner.setY(parseLength(content));
}
_sizeMax.setValue(m_position.x() + m_size.x() + m_paint.strokeWidth,
m_position.y() + m_size.y() + m_paint.strokeWidth);
_sizeMax.setValue(this.position.x() + this.size.x() + this.paint.strokeWidth,
this.position.y() + this.size.y() + this.paint.strokeWidth);
return true;
}
void esvg::Rectangle::display(int32_t _spacing) {
Log.debug(spacingDist(_spacing) << "Rectangle : pos=" << m_position << " size=" << m_size << " corner=" << m_roundedCorner);
void esvg::Rectangle::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Rectangle : pos=" << this.position << " size=" << this.size << " corner=" << this.roundedCorner);
}
esvg::render::Path esvg::Rectangle::createPath() {
esvg::render::Path out;
out.clear();
if ( m_roundedCorner.x() == 0.0f
|| m_roundedCorner.y() == 0.0f) {
out.moveTo(false, m_position);
out.lineToH(true, m_size.x());
out.lineToV(true, m_size.y());
out.lineToH(true, -m_size.x());
if ( this.roundedCorner.x() == 0.0f
|| this.roundedCorner.y() == 0.0f) {
out.moveTo(false, this.position);
out.lineToH(true, this.size.x());
out.lineToV(true, this.size.y());
out.lineToH(true, -this.size.x());
} else {
// Rounded rectangle
out.moveTo(false, m_position + Vector2f(m_roundedCorner.x(), 0.0f));
out.lineToH(true, m_size.x()-m_roundedCorner.x()*2.0f);
out.curveTo(true, Vector2f(m_roundedCorner.x()*esvg::kappa90, 0.0f),
Vector2f(m_roundedCorner.x(), m_roundedCorner.y() * (1.0f - esvg::kappa90)),
Vector2f(m_roundedCorner.x(), m_roundedCorner.y()) );
out.lineToV(true, m_size.y()-m_roundedCorner.y()*2.0f);
out.curveTo(true, Vector2f(0.0f, m_roundedCorner.y() * esvg::kappa90),
Vector2f(-m_roundedCorner.x()* (1.0f - esvg::kappa90), m_roundedCorner.y()),
Vector2f(-m_roundedCorner.x(), m_roundedCorner.y()) );
out.lineToH(true, -(m_size.x()-m_roundedCorner.x()*2.0f));
out.curveTo(true, Vector2f(-m_roundedCorner.x()*esvg::kappa90, 0.0f),
Vector2f(-m_roundedCorner.x(), -m_roundedCorner.y() * (1.0f - esvg::kappa90)),
Vector2f(-m_roundedCorner.x(), -m_roundedCorner.y()) );
out.lineToV(true, -(m_size.y()-m_roundedCorner.y()*2.0f));
out.curveTo(true, Vector2f(0.0f, -m_roundedCorner.y() * esvg::kappa90),
Vector2f(m_roundedCorner.x()* (1.0f - esvg::kappa90), -m_roundedCorner.y()),
Vector2f(m_roundedCorner.x(), -m_roundedCorner.y()) );
out.moveTo(false, this.position + Vector2f(this.roundedCorner.x(), 0.0f));
out.lineToH(true, this.size.x()-this.roundedCorner.x()*2.0f);
out.curveTo(true, Vector2f(this.roundedCorner.x()*esvg::kappa90, 0.0f),
Vector2f(this.roundedCorner.x(), this.roundedCorner.y() * (1.0f - esvg::kappa90)),
Vector2f(this.roundedCorner.x(), this.roundedCorner.y()) );
out.lineToV(true, this.size.y()-this.roundedCorner.y()*2.0f);
out.curveTo(true, Vector2f(0.0f, this.roundedCorner.y() * esvg::kappa90),
Vector2f(-this.roundedCorner.x()* (1.0f - esvg::kappa90), this.roundedCorner.y()),
Vector2f(-this.roundedCorner.x(), this.roundedCorner.y()) );
out.lineToH(true, -(this.size.x()-this.roundedCorner.x()*2.0f));
out.curveTo(true, Vector2f(-this.roundedCorner.x()*esvg::kappa90, 0.0f),
Vector2f(-this.roundedCorner.x(), -this.roundedCorner.y() * (1.0f - esvg::kappa90)),
Vector2f(-this.roundedCorner.x(), -this.roundedCorner.y()) );
out.lineToV(true, -(this.size.y()-this.roundedCorner.y()*2.0f));
out.curveTo(true, Vector2f(0.0f, -this.roundedCorner.y() * esvg::kappa90),
Vector2f(this.roundedCorner.x()* (1.0f - esvg::kappa90), -this.roundedCorner.y()),
Vector2f(this.roundedCorner.x(), -this.roundedCorner.y()) );
}
out.close();
return out;
}
void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Rectangle: fill=" << m_paint.fill.first << "/" << m_paint.fill.second
<< " stroke=" << m_paint.stroke.first << "/" << m_paint.stroke.second);
void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
Log.verbose(spacingDist(_level) << "DRAW esvg::Rectangle: fill=" << this.paint.fill.first << "/" << this.paint.fill.second
<< " stroke=" << this.paint.stroke.first << "/" << this.paint.stroke.second);
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
@ -102,10 +102,10 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int
esvg::render::SegmentList listSegmentStroke;
esvg::render::Weight tmpFill;
esvg::render::Weight tmpStroke;
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(m_paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorFill = esvg::render::createColor(this.paint.fill, mtx);
ememory::SharedPtr<esvg::render::DynamicColor> colorStroke;
if (m_paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(m_paint.stroke, mtx);
if (this.paint.strokeWidth > 0.0f) {
colorStroke = esvg::render::createColor(this.paint.stroke, mtx);
}
// Check if we need to display background
if (colorFill != null) {
@ -120,10 +120,10 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int
// check if we need to display stroke:
if (colorStroke != null) {
listSegmentStroke.createSegmentListStroke(listPoints,
m_paint.strokeWidth,
m_paint.lineCap,
m_paint.lineJoin,
m_paint.miterLimit);
this.paint.strokeWidth,
this.paint.lineCap,
this.paint.lineJoin,
this.paint.miterLimit);
colorStroke->setViewPort(listSegmentStroke.getViewPort());
listSegmentStroke.applyMatrix(mtx);
// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
@ -136,7 +136,7 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int
colorFill,
tmpStroke,
colorStroke,
m_paint.opacity);
this.paint.opacity);
#ifdef DEBUG
_myRenderer.addDebugSegment(listSegmentFill);
_myRenderer.addDebugSegment(listSegmentStroke);
@ -145,21 +145,21 @@ void esvg::Rectangle::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int
void esvg::Rectangle::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW Shape esvg::Rectangle");
esvg::render::Path listElement = createPath();
mat2x3 mtx = m_transformMatrix;
mat2x3 mtx = this.transformMatrix;
mtx *= _basicTrans;
esvg::render::PointList listPoints;
listPoints = listElement.generateListPoints(_level, _recurtionMax, _threshold);
listPoints.applyMatrix(mtx);
for (auto &it : listPoints.m_data) {
for (auto &it : listPoints.this.data) {
List<Vector2f> listPoint;
for (auto &itDot : it) {
listPoint.pushBack(itDot.m_pos);
listPoint.pushBack(itDot.this.pos);
}
_out.pushBack(listPoint);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,27 +6,34 @@
*/
#pragma once
#include <esvg/Base.hpp>
#include<esvg/Base.hpp>
namespace esvg {
class Rectangle : public esvg::Base {
namespace esvg{
class Rectangle extends esvg::Base
{
private:
Vector2f m_position; //!< position of the rectangle
Vector2f m_size; //!< size of the rectangle
Vector2f m_roundedCorner; //!< property of the rounded corner
Vector2f this.position; //!< position of the rectangle
Vector2f this.size; //!< size of the rectangle
Vector2f this.roundedCorner; //!< property of the rounded corner
public:
Rectangle(PaintState _parentPaintState);
~Rectangle();
bool parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(int32_t _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
Rectangle(PaintState _parentPaintState);~
Rectangle();
boolean parseXML(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) override;
void display(final int _spacing) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) override;
void drawShapePoints(List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
private:
esvg::render::Path createPath();
};
}
esvg::render::
Path createPath();
};}

View File

@ -9,26 +9,26 @@
#include <etk/uri/Uri.hpp>
#include <etk/uri/provider/provider.hpp>
esvg::Renderer::Renderer(const Vector2i& _size, esvg::Document* _document, bool _visualDebug) :
esvg::Renderer::Renderer(const Vector2i& _size, esvg::Document* _document, boolean _visualDebug) :
#ifdef DEBUG
m_visualDebug(_visualDebug),
m_factor(1),
this.visualDebug(_visualDebug),
this.factor(1),
#endif
m_interpolationRecurtionMax(10),
m_interpolationThreshold(0.25f),
m_nbSubScanLine(8),
m_document(_document) {
this.interpolationRecurtionMax(10),
this.interpolationThreshold(0.25f),
this.nbSubScanLine(8),
this.document(_document) {
#ifdef DEBUG
if (m_visualDebug == true) {
m_factor = 20;
if (this.visualDebug == true) {
this.factor = 20;
}
#endif
setSize(_size);
}
esvg::Renderer::~Renderer() {
m_buffer.clear();
m_size = Vector2i(0,0);
this.buffer.clear();
this.size = Vector2i(0,0);
}
etk::Color<float,4> esvg::Renderer::mergeColor(etk::Color<float,4> _base, etk::Color<float,4> _integration) {
@ -59,16 +59,16 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
ememory::SharedPtr<esvg::render::DynamicColor>& _colorStroke,
float _opacity) {
if (_colorFill != null) {
//_colorFill->setViewPort(etk::Pair<Vector2f, Vector2f>(Vector2f(0,0), Vector2f(sizeX, sizeY)));
_colorFill->generate(m_document);
//_colorFill->setViewPort(Pair<Vector2f, Vector2f>(Vector2f(0,0), Vector2f(sizeX, sizeY)));
_colorFill->generate(this.document);
}
if (_colorStroke != null) {
//_colorStroke->setViewPort(etk::Pair<Vector2f, Vector2f>(Vector2f(0,0), Vector2f(sizeX, sizeY)));
_colorStroke->generate(m_document);
//_colorStroke->setViewPort(Pair<Vector2f, Vector2f>(Vector2f(0,0), Vector2f(sizeX, sizeY)));
_colorStroke->generate(this.document);
}
// all together
for (int32_t yyy=0; yyy<m_size.y(); ++yyy) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
for (int yyy=0; yyy<this.size.y(); ++yyy) {
for (int xxx=0; xxx<this.size.x(); ++xxx) {
Vector2i pos(xxx, yyy);
float valueFill = _weightFill.get(pos);
float valueStroke = _weightStroke.get(pos);
@ -88,14 +88,14 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
etk::Color<float,4> intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
intermediateColor.setA(intermediateColor.a() * _opacity);
#if DEBUG
for (int32_t deltaY=0; deltaY<m_factor; ++deltaY) {
for (int32_t deltaX=0; deltaX<m_factor; ++deltaX) {
int32_t id = m_size.x()*m_factor*(yyy*m_factor+deltaY) + (xxx*m_factor+deltaX);
m_buffer[id] = mergeColor(m_buffer[id], intermediateColor);
for (int deltaY=0; deltaY<this.factor; ++deltaY) {
for (int deltaX=0; deltaX<this.factor; ++deltaX) {
int id = this.size.x()*this.factor*(yyy*this.factor+deltaY) + (xxx*this.factor+deltaX);
this.buffer[id] = mergeColor(this.buffer[id], intermediateColor);
}
}
#else
m_buffer[m_size.x()*yyy + xxx] = mergeColor(m_buffer[m_size.x()*yyy + xxx], intermediateColor);
this.buffer[this.size.x()*yyy + xxx] = mergeColor(this.buffer[this.size.x()*yyy + xxx], intermediateColor);
#endif
}
}
@ -105,28 +105,28 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
if (tmpColor != null) {
esvg::render::SegmentList listSegment;
// Display bounding box
listSegment.addSegment(esvg::render::Point(tmpColor->m_viewPort.first),
esvg::render::Point(Vector2f(tmpColor->m_viewPort.first.x(), tmpColor->m_viewPort.second.y()) ),
listSegment.addSegment(esvg::render::Point(tmpColor->this.viewPort.first),
esvg::render::Point(Vector2f(tmpColor->this.viewPort.first.x(), tmpColor->this.viewPort.second.y()) ),
false);
listSegment.addSegment(esvg::render::Point(Vector2f(tmpColor->m_viewPort.first.x(), tmpColor->m_viewPort.second.y()) ),
esvg::render::Point(tmpColor->m_viewPort.second),
listSegment.addSegment(esvg::render::Point(Vector2f(tmpColor->this.viewPort.first.x(), tmpColor->this.viewPort.second.y()) ),
esvg::render::Point(tmpColor->this.viewPort.second),
false);
listSegment.addSegment(esvg::render::Point(tmpColor->m_viewPort.second),
esvg::render::Point(Vector2f(tmpColor->m_viewPort.second.x(), tmpColor->m_viewPort.first.y()) ),
listSegment.addSegment(esvg::render::Point(tmpColor->this.viewPort.second),
esvg::render::Point(Vector2f(tmpColor->this.viewPort.second.x(), tmpColor->this.viewPort.first.y()) ),
false);
listSegment.addSegment(esvg::render::Point(Vector2f(tmpColor->m_viewPort.second.x(), tmpColor->m_viewPort.first.y()) ),
esvg::render::Point(tmpColor->m_viewPort.first),
listSegment.addSegment(esvg::render::Point(Vector2f(tmpColor->this.viewPort.second.x(), tmpColor->this.viewPort.first.y()) ),
esvg::render::Point(tmpColor->this.viewPort.first),
false);
listSegment.applyMatrix(tmpColor->m_matrix);
listSegment.applyMatrix(tmpColor->this.matrix);
// display the gradient axis
listSegment.addSegment(esvg::render::Point(tmpColor->m_pos1),
esvg::render::Point(tmpColor->m_pos2),
listSegment.addSegment(esvg::render::Point(tmpColor->this.pos1),
esvg::render::Point(tmpColor->this.pos2),
false);
/*
mat2x3 m_matrix;
etk::Pair<Vector2f, Vector2f> m_viewPort;
Vector2f m_pos1;
Vector2f m_pos2;
mat2x3 this.matrix;
Pair<Vector2f, Vector2f> this.viewPort;
Vector2f this.pos1;
Vector2f this.pos2;
*/
addDebugSegment(listSegment);
}
@ -135,17 +135,17 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
#ifdef DEBUG
void esvg::Renderer::addDebugSegment(const esvg::render::SegmentList& _listSegment) {
if (m_visualDebug == false) {
if (this.visualDebug == false) {
return;
}
Vector2i dynamicSize = m_size * m_factor;
Vector2i dynamicSize = this.size * this.factor;
// for each lines:
for (int32_t yyy=0; yyy<dynamicSize.y(); ++yyy) {
for (int yyy=0; yyy<dynamicSize.y(); ++yyy) {
// Reduce the number of lines in the subsampling parsing:
List<esvg::render::Segment> availlableSegmentPixel;
for (auto &it : _listSegment.m_data) {
if ( it.p0.y() * m_factor <= float(yyy+1)
&& it.p1.y() * m_factor >= float(yyy)) {
for (auto &it : _listSegment.this.data) {
if ( it.p0.y() * this.factor <= float(yyy+1)
&& it.p1.y() * this.factor >= float(yyy)) {
availlableSegmentPixel.pushBack(it);
}
}
@ -154,40 +154,40 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
List<esvg::render::Segment> availlableSegment;
// find in the subList ...
for (auto &it : availlableSegmentPixel) {
if ( it.p0.y() * m_factor <= subSamplingCenterPos
&& it.p1.y() * m_factor >= subSamplingCenterPos ) {
if ( it.p0.y() * this.factor <= subSamplingCenterPos
&& it.p1.y() * this.factor >= subSamplingCenterPos ) {
availlableSegment.pushBack(it);
}
}
// x position, angle
List<etk::Pair<float, float>> listPosition;
List<Pair<float, float>> listPosition;
for (auto &it : availlableSegment) {
Vector2f delta = it.p0 * m_factor - it.p1 * m_factor;
Vector2f delta = it.p0 * this.factor - it.p1 * this.factor;
// x = coefficent*y+bbb;
float coefficient = delta.x()/delta.y();
float bbb = it.p0.x() * m_factor - coefficient*it.p0.y() * m_factor;
float bbb = it.p0.x() * this.factor - coefficient*it.p0.y() * this.factor;
float xpos = coefficient * subSamplingCenterPos + bbb;
if ( xpos >= 0
&& xpos < dynamicSize.x()
&& yyy >= 0
&& yyy < dynamicSize.y() ) {
if (it.direction == 1.0f) {
m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))] = etk::color::blue;
this.buffer[(dynamicSize.x()*yyy + int(xpos))] = etk::color::blue;
} else {
m_buffer[(dynamicSize.x()*yyy + int32_t(xpos))] = etk::color::darkRed;
this.buffer[(dynamicSize.x()*yyy + int(xpos))] = etk::color::darkRed;
}
}
}
}
// for each colomn:
for (int32_t xxx=0; xxx<dynamicSize.x(); ++xxx) {
for (int xxx=0; xxx<dynamicSize.x(); ++xxx) {
// Reduce the number of lines in the subsampling parsing:
List<esvg::render::Segment> availlableSegmentPixel;
for (auto &it : _listSegment.m_data) {
if ( ( it.p0.x() * m_factor <= float(xxx+1)
&& it.p1.x() * m_factor >= float(xxx) )
|| ( it.p0.x() * m_factor >= float(xxx+1)
&& it.p1.x() * m_factor <= float(xxx) ) ) {
for (auto &it : _listSegment.this.data) {
if ( ( it.p0.x() * this.factor <= float(xxx+1)
&& it.p1.x() * this.factor >= float(xxx) )
|| ( it.p0.x() * this.factor >= float(xxx+1)
&& it.p1.x() * this.factor <= float(xxx) ) ) {
availlableSegmentPixel.pushBack(it);
}
}
@ -196,32 +196,32 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
List<esvg::render::Segment> availlableSegment;
// find in the subList ...
for (auto &it : availlableSegmentPixel) {
if ( ( it.p0.x() * m_factor <= subSamplingCenterPos
&& it.p1.x() * m_factor >= subSamplingCenterPos)
|| ( it.p0.x() * m_factor >= subSamplingCenterPos
&& it.p1.x() * m_factor <= subSamplingCenterPos) ) {
if ( ( it.p0.x() * this.factor <= subSamplingCenterPos
&& it.p1.x() * this.factor >= subSamplingCenterPos)
|| ( it.p0.x() * this.factor >= subSamplingCenterPos
&& it.p1.x() * this.factor <= subSamplingCenterPos) ) {
availlableSegment.pushBack(it);
}
}
// x position, angle
List<etk::Pair<float, float>> listPosition;
List<Pair<float, float>> listPosition;
for (auto &it : availlableSegment) {
Vector2f delta = it.p0 * m_factor - it.p1 * m_factor;
Vector2f delta = it.p0 * this.factor - it.p1 * this.factor;
// x = coefficent*y+bbb;
if (delta.x() == 0) {
continue;
}
float coefficient = delta.y()/delta.x();
float bbb = it.p0.y() * m_factor - coefficient*it.p0.x() * m_factor;
float bbb = it.p0.y() * this.factor - coefficient*it.p0.x() * this.factor;
float ypos = coefficient * subSamplingCenterPos + bbb;
if ( ypos >= 0
&& ypos < dynamicSize.y()
&& xxx >= 0
&& xxx < dynamicSize.y() ) {
if (it.direction == 1.0f) {
m_buffer[(dynamicSize.x()*int32_t(ypos) + xxx)] = etk::color::blue;
this.buffer[(dynamicSize.x()*int(ypos) + xxx)] = etk::color::blue;
} else {
m_buffer[(dynamicSize.x()*int32_t(ypos) + xxx)] = etk::color::darkRed;
this.buffer[(dynamicSize.x()*int(ypos) + xxx)] = etk::color::darkRed;
}
}
}
@ -231,7 +231,7 @@ void esvg::Renderer::print(const esvg::render::Weight& _weightFill,
void esvg::Renderer::writePPM(const etk::Uri& _uri) {
if (m_buffer.size() == 0) {
if (this.buffer.size() == 0) {
return;
}
auto fileIo = etk::uri::get(_uri);
@ -243,18 +243,18 @@ void esvg::Renderer::writePPM(const etk::Uri& _uri) {
Log.error("Can not open (r) the file : " << _uri);
return;
}
int32_t sizeX = m_size.x();
int32_t sizeY = m_size.y();
int sizeX = this.size.x();
int sizeY = this.size.y();
#if DEBUG
sizeX *= m_factor;
sizeY *= m_factor;
sizeX *= this.factor;
sizeY *= this.factor;
#endif
Log.debug("Generate ppm : " << m_size << " debug size=" << Vector2i(sizeX,sizeY));
Log.debug("Generate ppm : " << this.size << " debug size=" << Vector2i(sizeX,sizeY));
char tmpValue[1024];
sprintf(tmpValue, "P6 %d %d 255 ", sizeX, sizeY);
fileIo->write(tmpValue,1,sizeof(tmpValue));
for (int32_t iii=0 ; iii<sizeX*sizeY; iii++) {
etk::Color<uint8_t,3> tmp = m_buffer[iii];
for (int iii=0 ; iii<sizeX*sizeY; iii++) {
etk::Color<uint8_t,3> tmp = this.buffer[iii];
fileIo->write(&tmp, 1, 3);
}
fileIo->close();
@ -264,39 +264,39 @@ extern "C" {
#pragma pack(push,1)
struct bitmapFileHeader {
int16_t bfType;
int32_t bfSize;
int32_t bfReserved;
int32_t bfOffBits;
int bfSize;
int bfReserved;
int bfOffBits;
};
struct bitmapInfoHeader {
int32_t biSize;
int32_t biWidth;
int32_t biHeight;
int biSize;
int biWidth;
int biHeight;
int16_t biPlanes;
int16_t biBitCount;
int32_t biCompression;
int32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
int biCompression;
int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
#ifndef PLOPPP
int32_t biClrUsed;
int32_t biClrImportant;
int biClrUsed;
int biClrImportant;
#else
// https://en.wikipedia.org/wiki/BMP_file_format / example 2
int32_t biPaletteNumber;
int32_t biImportantColor;
int32_t biBitMaskRed;
int32_t biBitMaskGreen;
int32_t biBitMaskBlue;
int32_t biBitMaskAlpha;
int32_t biLCSColorSpace;
int32_t biUnused[16];
int biPaletteNumber;
int biImportantColor;
int biBitMaskRed;
int biBitMaskGreen;
int biBitMaskBlue;
int biBitMaskAlpha;
int biLCSColorSpace;
int biUnused[16];
#endif
};
#pragma pack(pop)
}
void esvg::Renderer::writeBMP(const etk::Uri& _uri) {
if (m_buffer.size() == 0) {
if (this.buffer.size() == 0) {
return;
}
auto fileIo = etk::uri::get(_uri);
@ -311,11 +311,11 @@ void esvg::Renderer::writeBMP(const etk::Uri& _uri) {
struct bitmapFileHeader fileHeader;
struct bitmapInfoHeader infoHeader;
int32_t sizeX = m_size.x();
int32_t sizeY = m_size.y();
int sizeX = this.size.x();
int sizeY = this.size.y();
#if DEBUG
sizeX *= m_factor;
sizeY *= m_factor;
sizeX *= this.factor;
sizeY *= this.factor;
#endif
fileHeader.bfType = 0x4D42;
@ -348,7 +348,7 @@ void esvg::Renderer::writeBMP(const etk::Uri& _uri) {
infoHeader.biBitMaskBlue =0x0000FF00;
infoHeader.biBitMaskAlpha = 0x000000FF;
infoHeader.biLCSColorSpace = 0x73524742; // "Win "
for (int32_t jjj=0; jjj<16; ++jjj) {
for (int jjj=0; jjj<16; ++jjj) {
infoHeader.biUnused[jjj] = 0;
}
infoHeader.biUnused[12] = 0x00000002;
@ -358,9 +358,9 @@ void esvg::Renderer::writeBMP(const etk::Uri& _uri) {
fileIo->write(&infoHeader, sizeof(struct bitmapInfoHeader), 1);
uint8_t data[16];
for(int32_t yyy=sizeY-1; yyy>=0; --yyy) {
for(int32_t xxx=0; xxx<sizeX; ++xxx) {
const etk::Color<uint8_t,4>& tmpColor = m_buffer[sizeX*yyy + xxx];
for(int yyy=sizeY-1; yyy>=0; --yyy) {
for(int xxx=0; xxx<sizeX; ++xxx) {
const etk::Color<uint8_t,4>& tmpColor = this.buffer[sizeX*yyy + xxx];
uint8_t* pointer = data;
#ifndef PLOPPP
*pointer++ = tmpColor.a();
@ -381,47 +381,47 @@ void esvg::Renderer::writeBMP(const etk::Uri& _uri) {
void esvg::Renderer::setSize(const Vector2i& _size) {
m_size = _size;
m_buffer.resize(m_size.x() * m_size.y()
this.size = _size;
this.buffer.resize(this.size.x() * this.size.y()
#if DEBUG
* m_factor * m_factor
* this.factor * this.factor
#endif
, etk::color::none);
}
const Vector2i& esvg::Renderer::getSize() const {
return m_size;
return this.size;
}
List<etk::Color<float,4>> esvg::Renderer::getData() {
return m_buffer;
return this.buffer;
}
void esvg::Renderer::setInterpolationRecurtionMax(int32_t _value) {
m_interpolationRecurtionMax = etk::avg(1, _value, 200);
void esvg::Renderer::setInterpolationRecurtionMax(int _value) {
this.interpolationRecurtionMax = etk::avg(1, _value, 200);
}
int32_t esvg::Renderer::getInterpolationRecurtionMax() const {
return m_interpolationRecurtionMax;
int esvg::Renderer::getInterpolationRecurtionMax() const {
return this.interpolationRecurtionMax;
}
void esvg::Renderer::setInterpolationThreshold(float _value) {
m_interpolationThreshold = etk::avg(0.0f, _value, 20000.0f);
this.interpolationThreshold = etk::avg(0.0f, _value, 20000.0f);
}
float esvg::Renderer::getInterpolationThreshold() const {
return m_interpolationThreshold;
return this.interpolationThreshold;
}
void esvg::Renderer::setNumberSubScanLine(int32_t _value) {
m_nbSubScanLine = etk::avg(1, _value, 200);
void esvg::Renderer::setNumberSubScanLine(int _value) {
this.nbSubScanLine = etk::avg(1, _value, 200);
}
int32_t esvg::Renderer::getNumberSubScanLine() const {
return m_nbSubScanLine;
int esvg::Renderer::getNumberSubScanLine() const {
return this.nbSubScanLine;
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,69 +6,78 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/Color.hpp>
#include <esvg/render/Weight.hpp>
#include <esvg/render/DynamicColor.hpp>
#include <etk/uri/uri.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<etk/Color.hpp>#include<esvg/render/Weight.hpp>#include<esvg/render/DynamicColor.hpp>#include<etk/uri/uri.hpp>
namespace esvg {
class Document;
class Renderer {
namespace esvg{
class Document;
class Renderer {
#ifdef DEBUG
private:
bool m_visualDebug;
int32_t m_factor;
boolean this.visualDebug;
int this.factor;
#endif
public:
Renderer(const Vector2i& _size, esvg::Document* _document, bool _visualDebug=false);
Renderer(const Vector2i& _size, esvg::Document* _document, boolean _visualDebug=false);
~Renderer();
protected:
Vector2i m_size;
Vector2i this.size;
public:
void setSize(const Vector2i& _size);
void setSize(const Vector2i& _size);
const Vector2i& getSize() const;
protected:
List<etk::Color<float,4>> m_buffer;
List<etk::Color<float,4>> this.buffer;
public:
List<etk::Color<float,4>> getData();
protected:
int32_t m_interpolationRecurtionMax;
int this.interpolationRecurtionMax;
public:
void setInterpolationRecurtionMax(int32_t _value);
int32_t getInterpolationRecurtionMax() const;
void setInterpolationRecurtionMax(int _value);
int getInterpolationRecurtionMax() const;
protected:
float m_interpolationThreshold;
float this.interpolationThreshold;
public:
void setInterpolationThreshold(float _value);
float getInterpolationThreshold() const;
void setInterpolationThreshold(float _value);
float getInterpolationThreshold() const;
protected:
int32_t m_nbSubScanLine;
int this.nbSubScanLine;
public:
void setNumberSubScanLine(int32_t _value);
int32_t getNumberSubScanLine() const;
void setNumberSubScanLine(int _value);
int getNumberSubScanLine() const;
public:
void writePPM(const etk::Uri& _uri);
void writeBMP(const etk::Uri& _uri);
void writePPM(const etk::Uri& _uri);
void writeBMP(const etk::Uri& _uri);
protected:
etk::Color<float,4> mergeColor(etk::Color<float,4> _base, etk::Color<float,4> _integration);
public:
void print(const esvg::render::Weight& _weightFill,
void print(const esvg::render::Weight& _weightFill,
ememory::SharedPtr<esvg::render::DynamicColor>& _colorFill,
const esvg::render::Weight& _weightStroke,
ememory::SharedPtr<esvg::render::DynamicColor>& _colorStroke,
float _opacity);
#ifdef DEBUG
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
void addDebug(const List<etk::Pair<Vector2f,Vector2f>>& _info);
void addDebugSegment(const esvg::render::SegmentList& _listSegment);
void addDebug(const List<Pair<Vector2f,Vector2f>>& _info);
#endif
protected:
esvg::Document* m_document;
esvg::Document* this.document;
public:
esvg::Document* getMainDocument() {
return m_document;
esvg::Document*
getMainDocument() {
return this.document;
}
};
}

View File

@ -0,0 +1,13 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
enum SpreadMethod {
PAD,
REFLECT,
REPEAT
};

View File

@ -15,13 +15,13 @@ esvg::Text::~Text() {
}
bool esvg::Text::parse(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
boolean esvg::Text::parse(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax) {
_sizeMax.setValue(0,0);
Log.error("NOT IMPLEMENTED");
return false;
}
void esvg::Text::display(int32_t _spacing) {
void esvg::Text::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Text");
}

View File

@ -1,19 +1,25 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <esvg/Base.hpp>
namespace esvg {
class Text : public esvg::Base {
public:
Text(PaintState _parentPaintState);
~Text();
bool parse(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax);
void display(int32_t _spacing) override;
};
class Text extends Base {
public Text(final PaintState _parentPaintState) {
super(_parentPaintState);
}
@Override
public boolean parse(const exml::Element& _element, mat2x3& _parentTrans, Vector2f& _sizeMax)
_sizeMax.setValue(0,0);
Log.error("NOT IMPLEMENTED");
return false;
}
@Override
public void display(final int _spacing) {
Log.debug(spacingDist(_spacing) << "Text");
}
}

View File

@ -1,22 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <etk/Stream.hpp>
namespace esvg {
enum cap {
cap_butt,
cap_round,
cap_square
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
etk::Stream& operator <<(etk::Stream& _os, enum esvg::cap _obj);
}

View File

@ -6,8 +6,8 @@
#include <esvg/debug.hpp>
int32_t esvg::getLogId() {
static int32_t g_val = elog::registerInstance("esvg");
int esvg::getLogId() {
static int g_val = elog::registerInstance("esvg");
return g_val;
}

View File

@ -20,10 +20,10 @@
#include <esvg/RadialGradient.hpp>
esvg::Document::Document() {
m_uri = "";
m_version = "0.0";
m_loadOK = false;
m_size.setValue(0,0);
this.uri = "";
this.version = "0.0";
this.loadOK = false;
this.size.setValue(0,0);
}
esvg::Document::~Document() {
@ -33,48 +33,48 @@ esvg::Document::~Document() {
void esvg::Document::displayDebug() {
Log.debug("Main SVG: size=" << m_size);
Log.debug("Main SVG: size=" << this.size);
Log.debug(" refs:");
for (size_t iii=0; iii<m_refList.size(); iii++) {
if (m_refList[iii] != null) {
m_refList[iii]->display(2);
for (size_t iii=0; iii<this.refList.size(); iii++) {
if (this.refList[iii] != null) {
this.refList[iii]->display(2);
}
}
Log.debug(" Nodes:");
for (size_t iii=0; iii<m_subElementList.size(); iii++) {
if (m_subElementList[iii] != null) {
m_subElementList[iii]->display(2);
for (size_t iii=0; iii<this.subElementList.size(); iii++) {
if (this.subElementList[iii] != null) {
this.subElementList[iii]->display(2);
}
}
}
void esvg::Document::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level) {
for (size_t iii=0; iii<m_subElementList.size(); iii++) {
if (m_subElementList[iii] != null) {
m_subElementList[iii]->draw(_myRenderer, _basicTrans);
void esvg::Document::draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level) {
for (size_t iii=0; iii<this.subElementList.size(); iii++) {
if (this.subElementList[iii] != null) {
this.subElementList[iii]->draw(_myRenderer, _basicTrans);
}
}
}
// FOR TEST only ...
void esvg::Document::generateAnImage(const etk::Uri& _uri, bool _visualDebug) {
generateAnImage(m_size, _uri, _visualDebug);
void esvg::Document::generateAnImage(const etk::Uri& _uri, boolean _visualDebug) {
generateAnImage(this.size, _uri, _visualDebug);
}
void esvg::Document::generateAnImage(const Vector2i& _size, const etk::Uri& _uri, bool _visualDebug) {
void esvg::Document::generateAnImage(const Vector2i& _size, const etk::Uri& _uri, boolean _visualDebug) {
Vector2i sizeRender = _size;
if (sizeRender.x() <= 0) {
sizeRender.setX(m_size.x());
sizeRender.setX(this.size.x());
}
if (sizeRender.y() <= 0) {
sizeRender.setY(m_size.y());
sizeRender.setY(this.size.y());
}
Log.debug("Generate size " << sizeRender);
ememory::SharedPtr<esvg::Renderer> renderedElement = ememory::makeShared<esvg::Renderer>(sizeRender, this, _visualDebug);
// create the first element matrix modification ...
mat2x3 basicTrans;
basicTrans *= etk::mat2x3Scale(Vector2f(sizeRender.x()/m_size.x(), sizeRender.y()/m_size.y()));
basicTrans *= etk::mat2x3Scale(Vector2f(sizeRender.x()/this.size.x(), sizeRender.y()/this.size.y()));
draw(*renderedElement, basicTrans);
@ -90,16 +90,16 @@ void esvg::Document::generateAnImage(const Vector2i& _size, const etk::Uri& _uri
List<etk::Color<float,4>> esvg::Document::renderImageFloatRGBA(Vector2i& _size) {
if (_size.x() <= 0) {
_size.setX(m_size.x());
_size.setX(this.size.x());
}
if (_size.y() <= 0) {
_size.setY(m_size.y());
_size.setY(this.size.y());
}
Log.debug("Generate size " << _size);
ememory::SharedPtr<esvg::Renderer> renderedElement = ememory::makeShared<esvg::Renderer>(_size, this);
// create the first element matrix modification ...
mat2x3 basicTrans;
basicTrans *= etk::mat2x3Scale(Vector2f(_size.x()/m_size.x(), _size.y()/m_size.y()));
basicTrans *= etk::mat2x3Scale(Vector2f(_size.x()/this.size.x(), _size.y()/this.size.y()));
draw(*renderedElement, basicTrans);
// direct return the generated data ...
@ -140,73 +140,73 @@ List<etk::Color<uint8_t,3>> esvg::Document::renderImageU8RGB(Vector2i& _size) {
}
void esvg::Document::clear() {
m_uri = "";
m_version = "0.0";
m_loadOK = true;
m_paint.clear();
m_size.setValue(0,0);
this.uri = "";
this.version = "0.0";
this.loadOK = true;
this.paint.clear();
this.size.setValue(0,0);
}
bool esvg::Document::parse(const etk::String& _data) {
boolean esvg::Document::parse(const etk::String& _data) {
clear();
exml::Document doc;
if (doc.parse(_data) == false) {
Log.error("Error occured when loading SVG: " << m_uri);
m_loadOK = false;
return m_loadOK;
Log.error("Error occured when loading SVG: " << this.uri);
this.loadOK = false;
return this.loadOK;
}
if (doc.nodes.size() == 0) {
Log.error("(l ?) No nodes in the SVG file ... '" << m_uri << "'");
m_loadOK = false;
return m_loadOK;
Log.error("(l ?) No nodes in the SVG file ... '" << this.uri << "'");
this.loadOK = false;
return this.loadOK;
}
exml::Element root = doc.nodes["svg"];
if (root.exist() == false) {
Log.error("(l ?) main node not find: 'svg' in '" << m_uri << "'");
m_loadOK = false;
return m_loadOK;
Log.error("(l ?) main node not find: 'svg' in '" << this.uri << "'");
this.loadOK = false;
return this.loadOK;
}
cleanStyleProperty(root);
m_loadOK = parseXMLData(root);
return m_loadOK;
this.loadOK = parseXMLData(root);
return this.loadOK;
}
bool esvg::Document::generate(etk::String& _data) {
boolean esvg::Document::generate(etk::String& _data) {
return false;
}
bool esvg::Document::load(const etk::Uri& _uri) {
boolean esvg::Document::load(const etk::Uri& _uri) {
clear();
m_uri = _uri;
this.uri = _uri;
exml::Document doc;
if (doc.load(m_uri) == false) {
Log.error("Error occured when loading SVG : " << m_uri);
m_loadOK = false;
return m_loadOK;
if (doc.load(this.uri) == false) {
Log.error("Error occured when loading SVG : " << this.uri);
this.loadOK = false;
return this.loadOK;
}
if (doc.nodes.size() == 0) {
Log.error("(l ?) No nodes in the SVG file ... '" << m_uri << "'");
m_loadOK = false;
return m_loadOK;
Log.error("(l ?) No nodes in the SVG file ... '" << this.uri << "'");
this.loadOK = false;
return this.loadOK;
}
exml::Element root = doc.nodes["svg"];
if (root.exist() == false) {
Log.error("(l ?) main node not find: 'svg' in '" << m_uri << "'");
m_loadOK = false;
return m_loadOK;
Log.error("(l ?) main node not find: 'svg' in '" << this.uri << "'");
this.loadOK = false;
return this.loadOK;
}
cleanStyleProperty(root);
m_loadOK = parseXMLData(root);
return m_loadOK;
this.loadOK = parseXMLData(root);
return this.loadOK;
}
bool esvg::Document::store(const etk::Uri& _uri) {
boolean esvg::Document::store(const etk::Uri& _uri) {
Log.todo("not implemented store in SVG...");
return false;
}
bool esvg::Document::cleanStyleProperty(const exml::Element& _root) {
boolean esvg::Document::cleanStyleProperty(const exml::Element& _root) {
// for each nodes:
for(auto it: _root.nodes) {
exml::Element child = it.toElement();
@ -237,16 +237,16 @@ bool esvg::Document::cleanStyleProperty(const exml::Element& _root) {
return true;
}
bool esvg::Document::parseXMLData(const exml::Element& _root, bool _isReference) {
boolean esvg::Document::parseXMLData(const exml::Element& _root, boolean _isReference) {
// get the svg version :
m_version = _root.attributes["version"];
this.version = _root.attributes["version"];
// parse ...
Vector2f pos(0,0);
if (_isReference == false) {
parseTransform(_root);
parsePosition(_root, pos, m_size);
parsePosition(_root, pos, this.size);
parsePaintAttr(_root);
Log.verbose("parsed .ROOT trans: " << m_transformMatrix);
Log.verbose("parsed .ROOT trans: " << this.transformMatrix);
} else {
Log.verbose("Parse Reference section ... (no attibute)");
}
@ -261,49 +261,49 @@ bool esvg::Document::parseXMLData(const exml::Element& _root, bool _isReference)
}
ememory::SharedPtr<esvg::Base> elementParser;
if (child.getValue() == "g") {
elementParser = ememory::makeShared<esvg::Group>(m_paint);
elementParser = ememory::makeShared<esvg::Group>(this.paint);
} else if (child.getValue() == "a") {
Log.info("Note : 'a' balise is parsed like a g balise ...");
elementParser = ememory::makeShared<esvg::Group>(m_paint);
elementParser = ememory::makeShared<esvg::Group>(this.paint);
} else if (child.getValue() == "title") {
m_title = "TODO : set the title here ...";
this.title = "TODO : set the title here ...";
continue;
} else if (child.getValue() == "path") {
elementParser = ememory::makeShared<esvg::Path>(m_paint);
elementParser = ememory::makeShared<esvg::Path>(this.paint);
} else if (child.getValue() == "rect") {
elementParser = ememory::makeShared<esvg::Rectangle>(m_paint);
elementParser = ememory::makeShared<esvg::Rectangle>(this.paint);
} else if (child.getValue() == "circle") {
elementParser = ememory::makeShared<esvg::Circle>(m_paint);
elementParser = ememory::makeShared<esvg::Circle>(this.paint);
} else if (child.getValue() == "ellipse") {
elementParser = ememory::makeShared<esvg::Ellipse>(m_paint);
elementParser = ememory::makeShared<esvg::Ellipse>(this.paint);
} else if (child.getValue() == "line") {
elementParser = ememory::makeShared<esvg::Line>(m_paint);
elementParser = ememory::makeShared<esvg::Line>(this.paint);
} else if (child.getValue() == "polyline") {
elementParser = ememory::makeShared<esvg::Polyline>(m_paint);
elementParser = ememory::makeShared<esvg::Polyline>(this.paint);
} else if (child.getValue() == "polygon") {
elementParser = ememory::makeShared<esvg::Polygon>(m_paint);
elementParser = ememory::makeShared<esvg::Polygon>(this.paint);
} else if (child.getValue() == "text") {
elementParser = ememory::makeShared<esvg::Text>(m_paint);
elementParser = ememory::makeShared<esvg::Text>(this.paint);
} else if (child.getValue() == "radialGradient") {
if (_isReference == false) {
Log.error("'" << child.getValue() << "' node must not be defined outside a defs Section");
continue;
} else {
elementParser = ememory::makeShared<esvg::RadialGradient>(m_paint);
elementParser = ememory::makeShared<esvg::RadialGradient>(this.paint);
}
} else if (child.getValue() == "linearGradient") {
if (_isReference == false) {
Log.error("'" << child.getValue() << "' node must not be defined outside a defs Section");
continue;
} else {
elementParser = ememory::makeShared<esvg::LinearGradient>(m_paint);
elementParser = ememory::makeShared<esvg::LinearGradient>(this.paint);
}
} else if (child.getValue() == "defs") {
if (_isReference == true) {
Log.error("'" << child.getValue() << "' node must not be defined in a defs Section");
continue;
} else {
bool retRefs = parseXMLData(child, true);
boolean retRefs = parseXMLData(child, true);
// TODO : Use retRefs ...
continue;
}
@ -320,7 +320,7 @@ bool esvg::Document::parseXMLData(const exml::Element& _root, bool _isReference)
Log.error("(l " << child.getPos() << ") error on node: '" << child.getValue() << "' allocation error or not supported ...");
continue;
}
if (elementParser->parseXML(child, m_transformMatrix, size) == false) {
if (elementParser->parseXML(child, this.transformMatrix, size) == false) {
Log.error("(l " << child.getPos() << ") error on node: '" << child.getValue() << "' Sub Parsing ERROR");
elementParser.reset();
continue;
@ -333,16 +333,16 @@ bool esvg::Document::parseXMLData(const exml::Element& _root, bool _isReference)
}
// add element in the system
if (_isReference == false) {
m_subElementList.pushBack(elementParser);
this.subElementList.pushBack(elementParser);
} else {
m_refList.pushBack(elementParser);
this.refList.pushBack(elementParser);
}
}
if ( m_size.x() == 0
|| m_size.y()==0) {
m_size.setValue((int32_t)maxSize.x(), (int32_t)maxSize.y());
if ( this.size.x() == 0
|| this.size.y()==0) {
this.size.setValue((int)maxSize.x(), (int)maxSize.y());
} else {
m_size.setValue((int32_t)m_size.x(), (int32_t)m_size.y());
this.size.setValue((int)this.size.x(), (int)this.size.y());
}
if (_isReference == false) {
displayDebug();
@ -357,7 +357,7 @@ ememory::SharedPtr<esvg::Base> esvg::Document::getReference(const etk::String& _
Log.error("request a reference with no name ... ");
return null;
}
for (auto &it : m_refList) {
for (auto &it : this.refList) {
if (it == null) {
continue;
}
@ -372,27 +372,27 @@ ememory::SharedPtr<esvg::Base> esvg::Document::getReference(const etk::String& _
List<etk::Vector<Vector2f>> esvg::Document::getLines(Vector2f _size) {
List<etk::Vector<Vector2f>> out;
if (_size.x() <= 0) {
_size.setX(m_size.x());
_size.setX(this.size.x());
}
if (_size.y() <= 0) {
_size.setY(m_size.y());
_size.setY(this.size.y());
}
Log.debug("lineification size " << _size);
// create the first element matrix modification ...
mat2x3 basicTrans;
basicTrans *= etk::mat2x3Scale(Vector2f(_size.x()/m_size.x(), _size.y()/m_size.y()));
basicTrans *= etk::mat2x3Scale(Vector2f(_size.x()/this.size.x(), _size.y()/this.size.y()));
drawShapePoints(out, 10, 0.25f, basicTrans);
return out;
}
void esvg::Document::drawShapePoints(List<etk::Vector<Vector2f>>& _out,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level) {
int _level) {
Log.verbose(spacingDist(_level) << "DRAW shape esvg::Document");
for (auto &it : m_subElementList) {
for (auto &it : this.subElementList) {
if (it != null) {
it->drawShapePoints(_out, _recurtionMax, _threshold, _basicTrans, _level+1);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,77 +6,88 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/Vector.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/uri/uri.hpp>
#include<etk/types.hpp>#include<etk/Vector.hpp>#include<etk/math/Vector2D.hpp>#include<etk/uri/uri.hpp>
#include <esvg/Base.hpp>
#include<esvg/Base.hpp>
/**
* @brief Main esvg namespace
* Main esvg namespace
*/
namespace esvg {
class Document : public esvg::Base {
namespace esvg{
class Document extends esvg::Base
{
private:
etk::Uri m_uri;
bool m_loadOK;
etk::String m_version;
etk::String m_title;
List<ememory::SharedPtr<esvg::Base>> m_subElementList; //!< sub-element list
List<ememory::SharedPtr<esvg::Base>> m_refList; //!< reference elements ...
Vector2f m_size;
etk::Uri this.uri;
boolean this.loadOK;
etk::String this.version;
etk::String this.title;
List<ememory::SharedPtr<esvg::Base>> this.subElementList; //!< sub-element list
List<ememory::SharedPtr<esvg::Base>> this.refList; //!< reference elements ...
Vector2f this.size;
public:
Document();
~Document();
void clear();
/**
* @brief parse a string that contain an svg stream
* @param[in] _data Data to parse
void clear();
/**
* parse a string that contain an svg stream
* @param _data Data to parse
* @return false : An error occured
* @return true : Parsing is OK
*/
bool parse(const etk::String& _data);
/**
* @brief generate a string that contain the created SVG
* @param[out] _data Data where the svg is stored
boolean parse(const etk::String& _data);
/**
* generate a string that contain the created SVG
* @param _data Data where the svg is stored
* @return false : An error occured
* @return true : Parsing is OK
*/
bool generate(etk::String& _data);
/**
* @brief Load the file that might contain the svg
* @param[in] _uri File of the svg
boolean generate(etk::String& _data);
/**
* Load the file that might contain the svg
* @param _uri File of the svg
* @return false : An error occured
* @return true : Parsing is OK
*/
bool load(const etk::Uri& _uri);
/**
* @brief Store the SVG in the file
* @param[in] _uri File of the svg
boolean load(const etk::Uri& _uri);
/**
* Store the SVG in the file
* @param _uri File of the svg
* @return false : An error occured
* @return true : Parsing is OK
*/
bool store(const etk::Uri& _uri);
boolean store(const etk::Uri& _uri);
protected:
/**
* @brief change all style in a xml atribute
* change all style in a xml atribute
*/
virtual bool cleanStyleProperty(const exml::Element& _root);
virtual bool parseXMLData(const exml::Element& _root, bool _isReference = false);
virtual
boolean cleanStyleProperty(const exml::Element& _root);
virtual
boolean parseXMLData(const exml::Element& _root, boolean _isReference = false);
public:
bool isLoadOk() {
return m_loadOK;
boolean isLoadOk() {
return this.loadOK;
};
/**
* @brief Display all the node in the svg file.
/**
* Display all the node in the svg file.
*/
void displayDebug();
// TODO: remove this fucntion : use generic function ...
void generateAnImage(const etk::Uri& _uri, bool _visualDebug=false);
void generateAnImage(const Vector2i& _size, const etk::Uri& _uri, bool _visualDebug=false);
// TODO: remove this fucntion : use generic function ...
void generateAnImage(const etk::Uri& _uri, boolean _visualDebug=false);
void generateAnImage(const Vector2i& _size, const etk::Uri& _uri, boolean _visualDebug=false);
/**
* @brief Generate Image in a specific format.
* Generate Image in a specific format.
* @param[in,out] _size Size expected of the rendered image (value <=0 if it need to be automatic.) return the size generate
* @return Vector of the data used to display (simple vector: generic to transmit)
*/
@ -86,20 +98,24 @@ namespace esvg {
List<etk::Color<uint8_t,4>> renderImageU8RGBA(Vector2i& _size);
//! @previous
List<etk::Color<uint8_t,3>> renderImageU8RGB(Vector2i& _size);
List<List<Vector2f>> getLines(Vector2f _size=Vector2f(256,256));
List<List<Vector2f>> getLines(final Vector2f _size=Vector2f(256,256));
protected:
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int32_t _level=0) override;
void draw(esvg::Renderer& _myRenderer, mat2x3& _basicTrans, int _level=0) override;
public:
Vector2f getDefinedSize() {
return m_size;
};
ememory::SharedPtr<esvg::Base> getReference(const etk::String& _name);
Vector2f getDefinedSize() {
return this.size;
};ememory::SharedPtr<esvg::Base>
getReference(const etk::String& _name);
protected:
void drawShapePoints(List<List<Vector2f>>& _out,
int32_t _recurtionMax,
void drawShapePoints(final List<List<Vector2f>>& _out,
int _recurtionMax,
float _threshold,
mat2x3& _basicTrans,
int32_t _level=1) override;
int _level=1) override;
};
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,16 +6,15 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/Stream.hpp>
#include<etk/types.hpp>#include<etk/Stream.hpp>
namespace esvg {
enum gradientUnits {
gradientUnits_userSpaceOnUse,
gradientUnits_objectBoundingBox
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
namespace esvg{enum esvg::gradientUnits _obj);
};/**
* Debug operator To display the curent element in a Human redeable information
*/
etk::Stream& operator <<(etk::Stream& _os, enum esvg::gradientUnits _obj);
etk::Stream&operator<<(etk::Stream&_os,
enum gradientUnits {
gradientUnits_userSpaceOnUse,
gradientUnits_objectBoundingBox
}

View File

@ -1,23 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <etk/Stream.hpp>
namespace esvg {
enum join {
join_miter,
join_round,
join_bevel
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
etk::Stream& operator <<(etk::Stream& _os, enum esvg::join _obj);
}

View File

@ -11,15 +11,15 @@
#include <esvg/esvg.hpp>
esvg::render::DynamicColorSpecial::DynamicColorSpecial(const etk::String& _link, const mat2x3& _mtx) :
m_linear(true),
m_colorName(_link),
m_matrix(_mtx),
m_viewPort(Vector2f(9999999999.0,9999999999.0),Vector2f(-9999999999.0,-9999999999.0)) {
this.linear(true),
this.colorName(_link),
this.matrix(_mtx),
this.viewPort(Vector2f(9999999999.0,9999999999.0),Vector2f(-9999999999.0,-9999999999.0)) {
}
void esvg::render::DynamicColorSpecial::setViewPort(const etk::Pair<Vector2f, Vector2f>& _viewPort) {
m_viewPort = _viewPort;
void esvg::render::DynamicColorSpecial::setViewPort(const Pair<Vector2f, Vector2f>& _viewPort) {
this.viewPort = _viewPort;
}
@ -41,10 +41,10 @@ static Vector2f getIntersect(const Vector2f& _point1,
}
etk::Color<float,4> esvg::render::DynamicColorSpecial::getColor(const Vector2i& _pos) const {
if (m_data.size() < 2) {
if (this.data.size() < 2) {
return etk::color::purple;
}
if (m_linear == true) {
if (this.linear == true) {
return getColorLinear(_pos);
} else {
return getColorRadial(_pos);
@ -54,23 +54,23 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColor(const Vector2i&
etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorLinear(const Vector2i& _pos) const {
float ratio = 0.0f;
if (m_unit == gradientUnits_userSpaceOnUse) {
Vector2f vectorBase = m_pos2 - m_pos1;
if (this.unit == gradientUnits_userSpaceOnUse) {
Vector2f vectorBase = this.pos2 - this.pos1;
Vector2f vectorOrtho(vectorBase.y(), -vectorBase.x());
Vector2f intersec = getIntersect(m_pos1, vectorBase,
Vector2f intersec = getIntersect(this.pos1, vectorBase,
Vector2f(_pos.x(), _pos.y()), vectorOrtho);
float baseSize = vectorBase.length();
Vector2f vectorBaseDraw = intersec - m_pos1;
Vector2f vectorBaseDraw = intersec - this.pos1;
float baseDraw = vectorBaseDraw.length();
ratio = baseDraw / baseSize;
switch(m_spread) {
switch(this.spread) {
case spreadMethod_pad:
if (vectorBase.dot(vectorBaseDraw) < 0) {
ratio *= -1.0;
}
break;
case spreadMethod_reflect:
ratio -= float((int32_t(ratio)>>1)<<1);
ratio -= float((int(ratio)>>1)<<1);
if (ratio > 1.0f) {
ratio = 2.0f-ratio;
}
@ -79,7 +79,7 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorLinear(const Vect
if (vectorBase.dot(vectorBaseDraw) < 0) {
ratio *= -1.0;
}
ratio -= float(int32_t(ratio));
ratio -= float(int(ratio));
if (ratio <0.0f) {
#ifndef __STDCPP_LLVM__
ratio = 1.0f-etk::abs(ratio);
@ -91,33 +91,33 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorLinear(const Vect
}
} else {
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
Vector2f intersecX = getIntersect(m_pos1, m_axeX,
Vector2f(_pos.x(), _pos.y()), m_axeY);
Vector2f intersecY = getIntersect(m_pos1, m_axeY,
Vector2f(_pos.x(), _pos.y()), m_axeX);
Vector2f vectorBaseDrawX = intersecX - m_pos1;
Vector2f vectorBaseDrawY = intersecY - m_pos1;
Vector2f intersecX = getIntersect(this.pos1, this.axeX,
Vector2f(_pos.x(), _pos.y()), this.axeY);
Vector2f intersecY = getIntersect(this.pos1, this.axeY,
Vector2f(_pos.x(), _pos.y()), this.axeX);
Vector2f vectorBaseDrawX = intersecX - this.pos1;
Vector2f vectorBaseDrawY = intersecY - this.pos1;
float baseDrawX = vectorBaseDrawX.length();
float baseDrawY = vectorBaseDrawY.length();
if (m_axeX.dot(vectorBaseDrawX) < 0) {
if (this.axeX.dot(vectorBaseDrawX) < 0) {
baseDrawX *= -1.0f;
}
if (m_axeY.dot(vectorBaseDrawY) < 0) {
if (this.axeY.dot(vectorBaseDrawY) < 0) {
baseDrawY *= -1.0f;
}
if (m_baseSize.x()+m_baseSize.y() != 0.0f) {
if ( m_baseSize.x() != 0.0f
&& m_baseSize.y() != 0.0f) {
ratio = (baseDrawX*m_baseSize.y() + baseDrawY*m_baseSize.x())/(m_baseSize.x()*m_baseSize.y()*2.0f);
} else if (m_baseSize.x() != 0.0f) {
ratio = baseDrawX/m_baseSize.x();
if (this.baseSize.x()+this.baseSize.y() != 0.0f) {
if ( this.baseSize.x() != 0.0f
&& this.baseSize.y() != 0.0f) {
ratio = (baseDrawX*this.baseSize.y() + baseDrawY*this.baseSize.x())/(this.baseSize.x()*this.baseSize.y()*2.0f);
} else if (this.baseSize.x() != 0.0f) {
ratio = baseDrawX/this.baseSize.x();
} else {
ratio = baseDrawY/m_baseSize.y();
ratio = baseDrawY/this.baseSize.y();
}
} else {
ratio = 1.0f;
}
switch(m_spread) {
switch(this.spread) {
case spreadMethod_pad:
// nothing to do ...
break;
@ -127,13 +127,13 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorLinear(const Vect
#else
ratio = abs(ratio);
#endif
ratio -= float((int32_t(ratio)>>1)<<1);
ratio -= float((int(ratio)>>1)<<1);
if (ratio > 1.0f) {
ratio = 2.0f-ratio;
}
break;
case spreadMethod_repeat:
ratio -= float(int32_t(ratio));
ratio -= float(int(ratio));
if (ratio <0.0f) {
#ifndef __STDCPP_LLVM__
ratio = 1.0f-etk::abs(ratio);
@ -144,25 +144,25 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorLinear(const Vect
break;
}
}
if (ratio <= m_data[0].first*0.01f) {
return m_data[0].second;
if (ratio <= this.data[0].first*0.01f) {
return this.data[0].second;
}
if (ratio >= m_data.back().first*0.01f) {
return m_data.back().second;
if (ratio >= this.data.back().first*0.01f) {
return this.data.back().second;
}
for (size_t iii=1; iii<m_data.size(); ++iii) {
if (ratio <= m_data[iii].first*0.01f) {
float localRatio = ratio - m_data[iii-1].first*0.01f;
localRatio = localRatio / ((m_data[iii].first - m_data[iii-1].first) * 0.01f);
return etk::Color<float,4>(m_data[iii-1].second.r() * (1.0-localRatio) + m_data[iii].second.r() * localRatio,
m_data[iii-1].second.g() * (1.0-localRatio) + m_data[iii].second.g() * localRatio,
m_data[iii-1].second.b() * (1.0-localRatio) + m_data[iii].second.b() * localRatio,
m_data[iii-1].second.a() * (1.0-localRatio) + m_data[iii].second.a() * localRatio);
for (size_t iii=1; iii<this.data.size(); ++iii) {
if (ratio <= this.data[iii].first*0.01f) {
float localRatio = ratio - this.data[iii-1].first*0.01f;
localRatio = localRatio / ((this.data[iii].first - this.data[iii-1].first) * 0.01f);
return etk::Color<float,4>(this.data[iii-1].second.r() * (1.0-localRatio) + this.data[iii].second.r() * localRatio,
this.data[iii-1].second.g() * (1.0-localRatio) + this.data[iii].second.g() * localRatio,
this.data[iii-1].second.b() * (1.0-localRatio) + this.data[iii].second.b() * localRatio,
this.data[iii-1].second.a() * (1.0-localRatio) + this.data[iii].second.a() * localRatio);
}
}
return etk::color::green;
}
static etk::Pair<Vector2f,Vector2f> intersectLineToCircle(const Vector2f& _pos1,
static Pair<Vector2f,Vector2f> intersectLineToCircle(const Vector2f& _pos1,
const Vector2f& _pos2,
const Vector2f& _center = Vector2f(0.0f, 0.0f),
float _radius = 1.0f) {
@ -180,10 +180,10 @@ static etk::Pair<Vector2f,Vector2f> intersectLineToCircle(const Vector2f& _pos1,
float distToCenter = (midpt - _center).length2();
if (distToCenter > _radius * _radius) {
return etk::Pair<Vector2f,Vector2f>(Vector2f(0.0,0.0), Vector2f(0.0,0.0));
return Pair<Vector2f,Vector2f>(Vector2f(0.0,0.0), Vector2f(0.0,0.0));
}
if (distToCenter == _radius * _radius) {
return etk::Pair<Vector2f,Vector2f>(midpt, midpt);
return Pair<Vector2f,Vector2f>(midpt, midpt);
}
float distToIntersection;
if (distToCenter == 0.0f) {
@ -200,59 +200,59 @@ static etk::Pair<Vector2f,Vector2f> intersectLineToCircle(const Vector2f& _pos1,
// normalize...
v1.safeNormalize();
v1 *= distToIntersection;
return etk::Pair<Vector2f,Vector2f>(midpt + v1, midpt - v1);
return Pair<Vector2f,Vector2f>(midpt + v1, midpt - v1);
}
etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorRadial(const Vector2i& _pos) const {
float ratio = 0.0f;
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object)..
Vector2f intersecX = getIntersect(m_pos1, m_axeX,
Vector2f(_pos.x(), _pos.y()), m_axeY);
Vector2f intersecY = getIntersect(m_pos1, m_axeY,
Vector2f(_pos.x(), _pos.y()), m_axeX);
Vector2f vectorBaseDrawX = intersecX - m_pos1;
Vector2f vectorBaseDrawY = intersecY - m_pos1;
Vector2f intersecX = getIntersect(this.pos1, this.axeX,
Vector2f(_pos.x(), _pos.y()), this.axeY);
Vector2f intersecY = getIntersect(this.pos1, this.axeY,
Vector2f(_pos.x(), _pos.y()), this.axeX);
Vector2f vectorBaseDrawX = intersecX - this.pos1;
Vector2f vectorBaseDrawY = intersecY - this.pos1;
float baseDrawX = vectorBaseDrawX.length();
float baseDrawY = vectorBaseDrawY.length();
// specal case when focal == center (this is faster ...)
if (m_centerIsFocal == true) {
if (this.centerIsFocal == true) {
ratio = Vector2f(baseDrawX, baseDrawY).length();
if (m_baseSize.x()+m_baseSize.y() != 0.0f) {
if ( m_baseSize.x() != 0.0f
&& m_baseSize.y() != 0.0f) {
ratio = Vector2f(baseDrawX/m_baseSize.x(), baseDrawY/m_baseSize.y()).length();
} else if (m_baseSize.x() != 0.0f) {
ratio = baseDrawX/m_baseSize.x();
if (this.baseSize.x()+this.baseSize.y() != 0.0f) {
if ( this.baseSize.x() != 0.0f
&& this.baseSize.y() != 0.0f) {
ratio = Vector2f(baseDrawX/this.baseSize.x(), baseDrawY/this.baseSize.y()).length();
} else if (this.baseSize.x() != 0.0f) {
ratio = baseDrawX/this.baseSize.x();
} else {
ratio = baseDrawY/m_baseSize.y();
ratio = baseDrawY/this.baseSize.y();
}
} else {
ratio = 1.0f;
}
} else {
// set the sense of the elements:
if (m_axeX.dot(vectorBaseDrawX) < 0) {
if (this.axeX.dot(vectorBaseDrawX) < 0) {
baseDrawX *= -1.0f;
}
if (m_axeY.dot(vectorBaseDrawY) < 0) {
if (this.axeY.dot(vectorBaseDrawY) < 0) {
baseDrawY *= -1.0f;
}
if (m_baseSize.y() != 0.0f) {
baseDrawY /= m_baseSize.y();
if (this.baseSize.y() != 0.0f) {
baseDrawY /= this.baseSize.y();
}
// normalize to 1.0f
baseDrawX /= m_baseSize.x();
if ( m_clipOut == true
baseDrawX /= this.baseSize.x();
if ( this.clipOut == true
&& baseDrawX <= -1.0f) {
ratio = 1.0f;
} else {
float tmpLength = -m_focalLength/m_baseSize.x();
float tmpLength = -this.focalLength/this.baseSize.x();
Vector2f focalCenter = Vector2f(tmpLength, 0.0f);
Vector2f currentPoint = Vector2f(baseDrawX, baseDrawY);
if (focalCenter == currentPoint) {
ratio = 0.0f;
} else {
etk::Pair<Vector2f,Vector2f> positions = intersectLineToCircle(focalCenter, currentPoint);
Pair<Vector2f,Vector2f> positions = intersectLineToCircle(focalCenter, currentPoint);
float lenghtBase = (currentPoint - focalCenter).length();
float lenghtBorder1 = (positions.first - focalCenter).length();
float lenghtBorder2 = (positions.second - focalCenter).length();
@ -260,18 +260,18 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorRadial(const Vect
}
}
}
switch(m_spread) {
switch(this.spread) {
case spreadMethod_pad:
// nothing to do ...
break;
case spreadMethod_reflect:
ratio -= float((int32_t(ratio)>>1)<<1);
ratio -= float((int(ratio)>>1)<<1);
if (ratio > 1.0f) {
ratio = 2.0f-ratio;
}
break;
case spreadMethod_repeat:
ratio -= float(int32_t(ratio));
ratio -= float(int(ratio));
if (ratio <0.0f) {
#ifndef __STDCPP_LLVM__
ratio = 1.0f-etk::abs(ratio);
@ -281,20 +281,20 @@ etk::Color<float,4> esvg::render::DynamicColorSpecial::getColorRadial(const Vect
}
break;
}
if (ratio <= m_data[0].first*0.01f) {
return m_data[0].second;
if (ratio <= this.data[0].first*0.01f) {
return this.data[0].second;
}
if (ratio >= m_data.back().first*0.01f) {
return m_data.back().second;
if (ratio >= this.data.back().first*0.01f) {
return this.data.back().second;
}
for (size_t iii=1; iii<m_data.size(); ++iii) {
if (ratio <= m_data[iii].first*0.01f) {
float localRatio = ratio - m_data[iii-1].first*0.01f;
localRatio = localRatio / ((m_data[iii].first - m_data[iii-1].first) * 0.01f);
return etk::Color<float,4>(m_data[iii-1].second.r() * (1.0-localRatio) + m_data[iii].second.r() * localRatio,
m_data[iii-1].second.g() * (1.0-localRatio) + m_data[iii].second.g() * localRatio,
m_data[iii-1].second.b() * (1.0-localRatio) + m_data[iii].second.b() * localRatio,
m_data[iii-1].second.a() * (1.0-localRatio) + m_data[iii].second.a() * localRatio);
for (size_t iii=1; iii<this.data.size(); ++iii) {
if (ratio <= this.data[iii].first*0.01f) {
float localRatio = ratio - this.data[iii-1].first*0.01f;
localRatio = localRatio / ((this.data[iii].first - this.data[iii-1].first) * 0.01f);
return etk::Color<float,4>(this.data[iii-1].second.r() * (1.0-localRatio) + this.data[iii].second.r() * localRatio,
this.data[iii-1].second.g() * (1.0-localRatio) + this.data[iii].second.g() * localRatio,
this.data[iii-1].second.b() * (1.0-localRatio) + this.data[iii].second.b() * localRatio,
this.data[iii-1].second.a() * (1.0-localRatio) + this.data[iii].second.a() * localRatio);
}
}
return etk::color::green;
@ -306,140 +306,140 @@ void esvg::render::DynamicColorSpecial::generate(esvg::Document* _document) {
Log.error("Get null input for document");
return;
}
ememory::SharedPtr<esvg::Base> base = _document->getReference(m_colorName);
ememory::SharedPtr<esvg::Base> base = _document->getReference(this.colorName);
if (base == null) {
Log.error("Can not get base : '" << m_colorName << "'");
Log.error("Can not get base : '" << this.colorName << "'");
return;
}
// Now we can know if we use linear or radial gradient ...
ememory::SharedPtr<esvg::LinearGradient> gradient = ememory::dynamicPointerCast<esvg::LinearGradient>(base);
if (gradient != null) {
m_linear = true;
this.linear = true;
Log.verbose("get for color linear:");
gradient->display(2);
m_unit = gradient->m_unit;
m_spread = gradient->m_spread;
Log.verbose(" viewport = {" << m_viewPort.first << "," << m_viewPort.second << "}");
Vector2f size = m_viewPort.second - m_viewPort.first;
this.unit = gradient->this.unit;
this.spread = gradient->this.spread;
Log.verbose(" viewport = {" << this.viewPort.first << "," << this.viewPort.second << "}");
Vector2f size = this.viewPort.second - this.viewPort.first;
esvg::Dimension dimPos1 = gradient->getPosition1();
m_pos1 = dimPos1.getPixel(size);
this.pos1 = dimPos1.getPixel(size);
if (dimPos1.getType() == esvg::distance_pourcent) {
m_pos1 += m_viewPort.first;
this.pos1 += this.viewPort.first;
}
esvg::Dimension dimPos2 = gradient->getPosition2();
m_pos2 = dimPos2.getPixel(size);
this.pos2 = dimPos2.getPixel(size);
if (dimPos2.getType() == esvg::distance_pourcent) {
m_pos2 += m_viewPort.first;
this.pos2 += this.viewPort.first;
}
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
Vector2f delta = m_pos2 - m_pos1;
Vector2f delta = this.pos2 - this.pos1;
if (delta.x() < 0.0f) {
m_axeX = Vector2f(-1.0f, 0.0f);
this.axeX = Vector2f(-1.0f, 0.0f);
} else {
m_axeX = Vector2f(1.0f, 0.0f);
this.axeX = Vector2f(1.0f, 0.0f);
}
if (delta.y() < 0.0f) {
m_axeY = Vector2f(0.0f, -1.0f);
this.axeY = Vector2f(0.0f, -1.0f);
} else {
m_axeY = Vector2f(0.0f, 1.0f);
this.axeY = Vector2f(0.0f, 1.0f);
}
// Move the positions ...
m_pos1 = m_matrix * m_pos1;
m_pos2 = m_matrix * m_pos2;
m_axeX = m_matrix.applyScaleRotation(m_axeX);
m_axeY = m_matrix.applyScaleRotation(m_axeY);
this.pos1 = this.matrix * this.pos1;
this.pos2 = this.matrix * this.pos2;
this.axeX = this.matrix.applyScaleRotation(this.axeX);
this.axeY = this.matrix.applyScaleRotation(this.axeY);
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
Vector2f intersecX = getIntersect(m_pos1, m_axeX,
m_pos2, m_axeY);
Vector2f intersecY = getIntersect(m_pos1, m_axeY,
m_pos2, m_axeX);
m_baseSize = Vector2f((m_pos1 - intersecX).length(),
(m_pos1 - intersecY).length());
Vector2f intersecX = getIntersect(this.pos1, this.axeX,
this.pos2, this.axeY);
Vector2f intersecY = getIntersect(this.pos1, this.axeY,
this.pos2, this.axeX);
this.baseSize = Vector2f((this.pos1 - intersecX).length(),
(this.pos1 - intersecY).length());
// get all the colors
m_data = gradient->getColors(_document);
this.data = gradient->getColors(_document);
} else {
m_linear = false;
this.linear = false;
ememory::SharedPtr<esvg::RadialGradient> gradient = ememory::dynamicPointerCast<esvg::RadialGradient>(base);
if (gradient == null) {
Log.error("Can not cast in a linear gradient: '" << m_colorName << "' ==> wrong type");
Log.error("Can not cast in a linear gradient: '" << this.colorName << "' ==> wrong type");
return;
}
Log.verbose("get for color Radial:");
gradient->display(2);
m_unit = gradient->m_unit;
m_spread = gradient->m_spread;
Log.verbose(" viewport = {" << m_viewPort.first << "," << m_viewPort.second << "}");
Vector2f size = m_viewPort.second - m_viewPort.first;
this.unit = gradient->this.unit;
this.spread = gradient->this.spread;
Log.verbose(" viewport = {" << this.viewPort.first << "," << this.viewPort.second << "}");
Vector2f size = this.viewPort.second - this.viewPort.first;
esvg::Dimension dimCenter = gradient->getCenter();
Vector2f center = dimCenter.getPixel(size);
if (dimCenter.getType() == esvg::distance_pourcent) {
center += m_viewPort.first;
center += this.viewPort.first;
}
esvg::Dimension dimFocal = gradient->getFocal();
Vector2f focal = dimFocal.getPixel(size);
if (dimFocal.getType() == esvg::distance_pourcent) {
focal += m_viewPort.first;
focal += this.viewPort.first;
}
esvg::Dimension1D dimRadius = gradient->getRadius();
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object)..
if (center == focal) {
m_centerIsFocal = true;
m_pos2.setX(dimRadius.getPixel(size.x()));
m_pos2.setY(dimRadius.getPixel(size.y()));
m_pos2 += center;
Vector2f delta = center - m_pos2;
this.centerIsFocal = true;
this.pos2.setX(dimRadius.getPixel(size.x()));
this.pos2.setY(dimRadius.getPixel(size.y()));
this.pos2 += center;
Vector2f delta = center - this.pos2;
if (delta.x() < 0.0f) {
m_axeX = Vector2f(-1.0f, 0.0f);
this.axeX = Vector2f(-1.0f, 0.0f);
} else {
m_axeX = Vector2f(1.0f, 0.0f);
this.axeX = Vector2f(1.0f, 0.0f);
}
if (delta.y() < 0.0f) {
m_axeY = Vector2f(0.0f, -1.0f);
this.axeY = Vector2f(0.0f, -1.0f);
} else {
m_axeY = Vector2f(0.0f, 1.0f);
this.axeY = Vector2f(0.0f, 1.0f);
}
m_pos1 = center;
this.pos1 = center;
} else {
m_centerIsFocal = false;
m_axeX = (center - focal).safeNormalize();
m_axeY = Vector2f(m_axeX.y(), -m_axeX.x());
this.centerIsFocal = false;
this.axeX = (center - focal).safeNormalize();
this.axeY = Vector2f(this.axeX.y(), -this.axeX.x());
m_pos2 = m_axeX * dimRadius.getPixel(size.x()) + m_axeY * dimRadius.getPixel(size.y());
m_pos2 += center;
m_pos1 = center;
this.pos2 = this.axeX * dimRadius.getPixel(size.x()) + this.axeY * dimRadius.getPixel(size.y());
this.pos2 += center;
this.pos1 = center;
}
// Move the positions ...
m_pos1 = m_matrix * m_pos1;
center = m_matrix * center;
m_pos2 = m_matrix * m_pos2;
m_axeX = m_matrix.applyScaleRotation(m_axeX);
m_axeY = m_matrix.applyScaleRotation(m_axeY);
this.pos1 = this.matrix * this.pos1;
center = this.matrix * center;
this.pos2 = this.matrix * this.pos2;
this.axeX = this.matrix.applyScaleRotation(this.axeX);
this.axeY = this.matrix.applyScaleRotation(this.axeY);
// in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object..
Vector2f intersecX = getIntersect(m_pos1, m_axeX,
m_pos2, m_axeY);
Vector2f intersecY = getIntersect(m_pos1, m_axeY,
m_pos2, m_axeX);
m_baseSize = Vector2f((intersecX - m_pos1).length(),
(intersecY - m_pos1).length());
if (m_centerIsFocal == false) {
m_focalLength = (center - m_matrix * focal).length();
if (m_focalLength >= m_baseSize.x()) {
Vector2f intersecX = getIntersect(this.pos1, this.axeX,
this.pos2, this.axeY);
Vector2f intersecY = getIntersect(this.pos1, this.axeY,
this.pos2, this.axeX);
this.baseSize = Vector2f((intersecX - this.pos1).length(),
(intersecY - this.pos1).length());
if (this.centerIsFocal == false) {
this.focalLength = (center - this.matrix * focal).length();
if (this.focalLength >= this.baseSize.x()) {
Log.debug("Change position of the Focal ... ==> set it inside the circle");
m_focalLength = m_baseSize.x()*0.999998f;
m_clipOut = true;
this.focalLength = this.baseSize.x()*0.999998f;
this.clipOut = true;
} else {
m_clipOut = false;
this.clipOut = false;
}
}
Log.verbose("baseSize=" << m_baseSize << " m_pos1=" << m_pos1 << " dim=" << dimCenter << " m_focal=" << m_focal << " m_pos2=" << m_pos2 << " dim=" << dimRadius);
Log.verbose("baseSize=" << this.baseSize << " this.pos1=" << this.pos1 << " dim=" << dimCenter << " this.focal=" << this.focal << " this.pos2=" << this.pos2 << " dim=" << dimRadius);
// get all the colors
m_data = gradient->getColors(_document);
this.data = gradient->getColors(_document);
}
}
ememory::SharedPtr<esvg::render::DynamicColor> esvg::render::createColor(etk::Pair<etk::Color<float,4>, etk::String> _color, const mat2x3& _mtx) {
ememory::SharedPtr<esvg::render::DynamicColor> esvg::render::createColor(Pair<etk::Color<float,4>, etk::String> _color, const mat2x3& _mtx) {
// Check if need to create a color:
if ( _color.first.a() == 0x00
&& _color.second == "") {

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,18 +6,12 @@
*/
#pragma once
#include <ememory/memory.hpp>
#include <etk/types.hpp>
#include <etk/Pair.hpp>
#include <etk/Color.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/math/Matrix2x3.hpp>
#include <esvg/gradientUnits.hpp>
#include <esvg/spreadMethod.hpp>
#include<ememory/memory.hpp>#include<etk/types.hpp>#include<etk/Pair.hpp>#include<etk/Color.hpp>#include<etk/math/Vector2D.hpp>#include<etk/math/Matrix2x3.hpp>#include<esvg/gradientUnits.hpp>#include<esvg/spreadMethod.hpp>
namespace esvg {
class Document;
namespace render {
namespace esvg{
class Document;
namespace render
{
class DynamicColor {
public:
DynamicColor() {
@ -25,44 +20,44 @@ namespace esvg {
virtual ~DynamicColor() {};
virtual etk::Color<float,4> getColor(const Vector2i& _pos) const = 0;
virtual void generate(esvg::Document* _document) = 0;
virtual void setViewPort(const etk::Pair<Vector2f, Vector2f>& _viewPort) = 0;
virtual void setViewPort(const Pair<Vector2f, Vector2f>& _viewPort) = 0;
};
class DynamicColorUni : public esvg::render::DynamicColor {
class DynamicColorUni extends esvg::render::DynamicColor {
public:
etk::Color<float,4> m_color;
etk::Color<float,4> this.color;
public:
DynamicColorUni(const etk::Color<float,4>& _color) :
m_color(_color) {
this.color(_color) {
}
virtual etk::Color<float,4> getColor(const Vector2i& _pos) const {
return m_color;
return this.color;
}
virtual void generate(esvg::Document* _document) {
// nothing to do ...
}
virtual void setViewPort(const etk::Pair<Vector2f, Vector2f>& _viewPort) {
virtual void setViewPort(const Pair<Vector2f, Vector2f>& _viewPort) {
// nothing to do ...
};
};
class DynamicColorSpecial : public esvg::render::DynamicColor {
class DynamicColorSpecial extends esvg::render::DynamicColor {
public:
bool m_linear;
esvg::spreadMethod m_spread;
esvg::gradientUnits m_unit;
etk::String m_colorName;
mat2x3 m_matrix;
etk::Pair<Vector2f, Vector2f> m_viewPort;
Vector2f m_pos1; // in radius ==> center
Vector2f m_pos2; // in radius ==> radius end position
Vector2f m_focal; // Specific radius
Vector2f m_axeX;
Vector2f m_axeY;
Vector2f m_baseSize;
float m_focalLength;
bool m_clipOut;
bool m_centerIsFocal;
List<etk::Pair<float, etk::Color<float,4>>> m_data;
boolean this.linear;
esvg::spreadMethod this.spread;
esvg::gradientUnits this.unit;
etk::String this.colorName;
mat2x3 this.matrix;
Pair<Vector2f, Vector2f> this.viewPort;
Vector2f this.pos1; // in radius ==> center
Vector2f this.pos2; // in radius ==> radius end position
Vector2f this.focal; // Specific radius
Vector2f this.axeX;
Vector2f this.axeY;
Vector2f this.baseSize;
float this.focalLength;
boolean this.clipOut;
boolean this.centerIsFocal;
List<Pair<float, etk::Color<float,4>>> this.data;
public:
DynamicColorSpecial(const etk::String& _link, const mat2x3& _mtx);
virtual etk::Color<float,4> getColor(const Vector2i& _pos) const;
@ -71,10 +66,9 @@ namespace esvg {
etk::Color<float,4> getColorRadial(const Vector2i& _pos) const;
public:
virtual void generate(esvg::Document* _document);
virtual void setViewPort(const etk::Pair<Vector2f, Vector2f>& _viewPort);
virtual void setViewPort(const Pair<Vector2f, Vector2f>& _viewPort);
};
ememory::SharedPtr<DynamicColor> createColor(etk::Pair<etk::Color<float,4>, etk::String> _color, const mat2x3& _mtx);
ememory::SharedPtr<DynamicColor> createColor(Pair<etk::Color<float,4>, etk::String> _color, const mat2x3& _mtx);
}
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,84 +6,69 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>
namespace esvg {
namespace render {
enum path {
path_stop,
path_close,
path_moveTo,
path_lineTo,
path_lineToH,
path_lineToV,
path_curveTo,
path_smoothCurveTo,
path_bezierCurveTo,
path_bezierSmoothCurveTo,
path_elliptic
};
class Element {
public:
Element(enum path _type, bool _relative=false) :
m_cmd(_type),
m_relative(_relative) {
namespace esvg{namespace render{
class Element {
public:
Element(enum path _type, boolean _relative=false) :
this.cmd(_type),
this.relative(_relative) {
}
virtual ~Element() { }
private:
enum path m_cmd;
enum path this.cmd;
public:
enum path getType() const {
return m_cmd;
return this.cmd;
}
protected:
bool m_relative;
boolean this.relative;
public:
bool getRelative() const {
return m_relative;
boolean getRelative() const {
return this.relative;
}
void setRelative(bool _relative) {
m_relative = _relative;
void setRelative(boolean _relative) {
this.relative = _relative;
}
protected:
Vector2f m_pos;
Vector2f this.pos;
public:
const Vector2f& getPos() const {
return m_pos;
return this.pos;
}
void setPos(const Vector2f& _val) {
m_pos = _val;
this.pos = _val;
}
protected:
Vector2f m_pos1;
Vector2f this.pos1;
public:
const Vector2f& getPos1() const {
return m_pos1;
return this.pos1;
}
void setPos1(const Vector2f& _val) {
m_pos1 = _val;
this.pos1 = _val;
}
protected:
Vector2f m_pos2;
Vector2f this.pos2;
public:
const Vector2f& getPos2() const {
return m_pos2;
return this.pos2;
}
void setPos2(const Vector2f& _val) {
m_pos2 = _val;
this.pos2 = _val;
}
public:
virtual etk::String display() const = 0;
};
}
/**
* @brief Debug operator To display the curent element in a Human redeable information
* Debug operator To display the curent element in a Human redeable information
*/
etk::Stream& operator <<(etk::Stream& _os, const esvg::render::Element& _obj);
/**
* @brief Debug operator To display the curent element in a Human redeable information
* Debug operator To display the curent element in a Human redeable information
*/
etk::Stream& operator <<(etk::Stream& _os, enum esvg::render::path _obj);
}
@ -99,3 +85,17 @@ namespace esvg {
#include <esvg/render/ElementBezierSmoothCurveTo.hpp>
#include <esvg/render/ElementElliptic.hpp>
;
enum path {
path_stop,
path_close,
path_moveTo,
path_lineTo,
path_lineToH,
path_lineToV,
path_curveTo,
path_smoothCurveTo,
path_bezierCurveTo,
path_bezierSmoothCurveTo,
path_elliptic
}

View File

@ -7,12 +7,12 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementBezierCurveTo::ElementBezierCurveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos):
esvg::render::ElementBezierCurveTo::ElementBezierCurveTo(boolean _relative, const Vector2f& _pos1, const Vector2f& _pos):
Element(esvg::render::path_bezierCurveTo, _relative) {
m_pos = _pos;
m_pos1 = _pos1;
this.pos = _pos;
this.pos1 = _pos1;
}
etk::String esvg::render::ElementBezierCurveTo::display() const {
return etk::String("pos=") + etk::toString(m_pos) + " pos1=" + etk::toString(m_pos1);
return etk::String("pos=") + etk::toString(this.pos) + " pos1=" + etk::toString(this.pos1);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -11,9 +12,9 @@
namespace esvg {
namespace render {
class ElementBezierCurveTo : public esvg::render::Element {
class ElementBezierCurveTo extends esvg::render::Element {
public:
ElementBezierCurveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos);
ElementBezierCurveTo(boolean _relative, const Vector2f& _pos1, const Vector2f& _pos);
public:
virtual etk::String display() const;
};

View File

@ -7,12 +7,12 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(bool _relative, const Vector2f& _pos):
esvg::render::ElementBezierSmoothCurveTo::ElementBezierSmoothCurveTo(boolean _relative, const Vector2f& _pos):
Element(esvg::render::path_bezierSmoothCurveTo, _relative) {
m_pos = _pos;
this.pos = _pos;
}
etk::String esvg::render::ElementBezierSmoothCurveTo::display() const {
return etk::String("pos=") + etk::toString(m_pos);
return etk::String("pos=") + etk::toString(this.pos);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -11,9 +12,9 @@
namespace esvg {
namespace render {
class ElementBezierSmoothCurveTo : public esvg::render::Element {
class ElementBezierSmoothCurveTo extends esvg::render::Element {
public:
ElementBezierSmoothCurveTo(bool _relative, const Vector2f& _pos);
ElementBezierSmoothCurveTo(boolean _relative, const Vector2f& _pos);
public:
virtual etk::String display() const;
};

View File

@ -7,7 +7,7 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementClose::ElementClose(bool _relative):
esvg::render::ElementClose::ElementClose(boolean _relative):
Element(esvg::render::path_close, _relative) {
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,18 +6,14 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/render/Element.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<esvg/render/Element.hpp>
namespace esvg {
namespace render {
class ElementClose : public esvg::render::Element {
namespace esvg{namespace render{
class ElementClose extends esvg::render::Element
{
public:
ElementClose(bool _relative=false);
ElementClose(boolean _relative=false);
public:
virtual etk::String display() const;
};
}
}
}}

View File

@ -7,15 +7,15 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementCurveTo::ElementCurveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos):
esvg::render::ElementCurveTo::ElementCurveTo(boolean _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos):
Element(esvg::render::path_curveTo, _relative) {
m_pos = _pos;
m_pos1 = _pos1;
m_pos2 = _pos2;
this.pos = _pos;
this.pos1 = _pos1;
this.pos2 = _pos2;
}
etk::String esvg::render::ElementCurveTo::display() const {
return etk::String("pos=") + etk::toString(m_pos) + " pos1=" + etk::toString(m_pos1) + " pos2=" + etk::toString(m_pos2);
return etk::String("pos=") + etk::toString(this.pos) + " pos1=" + etk::toString(this.pos1) + " pos2=" + etk::toString(this.pos2);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -10,9 +11,9 @@
namespace esvg {
namespace render {
class ElementCurveTo : public esvg::render::Element {
class ElementCurveTo extends esvg::render::Element {
public:
ElementCurveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos);
ElementCurveTo(boolean _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos);
public:
virtual etk::String display() const;
};

View File

@ -7,25 +7,25 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementElliptic::ElementElliptic(bool _relative,
const Vector2f& _radius, // in m_vec1
esvg::render::ElementElliptic::ElementElliptic(boolean _relative,
const Vector2f& _radius, // in this.vec1
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
boolean _largeArcFlag,
boolean _sweepFlag,
const Vector2f& _pos):
Element(esvg::render::path_elliptic, _relative) {
m_pos1 = _radius;
m_pos = _pos;
m_angle = _angle;
m_largeArcFlag = _largeArcFlag;
m_sweepFlag = _sweepFlag;
this.pos1 = _radius;
this.pos = _pos;
this.angle = _angle;
this.largeArcFlag = _largeArcFlag;
this.sweepFlag = _sweepFlag;
}
etk::String esvg::render::ElementElliptic::display() const {
return etk::String("pos=") + etk::toString(m_pos)
+ " radius=" + etk::toString(m_pos1)
+ " angle=" + etk::toString(m_angle)
+ " largeArcFlag=" + etk::toString(m_largeArcFlag)
+ " sweepFlag=" + etk::toString(m_sweepFlag);
return etk::String("pos=") + etk::toString(this.pos)
+ " radius=" + etk::toString(this.pos1)
+ " angle=" + etk::toString(this.angle)
+ " largeArcFlag=" + etk::toString(this.largeArcFlag)
+ " sweepFlag=" + etk::toString(this.sweepFlag);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -11,17 +12,17 @@
namespace esvg {
namespace render {
class ElementElliptic : public esvg::render::Element {
class ElementElliptic extends esvg::render::Element {
public:
float m_angle;
bool m_largeArcFlag;
bool m_sweepFlag;
float this.angle;
boolean this.largeArcFlag;
boolean this.sweepFlag;
public:
ElementElliptic(bool _relative,
const Vector2f& _radius, // in m_pos1
ElementElliptic(boolean _relative,
const Vector2f& _radius, // in this.pos1
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
boolean _largeArcFlag,
boolean _sweepFlag,
const Vector2f& _pos);
public:
virtual etk::String display() const;

View File

@ -7,12 +7,12 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementLineTo::ElementLineTo(bool _relative, const Vector2f& _pos):
esvg::render::ElementLineTo::ElementLineTo(boolean _relative, const Vector2f& _pos):
Element(esvg::render::path_lineTo, _relative) {
m_pos = _pos;
this.pos = _pos;
}
etk::String esvg::render::ElementLineTo::display() const {
return etk::String("pos=") + etk::toString(m_pos);
return etk::String("pos=") + etk::toString(this.pos);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -11,9 +12,9 @@
namespace esvg {
namespace render {
class ElementLineTo : public esvg::render::Element {
class ElementLineTo extends esvg::render::Element {
public:
ElementLineTo(bool _relative, const Vector2f& _pos);
ElementLineTo(boolean _relative, const Vector2f& _pos);
public:
virtual etk::String display() const;
};

View File

@ -7,12 +7,12 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementLineToH::ElementLineToH(bool _relative, float _posX):
esvg::render::ElementLineToH::ElementLineToH(boolean _relative, float _posX):
Element(esvg::render::path_lineToH, _relative) {
m_pos = Vector2f(_posX, 0.0f);
this.pos = Vector2f(_posX, 0.0f);
}
etk::String esvg::render::ElementLineToH::display() const {
return etk::String("posX=") + etk::toString(m_pos.x());
return etk::String("posX=") + etk::toString(this.pos.x());
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,18 +6,15 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/render/Element.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<esvg/render/Element.hpp>
namespace esvg {
namespace render {
class ElementLineToH : public esvg::render::Element {
namespace esvg{namespace render{
class ElementLineToH extends esvg::render::Element
{
public:
ElementLineToH(bool _relative, float _posX);
public:
virtual etk::String display() const;
ElementLineToH(boolean _relative, float _posX);public:
virtual etk::String display() const;
};
}
}
}}

View File

@ -7,12 +7,12 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementLineToV::ElementLineToV(bool _relative, float _posY):
esvg::render::ElementLineToV::ElementLineToV(boolean _relative, float _posY):
Element(esvg::render::path_lineToV, _relative) {
m_pos = Vector2f(0.0f, _posY);
this.pos = Vector2f(0.0f, _posY);
}
etk::String esvg::render::ElementLineToV::display() const {
return etk::String("posY=") + etk::toString(m_pos.y());
return etk::String("posY=") + etk::toString(this.pos.y());
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,19 +6,15 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/render/Element.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<esvg/render/Element.hpp>
namespace esvg {
namespace render {
class ElementLineToV : public esvg::render::Element {
namespace esvg{namespace render{
class ElementLineToV extends esvg::render::Element
{
public:
ElementLineToV(bool _relative, float _posY);
public:
virtual etk::String display() const;
ElementLineToV(boolean _relative, float _posY);public:
virtual etk::String display() const;
};
}
}
}}

View File

@ -7,12 +7,12 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementMoveTo::ElementMoveTo(bool _relative, const Vector2f& _pos):
esvg::render::ElementMoveTo::ElementMoveTo(boolean _relative, const Vector2f& _pos):
Element(esvg::render::path_moveTo, _relative) {
m_pos = _pos;
this.pos = _pos;
}
etk::String esvg::render::ElementMoveTo::display() const {
return etk::String("pos=") + etk::toString(m_pos);
return etk::String("pos=") + etk::toString(this.pos);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -11,9 +12,9 @@
namespace esvg {
namespace render {
class ElementMoveTo : public esvg::render::Element {
class ElementMoveTo extends esvg::render::Element {
public:
ElementMoveTo(bool _relative, const Vector2f& _pos);
ElementMoveTo(boolean _relative, const Vector2f& _pos);
public:
virtual etk::String display() const;
};

View File

@ -7,13 +7,13 @@
#include <esvg/render/Element.hpp>
#include <esvg/debug.hpp>
esvg::render::ElementSmoothCurveTo::ElementSmoothCurveTo(bool _relative, const Vector2f& _pos2, const Vector2f& _pos):
esvg::render::ElementSmoothCurveTo::ElementSmoothCurveTo(boolean _relative, const Vector2f& _pos2, const Vector2f& _pos):
Element(esvg::render::path_smoothCurveTo, _relative) {
m_pos = _pos;
m_pos2 = _pos2;
this.pos = _pos;
this.pos2 = _pos2;
}
etk::String esvg::render::ElementSmoothCurveTo::display() const {
return etk::String("pos=") + etk::toString(m_pos) + " pos2=" + etk::toString(m_pos2);
return etk::String("pos=") + etk::toString(this.pos) + " pos2=" + etk::toString(this.pos2);
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -11,9 +12,9 @@
namespace esvg {
namespace render {
class ElementSmoothCurveTo : public esvg::render::Element {
class ElementSmoothCurveTo extends esvg::render::Element {
public:
ElementSmoothCurveTo(bool _relative, const Vector2f& _pos2, const Vector2f& _pos);
ElementSmoothCurveTo(boolean _relative, const Vector2f& _pos2, const Vector2f& _pos);
public:
virtual etk::String display() const;
};

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,18 +6,14 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/render/Element.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<esvg/render/Element.hpp>
namespace esvg {
namespace render {
class ElementStop : public esvg::render::Element {
namespace esvg{namespace render{
class ElementStop extends esvg::render::Element
{
public:
ElementStop();
public:
virtual etk::String display() const;
};
}
}
}}

View File

@ -8,59 +8,59 @@
#include <esvg/render/Element.hpp>
void esvg::render::Path::clear() {
m_listElement.clear();
this.listElement.clear();
}
void esvg::render::Path::stop() {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementStop>());
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementStop>());
}
void esvg::render::Path::close(bool _relative) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementClose>(_relative));
void esvg::render::Path::close(boolean _relative) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementClose>(_relative));
}
void esvg::render::Path::moveTo(bool _relative, const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementMoveTo>(_relative, _pos));
void esvg::render::Path::moveTo(boolean _relative, const Vector2f& _pos) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementMoveTo>(_relative, _pos));
}
void esvg::render::Path::lineTo(bool _relative, const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementLineTo>(_relative, _pos));
void esvg::render::Path::lineTo(boolean _relative, const Vector2f& _pos) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementLineTo>(_relative, _pos));
}
void esvg::render::Path::lineToH(bool _relative, float _posX) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementLineToH>(_relative, _posX));
void esvg::render::Path::lineToH(boolean _relative, float _posX) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementLineToH>(_relative, _posX));
}
void esvg::render::Path::lineToV(bool _relative, float _posY) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementLineToV>(_relative, _posY));
void esvg::render::Path::lineToV(boolean _relative, float _posY) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementLineToV>(_relative, _posY));
}
void esvg::render::Path::curveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementCurveTo>(_relative, _pos1, _pos2, _pos));
void esvg::render::Path::curveTo(boolean _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementCurveTo>(_relative, _pos1, _pos2, _pos));
}
void esvg::render::Path::smoothCurveTo(bool _relative, const Vector2f& _pos2, const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementSmoothCurveTo>(_relative, _pos2, _pos));
void esvg::render::Path::smoothCurveTo(boolean _relative, const Vector2f& _pos2, const Vector2f& _pos) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementSmoothCurveTo>(_relative, _pos2, _pos));
}
void esvg::render::Path::bezierCurveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementBezierCurveTo>(_relative, _pos1, _pos));
void esvg::render::Path::bezierCurveTo(boolean _relative, const Vector2f& _pos1, const Vector2f& _pos) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementBezierCurveTo>(_relative, _pos1, _pos));
}
void esvg::render::Path::bezierSmoothCurveTo(bool _relative, const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementBezierSmoothCurveTo>(_relative, _pos));
void esvg::render::Path::bezierSmoothCurveTo(boolean _relative, const Vector2f& _pos) {
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementBezierSmoothCurveTo>(_relative, _pos));
}
void esvg::render::Path::ellipticTo(bool _relative,
void esvg::render::Path::ellipticTo(boolean _relative,
const Vector2f& _radius,
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
boolean _largeArcFlag,
boolean _sweepFlag,
const Vector2f& _pos) {
m_listElement.pushBack(ememory::makeShared<esvg::render::ElementElliptic>(_relative, _radius, _angle, _largeArcFlag, _sweepFlag, _pos));
this.listElement.pushBack(ememory::makeShared<esvg::render::ElementElliptic>(_relative, _radius, _angle, _largeArcFlag, _sweepFlag, _pos));
}
static const char* spacingDist(int32_t _spacing) {
static const char* spacingDist(int _spacing) {
static const char *tmpValue = " ";
if (_spacing>20) {
_spacing = 20;
@ -68,9 +68,9 @@ static const char* spacingDist(int32_t _spacing) {
return tmpValue + 20*4 - _spacing*4;
}
void esvg::render::Path::display(int32_t _spacing) {
void esvg::render::Path::display(int _spacing) {
Log.debug(spacingDist(_spacing) << "Path");
for(auto &it : m_listElement) {
for(auto &it : this.listElement) {
if (it == null) {
continue;
}
@ -80,13 +80,13 @@ void esvg::render::Path::display(int32_t _spacing) {
void interpolateCubicBezier(List<esvg::render::Point>& _listPoint,
int32_t _recurtionMax,
int _recurtionMax,
float _threshold,
Vector2f _pos1,
Vector2f _pos2,
Vector2f _pos3,
Vector2f _pos4,
int32_t _level,
int _level,
enum esvg::render::Point::type _type) {
if (_level > _recurtionMax) {
return;
@ -122,16 +122,16 @@ static float vectorAngle(Vector2f _uuu, Vector2f _vvv) {
return atan2(_uuu.cross(_vvv), _uuu.dot(_vvv));
}
esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, int32_t _recurtionMax, float _threshold) {
esvg::render::PointList esvg::render::Path::generateListPoints(int _level, int _recurtionMax, float _threshold) {
Log.verbose(spacingDist(_level) << "Generate List Points ... from a path");
esvg::render::PointList out;
List<esvg::render::Point> tmpListPoint;
Vector2f lastPosition(0.0f, 0.0f);
Vector2f lastAngle(0.0f, 0.0f);
int32_t lastPointId = -1;
bool PathStart = false;
int lastPointId = -1;
boolean PathStart = false;
// Foreach element, we move in the path:
for(auto &it : m_listElement) {
for(auto &it : this.listElement) {
if (it == null) {
continue;
}
@ -156,13 +156,13 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
Log.warning(spacingDist(_level+1) << " Request path close of not starting path ...");
} else {
// find the previous tart of the path ...
tmpListPoint.front().m_type = esvg::render::Point::type::join;
tmpListPoint.front().this.type = esvg::render::Point::type::join;
// Remove the last point if it is the same position...
Vector2f delta = (tmpListPoint.front().m_pos - tmpListPoint.back().m_pos).absolute();
Vector2f delta = (tmpListPoint.front().this.pos - tmpListPoint.back().this.pos).absolute();
if ( delta.x() <= 0.00001
&& delta.y() <= 0.00001) {
tmpListPoint.popBack();
Log.verbose(" Remove point Z property : " << tmpListPoint.back().m_pos << " with delta=" << delta);
Log.verbose(" Remove point Z property : " << tmpListPoint.back().this.pos << " with delta=" << delta);
}
out.addList(tmpListPoint);
tmpListPoint.clear();
@ -338,11 +338,11 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
}
{
ememory::SharedPtr<esvg::render::ElementElliptic> tmpIt(ememory::dynamicPointerCast<esvg::render::ElementElliptic>(it));
float angle = tmpIt->m_angle * (M_PI / 180.0);
float angle = tmpIt->this.angle * (M_PI / 180.0);
Log.todo(spacingDist(_level+1) << " Elliptic arc: radius=" << tmpIt->getPos1());
Log.todo(spacingDist(_level+1) << " angle=" << tmpIt->m_angle);
Log.todo(spacingDist(_level+1) << " m_largeArcFlag=" << tmpIt->m_largeArcFlag);
Log.todo(spacingDist(_level+1) << " m_sweepFlag=" << tmpIt->m_sweepFlag);
Log.todo(spacingDist(_level+1) << " angle=" << tmpIt->this.angle);
Log.todo(spacingDist(_level+1) << " this.largeArcFlag=" << tmpIt->this.largeArcFlag);
Log.todo(spacingDist(_level+1) << " this.sweepFlag=" << tmpIt->this.sweepFlag);
Vector2f lastPosStore(lastPosition);
@ -350,11 +350,11 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
lastPosition = Vector2f(0.0f, 0.0f);
}
Vector2f pos = lastPosition + it->getPos();
float rotationX = tmpIt->m_angle * (M_PI / 180.0);
float rotationX = tmpIt->this.angle * (M_PI / 180.0);
Vector2f radius = tmpIt->getPos1();
#ifdef DEBUG
m_debugInformation.addSegment(lastPosStore, pos);
this.debugInformation.addSegment(lastPosStore, pos);
#endif
Vector2f delta = lastPosStore - pos;
float ddd = delta.length();
@ -400,7 +400,7 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
sss = sqrtf(ssa / ssb);
#endif
}
if (tmpIt->m_largeArcFlag == tmpIt->m_sweepFlag) {
if (tmpIt->this.largeArcFlag == tmpIt->this.sweepFlag) {
sss *= -1.0f;
}
Vector2f centerPrime(sss * radius.x() * deltaPrim.y() / radius.y(),
@ -409,15 +409,15 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
mat2x3 matrix = etk::mat2x3Rotate(rotationX);
Vector2f center = (lastPosStore + pos)*0.5f + matrix*centerPrime;
#ifdef DEBUG
m_debugInformation.addSegment(center-Vector2f(3.0,3.0), center+Vector2f(3.0,3.0));
m_debugInformation.addSegment(center-Vector2f(3.0,-3.0), center+Vector2f(3.0,-3.0));
this.debugInformation.addSegment(center-Vector2f(3.0,3.0), center+Vector2f(3.0,3.0));
this.debugInformation.addSegment(center-Vector2f(3.0,-3.0), center+Vector2f(3.0,-3.0));
#endif
// Calculate theta1, and delta theta.
Vector2f vectorA = (deltaPrim - centerPrime) / radius;
Vector2f vectorB = (deltaPrim + centerPrime) / radius * -1.0f;
#ifdef DEBUG
m_debugInformation.addSegment(center, center+vectorA*radius.x());
m_debugInformation.addSegment(center, center+vectorB*radius.y());
this.debugInformation.addSegment(center, center+vectorA*radius.x());
this.debugInformation.addSegment(center, center+vectorB*radius.y());
#endif
// Initial angle
float theta1 = vectorAngle(Vector2f(1.0f,0.0f), vectorA);
@ -426,10 +426,10 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
// special case of invert angle...
if ( ( deltaTheta == float(M_PI)
|| deltaTheta == -float(M_PI))
&& tmpIt->m_sweepFlag == false) {
&& tmpIt->this.sweepFlag == false) {
deltaTheta *= -1.0f;
}
if (tmpIt->m_largeArcFlag == true) {
if (tmpIt->this.largeArcFlag == true) {
// Choose large arc
if (deltaTheta > 0.0f) {
deltaTheta -= 2.0f*M_PI;
@ -442,9 +442,9 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
// Split arc into max 90 degree segments.
// The loop assumes an iteration per end point (including start and end), this +1.
#ifndef __STDCPP_LLVM__
int32_t ndivs = int32_t(etk::abs(deltaTheta) / (M_PI*0.5f)) + 1;
int ndivs = int(etk::abs(deltaTheta) / (M_PI*0.5f)) + 1;
#else
int32_t ndivs = int32_t(fabs(deltaTheta) / (M_PI*0.5f)) + 1;
int ndivs = int(fabs(deltaTheta) / (M_PI*0.5f)) + 1;
#endif
float hda = (deltaTheta / float(ndivs)) * 0.5f;
#ifndef __STDCPP_LLVM__
@ -457,7 +457,7 @@ esvg::render::PointList esvg::render::Path::generateListPoints(int32_t _level, i
}
Vector2f pointPosPrevious(0.0,0.0);
Vector2f tangentPrevious(0.0,0.0);
for (int32_t iii=0; iii<=ndivs; ++iii) {
for (int iii=0; iii<=ndivs; ++iii) {
float a = theta1 + deltaTheta * (float(iii)/(float)ndivs);
#ifndef __STDCPP_LLVM__
delta = Vector2f(etk::cos(a), etk::sin(a));

View File

@ -1,55 +1,51 @@
package org.atriasoft.esvg.render;
import java.util.List;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/render/Element.hpp>
#include <esvg/render/PointList.hpp>
#include <ememory/memory.hpp>
#ifdef DEBUG
#include <esvg/render/SegmentList.hpp>
#endif
namespace esvg {
namespace render {
class Path {
public:
List<ememory::SharedPtr<esvg::render::Element>> m_listElement;
#ifdef DEBUG
esvg::render::SegmentList m_debugInformation;
#endif
public:
Path() {
}
~Path() {
}
void clear();
void stop();
void close(bool _relative=false);
void moveTo(bool _relative, const Vector2f& _pos);
void lineTo(bool _relative, const Vector2f& _pos);
void lineToH(bool _relative, float _posX);
void lineToV(bool _relative, float _posY);
void curveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos);
void smoothCurveTo(bool _relative, const Vector2f& _pos2, const Vector2f& _pos);
void bezierCurveTo(bool _relative, const Vector2f& _pos1, const Vector2f& _pos);
void bezierSmoothCurveTo(bool _relative, const Vector2f& _pos);
void ellipticTo(bool _relative,
class Path {
public List<Element> listElement;
SegmentList debugInformation;
public Path() {
}
void clear();
void stop();
void close(final boolean _relative=false);
void moveTo(final boolean _relative, const Vector2f& _pos);
void lineTo(final boolean _relative, const Vector2f& _pos);
void lineToH(boolean _relative, float _posX);
void lineToV(boolean _relative, float _posY);
void curveTo(final boolean _relative, const Vector2f& _pos1, const Vector2f& _pos2, const Vector2f& _pos);
void smoothCurveTo(final boolean _relative, const Vector2f& _pos2, const Vector2f& _pos);
void bezierCurveTo(final boolean _relative, const Vector2f& _pos1, const Vector2f& _pos);
void bezierSmoothCurveTo(final boolean _relative, const Vector2f& _pos);
void ellipticTo(final boolean _relative,
const Vector2f& _radius,
float _angle,
bool _largeArcFlag,
bool _sweepFlag,
boolean _largeArcFlag,
boolean _sweepFlag,
const Vector2f& _pos);
void display(int32_t _spacing);
esvg::render::PointList generateListPoints(int32_t _level, int32_t _recurtionMax = 10, float _threshold = 0.25f);
void display(int _spacing);esvg::render::PointList generateListPoints(final int _level, final int _recurtionMax = 10, float _threshold = 0.25f);
};
}
}
}}

View File

@ -8,24 +8,24 @@
#include <esvg/debug.hpp>
void esvg::render::Point::setEndPath() {
if (m_type == esvg::render::Point::type::interpolation) {
if (this.type == esvg::render::Point::type::interpolation) {
Log.warning("Request stop path of an interpolate Point");
m_type = esvg::render::Point::type::stop;
this.type = esvg::render::Point::type::stop;
return;
}
if (m_type == esvg::render::Point::type::stop) {
if (this.type == esvg::render::Point::type::stop) {
Log.warning("Request stop path of an STOP Point");
return;
}
if (m_type == esvg::render::Point::type::start) {
m_type = esvg::render::Point::type::single;
if (this.type == esvg::render::Point::type::start) {
this.type = esvg::render::Point::type::single;
return;
}
m_type = esvg::render::Point::type::stop;
this.type = esvg::render::Point::type::stop;
}
void esvg::render::Point::normalize(const Vector2f& _nextPoint) {
m_delta = _nextPoint - m_pos;
m_len = m_delta.length();
this.delta = _nextPoint - this.pos;
this.len = this.delta.length();
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -22,24 +23,24 @@ namespace esvg {
};
public:
// TODO : Clean all element here ...
Vector2f m_pos; //!< position of the point
enum esvg::render::Point::type m_type;
Vector2f m_miterAxe;
Vector2f m_orthoAxePrevious;
Vector2f m_orthoAxeNext;
Vector2f m_posPrevious;
Vector2f m_posNext;
Vector2f m_delta;
float m_len;
Vector2f this.pos; //!< position of the point
enum esvg::render::Point::type this.type;
Vector2f this.miterAxe;
Vector2f this.orthoAxePrevious;
Vector2f this.orthoAxeNext;
Vector2f this.posPrevious;
Vector2f this.posNext;
Vector2f this.delta;
float this.len;
// TODO: Update List to support not having it ...
Point() :
m_pos(0,0),
m_type(esvg::render::Point::type::join) {
this.pos(0,0),
this.type(esvg::render::Point::type::join) {
// nothing to do ...
}
Point(const Vector2f& _pos, enum esvg::render::Point::type _type = esvg::render::Point::type::join) :
m_pos(_pos),
m_type(_type) {
this.pos(_pos),
this.type(_type) {
// nothing to do ...
}
void setEndPath();

View File

@ -12,51 +12,51 @@ esvg::render::PointList::PointList() {
}
void esvg::render::PointList::addList(List<esvg::render::Point>& _list) {
m_data.pushBack(_list);
this.data.pushBack(_list);
// TODO : Add a checker of correct list ...
}
void esvg::render::PointList::applyMatrix(const mat2x3& _transformationMatrix) {
for (auto &it : m_data) {
for (auto &it : this.data) {
for (auto &val : it) {
val.m_pos = _transformationMatrix * val.m_pos;
val.this.pos = _transformationMatrix * val.this.pos;
}
}
}
etk::Pair<Vector2f, Vector2f> esvg::render::PointList::getViewPort() {
etk::Pair<Vector2f, Vector2f> out(Vector2f(9999999999.0,9999999999.0),Vector2f(-9999999999.0,-9999999999.0));
for (auto &it : m_data) {
Pair<Vector2f, Vector2f> esvg::render::PointList::getViewPort() {
Pair<Vector2f, Vector2f> out(Vector2f(9999999999.0,9999999999.0),Vector2f(-9999999999.0,-9999999999.0));
for (auto &it : this.data) {
for (auto &it2 : it) {
out.first.setMin(it2.m_pos);
out.second.setMax(it2.m_pos);
out.first.setMin(it2.this.pos);
out.second.setMax(it2.this.pos);
}
}
return out;
}
void esvg::render::PointList::display() {
Log.verbose(" Display list of points : size=" << m_data.size());
for (auto &it : m_data) {
Log.verbose(" Display list of points : size=" << this.data.size());
for (auto &it : this.data) {
Log.verbose(" Find List " << it.size() << " members");
for (size_t iii=0;
iii < it.size();
++iii) {
switch (it[iii].m_type) {
switch (it[iii].this.type) {
case esvg::render::Point::type::single:
Log.verbose(" [" << iii << "] Find Single " << it[iii].m_pos);
Log.verbose(" [" << iii << "] Find Single " << it[iii].this.pos);
break;
case esvg::render::Point::type::start:
Log.verbose(" [" << iii << "] Find Start " << it[iii].m_pos);
Log.verbose(" [" << iii << "] Find Start " << it[iii].this.pos);
break;
case esvg::render::Point::type::stop:
Log.verbose(" [" << iii << "] Find Stop " << it[iii].m_pos);
Log.verbose(" [" << iii << "] Find Stop " << it[iii].this.pos);
break;
case esvg::render::Point::type::interpolation:
Log.verbose(" [" << iii << "] Find interpolation " << it[iii].m_pos);
Log.verbose(" [" << iii << "] Find interpolation " << it[iii].this.pos);
break;
case esvg::render::Point::type::join:
Log.verbose(" [" << iii << "] Find Join " << it[iii].m_pos);
Log.verbose(" [" << iii << "] Find Join " << it[iii].this.pos);
break;
}
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,24 +6,19 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/math/Matrix2x3.hpp>
#include <etk/Pair.hpp>
#include <esvg/render/Element.hpp>
#include <esvg/render/Point.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<etk/math/Matrix2x3.hpp>#include<etk/Pair.hpp>#include<esvg/render/Element.hpp>#include<esvg/render/Point.hpp>
namespace esvg {
namespace render {
class PointList {
public:
List<List<esvg::render::Point>> m_data;
namespace esvg{namespace render{
class PointList {
public:
List<List<esvg::render::Point>> this.data;
public:
PointList();
void addList(List<esvg::render::Point>& _list);
void display();
void applyMatrix(const mat2x3& _transformationMatrix);
etk::Pair<Vector2f, Vector2f> getViewPort();
};
}
}
void addList(List<esvg::render::Point>& _list);
void display();
void applyMatrix(const mat2x3& _transformationMatrix);
Pair<Vector2f, Vector2f> getViewPort();
};}}

View File

@ -8,31 +8,31 @@
#include <esvg/debug.hpp>
esvg::render::Scanline::Scanline(size_t _size) {
m_data.resize(_size, 0.0f);
this.data.resize(_size, 0.0f);
}
size_t esvg::render::Scanline::size() const {
return m_data.size();
return this.data.size();
}
void esvg::render::Scanline::clear(float _fill) {
for (auto &it : m_data) {
for (auto &it : this.data) {
it = _fill;
}
}
float esvg::render::Scanline::get(int32_t _pos) const {
float esvg::render::Scanline::get(int _pos) const {
if( _pos >= 0
&& size_t(_pos) < m_data.size()) {
return m_data[_pos];
&& size_t(_pos) < this.data.size()) {
return this.data[_pos];
}
return 0;
}
void esvg::render::Scanline::set(int32_t _pos, float _newColor) {
void esvg::render::Scanline::set(int _pos, float _newColor) {
if( _pos >= 0
&& size_t(_pos) < m_data.size()) {
m_data[_pos] = _newColor;
&& size_t(_pos) < this.data.size()) {
this.data[_pos] = _newColor;
}
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,25 +6,26 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>
namespace esvg {
namespace render {
class Scanline {
private:
List<float> m_data;
namespace esvg{namespace render{
class Scanline {
private:
List<float> this.data;
public:
// constructor :
Scanline(size_t _size=32);
Scanline(final size_t _size=32);
// destructor
~Scanline() { };
public:
~
Scanline() {};
public:
size_t size() const;
void clear(float _fill);
float get(int32_t _pos) const;
void set(int32_t _pos, float _newColor);
};
}
}
void clear(float _fill);
float get(final int _pos) const;
void set(int _pos, float _newColor);
};}}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,23 +6,20 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <etk/math/Matrix2x3.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<etk/math/Matrix2x3.hpp>
namespace esvg {
namespace render {
class Segment {
public:
namespace esvg{namespace render{
class Segment {
public:
// TODO: Update List to support not having it ...
Segment();
Segment(const Vector2f& _p0, const Vector2f& _p1);
Segment(const Vector2f& _p0, const Vector2f& _p1);
Vector2f p0;
Vector2f p1;
int32_t direction;
void applyMatrix(const mat2x3& _transformationMatrix);
void createDirection();
};
}
}
int direction;
void applyMatrix(const mat2x3& _transformationMatrix);
void createDirection();
};}}

View File

@ -13,32 +13,32 @@ esvg::render::SegmentList::SegmentList() {
}
#ifdef DEBUG
void esvg::render::SegmentList::addSegment(const Vector2f& _pos0, const Vector2f& _pos1) {
m_data.pushBack(Segment(_pos0, _pos1));
this.data.pushBack(Segment(_pos0, _pos1));
}
#endif
void esvg::render::SegmentList::addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1) {
// Skip horizontal Segments
if (_pos0.m_pos.y() == _pos1.m_pos.y()) {
if (_pos0.this.pos.y() == _pos1.this.pos.y()) {
// remove /0 operation
return;
}
m_data.pushBack(Segment(_pos0.m_pos, _pos1.m_pos));
this.data.pushBack(Segment(_pos0.this.pos, _pos1.this.pos));
}
void esvg::render::SegmentList::addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1, bool _disableHorizontal) {
void esvg::render::SegmentList::addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1, boolean _disableHorizontal) {
// Skip horizontal Segments
if ( _disableHorizontal == true
&& _pos0.m_pos.y() == _pos1.m_pos.y()) {
&& _pos0.this.pos.y() == _pos1.this.pos.y()) {
// remove /0 operation
return;
}
m_data.pushBack(Segment(_pos0.m_pos, _pos1.m_pos));
this.data.pushBack(Segment(_pos0.this.pos, _pos1.this.pos));
}
etk::Pair<Vector2f, Vector2f> esvg::render::SegmentList::getViewPort() {
etk::Pair<Vector2f, Vector2f> out(Vector2f(9999999999.0,9999999999.0),Vector2f(-9999999999.0,-9999999999.0));
for (auto &it : m_data) {
Pair<Vector2f, Vector2f> esvg::render::SegmentList::getViewPort() {
Pair<Vector2f, Vector2f> out(Vector2f(9999999999.0,9999999999.0),Vector2f(-9999999999.0,-9999999999.0));
for (auto &it : this.data) {
out.first.setMin(it.p0);
out.second.setMax(it.p0);
out.first.setMin(it.p1);
@ -47,7 +47,7 @@ etk::Pair<Vector2f, Vector2f> esvg::render::SegmentList::getViewPort() {
return out;
}
void esvg::render::SegmentList::createSegmentList(const esvg::render::PointList& _listPoint) {
for (auto &it : _listPoint.m_data) {
for (auto &it : _listPoint.this.data) {
// Build Segments
for (size_t iii=0, jjj=it.size()-1;
iii < it.size();
@ -78,8 +78,8 @@ void esvg::render::SegmentList::createSegmentListStroke(const Vector2f& _point1,
const Vector2f& _point2,
const Vector2f& _center,
float _width,
bool _isStart) {
int32_t nbDot = int32_t(_width);
boolean _isStart) {
int nbDot = int(_width);
if (nbDot <= 2) {
nbDot = 2;
}
@ -122,7 +122,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
enum esvg::cap _cap,
enum esvg::join _join,
float _miterLimit) {
for (auto &itListPoint : _listPoint.m_data) {
for (auto &itListPoint : _listPoint.this.data) {
// generate for every point all the orthogonal elements
//
// normal edge * end path
@ -137,101 +137,101 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
// . * * . * * * * * * * * * * * * *
// * *
// * *
for (int64_t idPevious=itListPoint.size()-1, idCurrent=0, idNext=1;
idCurrent < int64_t(itListPoint.size());
for (long idPevious=itListPoint.size()-1, idCurrent=0, idNext=1;
idCurrent < long(itListPoint.size());
idPevious = idCurrent++, idNext++) {
if (idNext == int64_t(itListPoint.size())) {
if (idNext == long(itListPoint.size())) {
idNext = 0;
}
if ( itListPoint[idCurrent].m_type == esvg::render::Point::type::join
|| itListPoint[idCurrent].m_type == esvg::render::Point::type::interpolation) {
if ( itListPoint[idCurrent].this.type == esvg::render::Point::type::join
|| itListPoint[idCurrent].this.type == esvg::render::Point::type::interpolation) {
if (idPevious < 0 ) {
Log.error("an error occure a previous ID is < 0.... ");
continue;
}
if (idNext >= int64_t(itListPoint.size())) {
if (idNext >= long(itListPoint.size())) {
Log.error("an error occure a next ID is >= nbPoint len .... ");
continue;
}
//Log.debug("JOIN : id : prev/curr/next : " << idPevious << "/" << idCurrent << "/" << idNext);
//Log.debug("JOIN : val : prev/curr/next : " << itListPoint[idPevious].m_pos << "/" << itListPoint[idCurrent].m_pos << "/" << itListPoint[idNext].m_pos);
Vector2f vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
//Log.debug("JOIN : val : prev/curr/next : " << itListPoint[idPevious].this.pos << "/" << itListPoint[idCurrent].this.pos << "/" << itListPoint[idNext].this.pos);
Vector2f vecA = itListPoint[idCurrent].this.pos - itListPoint[idPevious].this.pos;
//Log.debug("JOIN : vecA : " << vecA);
vecA.safeNormalize();
Vector2f vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
Vector2f vecB = itListPoint[idNext].this.pos - itListPoint[idCurrent].this.pos;
//Log.debug("JOIN : vecB : " << vecB);
vecB.safeNormalize();
Vector2f vecC = vecA - vecB;
//Log.debug("JOIN : vecC : " << vecC);
if (vecC == Vector2f(0.0f, 0.0f)) {
// special case: 1 line ...
itListPoint[idCurrent].m_miterAxe = Vector2f(vecA.y(), vecA.x());
itListPoint[idCurrent].this.miterAxe = Vector2f(vecA.y(), vecA.x());
} else {
vecC.safeNormalize();
itListPoint[idCurrent].m_miterAxe = vecC;
itListPoint[idCurrent].this.miterAxe = vecC;
}
itListPoint[idCurrent].m_posPrevious = itListPoint[idPevious].m_pos;
itListPoint[idCurrent].m_posNext = itListPoint[idNext].m_pos;
vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
itListPoint[idCurrent].this.posPrevious = itListPoint[idPevious].this.pos;
itListPoint[idCurrent].this.posNext = itListPoint[idNext].this.pos;
vecB = itListPoint[idNext].this.pos - itListPoint[idCurrent].this.pos;
vecB.safeNormalize();
itListPoint[idCurrent].m_orthoAxeNext = Vector2f(vecB.y(), -vecB.x());
vecB = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
itListPoint[idCurrent].this.orthoAxeNext = Vector2f(vecB.y(), -vecB.x());
vecB = itListPoint[idCurrent].this.pos - itListPoint[idPevious].this.pos;
vecB.safeNormalize();
itListPoint[idCurrent].m_orthoAxePrevious = Vector2f(vecB.y(), -vecB.x());
//Log.debug("JOIN : miterAxe " << itListPoint[idCurrent].m_miterAxe);
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type::start) {
itListPoint[idCurrent].m_posNext = itListPoint[idNext].m_pos;
Vector2f vecB = itListPoint[idNext].m_pos - itListPoint[idCurrent].m_pos;
itListPoint[idCurrent].this.orthoAxePrevious = Vector2f(vecB.y(), -vecB.x());
//Log.debug("JOIN : miterAxe " << itListPoint[idCurrent].this.miterAxe);
} else if (itListPoint[idCurrent].this.type == esvg::render::Point::type::start) {
itListPoint[idCurrent].this.posNext = itListPoint[idNext].this.pos;
Vector2f vecB = itListPoint[idNext].this.pos - itListPoint[idCurrent].this.pos;
vecB.safeNormalize();
itListPoint[idCurrent].m_miterAxe = Vector2f(vecB.y(), -vecB.x());
itListPoint[idCurrent].m_orthoAxePrevious = itListPoint[idCurrent].m_miterAxe;
itListPoint[idCurrent].m_orthoAxeNext = itListPoint[idCurrent].m_miterAxe;
} else if (itListPoint[idCurrent].m_type == esvg::render::Point::type::stop) {
itListPoint[idCurrent].this.miterAxe = Vector2f(vecB.y(), -vecB.x());
itListPoint[idCurrent].this.orthoAxePrevious = itListPoint[idCurrent].this.miterAxe;
itListPoint[idCurrent].this.orthoAxeNext = itListPoint[idCurrent].this.miterAxe;
} else if (itListPoint[idCurrent].this.type == esvg::render::Point::type::stop) {
if (idPevious < 0 ) {
Log.error("an error occure a previous ID is < 0.... ");
continue;
}
itListPoint[idCurrent].m_posPrevious = itListPoint[idPevious].m_pos;
Vector2f vecA = itListPoint[idCurrent].m_pos - itListPoint[idPevious].m_pos;
itListPoint[idCurrent].this.posPrevious = itListPoint[idPevious].this.pos;
Vector2f vecA = itListPoint[idCurrent].this.pos - itListPoint[idPevious].this.pos;
vecA.safeNormalize();
itListPoint[idCurrent].m_miterAxe = Vector2f(vecA.y(), -vecA.x());
itListPoint[idCurrent].m_orthoAxePrevious = itListPoint[idCurrent].m_miterAxe;
itListPoint[idCurrent].m_orthoAxeNext = itListPoint[idCurrent].m_miterAxe;
itListPoint[idCurrent].this.miterAxe = Vector2f(vecA.y(), -vecA.x());
itListPoint[idCurrent].this.orthoAxePrevious = itListPoint[idCurrent].this.miterAxe;
itListPoint[idCurrent].this.orthoAxeNext = itListPoint[idCurrent].this.miterAxe;
} else {
Log.todo("Unsupported type of point ....");
}
}
// create segment list:
bool haveStartLine = false;
boolean haveStartLine = false;
Vector2f leftPoint(0,0);
Vector2f rightPoint(0,0);
if (itListPoint.size() > 0) {
if (itListPoint.front().m_type == esvg::render::Point::type::join) {
if (itListPoint.front().this.type == esvg::render::Point::type::join) {
const esvg::render::Point& it = itListPoint.back();
// Calculate the perpendiculary axis ...
leftPoint = itListPoint.back().m_pos
+ itListPoint.back().m_orthoAxePrevious*_width*0.5f;
rightPoint = itListPoint.back().m_pos
- itListPoint.back().m_orthoAxePrevious*_width*0.5f;
leftPoint = itListPoint.back().this.pos
+ itListPoint.back().this.orthoAxePrevious*_width*0.5f;
rightPoint = itListPoint.back().this.pos
- itListPoint.back().this.orthoAxePrevious*_width*0.5f;
// cyclic path...
if (it.m_type == esvg::render::Point::type::interpolation) {
leftPoint = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
rightPoint = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
} else if (it.m_type == esvg::render::Point::type::join) {
if (it.this.type == esvg::render::Point::type::interpolation) {
leftPoint = getIntersect(leftPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
rightPoint = getIntersect(rightPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
} else if (it.this.type == esvg::render::Point::type::join) {
// Calculate the perpendiculary axis ...
leftPoint = it.m_pos
+ it.m_orthoAxePrevious*_width*0.5f;
rightPoint = it.m_pos
- it.m_orthoAxePrevious*_width*0.5f;
leftPoint = it.this.pos
+ it.this.orthoAxePrevious*_width*0.5f;
rightPoint = it.this.pos
- it.this.orthoAxePrevious*_width*0.5f;
// project on the miter Axis ...
switch (_join) {
case esvg::join_miter:
{
Vector2f left = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f right = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f left = getIntersect(leftPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
Vector2f right = getIntersect(rightPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
// Check the miter limit:
float limitRight = (left - it.m_pos).length() / _width * 2.0f;
float limitLeft = (right - it.m_pos).length() / _width * 2.0f;
float limitRight = (left - it.this.pos).length() / _width * 2.0f;
float limitLeft = (right - it.this.pos).length() / _width * 2.0f;
Log.verbose(" miter Limit: " << limitRight << " " << limitLeft << " <= " << _miterLimit);
if ( limitRight <= _miterLimit
&& limitLeft <= _miterLimit) {
@ -245,17 +245,17 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
case esvg::join_round:
case esvg::join_bevel:
{
Vector2f axePrevious = (it.m_pos-it.m_posPrevious).safeNormalize();
Vector2f axeNext = (it.m_posNext - it.m_pos).safeNormalize();
Vector2f axePrevious = (it.this.pos-it.this.posPrevious).safeNormalize();
Vector2f axeNext = (it.this.posNext - it.this.pos).safeNormalize();
float cross = axePrevious.cross(axeNext);
if (cross > 0.0f) {
rightPoint = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
leftPoint = it.m_pos
+ it.m_orthoAxeNext*_width*0.5f;
rightPoint = getIntersect(rightPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
leftPoint = it.this.pos
+ it.this.orthoAxeNext*_width*0.5f;
} else {
leftPoint = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
rightPoint = it.m_pos
- it.m_orthoAxeNext*_width*0.5f;
leftPoint = getIntersect(leftPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
rightPoint = it.this.pos
- it.this.orthoAxeNext*_width*0.5f;
}
break;
}
@ -266,13 +266,13 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
}
}
for (auto &it : itListPoint) {
switch (it.m_type) {
switch (it.this.type) {
case esvg::render::Point::type::single:
// just do nothing ....
Log.verbose("Find Single " << it.m_pos);
Log.verbose("Find Single " << it.this.pos);
break;
case esvg::render::Point::type::start:
Log.verbose("Find Start " << it.m_pos);
Log.verbose("Find Start " << it.this.pos);
if (haveStartLine == true) {
// close previous :
Log.warning(" find a non close path ...");
@ -282,7 +282,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
startStopPoint(leftPoint, rightPoint, it, _cap, _width, true);
break;
case esvg::render::Point::type::stop:
Log.verbose("Find Stop " << it.m_pos);
Log.verbose("Find Stop " << it.this.pos);
if (haveStartLine == false) {
Log.warning("find close path without start part ...");
break;
@ -292,9 +292,9 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
break;
case esvg::render::Point::type::interpolation:
{
Log.verbose("Find interpolation " << it.m_pos);
Vector2f left = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f right = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Log.verbose("Find interpolation " << it.this.pos);
Vector2f left = getIntersect(leftPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
Vector2f right = getIntersect(rightPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
//Draw from previous point:
addSegment(leftPoint, left);
Log.verbose(" segment :" << leftPoint << " -> " << left);
@ -305,15 +305,15 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
}
break;
case esvg::render::Point::type::join:
Log.verbose("Find join " << it.m_pos);
Log.verbose("Find join " << it.this.pos);
switch (_join) {
case esvg::join_miter:
{
Vector2f left = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f right = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f left = getIntersect(leftPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
Vector2f right = getIntersect(rightPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
// Check the miter limit:
float limitRight = (left - it.m_pos).length() / _width * 2.0f;
float limitLeft = (right - it.m_pos).length() / _width * 2.0f;
float limitRight = (left - it.this.pos).length() / _width * 2.0f;
float limitLeft = (right - it.this.pos).length() / _width * 2.0f;
Log.verbose(" miter Limit: " << limitRight << " " << limitLeft << " <= " << _miterLimit);
if ( limitRight <= _miterLimit
&& limitLeft <= _miterLimit) {
@ -333,15 +333,15 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
case esvg::join_round:
case esvg::join_bevel:
{
Vector2f axePrevious = (it.m_pos-it.m_posPrevious).safeNormalize();
Vector2f axeNext = (it.m_posNext - it.m_pos).safeNormalize();
Vector2f axePrevious = (it.this.pos-it.this.posPrevious).safeNormalize();
Vector2f axeNext = (it.this.posNext - it.this.pos).safeNormalize();
float cross = axePrevious.cross(axeNext);
if (cross > 0.0f) {
Vector2f right = getIntersect(rightPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f left1 = it.m_pos
+ it.m_orthoAxePrevious*_width*0.5f;
Vector2f left2 = it.m_pos
+ it.m_orthoAxeNext*_width*0.5f;
Vector2f right = getIntersect(rightPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
Vector2f left1 = it.this.pos
+ it.this.orthoAxePrevious*_width*0.5f;
Vector2f left2 = it.this.pos
+ it.this.orthoAxeNext*_width*0.5f;
//Draw from previous point:
addSegment(leftPoint, left1);
Log.verbose(" segment :" << leftPoint << " -> " << left1);
@ -352,7 +352,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
}else {
createSegmentListStroke(left1,
left2,
it.m_pos,
it.this.pos,
_width,
false);
}
@ -361,11 +361,11 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
leftPoint = left2;
rightPoint = right;
} else {
Vector2f left = getIntersect(leftPoint, it.m_pos-it.m_posPrevious, it.m_pos, it.m_miterAxe);
Vector2f right1 = it.m_pos
- it.m_orthoAxePrevious*_width*0.5f;
Vector2f right2 = it.m_pos
- it.m_orthoAxeNext*_width*0.5f;//Draw from previous point:
Vector2f left = getIntersect(leftPoint, it.this.pos-it.this.posPrevious, it.this.pos, it.this.miterAxe);
Vector2f right1 = it.this.pos
- it.this.orthoAxePrevious*_width*0.5f;
Vector2f right2 = it.this.pos
- it.this.orthoAxeNext*_width*0.5f;//Draw from previous point:
addSegment(leftPoint, left);
Log.verbose(" segment :" << leftPoint << " -> " << left);
addSegment(right1, rightPoint);
@ -377,7 +377,7 @@ void esvg::render::SegmentList::createSegmentListStroke(esvg::render::PointList&
} else {
createSegmentListStroke(right1,
right2,
it.m_pos,
it.this.pos,
_width,
true);
}
@ -398,14 +398,14 @@ void esvg::render::SegmentList::startStopPoint(Vector2f& _leftPoint,
const esvg::render::Point& _point,
enum esvg::cap _cap,
float _width,
bool _isStart) {
boolean _isStart) {
switch (_cap) {
case esvg::cap_butt:
{
Vector2f left = _point.m_pos
+ _point.m_miterAxe*_width*0.5f;
Vector2f right = _point.m_pos
- _point.m_miterAxe*_width*0.5f;
Vector2f left = _point.this.pos
+ _point.this.miterAxe*_width*0.5f;
Vector2f right = _point.this.pos
- _point.this.miterAxe*_width*0.5f;
if (_isStart == false) {
//Draw from previous point:
addSegment(_leftPoint, left);
@ -427,10 +427,10 @@ void esvg::render::SegmentList::startStopPoint(Vector2f& _leftPoint,
case esvg::cap_round:
{
if (_isStart == false) {
Vector2f left = _point.m_pos
+ _point.m_miterAxe*_width*0.5f;
Vector2f right = _point.m_pos
- _point.m_miterAxe*_width*0.5f;
Vector2f left = _point.this.pos
+ _point.this.miterAxe*_width*0.5f;
Vector2f right = _point.this.pos
- _point.this.miterAxe*_width*0.5f;
if (_isStart == false) {
//Draw from previous point:
addSegment(_leftPoint, left);
@ -441,19 +441,19 @@ void esvg::render::SegmentList::startStopPoint(Vector2f& _leftPoint,
_leftPoint = left;
_rightPoint = right;
}
int32_t nbDot = int32_t(_width);
int nbDot = int(_width);
if (nbDot <= 2) {
nbDot = 2;
}
float baseAngle = M_PI/float(nbDot);
float iii;
_leftPoint = _point.m_pos
+ _point.m_miterAxe*_width*0.5f;
_rightPoint = _point.m_pos
- _point.m_miterAxe*_width*0.5f;
_leftPoint = _point.this.pos
+ _point.this.miterAxe*_width*0.5f;
_rightPoint = _point.this.pos
- _point.this.miterAxe*_width*0.5f;
createSegmentListStroke(_leftPoint,
_rightPoint,
_point.m_pos,
_point.this.pos,
_width,
_isStart);
}
@ -462,14 +462,14 @@ void esvg::render::SegmentList::startStopPoint(Vector2f& _leftPoint,
{
Vector2f nextAxe;
if (_isStart == true) {
nextAxe = _point.m_posNext - _point.m_pos;
nextAxe = _point.this.posNext - _point.this.pos;
} else {
nextAxe = _point.m_posPrevious - _point.m_pos;
nextAxe = _point.this.posPrevious - _point.this.pos;
}
Vector2f left = _point.m_pos
+ _point.m_miterAxe*_width*0.5f;
Vector2f right = _point.m_pos
- _point.m_miterAxe*_width*0.5f;
Vector2f left = _point.this.pos
+ _point.this.miterAxe*_width*0.5f;
Vector2f right = _point.this.pos
- _point.this.miterAxe*_width*0.5f;
mat2x3 tmpMat = etk::mat2x3Translate(nextAxe.safeNormalize()*_width*-0.5f);
left = tmpMat*left;
right = tmpMat*right;
@ -501,7 +501,7 @@ void esvg::render::SegmentList::startStopPoint(Vector2f& _leftPoint,
}
void esvg::render::SegmentList::applyMatrix(const mat2x3& _transformationMatrix) {
for (auto &it : m_data) {
for (auto &it : this.data) {
it.applyMatrix(_transformationMatrix);
}
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,27 +6,25 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/cap.hpp>
#include <esvg/join.hpp>
#include <esvg/render/Segment.hpp>
#include <esvg/render/PointList.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<esvg/cap.hpp>#include<esvg/join.hpp>#include<esvg/render/Segment.hpp>#include<esvg/render/PointList.hpp>
namespace esvg {
namespace render {
class SegmentList {
namespace esvg{namespace render{
class SegmentList {
public:
List<esvg::render::Segment> this.data;
public:
List<esvg::render::Segment> m_data;
public:
SegmentList();
#ifdef DEBUG
void addSegment(const Vector2f& _pos0, const Vector2f& _pos1);
SegmentList();#ifdef DEBUG
void addSegment(const Vector2f& _pos0, const Vector2f& _pos1);
#endif
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1);
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1, bool _disableHorizontal);
void createSegmentList(const esvg::render::PointList& _listPoint);
void createSegmentListStroke(esvg::render::PointList& _listPoint,
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1);
void addSegment(const esvg::render::Point& _pos0, const esvg::render::Point& _pos1, boolean _disableHorizontal);
void createSegmentList(const esvg::render::PointList& _listPoint);
void createSegmentListStroke(esvg::render::PointList& _listPoint,
float _width,
enum esvg::cap _cap,
enum esvg::join _join,
@ -36,14 +35,14 @@ namespace esvg {
const esvg::render::Point& _point,
enum esvg::cap _cap,
float _width,
bool _isStart);
boolean _isStart);
void createSegmentListStroke(const Vector2f& _point1,
const Vector2f& _point2,
const Vector2f& _center,
float _width,
bool _isStart);
boolean _isStart);
public:
etk::Pair<Vector2f, Vector2f> getViewPort();
Pair<Vector2f, Vector2f> getViewPort();
void applyMatrix(const mat2x3& _transformationMatrix);
};
}

View File

@ -9,12 +9,12 @@
#include <etk/algorithm.hpp>
esvg::render::Weight::Weight() :
m_size(0,0) {
this.size(0,0) {
}
esvg::render::Weight::Weight(const Vector2i& _size) :
m_size(_size) {
this.size(_size) {
resize(_size);
}
@ -23,79 +23,79 @@ esvg::render::Weight::~Weight() {
}
void esvg::render::Weight::resize(const Vector2i& _size) {
m_size = _size;
this.size = _size;
float tmp(0);
m_data.resize(m_size.x()*m_size.y(), tmp);
if ((uint32_t)m_size.x()*m_size.y() > m_data.size()) {
this.data.resize(this.size.x()*this.size.y(), tmp);
if ((uint)this.size.x()*this.size.y() > this.data.size()) {
Log.warning("Wrong weigth buffer size ...");
return;
}
}
const Vector2i& esvg::render::Weight::getSize() const {
return m_size;
return this.size;
}
int32_t esvg::render::Weight::getWidth() const {
return m_size.x();
int esvg::render::Weight::getWidth() const {
return this.size.x();
}
int32_t esvg::render::Weight::getHeight() const {
return m_size.y();
int esvg::render::Weight::getHeight() const {
return this.size.y();
}
void esvg::render::Weight::clear(float _fill) {
for (int32_t iii=0; iii<m_size.x()*m_size.y(); iii++) {
m_data[iii] = _fill;
for (int iii=0; iii<this.size.x()*this.size.y(); iii++) {
this.data[iii] = _fill;
}
}
float esvg::render::Weight::get(const Vector2i& _pos) const {
if ( _pos.x()>=0 && _pos.x()<m_size.x()
&& _pos.y()>=0 && _pos.y()<m_size.y()) {
return m_data[_pos.x()+_pos.y()*m_size.x()];
if ( _pos.x()>=0 && _pos.x()<this.size.x()
&& _pos.y()>=0 && _pos.y()<this.size.y()) {
return this.data[_pos.x()+_pos.y()*this.size.x()];
}
return 0;
}
void esvg::render::Weight::set(const Vector2i& _pos, float _newColor) {
if ( _pos.x()>=0 && _pos.x()<m_size.x()
&& _pos.y()>=0 && _pos.y()<m_size.y()) {
m_data[_pos.x()+_pos.y()*m_size.x()] = _newColor;
if ( _pos.x()>=0 && _pos.x()<this.size.x()
&& _pos.y()>=0 && _pos.y()<this.size.y()) {
this.data[_pos.x()+_pos.y()*this.size.x()] = _newColor;
}
}
void esvg::render::Weight::set(int32_t _posY, const esvg::render::Scanline& _data) {
void esvg::render::Weight::set(int _posY, const esvg::render::Scanline& _data) {
if ( _posY>=0
&& _posY<m_size.y()) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
m_data[xxx+_posY*m_size.x()] = _data.get(xxx);
&& _posY<this.size.y()) {
for (int xxx=0; xxx<this.size.x(); ++xxx) {
this.data[xxx+_posY*this.size.x()] = _data.get(xxx);
}
}
}
void esvg::render::Weight::append(int32_t _posY, const esvg::render::Scanline& _data) {
void esvg::render::Weight::append(int _posY, const esvg::render::Scanline& _data) {
if ( _posY>=0
&& _posY<m_size.y()) {
for (int32_t xxx=0; xxx<m_size.x(); ++xxx) {
m_data[xxx+_posY*m_size.x()] += _data.get(xxx);
&& _posY<this.size.y()) {
for (int xxx=0; xxx<this.size.x(); ++xxx) {
this.data[xxx+_posY*this.size.x()] += _data.get(xxx);
}
}
}
bool sortXPosFunction(const etk::Pair<float,int32_t>& _e1, const etk::Pair<float,int32_t>& _e2) {
boolean sortXPosFunction(const Pair<float,int>& _e1, const Pair<float,int>& _e2) {
return _e1.first < _e2.first;
}
void esvg::render::Weight::generate(Vector2i _size, int32_t _subSamplingCount, const esvg::render::SegmentList& _listSegment) {
void esvg::render::Weight::generate(Vector2i _size, int _subSamplingCount, const esvg::render::SegmentList& _listSegment) {
resize(_size);
// for each lines:
for (int32_t yyy=0; yyy<_size.y(); ++yyy) {
for (int yyy=0; yyy<_size.y(); ++yyy) {
Log.verbose("Weighting ... " << yyy << " / " << _size.y());
// Reduce the number of lines in the subsampling parsing:
List<Segment> availlableSegmentPixel;
for (auto &it : _listSegment.m_data) {
for (auto &it : _listSegment.this.data) {
if ( it.p0.y() < float(yyy+1)
&& it.p1.y() > float(yyy)) {
availlableSegmentPixel.pushBack(it);
@ -107,7 +107,7 @@ void esvg::render::Weight::generate(Vector2i _size, int32_t _subSamplingCount, c
Log.verbose(" Find Basic segments " << availlableSegmentPixel.size());
// This represent the pondaration on the subSampling
float deltaSize = 1.0f/_subSamplingCount;
for (int32_t kkk=0; kkk<_subSamplingCount ; ++kkk) {
for (int kkk=0; kkk<_subSamplingCount ; ++kkk) {
Log.verbose(" Scanline ... " << kkk << " / " << _subSamplingCount);
Scanline scanline(_size.x());
//find all the segment that cross the middle of the line of the center of the pixel line:
@ -135,57 +135,57 @@ void esvg::render::Weight::generate(Vector2i _size, int32_t _subSamplingCount, c
Log.verbose(" Availlable Segment " << it.p0 << " -> " << it.p1 << " dir=" << it.direction);
}
// x position, angle
List<etk::Pair<float, int32_t>> listPosition;
List<Pair<float, int>> listPosition;
for (auto &it : availlableSegment) {
Vector2f delta = it.p0 - it.p1;
// x = coefficent*y+bbb;
float coefficient = delta.x()/delta.y();
float bbb = it.p0.x() - coefficient*it.p0.y();
float xpos = coefficient * subSamplingCenterPos + bbb;
listPosition.pushBack(etk::Pair<float,int32_t>(xpos, it.direction));
listPosition.pushBack(Pair<float,int>(xpos, it.direction));
}
Log.verbose(" List position " << listPosition.size());
// now we order position of the xPosition:
etk::algorithm::quickSort(listPosition, sortXPosFunction);
// move through all element in the point:
int32_t lastState = 0;
int lastState = 0;
float currentValue = 0.0f;
int32_t lastPos = -1;
int32_t currentPos = -1;
int lastPos = -1;
int currentPos = -1;
float lastX = 0.0f;
// * | \---------------/ |
// * current pos
// * pos ...
// TODO : Code the Odd/even and non-zero ...
for (auto &it : listPosition) {
if (currentPos != int32_t(it.first)) {
if (currentPos != int(it.first)) {
// fill to the new pos -1:
#if __CPP_VERSION__ >= 2011 && !defined(__TARGET_OS__MacOs) && !defined(__TARGET_OS__IOs)
float endValue = float(etk::min(1,etk::abs(lastState))) * deltaSize;
#else
float endValue = float(etk::min(1,abs(lastState))) * deltaSize;
#endif
for (int32_t iii=currentPos+1; iii<int32_t(it.first); ++iii) {
for (int iii=currentPos+1; iii<int(it.first); ++iii) {
scanline.set(iii, endValue);
}
currentPos = int32_t(it.first);
currentPos = int(it.first);
currentValue = endValue;
}
int32_t oldState = lastState;
int oldState = lastState;
lastState += it.second;
if (oldState == 0) {
// nothing to draw before ...
float ratio = 1.0f - (it.first - float(int32_t(it.first)));
float ratio = 1.0f - (it.first - float(int(it.first)));
currentValue += ratio * deltaSize;
} else if (lastState == 0) {
// something new to draw ...
float ratio = 1.0f - (it.first - float(int32_t(it.first)));
float ratio = 1.0f - (it.first - float(int(it.first)));
currentValue -= ratio * deltaSize;
} else {
// nothing to do ...
}
if (currentPos == int32_t(it.first)) {
if (currentPos == int(it.first)) {
scanline.set(currentPos, currentValue);
}
}
@ -193,7 +193,7 @@ void esvg::render::Weight::generate(Vector2i _size, int32_t _subSamplingCount, c
if (lastState != 0) {
// just past the last state to the end of the image ...
Log.error("end of Path whith no end ... " << currentPos << " -> " << _size.x());
for (int32_t xxx=currentPos; xxx<_size.x(); ++xxx) {
for (int xxx=currentPos; xxx<_size.x(); ++xxx) {
scanline.set(xxx, 100.0);
}
}

View File

@ -1,3 +1,4 @@
package org.atriasoft.esvg.render;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
@ -5,38 +6,42 @@
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <esvg/render/Scanline.hpp>
#include <esvg/render/SegmentList.hpp>
#include<etk/types.hpp>#include<etk/math/Vector2D.hpp>#include<esvg/render/Scanline.hpp>#include<esvg/render/SegmentList.hpp>
namespace esvg {
namespace render {
class Weight {
private:
Vector2i m_size;
List<float> m_data;
namespace esvg{namespace render{
class Weight {
private:
Vector2i this.size;
List<float> this.data;
public:
// constructor :
Weight();
Weight(const Vector2i& _size);
Weight(const Vector2i& _size);
// destructor
~Weight();
// -----------------------------------------------
// -- basic tools :
// -----------------------------------------------
public:
void resize(const Vector2i& _size);
void resize(const Vector2i& _size);
const Vector2i& getSize() const;
int32_t getWidth() const;
int32_t getHeight() const;
void clear(float _fill);
float get(const Vector2i& _pos) const;
void set(const Vector2i& _pos, float _newColor);
void set(int32_t _posY, const esvg::render::Scanline& _data);
void append(int32_t _posY, const esvg::render::Scanline& _data);
void generate(Vector2i _size, int32_t _subSamplingCount, const esvg::render::SegmentList& _listSegment);
int getWidth() const;
int getHeight() const;
void clear(float _fill);
float get(const Vector2i& _pos) const;
void set(const Vector2i& _pos, float _newColor);
void set(final int _posY, const esvg::render::Scanline& _data);
void append(final int _posY, const esvg::render::Scanline& _data);
void generate(final Vector2i _size, final int _subSamplingCount, const esvg::render::SegmentList& _listSegment);
};
}
}
}}

View File

@ -1,23 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <etk/Stream.hpp>
namespace esvg {
enum spreadMethod {
spreadMethod_pad,
spreadMethod_reflect,
spreadMethod_repeat
};
/**
* @brief Debug operator To display the curent element in a Human redeable information
*/
etk::Stream& operator <<(etk::Stream& _os, enum esvg::spreadMethod _obj);
}

View File

@ -12,4 +12,4 @@
#pragma once
extern bool g_visualDebug;
extern boolean g_visualDebug;

View File

@ -9,13 +9,13 @@
#include <etest/etest.hpp>
#include <etk/etk.hpp>
bool g_visualDebug = false;
boolean g_visualDebug = false;
int main(int _argc, const char *_argv[]) {
etest::init(_argc, _argv);
etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) {
for (int iii=0; iii<_argc ; ++iii) {
etk::String data = _argv[iii];
#ifdef DEBUG
if (data == "--visual-test") {