From b736697ec7b1f55ea56e58d256abe6f9729ddb46 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 11 Apr 2019 14:48:05 +0900 Subject: [PATCH 01/18] vg_common_svg : Add missing eet data descriptor Summary: Add descriptor to get the value of user_space, which is a member of Svg_Style_Gradient. Test Plan: N/A Reviewers: Hermet, smohanty Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8594 --- src/static_libs/vg_common/vg_common_svg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/static_libs/vg_common/vg_common_svg.c b/src/static_libs/vg_common/vg_common_svg.c index d960d9d042..1c33e6454e 100644 --- a/src/static_libs/vg_common/vg_common_svg.c +++ b/src/static_libs/vg_common/vg_common_svg.c @@ -158,6 +158,7 @@ _eet_for_style_gradient(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_eet_style_gradient_node, Svg_Style_Gradient, "type", type, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_eet_style_gradient_node, Svg_Style_Gradient, "id", id, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_eet_style_gradient_node, Svg_Style_Gradient, "spread", spread, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_eet_style_gradient_node, Svg_Style_Gradient, "user_space", user_space, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_LIST(_eet_style_gradient_node, Svg_Style_Gradient, "stops", stops, _eet_gradient_stops_node); EET_DATA_DESCRIPTOR_ADD_SUB(_eet_style_gradient_node, Svg_Style_Gradient, "radial", radial, _eet_radial_gradient_node); EET_DATA_DESCRIPTOR_ADD_SUB(_eet_style_gradient_node, Svg_Style_Gradient, "linear", linear, _eet_linear_gradient_node); From 9dc611784eb6c20c033289c5076a814d37f1bd8e Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 11 Apr 2019 17:18:10 +0900 Subject: [PATCH 02/18] svg_parse: Support gradient when is not declared. Summary: Even if linear or radius gradient is declared, it will not be output if there is no It can be supported because it stores the declared gradient in loader.gradient. Test Plan: N/A Reviewers: Hermet, smohanty Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8591 --- src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c index 4d70b0ee5a..950db2bea1 100644 --- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c +++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c @@ -2297,6 +2297,15 @@ evas_vg_load_file_open_svg(Eina_File *file, defs = loader.doc->node.doc.defs; if (defs) _update_gradient(loader.doc, defs->node.defs.gradients); + else + { + if (loader.gradient) + { + Eina_List* gradient_list = eina_list_append(NULL, loader.gradient); + _update_gradient(loader.doc, gradient_list); + eina_list_free(gradient_list); + } + } *error = EVAS_LOAD_ERROR_NONE; } From c3907032b6de5e24867e15e09af8f9146810a8cc Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Thu, 11 Apr 2019 10:36:53 +0200 Subject: [PATCH 03/18] efl-mono: Allow generating doc refs for methods without class Summary: Methods without a class (global) make the previous code crash because func.klass contains something (it cannot be NULL because it is a reference) but you cannot make much calls on this something. Test Plan: Currently there are no such references, but I need this working for upcoming patches. Reviewers: lauromoura, vitor.sousa Reviewed By: vitor.sousa Subscribers: vitor.sousa, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8585 --- src/bin/eolian_mono/eolian/mono/documentation.hh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh index 1d65bcb076..e7666a922c 100644 --- a/src/bin/eolian_mono/eolian/mono/documentation.hh +++ b/src/bin/eolian_mono/eolian/mono/documentation.hh @@ -104,8 +104,7 @@ struct documentation_generator static std::string function_conversion(attributes::function_def const& func) { - attributes::klass_def klass(get_klass(func.klass, func.unit), func.unit); - std::string name = name_helpers::klass_full_concrete_or_interface_name(klass); + std::string name = name_helpers::klass_full_concrete_or_interface_name(func.klass); switch (func.type) { // managed_method_name takes care of reordering the function name so the get/set goes first @@ -114,8 +113,8 @@ struct documentation_generator case attributes::function_type::prop_set: case attributes::function_type::prop_get: if (blacklist::is_function_blacklisted(func.c_name))return ""; - name += "."; - name += name_helpers::managed_method_name(klass.eolian_name, func.name); + if (!name.empty()) name += "."; + name += name_helpers::managed_method_name(func.klass.eolian_name, func.name); break; default: // No need to deal with property as function_defs are converted to get/set when building a given klass_def. From 748070125ff43c001feb8e191cf2be8d0f59d01d Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Thu, 11 Apr 2019 10:37:33 +0200 Subject: [PATCH 04/18] efl-mono: Allow doc XML tags to be nested Summary: This allows inserting nested tags like: bla bla bla The generate_tag_example() is currently unused but serves as an example. Depends on D8585 Test Plan: Not much, unless you want to manually call generate_tag_example() (Which I have done, and it works, I promise). Reviewers: lauromoura, vitor.sousa Reviewed By: vitor.sousa Subscribers: vitor.sousa, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8587 --- .../eolian_mono/eolian/mono/documentation.hh | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh index e7666a922c..c46cbd4231 100644 --- a/src/bin/eolian_mono/eolian/mono/documentation.hh +++ b/src/bin/eolian_mono/eolian/mono/documentation.hh @@ -244,7 +244,19 @@ struct documentation_generator /// Tag generator helpers template - bool generate_tag(OutputIterator sink, std::string const& tag, std::string const &text, Context const& context, std::string tag_params = "") const + bool generate_opening_tag(OutputIterator sink, std::string const& tag, Context const& context, std::string tag_params = "") const + { + return as_generator("<" << tag << tag_params << ">").generate(sink, attributes::unused, context); + } + + template + bool generate_closing_tag(OutputIterator sink, std::string const& tag, Context const& context) const + { + return as_generator("").generate(sink, attributes::unused, context); + } + + template + bool generate_escaped_content(OutputIterator sink, std::string const &text, Context const& context) const { std::string new_text; if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context)) @@ -256,14 +268,24 @@ struct documentation_generator std::istringstream ss(new_text); std::string para; - std::string final_text = "<" + tag + tag_params + ">"; + std::string final_text; bool first = true; while (std::getline(ss, para)) { if (first) final_text += para; else final_text += "\n" + tabs + para; first = false; } - return as_generator(scope_tab(scope_size) << "/// " << final_text << "\n").generate(sink, attributes::unused, context); + return as_generator(final_text).generate(sink, attributes::unused, context); + } + + template + bool generate_tag(OutputIterator sink, std::string const& tag, std::string const &text, Context const& context, std::string tag_params = "") const + { + if (!as_generator(scope_tab(scope_size) << "/// ").generate(sink, attributes::unused, context)) return false; + if (!generate_opening_tag(sink, tag, context, tag_params)) return false; + if (!generate_escaped_content(sink, text, context)) return false; + if (!generate_closing_tag(sink, tag, context)) return false; + return as_generator("\n").generate(sink, attributes::unused, context); } template @@ -290,6 +312,18 @@ struct documentation_generator return generate_tag(sink, "value", text, context); } + template + bool generate_tag_example(OutputIterator sink, std::string const& example, Context const& context) const + { + if (!as_generator(scope_tab(scope_size) << "/// ").generate(sink, attributes::unused, context)) return false; + if (!generate_opening_tag(sink, "example", context)) return false; + if (!generate_opening_tag(sink, "code", context)) return false; + if (!generate_escaped_content(sink, example, context)) return false; + if (!generate_closing_tag(sink, "code", context)) return false; + if (!generate_closing_tag(sink, "example", context)) return false; + return as_generator("\n").generate(sink, attributes::unused, context); + } + // Actual exported generators template bool generate(OutputIterator sink, Attribute const& attr, Context const& context) const From 04a41a37127e4491428ebce70689c180cb12418a Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Thu, 11 Apr 2019 10:38:40 +0200 Subject: [PATCH 05/18] mono-docs: Allow embedding external examples Summary: New option added to eolian_gen: -e This specifies a directory to search for examples. If a file is found with the same name as an EFL C# class (e.g. Efl.Ui.Button.cs) or as an EFL C# method or property (e.g. Efl.IText.Text.cs, Efl.IText.SetText.cs) its full contents will be embedded in the documentation for that class or method within and tags. This is, in turn, is parsed by DocFX and shown in Example boxes in the generated pages. If an example file is not found, no examples are embedded for that object. If -e is not used, no examples are embedded for any object. New option added to meson: mono-examples-dir to point to the examples directory. This directory is then passed to eolian_mono through -e. Do not use it (or define it to nothing) to disable example embedding. No performance drop has been observed because of these extra tests. Right now examples can only be given for base classes, not for derived ones (i.e. Efl.IText.Text but not Efl.Ui.Button.Text). This will be addressed in a later commit. Feature Depends on D8587 Test Plan: Create an examples folder and put some files in it: ``` mkdir /tmp/examples echo 'var button = new Efl.Ui.Button();' > /tmp/examples/Efl.Ui.Button.cs echo 'button.AutoRepeatEnabled = true;' > /tmp/examples/Efl.Ui.IAutorepeat.AutorepeatEnabled.cs echo 'button.SetAutoRepeatEnabled(true);' > /tmp/examples/Efl.Ui.IAutorepeat.SetAutorepeatEnabled.cs ``` Configure meson to embed examples and build: ``` meson configure -Dmono-examples-dir=/tmp/examples ninja ``` Examine the generated efl_ui_button.eo.cs file to see embedded tags, or run DocFX and bask in the glory of documentation pages with examples: ``` cd doc/docfx ./gendoc.sh ``` Reviewers: lauromoura, felipealmeida, vitor.sousa, zmike, bu5hm4n Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8592 --- meson_options.txt | 6 ++++ .../eolian_mono/eolian/mono/documentation.hh | 34 +++++++++++++++---- .../eolian/mono/generation_contexts.hh | 1 + src/bin/eolian_mono/eolian_mono.cc | 13 +++++-- src/bindings/mono/meson.build | 1 + 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index 105f4cf9cb..0b6b0bb917 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -323,6 +323,12 @@ option('mono-beta', description: 'Flag for enabling @beta Eo methods in the api' ) +option('mono-examples-dir', + type: 'string', + value: '', + description: 'Directory where eolian_mono will search for examples to embed into the documentation' +) + option('lua-interpreter', type: 'combo', choices: ['luajit', 'lua'], diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh index c46cbd4231..0460b5783e 100644 --- a/src/bin/eolian_mono/eolian/mono/documentation.hh +++ b/src/bin/eolian_mono/eolian/mono/documentation.hh @@ -313,12 +313,22 @@ struct documentation_generator } template - bool generate_tag_example(OutputIterator sink, std::string const& example, Context const& context) const + bool generate_tag_example(OutputIterator sink, std::string const& object_name, Context const& context) const { + auto options = efl::eolian::grammar::context_find_tag(context); + // Example embedding not requested + if (options.examples_dir.empty()) return true; + std::string file_name = options.examples_dir + object_name + ".cs"; + std::ifstream exfile(file_name); + // There is no example file for this class or method, just return + if (!exfile.good()) return true; + std::stringstream example_buff; + example_buff << exfile.rdbuf(); + if (!as_generator(scope_tab(scope_size) << "/// ").generate(sink, attributes::unused, context)) return false; if (!generate_opening_tag(sink, "example", context)) return false; if (!generate_opening_tag(sink, "code", context)) return false; - if (!generate_escaped_content(sink, example, context)) return false; + if (!generate_escaped_content(sink, example_buff.str(), context)) return false; if (!generate_closing_tag(sink, "code", context)) return false; if (!generate_closing_tag(sink, "example", context)) return false; return as_generator("\n").generate(sink, attributes::unused, context); @@ -331,6 +341,15 @@ struct documentation_generator return generate(sink, attr.documentation, context); } + template + bool generate(OutputIterator sink, attributes::klass_def const& klass, Context const& context) const + { + if (!generate(sink, klass.documentation, context)) return false; + + std::string klass_name = name_helpers::klass_full_concrete_or_interface_name(klass); + return generate_tag_example(sink, klass_name, context); + } + template bool generate(OutputIterator sink, attributes::property_def const& prop, Context const& context) const { @@ -343,9 +362,12 @@ struct documentation_generator else if (prop.getter.is_engaged()) text = prop.getter->return_documentation.full_text; // If there are no docs at all, do not generate tag - else return true; + if (!text.empty()) + if (!generate_tag_value(sink, text, context)) return false; - return generate_tag_value(sink, text, context); + std::string managed_name = name_helpers::klass_full_concrete_or_interface_name(prop.klass); + managed_name += "." + name_helpers::property_managed_name(prop); + return generate_tag_example(sink, managed_name, context); } template @@ -381,7 +403,7 @@ struct documentation_generator if (!generate_tag_return(sink, func.return_documentation.full_text, context)) return false; - return true; + return generate_tag_example(sink, function_conversion(func), context); } template @@ -397,7 +419,7 @@ struct documentation_generator if (!generate_tag_return(sink, func.return_documentation.full_text, context)) return false; - return true; + return generate_tag_example(sink, function_conversion(func), context); } template diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh index 25ac3098fb..ff6c0391ba 100644 --- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh +++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh @@ -78,6 +78,7 @@ struct eolian_state_context { struct options_context { bool want_beta; + std::string examples_dir; }; } diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc index 0fcc63fa42..8f24f762f0 100644 --- a/src/bin/eolian_mono/eolian_mono.cc +++ b/src/bin/eolian_mono/eolian_mono.cc @@ -43,6 +43,7 @@ struct options_type std::vector include_dirs; std::string in_file; std::string out_file; + std::string examples_dir; std::string dllimport; mutable Eolian_State* state; mutable Eolian_Unit const* unit; @@ -145,7 +146,8 @@ run(options_type const& opts) auto context = context_add_tag(eolian_mono::indentation_context{0}, context_add_tag(eolian_mono::eolian_state_context{opts.state}, - context_add_tag(eolian_mono::options_context{opts.want_beta}, + context_add_tag(eolian_mono::options_context{opts.want_beta, + opts.examples_dir}, context_add_tag(eolian_mono::library_context{opts.dllimport, opts.v_major, opts.v_minor, @@ -294,6 +296,7 @@ _usage(const char *progname) << " -r, --recurse Recurse input directories loading .eo files." << std::endl << " -v, --version Print the version." << std::endl << " -b, --beta Enable @beta methods." << std::endl + << " -e, --example-dir Folder to search for example files." << std::endl << " -h, --help Print this help." << std::endl; exit(EXIT_FAILURE); } @@ -324,9 +327,10 @@ opts_get(int argc, char **argv) { "vmin", required_argument, 0, 'm' }, { "references", required_argument, 0, 'r'}, { "beta", no_argument, 0, 'b'}, + { "example-dir", required_argument, 0, 'e' }, { 0, 0, 0, 0 } }; - const char* options = "I:D:o:c:M:m:ar:vhb"; + const char* options = "I:D:o:c:M:m:ar:vhbe:"; int c, idx; while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1) @@ -382,6 +386,11 @@ opts_get(int argc, char **argv) { opts.want_beta = true; } + else if (c == 'e') + { + opts.examples_dir = optarg; + if (!opts.examples_dir.empty() && opts.examples_dir.back() != '/') opts.examples_dir += "/"; + } } if (optind == argc-1) { diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build index dc2c856404..e7c5e00d9a 100644 --- a/src/bindings/mono/meson.build +++ b/src/bindings/mono/meson.build @@ -127,6 +127,7 @@ foreach lib : mono_sublibs command : [eolian_mono_gen, beta_option, '-I', meson.current_source_dir(), eolian_include_directories, '--dllimport', package_name, '-o', join_paths(meson.current_build_dir(), mono_gen_file + '.cs'), + '-e', get_option('mono-examples-dir'), '@INPUT@']) endif endforeach From 83d5ea1a42c2f80593e18aeefddc8bc964cf82f1 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 11 Apr 2019 19:12:40 +0900 Subject: [PATCH 06/18] ector_software_rasterizer: Implement mask blending function. Summary: Add Mask blend function(Add, Substract, Intersect, Difference) this blending function only use mask blending case. Test Plan: N/A Reviewers: Hermet Reviewed By: Hermet Subscribers: cedric, kimcinoo, #reviewers, smohanty, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8509 --- .../software/ector_software_rasterizer.c | 173 +++++++++++++++++- 1 file changed, 163 insertions(+), 10 deletions(-) diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c index d9b3351248..b2b5779f69 100644 --- a/src/lib/ector/software/ector_software_rasterizer.c +++ b/src/lib/ector/software/ector_software_rasterizer.c @@ -11,8 +11,23 @@ #include "draw.h" +//FIXME: This enum add temporarily to help understanding of additional code +//related to masking in prepare_mask. +//This needs to be formally declared through the eo class. +typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE +{ + EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE +}EFL_CANVAS_VG_NODE_BLEND_TYPE; +// + static void -_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) +_blend_argb(int count, const SW_FT_Span *spans, void *user_data) { Span_Data *sd = user_data; uint32_t color, *buffer, *target; @@ -34,7 +49,7 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) } static void -_blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data) +_blend_alpha(int count, const SW_FT_Span *spans, void *user_data) { Span_Data *sd = user_data; const int pix_stride = sd->raster_buffer->stride / 4; @@ -77,7 +92,7 @@ _blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data } static void -_blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_data) +_blend_alpha_inv(int count, const SW_FT_Span *spans, void *user_data) { Span_Data *sd = user_data; const int pix_stride = sd->raster_buffer->stride / 4; @@ -120,6 +135,122 @@ _blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_d } } +static void +_blend_mask_add(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mbuffer = mask->pixels.u32; + + while (count--) + { + uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len); + memset(ttarget, 0x00, sizeof(uint32_t) * spans->len); + uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + for (int i = 0; i < spans->len; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255; + uint32_t aout = (int)(((adst * (1 - asrc)) + asrc) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } + ++spans; + } +} + +static void +_blend_mask_sub(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mtarget = mask->pixels.u32; + + int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h; + uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize); + memset(tbuffer, 0x00, sizeof(uint32_t) * tsize); + + while (count--) + { + uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + ++spans; + } + + for(int i = 0; i < tsize; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255; + uint32_t aout = (int)((adst * (1 - asrc)) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } +} + + +static void +_blend_mask_ins(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mtarget = mask->pixels.u32; + + int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h; + uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize); + memset(tbuffer, 0x00, sizeof(uint32_t) * tsize); + + while (count--) + { + uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + ++spans; + } + + for(int i = 0; i < tsize; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255; + uint32_t aout = (int)((adst * asrc) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } +} + + +static void +_blend_mask_diff(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mbuffer = mask->pixels.u32; + + while (count--) + { + uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len); + memset(ttarget, 0x00, sizeof(uint32_t) * spans->len); + uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + for (int i = 0; i < spans->len; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255; + uint32_t aout = (int)((((1 - adst) * asrc) + ((1 - asrc) * adst)) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } + ++spans; + } +} + #define BLEND_GRADIENT_BUFFER_SIZE 2048 typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length); @@ -362,14 +493,32 @@ _adjust_span_fill_methods(Span_Data *spdata) case Solid: { if (spdata->mask) - { - if (spdata->mask_op == 2) - spdata->unclipped_blend = &_blend_color_argb_with_maskInvA; - else - spdata->unclipped_blend = &_blend_color_argb_with_maskA; - } + { + switch (spdata->mask_op) + { + default: + case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA: + spdata->unclipped_blend = &_blend_alpha; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV: + spdata->unclipped_blend = &_blend_alpha_inv; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD: + spdata->unclipped_blend = &_blend_mask_add; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT: + spdata->unclipped_blend = &_blend_mask_sub; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT: + spdata->unclipped_blend = &_blend_mask_ins; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE: + spdata->unclipped_blend = &_blend_mask_diff; + break; + } + } else - spdata->unclipped_blend = &_blend_color_argb; + spdata->unclipped_blend = &_blend_argb; } break; case LinearGradient: @@ -378,6 +527,10 @@ _adjust_span_fill_methods(Span_Data *spdata) break; } + //FIXME: Mask and mask case is not use clipping. + if (spdata->mask_op >= EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD) + spdata->clip.enabled = EINA_FALSE; + // Clipping Function if (spdata->clip.enabled) { From b849ad902207dda976f6470df6e32b9d8aa40385 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 11 Apr 2019 19:20:03 +0900 Subject: [PATCH 07/18] efl_canvas_vg_container : Support mask tree for multiple mask. Summary: If another mask is set in the mask source, the rendering of the mask is performed in order. The mask will render one buffer in order. And depending on some types, the initial values of the buffers may be different. (alpha zero or 255). If the implementation for masking is efl_canvas_vg_node_mask_set(layer, mask1, MASKADD); efl_canvas_vg_node_mask_set(mask1, mask2, MASKSUBSTRACT); efl_canvas_vg_node_mask_set(mask3, mask4, MASKINTERSECT); Supports rendering for consecutive masks. Reviewers: Hermet, cedric Reviewed By: Hermet Subscribers: #reviewers, #committers, smohanty, kimcinoo Tags: #efl Differential Revision: https://phab.enlightenment.org/D8517 --- src/lib/evas/canvas/efl_canvas_vg_container.c | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c index 699ea8dccc..7623401896 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_container.c +++ b/src/lib/evas/canvas/efl_canvas_vg_container.c @@ -5,6 +5,23 @@ #define MY_CLASS EFL_CANVAS_VG_CONTAINER_CLASS + +//FIXME: This enum add temporarily to help understanding of additional code +//related to masking in prepare_mask. +//This needs to be formally declared through the eo class. +//This is a list of blending supported via efl_canvas_vg_node_mask_set(). +typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE +{ + EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE +}EFL_CANVAS_VG_NODE_BLEND_TYPE; +// + static void _invalidate_cb(void *data EINA_UNUSED, const Efl_Event *event) { @@ -53,6 +70,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object void *engine, void *output, void *context, Ector_Surface *surface, Eina_Matrix3 *ptransform, + Eina_Matrix3 *ctransform, Ector_Buffer *mask, int mask_op) { @@ -60,6 +78,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(mask_obj, EFL_CANVAS_VG_NODE_CLASS); if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return pd->mask.buffer; + uint32_t init_buffer = 0x0; //1. Mask Size Eina_Rect mbound; @@ -68,7 +87,9 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object mbound.w = obj->cur->geometry.w; mbound.h = obj->cur->geometry.h; -// efl_gfx_path_bounds_get(mask, &mbound); + //FIXME: If mask typs is SUBSTRACT or INTERSECT, buffer fills in white color(Full alpha color). + if (pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT || pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT) + init_buffer = 0xFFFFFFFF; //2. Reusable ector buffer? if (!pd->mask.buffer || (pd->mask.bound.w != mbound.w) || @@ -76,7 +97,8 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object { if (pd->mask.pixels) free(pd->mask.pixels); if (pd->mask.buffer) efl_unref(pd->mask.buffer); - pd->mask.pixels = calloc(sizeof(uint32_t), mbound.w * mbound.h); + pd->mask.pixels = malloc(sizeof(uint32_t) * (mbound.w * mbound.h)); + memset(pd->mask.pixels, init_buffer, sizeof(uint32_t) * (mbound.w * mbound.h)); pd->mask.buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas, mbound.w, mbound.h, EFL_GFX_COLORSPACE_ARGB8888, @@ -93,7 +115,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object else { if (pd->mask.pixels) - memset(pd->mask.pixels, 0x0, sizeof(uint32_t) * mbound.w * mbound.h); + memset(pd->mask.pixels, init_buffer, sizeof(uint32_t) * mbound.w * mbound.h); } pd->mask.bound.x = mbound.x; @@ -101,6 +123,22 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object if (!pd->mask.buffer) ERR("Mask Buffer is invalid"); + //FIXME: This code means that there is another masking container. + if (pd->mask.option != EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE) + { + Efl_Canvas_Vg_Container_Data *src_pd = pd; + mask = pd->mask.buffer; + for (Efl_VG *mask_src = pd->mask_src; mask_src; mask_src = src_pd->mask_src) + { + Efl_Canvas_Vg_Container_Data *target_pd = NULL; + src_pd = efl_data_scope_get(mask_src, MY_CLASS); + target_pd = efl_data_scope_get(eina_list_nth(src_pd->mask.target, 0), MY_CLASS); + _evas_vg_render_pre(obj, mask_src, + engine, output, context, surface, + ctransform, mask, target_pd->mask.option); + } + } + //3. Prepare Drawing shapes. _evas_vg_render_pre(obj, mask_obj, engine, output, context, @@ -140,12 +178,12 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd, EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); //Container may have mask source. - if (pd->mask_src) + if (pd->mask_src && !pd->mask.target) { + mask_op = pd->mask.option; mask = _prepare_mask(vg_pd, pd->mask_src, engine, output, context, surface, - ptransform, mask, mask_op); - mask_op = pd->mask.option; + ptransform, ctransform, mask, mask_op); } EINA_LIST_FOREACH(pd->children, l, child) From 479488335c587e0a2ffe7e468f52b6062a40533d Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Thu, 11 Apr 2019 13:18:33 +0200 Subject: [PATCH 08/18] mono-docs: Properly indent code examples First code line was indented differently by DocFX because of tabs, whitespace or who knows what. This adds a newline after the tag so all code lines have the same indentation. --- src/bin/eolian_mono/eolian/mono/documentation.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh index 0460b5783e..d603e0bb99 100644 --- a/src/bin/eolian_mono/eolian/mono/documentation.hh +++ b/src/bin/eolian_mono/eolian/mono/documentation.hh @@ -323,7 +323,8 @@ struct documentation_generator // There is no example file for this class or method, just return if (!exfile.good()) return true; std::stringstream example_buff; - example_buff << exfile.rdbuf(); + // Start with a newline so the first line renders with same indentation as the rest + example_buff << std::endl << exfile.rdbuf(); if (!as_generator(scope_tab(scope_size) << "/// ").generate(sink, attributes::unused, context)) return false; if (!generate_opening_tag(sink, "example", context)) return false; From b17e7fa95ba513139ab98572251edcb36d087345 Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Thu, 11 Apr 2019 20:14:43 +0900 Subject: [PATCH 09/18] efl_ui_list: fix to delete sub objects in efl_object_invalidate widget's sub objects and callbacks should be deleted in efl_object_invalidate instead of efl_object_destructor. @fix --- src/lib/elementary/efl_ui_list.c | 6 ++++-- src/lib/elementary/efl_ui_list.eo | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/elementary/efl_ui_list.c b/src/lib/elementary/efl_ui_list.c index 1cb6f1061e..978aae3271 100644 --- a/src/lib/elementary/efl_ui_list.c +++ b/src/lib/elementary/efl_ui_list.c @@ -467,7 +467,7 @@ _efl_ui_list_efl_object_finalize(Eo *obj, } EOLIAN static void -_efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd) +_efl_ui_list_efl_object_invalidate(Eo *obj, Efl_Ui_List_Data *pd) { _scroll_edje_object_detach(obj); @@ -488,12 +488,14 @@ _efl_ui_list_efl_object_destructor(Eo *obj, Efl_Ui_List_Data *pd) efl_del(pd->box); pd->box = NULL; + efl_del(pd->pan); pd->pan = NULL; + efl_del(pd->smanager); pd->smanager = NULL; - efl_destructor(efl_super(obj, MY_CLASS)); + efl_invalidate(efl_super(obj, MY_CLASS)); } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_list.eo b/src/lib/elementary/efl_ui_list.eo index 988c78c5cc..8a77e37261 100644 --- a/src/lib/elementary/efl_ui_list.eo +++ b/src/lib/elementary/efl_ui_list.eo @@ -42,7 +42,7 @@ class @beta Efl.Ui.List extends Efl.Ui.Layout_Base implements //Efl.Object Efl.Object.constructor; Efl.Object.finalize; - Efl.Object.destructor; + Efl.Object.invalidate; //Efl.Canvas Efl.Canvas.Group.group_calculate; From a12bd0ad305eccc983ed6cba658b80105620748d Mon Sep 17 00:00:00 2001 From: Vincent Torri Date: Thu, 11 Apr 2019 17:51:13 +0100 Subject: [PATCH 10/18] elementary: rename ELEMENTARY_BUILD to EFL_BUILD like all other libs Test Plan: compilation Reviewers: cedric, raster, zmike Subscribers: #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8598 --- src/lib/elementary/Elementary.h | 4 ++-- src/lib/elementary/elementary_config.h | 2 +- src/lib/elementary/elm_module_helper.h | 2 +- src/lib/elementary/elm_priv.h | 2 +- src/modules/elementary/access_output/mod.c | 4 +++- .../elementary/clock_input_ctxpopup/clock_input_ctxpopup.c | 4 +++- src/modules/elementary/prefs/prefs_iface.c | 4 +++- src/modules/elementary/test_entry/mod.c | 4 +++- src/modules/elementary/test_map/mod.c | 4 +++- src/modules/elementary/web/none/elm_web_none.c | 4 +++- 10 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 119a3edfaa..67688ea155 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -87,7 +87,7 @@ #endif #ifdef _WIN32 -# ifdef ELEMENTARY_BUILD +# ifdef EFL_BUILD # ifdef DLL_EXPORT # define EAPI __declspec(dllexport) # else @@ -384,7 +384,7 @@ typedef Eo Efl_Ui_Pager; } #endif -#ifndef ELEMENTARY_BUILD +#ifndef EFL_BUILD # undef EAPI # define EAPI #endif diff --git a/src/lib/elementary/elementary_config.h b/src/lib/elementary/elementary_config.h index 9bff045c04..6074510b0d 100644 --- a/src/lib/elementary/elementary_config.h +++ b/src/lib/elementary/elementary_config.h @@ -9,7 +9,7 @@ #define ELM_CONFIG_ICON_THEME_ELEMENTARY "_Elementary_Icon_Theme" -#if defined(ELEMENTARY_BUILD) || defined(ELM_INTERNAL_API_ARGESFSDFEFC) +#if defined(EFL_BUILD) || defined(ELM_INTERNAL_API_ARGESFSDFEFC) #define EFL_UI_WIDGET_PROTECTED #define EFL_CANVAS_OBJECT_PROTECTED #define EFL_CANVAS_GROUP_PROTECTED diff --git a/src/lib/elementary/elm_module_helper.h b/src/lib/elementary/elm_module_helper.h index 8f882dabaa..eba3237266 100644 --- a/src/lib/elementary/elm_module_helper.h +++ b/src/lib/elementary/elm_module_helper.h @@ -13,7 +13,7 @@ #endif #ifdef _WIN32 -# ifdef ELEMENTARY_BUILD +# ifdef EFL_BUILD # ifdef DLL_EXPORT # define EAPI __declspec(dllexport) # else diff --git a/src/lib/elementary/elm_priv.h b/src/lib/elementary/elm_priv.h index 54c32cf9a6..fa262e2646 100644 --- a/src/lib/elementary/elm_priv.h +++ b/src/lib/elementary/elm_priv.h @@ -35,7 +35,7 @@ # endif # ifdef _WIN32 -# ifdef ELEMENTARY_BUILD +# ifdef EFL_BUILD # ifdef DLL_EXPORT # define EAPI __declspec(dllexport) # else diff --git a/src/modules/elementary/access_output/mod.c b/src/modules/elementary/access_output/mod.c index f1c9dafd46..f51b512a47 100644 --- a/src/modules/elementary/access_output/mod.c +++ b/src/modules/elementary/access_output/mod.c @@ -4,7 +4,9 @@ #include "Elementary.h" -#define ELEMENTARY_BUILD +#ifndef EFL_BUILD +# define EFL_BUILD +#endif #undef ELM_MODULE_HELPER_H #include "elm_module_helper.h" diff --git a/src/modules/elementary/clock_input_ctxpopup/clock_input_ctxpopup.c b/src/modules/elementary/clock_input_ctxpopup/clock_input_ctxpopup.c index 5daabebe0a..077bd7d14e 100644 --- a/src/modules/elementary/clock_input_ctxpopup/clock_input_ctxpopup.c +++ b/src/modules/elementary/clock_input_ctxpopup/clock_input_ctxpopup.c @@ -9,7 +9,9 @@ #include "elm_ctxpopup_item_eo.h" #include "elm_ctxpopup_eo.h" -#define ELEMENTARY_BUILD +#ifndef EFL_BUILD +# define EFL_BUILD +#endif #undef ELM_MODULE_HELPER_H #include "elm_module_helper.h" diff --git a/src/modules/elementary/prefs/prefs_iface.c b/src/modules/elementary/prefs/prefs_iface.c index 4943cd4566..d09658a052 100644 --- a/src/modules/elementary/prefs/prefs_iface.c +++ b/src/modules/elementary/prefs/prefs_iface.c @@ -4,7 +4,9 @@ #include "Elementary.h" -#define ELEMENTARY_BUILD +#ifndef EFL_BUILD +# define EFL_BUILD +#endif #undef ELM_MODULE_HELPER_H #include "private.h" diff --git a/src/modules/elementary/test_entry/mod.c b/src/modules/elementary/test_entry/mod.c index 0d16e22226..b80cb182ce 100644 --- a/src/modules/elementary/test_entry/mod.c +++ b/src/modules/elementary/test_entry/mod.c @@ -4,7 +4,9 @@ #include "Elementary.h" -#define ELEMENTARY_BUILD +#ifndef EFL_BUILD +# define EFL_BUILD +#endif #undef ELM_MODULE_HELPER_H #include "elm_module_helper.h" diff --git a/src/modules/elementary/test_map/mod.c b/src/modules/elementary/test_map/mod.c index 4d7db03284..15c4ff3344 100644 --- a/src/modules/elementary/test_map/mod.c +++ b/src/modules/elementary/test_map/mod.c @@ -6,7 +6,9 @@ #include "elm_module_helper.h" #include "elm_widget_map.h" -#define ELEMENTARY_BUILD +#ifndef EFL_BUILD +# define EFL_BUILD +#endif #undef ELM_MODULE_HELPER_H #include "elm_module_helper.h" diff --git a/src/modules/elementary/web/none/elm_web_none.c b/src/modules/elementary/web/none/elm_web_none.c index 6ac26507ed..d601460bda 100644 --- a/src/modules/elementary/web/none/elm_web_none.c +++ b/src/modules/elementary/web/none/elm_web_none.c @@ -9,7 +9,9 @@ #include "elm_priv.h" #include "elm_widget_web.h" -#define ELEMENTARY_BUILD +#ifndef EFL_BUILD +# define EFL_BUILD +#endif #undef ELM_MODULE_HELPER_H #include "elm_module_helper.h" #include "elm_web_none_eo.h" From 638a36ea9a4d0bb9c77f1312cf556589a1250fc6 Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Fri, 12 Apr 2019 15:45:37 +0900 Subject: [PATCH 11/18] efl_ui_widget: Fix disabled set calling without meaning. Summary: The efl_ui_widget_disabled_set calling even the state is not change when widget create and destroy. It broken backward compatibility. T7799 @fix Reviewers: bu5hm4n, Jaehyun_Cho Reviewed By: Jaehyun_Cho Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8600 --- src/lib/elementary/efl_ui_widget.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index 15585ca731..c56990f8b3 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -1373,8 +1373,16 @@ _disabled_counter_get(Eo *widget) static void _mirror_disabled_state(Eo *obj, Elm_Widget_Smart_Data *pd, int disabled_delta) { + int prev_disabled = pd->disabled; + pd->disabled = (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0) + disabled_delta; + //The current disabled state is the same as the parent + //when the parent is assigned or changed, no further action is required. + if (((prev_disabled > 0 && pd->disabled > 0)) || + ((prev_disabled <= 0 && pd->disabled <= 0))) + return; + //we should not call disabled_set when things are invalidated //otherwise we will unleashe an amount of errors in efl_ui_layout if (efl_invalidated_get(obj)) return; From 48c27364fce82e2bb7743d2e4bd5d29863c7f57d Mon Sep 17 00:00:00 2001 From: Yeongjong Lee Date: Fri, 12 Apr 2019 09:12:51 +0200 Subject: [PATCH 12/18] efl_ui_widget: avoid calling null parent Summary: This will fix unnecessary warnings on P280. Thanks to segfaultxavi for reporting. ref T7796 Reviewers: zmike, segfaultxavi Reviewed By: segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7796 Differential Revision: https://phab.enlightenment.org/D8599 --- src/lib/elementary/efl_ui_widget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index c56990f8b3..99da93aa3b 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -1421,7 +1421,6 @@ _efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widg */ double scale, prev_scale = efl_gfx_entity_scale_get(obj); Elm_Theme *th, *prev_th = elm_widget_theme_get(obj); - Eina_Bool mirrored, pmirrored = efl_ui_mirrored_get(parent); int disabled_delta = pd->disabled - (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0); old_parent = pd->parent_obj; @@ -1430,6 +1429,7 @@ _efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widg // now lets sync up all states if (pd->parent_obj) { + Eina_Bool mirrored, pmirrored = efl_ui_mirrored_get(pd->parent_obj); scale = efl_gfx_entity_scale_get(obj); th = elm_widget_theme_get(obj); mirrored = efl_ui_mirrored_get(obj); From f43c19ac3288f88b716be66ba8ea9106af8ec736 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 12 Apr 2019 10:29:42 +0100 Subject: [PATCH 13/18] evas map - mark npoints param as unused because it is remove warning --- src/lib/evas/common/evas_map_image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/evas/common/evas_map_image.c b/src/lib/evas/common/evas_map_image.c index 5036841a98..115e77cafd 100644 --- a/src/lib/evas/common/evas_map_image.c +++ b/src/lib/evas/common/evas_map_image.c @@ -890,7 +890,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst, } EAPI void -evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y) +evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints EINA_UNUSED, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y) { //The best quaility requsted. if (anti_alias && smooth) From eaf78210e8547d8f32063aa4e361888080d7886b Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 12 Apr 2019 11:18:38 +0100 Subject: [PATCH 14/18] evas common - convert - rotate tiled - fix const ptr warnings --- src/lib/evas/common/evas_convert_rgb_32.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/evas/common/evas_convert_rgb_32.c b/src/lib/evas/common/evas_convert_rgb_32.c index 11671466b2..c3ac3dfe60 100644 --- a/src/lib/evas/common/evas_convert_rgb_32.c +++ b/src/lib/evas/common/evas_convert_rgb_32.c @@ -56,10 +56,10 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int for (y = 0; y < h; y++) { \ const pix_type *s = &(src[h - y - 1]); \ pix_type *d = &(dst[dst_stride * y]); \ - pix_type *ptr1 = s; \ - pix_type *ptr2 = ptr1 + src_stride; \ - pix_type *ptr3 = ptr2 + src_stride; \ - pix_type *ptr4 = ptr3 + src_stride; \ + const pix_type *ptr1 = s; \ + const pix_type *ptr2 = ptr1 + src_stride; \ + const pix_type *ptr3 = ptr2 + src_stride; \ + const pix_type *ptr4 = ptr3 + src_stride; \ for(x = 0; x < w; x += 4) { \ pix_type s_array[4] = { *ptr1, *ptr2, *ptr3, *ptr4 }; \ vst1q_s32(d, vld1q_s32(s_array)); \ @@ -90,10 +90,10 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int for (y = 0; y < h; y++) { \ const pix_type *s = &(src[(src_stride * (w - 1)) + y]); \ pix_type *d = &(dst[dst_stride * y]); \ - pix_type *ptr1 = s; \ - pix_type *ptr2 = ptr1 + src_stride; \ - pix_type *ptr3 = ptr2 + src_stride; \ - pix_type *ptr4 = ptr3 + src_stride; \ + const pix_type *ptr1 = s; \ + const pix_type *ptr2 = ptr1 + src_stride; \ + const pix_type *ptr3 = ptr2 + src_stride; \ + const pix_type *ptr4 = ptr3 + src_stride; \ for(x = 0; x < w; x+=4) { \ pix_type s_array[4] = { *ptr1, *ptr2, *ptr3, *ptr4 }; \ vst1q_s32(d, vld1q_s32(s_array)); \ From ebf2ca3c5b398dc70f63e52c12105368b36e6d0e Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 12 Apr 2019 11:23:57 +0100 Subject: [PATCH 15/18] evas common - tiled rotate - fix signedness of neon intrinsics - warning --- src/lib/evas/common/evas_convert_rgb_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/evas/common/evas_convert_rgb_32.c b/src/lib/evas/common/evas_convert_rgb_32.c index c3ac3dfe60..28acdfb364 100644 --- a/src/lib/evas/common/evas_convert_rgb_32.c +++ b/src/lib/evas/common/evas_convert_rgb_32.c @@ -62,7 +62,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int const pix_type *ptr4 = ptr3 + src_stride; \ for(x = 0; x < w; x += 4) { \ pix_type s_array[4] = { *ptr1, *ptr2, *ptr3, *ptr4 }; \ - vst1q_s32(d, vld1q_s32(s_array)); \ + vst1q_u32(d, vld1q_u32(s_array)); \ d += 4; \ ptr1 += klght; \ ptr2 += klght; \ @@ -96,7 +96,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int const pix_type *ptr4 = ptr3 + src_stride; \ for(x = 0; x < w; x+=4) { \ pix_type s_array[4] = { *ptr1, *ptr2, *ptr3, *ptr4 }; \ - vst1q_s32(d, vld1q_s32(s_array)); \ + vst1q_u32(d, vld1q_u32(s_array)); \ d += 4; \ ptr1 += klght; \ ptr2 += klght; \ From ae77e5836634d59ab576878fb3e2577e4e5c3e78 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 12 Apr 2019 12:56:40 +0100 Subject: [PATCH 16/18] evas - fix crash/junk pixel content but with tiled rotate at 270 + neon @fix --- src/lib/evas/common/evas_convert_rgb_32.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/evas/common/evas_convert_rgb_32.c b/src/lib/evas/common/evas_convert_rgb_32.c index 28acdfb364..68d3a95b22 100644 --- a/src/lib/evas/common/evas_convert_rgb_32.c +++ b/src/lib/evas/common/evas_convert_rgb_32.c @@ -91,17 +91,17 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int const pix_type *s = &(src[(src_stride * (w - 1)) + y]); \ pix_type *d = &(dst[dst_stride * y]); \ const pix_type *ptr1 = s; \ - const pix_type *ptr2 = ptr1 + src_stride; \ - const pix_type *ptr3 = ptr2 + src_stride; \ - const pix_type *ptr4 = ptr3 + src_stride; \ - for(x = 0; x < w; x+=4) { \ + const pix_type *ptr2 = ptr1 - src_stride; \ + const pix_type *ptr3 = ptr2 - src_stride; \ + const pix_type *ptr4 = ptr3 - src_stride; \ + for(x = 0; x < w; x += 4) { \ pix_type s_array[4] = { *ptr1, *ptr2, *ptr3, *ptr4 }; \ vst1q_u32(d, vld1q_u32(s_array)); \ d += 4; \ - ptr1 += klght; \ - ptr2 += klght; \ - ptr3 += klght; \ - ptr4 += klght; \ + ptr1 -= klght; \ + ptr2 -= klght; \ + ptr3 -= klght; \ + ptr4 -= klght; \ } \ } \ } \ @@ -111,7 +111,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int pix_type *d = &(dst[dst_stride * y]); \ for (x = 0; x < w; x++) { \ *d++ = *s; \ - s += src_stride; \ + s -= src_stride; \ } \ } \ } \ From 37eee70d56aeff8649822cab62f736512cebf5d0 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Fri, 12 Apr 2019 15:48:36 +0200 Subject: [PATCH 17/18] elua: add all missing eolian api bindings --- src/bindings/luajit/eolian.lua | 140 +++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua index 4d17e4790d..0b99715ed9 100644 --- a/src/bindings/luajit/eolian.lua +++ b/src/bindings/luajit/eolian.lua @@ -17,6 +17,7 @@ ffi.cdef [[ typedef struct _Eolian_Object Eolian_Object; typedef struct _Eolian_Class Eolian_Class; typedef struct _Eolian_Function Eolian_Function; + typedef struct _Eolian_Part Eolian_Part; typedef struct _Eolian_Type Eolian_Type; typedef struct _Eolian_Typedecl Eolian_Typedecl; typedef struct _Eolian_Function_Parameter Eolian_Function_Parameter; @@ -31,6 +32,9 @@ ffi.cdef [[ typedef struct _Eolian_Value Eolian_Value; typedef struct _Eolian_Unit Eolian_Unit; + typedef void (*Eolian_Panic_Cb)(const Eolian_State *state, const char *msg); + typedef void (*Eolian_Error_Cb)(const Eolian_Object *obj, const char *msg, void *data); + typedef enum { EOLIAN_OBJECT_UNKNOWN = 0, EOLIAN_OBJECT_CLASS, @@ -288,7 +292,11 @@ ffi.cdef [[ int eolian_shutdown(void); Eolian_State *eolian_state_new(void); void eolian_state_free(Eolian_State *state); + Eolian_Panic_Cb eolian_state_panic_cb_set(Eolian_State *state, Eolian_Panic_Cb cb); + Eolian_Error_Cb eolian_state_error_cb_set(Eolian_State *state, Eolian_Error_Cb cb); + void *eolian_state_error_data_set(Eolian_State *state, void *data); Eolian_Object_Type eolian_object_type_get(const Eolian_Object *obj); + const Eolian_Unit *eolian_object_unit_get(const Eolian_Object *obj); const char *eolian_object_file_get(const Eolian_Object *obj); int eolian_object_line_get(const Eolian_Object *obj); int eolian_object_column_get(const Eolian_Object *obj); @@ -309,8 +317,10 @@ ffi.cdef [[ const Eolian_Unit *eolian_state_unit_by_file_get(const Eolian_State *state, const char *file_name); Eina_Iterator *eolian_state_units_get(const Eolian_State *state); + const Eolian_State *eolian_unit_state_get(const Eolian_Unit *unit); Eina_Iterator *eolian_unit_children_get(const Eolian_Unit *unit); const char *eolian_unit_file_get(const Eolian_Unit *unit); + const char *eolian_unit_file_path_get(const Eolian_Unit *unit); const Eolian_Object *eolian_unit_object_by_name_get(const Eolian_Unit *unit, const char *name); Eina_Iterator *eolian_unit_objects_get(const Eolian_Unit *unit); const Eolian_Class *eolian_unit_class_by_name_get(const Eolian_Unit *unit, const char *class_name); @@ -336,8 +346,10 @@ ffi.cdef [[ Eolian_Class_Type eolian_class_type_get(const Eolian_Class *klass); const Eolian_Documentation *eolian_class_documentation_get(const Eolian_Class *klass); const char *eolian_class_eo_prefix_get(const Eolian_Class *klass); + const char *eolian_class_event_prefix_get(const Eolian_Class *klass); const char *eolian_class_data_type_get(const Eolian_Class *klass); const Eolian_Class *eolian_class_parent_get(const Eolian_Class *klass); + Eina_Iterator *eolian_class_requires_get(const Eolian_Class *klass); Eina_Iterator *eolian_class_extensions_get(const Eolian_Class *klass); Eina_Iterator *eolian_class_functions_get(const Eolian_Class *klass, Eolian_Function_Type func_type); Eolian_Function_Type eolian_function_type_get(const Eolian_Function *function_id); @@ -363,6 +375,7 @@ ffi.cdef [[ const Eolian_Documentation *eolian_function_return_documentation_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype); Eina_Bool eolian_function_return_is_warn_unused(const Eolian_Function *foo_id, Eolian_Function_Type ftype); Eina_Bool eolian_function_object_is_const(const Eolian_Function *function_id); + const Eolian_Class *eolian_function_class_get(const Eolian_Function *function_id); const Eolian_Class *eolian_implement_class_get(const Eolian_Implement *impl); const Eolian_Class *eolian_implement_implementing_class_get(const Eolian_Implement *impl); const Eolian_Function *eolian_implement_function_get(const Eolian_Implement *impl, Eolian_Function_Type *func_type); @@ -376,6 +389,7 @@ ffi.cdef [[ const Eolian_Class *eolian_constructor_class_get(const Eolian_Constructor *ctor); const Eolian_Function *eolian_constructor_function_get(const Eolian_Constructor *ctor); Eina_Bool eolian_constructor_is_optional(const Eolian_Constructor *ctor); + Eina_Bool eolian_constructor_is_ctor_param(const Eolian_Constructor *ctor); Eina_Iterator *eolian_class_constructors_get(const Eolian_Class *klass); Eina_Iterator *eolian_class_events_get(const Eolian_Class *klass); const Eolian_Type *eolian_event_type_get(const Eolian_Event *event); @@ -384,12 +398,18 @@ ffi.cdef [[ Eolian_Object_Scope eolian_event_scope_get(const Eolian_Event *event); Eina_Bool eolian_event_is_hot(const Eolian_Event *event); Eina_Bool eolian_event_is_restart(const Eolian_Event *event); + Eina_Iterator *eolian_class_parts_get(const Eolian_Class *klass); const char *eolian_event_c_name_get(const Eolian_Event *event); + const Eolian_Class *eolian_part_class_get(const Eolian_Part *part); + const Eolian_Documentation *eolian_part_documentation_get(const Eolian_Part *part); + const Eolian_Event *eolian_class_event_by_name_get(const Eolian_Class *klass, const char *event_name); Eina_Bool eolian_class_ctor_enable_get(const Eolian_Class *klass); Eina_Bool eolian_class_dtor_enable_get(const Eolian_Class *klass); const char *eolian_class_c_get_function_name_get(const Eolian_Class *klass); Eolian_Type_Type eolian_type_type_get(const Eolian_Type *tp); Eolian_Type_Builtin_Type eolian_type_builtin_type_get(const Eolian_Type *tp); + const char *eolian_class_c_name_get(const Eolian_Class *klass); + const char *eolian_class_c_data_type_get(const Eolian_Class *klass); Eolian_Typedecl_Type eolian_typedecl_type_get(const Eolian_Typedecl *tp); Eina_Iterator *eolian_typedecl_struct_fields_get(const Eolian_Typedecl *tp); const Eolian_Struct_Type_Field *eolian_typedecl_struct_field_get(const Eolian_Typedecl *tp, const char *field); @@ -534,6 +554,14 @@ local object_idx, wrap_object = gen_wrap { return tonumber(eolian.eolian_object_type_get(cast_obj(self))) end, + unit_get = function(self) + local v = eolian.eolian_object_unit_get(cast_obj(self)) + if v == nil then + return nil + end + return v + end, + line_get = function(self) return tonumber(eolian.eolian_object_line_get(cast_obj(self))) end, @@ -579,6 +607,12 @@ local object_idx, wrap_object = gen_wrap { ffi.metatype("Eolian_Object", { __index = object_idx }) local unit_idx, wrap_unit = gen_wrap { + state_get = function(self) + local v = eolian.eolian_unit_state_get(cast_unit(self)) + if v == nil then return nil end + return v + end, + children_get = function(self) return Ptr_Iterator("const Eolian_Unit*", eolian.eolian_unit_children_get(cast_unit(self))) @@ -590,6 +624,12 @@ local unit_idx, wrap_unit = gen_wrap { return ffi.string(v) end, + file_path_get = function(self) + local v = eolian.eolian_unit_file_path_get(cast_unit(self)) + if v == nil then return nil end + return ffi.string(v) + end, + object_by_name_get = function(self, name) local v = eolian.eolian_unit_object_by_name_get(cast_unit(self), name) if v == nil then return nil end @@ -670,8 +710,43 @@ local unit_idx, wrap_unit = gen_wrap { ffi.metatype("Eolian_Unit", { __index = unit_idx }) +local panic_cbs = {} +local error_cbs = {} + +local obj_to_idx = function(obj) + return tonumber(ffi.cast("size_t", obj)) +end + +local panic_cb, err_cb + +panic_cb = ffi.gc(ffi.cast("Eolian_Panic_Cb", function(state, msg) + local pcb = panic_cbs[obj_to_idx(self)] + assert(pcb, "internal error: no prror cb") + pcb(state, ffi.string(msg)) +end), function(cb) + cb:free() +end) + +err_cb = ffi.gc(ffi.cast("Eolian_Panic_Cb", function(obj, msg, data) + local ecb = error_cbs[obj_to_idx(self)] + assert(ecb, "internal error: no error cb") + ecb(obj, ffi.string(msg)) +end), function(cb) + cb:free() +end) + ffi.metatype("Eolian_State", { __index = wrap_unit { + panic_cb_set = function(self, cb) + panic_cbs[obj_to_idx(self)] = cb + eolian.eolian_state_panic_cb_set(self, panic_cb) + end, + + error_cb_set = function(self, cb) + error_cbs[obj_to_idx(self)] = cb + eolian.eolian_state_error_cb_set(self, err_cb) + end, + directory_add = function(self, dir) return eolian.eolian_state_directory_add(self, dir) ~= 0 end, @@ -770,6 +845,9 @@ ffi.metatype("Eolian_State", { end }, __gc = function(self) + local idx = obj_to_idx(self) + panic_cbs[idx] = nil + error_cbs[idx] = nil eolian.eolian_state_free(self) end }) @@ -1127,6 +1205,12 @@ M.Function = ffi.metatype("Eolian_Function", { is_const = function(self) return eolian.eolian_function_object_is_const(self) ~= 0 + end, + + class_get = function(self) + local v = eolian.eolian_function_class_get(self) + if v == nil then return nil end + return v end } }) @@ -1241,6 +1325,10 @@ ffi.metatype("Eolian_Constructor", { is_optional = function(self) return eolian.eolian_constructor_is_optional(self) ~= 0 + end, + + is_ctor_param = function(self) + return eolian.eolian_constructor_is_ctor_param(self) ~= 0 end } }) @@ -1285,6 +1373,22 @@ ffi.metatype("Eolian_Event", { } }) +ffi.metatype("Eolian_Part", { + __index = wrap_object { + class_get = function(self) + local v = eolian.eolian_part_class_get(self) + if v == nil then return nil end + return v + end, + + documentation_get = function(self) + local v = eolian.eolian_part_documentation_get(self) + if v == nil then return nil end + return v + end + } +}) + M.class_type = { UNKNOWN = 0, REGULAR = 1, @@ -1315,6 +1419,14 @@ M.Class = ffi.metatype("Eolian_Class", { return ffi.string(v) end, + event_prefix_get = function(self) + local v = eolian.eolian_class_event_prefix_get(self) + if v == nil then + return self:eo_prefix_get() + end + return ffi.string(v) + end, + data_type_get = function(self) local v = eolian.eolian_class_data_type_get(self) if v == nil then return nil end @@ -1332,6 +1444,11 @@ M.Class = ffi.metatype("Eolian_Class", { eolian.eolian_class_extensions_get(self)) end, + requires_get = function(self) + return Ptr_Iterator("const Eolian_Class*", + eolian.eolian_class_requires_get(self)) + end, + functions_get = function(self, func_type) return Ptr_Iterator("const Eolian_Function*", eolian.eolian_class_functions_get(self, func_type)) @@ -1359,6 +1476,17 @@ M.Class = ffi.metatype("Eolian_Class", { eolian.eolian_class_events_get(self)) end, + event_by_name_get = function(self, name) + local v = eolian.eolian_class_event_by_name_get(self, name) + if v == nil then return nil end + return v + end, + + parts_get = function(self) + return Ptr_Iterator("const Eolian_Part*", + eolian.eolian_class_parts_get(self)) + end, + ctor_enable_get = function(self) return eolian.eolian_class_ctor_enable_get(self) ~= 0 end, @@ -1371,6 +1499,18 @@ M.Class = ffi.metatype("Eolian_Class", { local v = eolian.eolian_class_c_get_function_name_get(self) if v == nil then return nil end return ffi_stringshare(v) + end, + + c_name_get = function(self) + local v = eolian.eolian_class_c_name_get(self) + if v == nil then return nil end + return ffi_stringshare(v) + end, + + c_data_type_get = function(self) + local v = eolian.eolian_class_c_data_type_get(self) + if v == nil then return nil end + return ffi_stringshare(v) end } }) From 8c45aca05ed30da51972ef3122a4f0d7e7a94933 Mon Sep 17 00:00:00 2001 From: Xavi Artigas Date: Thu, 11 Apr 2019 12:40:21 +0200 Subject: [PATCH 18/18] mono-docs: Allow derived classes to have external examples Summary: You can now have external example files for derived classes (Efl.Ui.Button.SetText) as well as for base classes (Efl.IText.SetText). If both files are present, both examples are embedded in the docs. The more examples the better! Examples for classes in-between the hierarchy (Efl.Ui.Widget.SetText) are not picked up. Might be worth examining in the future. Test Plan: Create example files for both `Efl.Ui.Button.AutorepeatEnabled.cs` and `Efl.Ui.IAutorepeat.AutorepeatEnabled.cs`. You should see both examples appearing in the docs. Reviewers: lauromoura, vitor.sousa Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8597 --- .../eolian_mono/eolian/mono/documentation.hh | 39 +++++++++++++++---- .../eolian/mono/generation_contexts.hh | 1 + src/bin/eolian_mono/eolian/mono/klass.hh | 16 ++++++-- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh index d603e0bb99..1cea16e9e8 100644 --- a/src/bin/eolian_mono/eolian/mono/documentation.hh +++ b/src/bin/eolian_mono/eolian/mono/documentation.hh @@ -313,12 +313,12 @@ struct documentation_generator } template - bool generate_tag_example(OutputIterator sink, std::string const& object_name, Context const& context) const + bool generate_tag_example(OutputIterator sink, std::string const& full_object_name, Context const& context) const { auto options = efl::eolian::grammar::context_find_tag(context); // Example embedding not requested if (options.examples_dir.empty()) return true; - std::string file_name = options.examples_dir + object_name + ".cs"; + std::string file_name = options.examples_dir + full_object_name + ".cs"; std::ifstream exfile(file_name); // There is no example file for this class or method, just return if (!exfile.good()) return true; @@ -335,6 +335,24 @@ struct documentation_generator return as_generator("\n").generate(sink, attributes::unused, context); } + template + bool generate_all_tag_examples(OutputIterator sink, std::string const & full_class_name, std::string const& object_name, Context const& context) const + { + // Take example from derived class + auto derived_klass = efl::eolian::grammar::context_find_tag(context); + std::string derived_full_name = + derived_klass.name.empty() ? object_name : derived_klass.name + "." + object_name; + std::string base_full_name = + full_class_name.empty() ? object_name : full_class_name + "." + object_name; + if (!derived_klass.name.empty()) + { + if (!generate_tag_example(sink, derived_full_name, context)) return false; + } + if (derived_full_name.compare(base_full_name) == 0) return true; + // Take example from base class + return generate_tag_example(sink, base_full_name, context); + } + // Actual exported generators template bool generate(OutputIterator sink, Attribute const& attr, Context const& context) const @@ -366,9 +384,10 @@ struct documentation_generator if (!text.empty()) if (!generate_tag_value(sink, text, context)) return false; - std::string managed_name = name_helpers::klass_full_concrete_or_interface_name(prop.klass); - managed_name += "." + name_helpers::property_managed_name(prop); - return generate_tag_example(sink, managed_name, context); + return generate_all_tag_examples(sink, + name_helpers::klass_full_concrete_or_interface_name(prop.klass), + name_helpers::property_managed_name(prop), + context); } template @@ -404,7 +423,10 @@ struct documentation_generator if (!generate_tag_return(sink, func.return_documentation.full_text, context)) return false; - return generate_tag_example(sink, function_conversion(func), context); + return generate_all_tag_examples(sink, + name_helpers::klass_full_concrete_or_interface_name(func.klass), + name_helpers::managed_method_name(func.klass.eolian_name, func.name), + context); } template @@ -420,7 +442,10 @@ struct documentation_generator if (!generate_tag_return(sink, func.return_documentation.full_text, context)) return false; - return generate_tag_example(sink, function_conversion(func), context); + return generate_all_tag_examples(sink, + name_helpers::klass_full_concrete_or_interface_name(func.klass), + name_helpers::managed_method_name(func.klass.eolian_name, func.name), + context); } template diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh index ff6c0391ba..dc72696342 100644 --- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh +++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh @@ -20,6 +20,7 @@ struct class_context variables, }; wrapper_kind current_wrapper_kind; + std::string name; }; struct indentation_context diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index 87ad1bd5a7..4664446dbf 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -117,7 +117,9 @@ struct klass // Interface class if(class_type == "interface") { - auto iface_cxt = context_add_tag(class_context{class_context::interface}, context); + auto iface_cxt = context_add_tag(class_context{class_context::interface, + name_helpers::klass_full_concrete_or_interface_name(cls)}, + context); if(!as_generator(documentation).generate(sink, cls, iface_cxt)) return false; @@ -195,7 +197,9 @@ struct klass // Concrete class for interfaces, mixins, etc. if(class_type != "class" && class_type != "abstract class") { - auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context); + auto concrete_cxt = context_add_tag(class_context{class_context::concrete, + name_helpers::klass_full_concrete_or_interface_name(cls)}, + context); auto concrete_name = name_helpers::klass_concrete_name(cls); auto interface_name = name_helpers::klass_interface_name(cls); @@ -277,7 +281,9 @@ struct klass // Inheritable class if(class_type == "class" || class_type == "abstract class") { - auto inherit_cxt = context_add_tag(class_context{class_context::inherit}, context); + auto inherit_cxt = context_add_tag(class_context{class_context::inherit, + name_helpers::klass_full_concrete_or_interface_name(cls)}, + context); // Class header if(!as_generator @@ -351,7 +357,9 @@ struct klass // Native Inherit class //if(class_type == "class") { - auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context); + auto inative_cxt = context_add_tag(class_context{class_context::inherit_native, + name_helpers::klass_full_concrete_or_interface_name(cls)}, + context); auto native_inherit_name = name_helpers::klass_native_inherit_name(cls); auto inherit_name = name_helpers::klass_inherit_name(cls); std::string base_name;