Merge branch 'master' into devs/hermet/lottie

This commit is contained in:
Hermet Park 2019-07-15 13:23:37 +09:00
commit 30d702a3ac
113 changed files with 2561 additions and 483 deletions

View File

@ -497,6 +497,7 @@ static void st_collections_group_parts_part_description_map_perspective_on
static void st_collections_group_parts_part_description_map_color(void);
static void st_collections_group_parts_part_description_map_zoom_x(void);
static void st_collections_group_parts_part_description_map_zoom_y(void);
static void st_collections_group_parts_part_description_map_zoom_center(void);
static void st_collections_group_parts_part_description_perspective_zplane(void);
static void st_collections_group_parts_part_description_perspective_focal(void);
static void st_collections_group_parts_part_api(void);
@ -1032,6 +1033,7 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.parts.part.description.map.color", st_collections_group_parts_part_description_map_color},
{"collections.group.parts.part.description.map.zoom.x", st_collections_group_parts_part_description_map_zoom_x},
{"collections.group.parts.part.description.map.zoom.y", st_collections_group_parts_part_description_map_zoom_y},
{"collections.group.parts.part.description.map.zoom.center", st_collections_group_parts_part_description_map_zoom_center},
{"collections.group.parts.part.description.perspective.zplane", st_collections_group_parts_part_description_perspective_zplane},
{"collections.group.parts.part.description.perspective.focal", st_collections_group_parts_part_description_perspective_focal},
{"collections.group.parts.part.description.params.int", st_collections_group_parts_part_description_params_int},
@ -6464,6 +6466,7 @@ _part_desc_free(Edje_Part_Collection *pc,
part_lookup_del(pc, &(ed->map.id_persp));
part_lookup_del(pc, &(ed->map.id_light));
part_lookup_del(pc, &(ed->map.rot.id_center));
part_lookup_del(pc, &(ed->map.zoom.id_center));
switch (ep->type)
{
@ -8617,6 +8620,7 @@ ob_collections_group_parts_part_description(void)
ed->map.id_persp = -1;
ed->map.id_light = -1;
ed->map.rot.id_center = -1;
ed->map.zoom.id_center = -1;
ed->map.rot.x = FROM_DOUBLE(0.0);
ed->map.rot.y = FROM_DOUBLE(0.0);
ed->map.rot.z = FROM_DOUBLE(0.0);
@ -8776,6 +8780,7 @@ st_collections_group_parts_part_description_inherit(void)
data_queue_copied_part_lookup(pc, &parent->map.id_persp, &ed->map.id_persp);
data_queue_copied_part_lookup(pc, &parent->map.id_light, &ed->map.id_light);
data_queue_copied_part_lookup(pc, &parent->map.rot.id_center, &ed->map.rot.id_center);
data_queue_copied_part_lookup(pc, &parent->map.zoom.id_center, &ed->map.zoom.id_center);
/* make sure all the allocated memory is getting copied, not just
* referenced
@ -14313,6 +14318,57 @@ st_collections_group_parts_part_description_map_light(void)
}
}
/** @edcsubsection{collections_group_parts_description_map_zoom,
* Group.Parts.Part.Description.Map.Zoom} */
/**
@page edcref
@block
rotation
@context
map {
..
zoom {
center: "name";
x: 1.0;
y: 1.0;
}
..
}
@description
Zooms the part, optionally from the center on another part.
@endblock
@property
center
@parameters
[another part's name]
@effect
This sets the part that is used as the center of zoom when
zooming the part with this description. The part's center point
is used as the zoom center when applying zoom from the
x and y axes. If no center is given, the parts original center
itself is used for the zoom center.
@endproperty
*/
static void
st_collections_group_parts_part_description_map_zoom_center(void)
{
Edje_Part_Collection *pc;
check_arg_count(1);
pc = eina_list_data_get(eina_list_last(edje_collections));
{
char *name;
name = parse_str(0);
data_queue_part_lookup(pc, name, &(current_desc->map.zoom.id_center));
free(name);
}
}
/**
@page edcref
@property

View File

@ -299,7 +299,8 @@ pack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
index = efl_ui_range_value_get(param->pack_sp);
if (index > cnt)
efl_ui_range_value_set(param->pack_sp, cnt);
efl_ui_range_limits_set(param->pack_sp, 0, cnt);
if (cnt > 0)
efl_ui_range_limits_set(param->pack_sp, 0, cnt);
if (cnt > 0)
{
@ -310,7 +311,8 @@ pack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
index = efl_ui_range_value_get(param->unpack_sp);
if (index > cnt)
efl_ui_range_value_set(param->unpack_sp, cnt);
efl_ui_range_limits_set(param->unpack_sp, 0, cnt);
if (cnt > 0)
efl_ui_range_limits_set(param->unpack_sp, 0, cnt);
}
else
{
@ -502,6 +504,7 @@ pack_cb(void *data,
Eo *spotlight = params->spotlight;
Eo *btn, *box, *in_box1, *in_box2, *sp1, *sp2;
Pack_Params *pack_param;
int num;
btn = efl_add(EFL_UI_BUTTON_CLASS, navi,
efl_text_set(efl_added, "Back"),
@ -517,11 +520,13 @@ pack_cb(void *data,
efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL));
sp1 = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box1,
efl_ui_range_limits_set(efl_added, 0,
efl_content_count(spotlight)),
efl_ui_range_value_set(efl_added,
efl_ui_spotlight_active_index_get(spotlight)));
sp1 = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box1);
num = efl_content_count(spotlight);
if (num)
efl_ui_range_limits_set(sp1, 0, num);
num = efl_ui_spotlight_active_index_get(spotlight);
if (num >= 0)
efl_ui_range_value_set(sp1, num);
in_box2 = efl_add(EFL_UI_BOX_CLASS, box,
efl_gfx_arrangement_content_padding_set(efl_added, 10, 10, EINA_TRUE),

View File

@ -11,6 +11,8 @@
#include <Eina.h>
static const std::string BETA_REF_SUFFIX = " (object still in beta stage)";
namespace eolian_mono {
struct documentation_generator
@ -128,32 +130,38 @@ struct documentation_generator
}
// Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag
static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail)
static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail,
bool want_beta)
{
const Eolian_Object *data, *data2;
::Eolian_Object_Type type =
::eolian_doc_token_ref_resolve(token, state, &data, &data2);
std::string ref;
bool is_beta = false;
switch(type)
{
case ::EOLIAN_OBJECT_STRUCT_FIELD:
ref = name_helpers::managed_namespace(::eolian_object_name_get(data));
ref += ".";
ref += ::eolian_object_name_get(data2);
is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
if (blacklist::is_struct_blacklisted(ref)) return "";
break;
case ::EOLIAN_OBJECT_EVENT:
ref = object_ref_conversion(data);
ref += ".";
ref += name_helpers::managed_event_name(::eolian_object_name_get(data2));
is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
break;
case ::EOLIAN_OBJECT_ENUM_FIELD:
ref = name_helpers::managed_namespace(::eolian_object_name_get(data));
ref += ".";
ref += name_helpers::enum_field_managed_name(::eolian_object_name_get(data2));
is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
break;
case ::EOLIAN_OBJECT_FUNCTION:
ref += function_conversion(data, (const ::Eolian_Function *)data2, name_tail);
is_beta = eolian_object_is_beta(data) || eolian_object_is_beta(data2);
break;
case ::EOLIAN_OBJECT_VARIABLE:
if (::eolian_variable_type_get((::Eolian_Variable *)data) == ::EOLIAN_VAR_CONSTANT)
@ -173,16 +181,21 @@ struct documentation_generator
break;
case ::EOLIAN_OBJECT_CLASS:
ref = object_ref_conversion(data);
is_beta = eolian_object_is_beta(data);
break;
default:
ref = name_helpers::managed_namespace(::eolian_object_name_get(data));
is_beta = eolian_object_is_beta(data);
break;
}
if (!ref.empty() && !want_beta && is_beta)
ref += BETA_REF_SUFFIX;
return ref;
}
// Turns EO documentation syntax into C# triple-slash XML comment syntax
static std::string syntax_conversion(std::string text, const Eolian_State *state)
static std::string syntax_conversion(std::string text, const Eolian_State *state, bool want_beta)
{
std::string new_text, ref;
::Eolian_Doc_Token token;
@ -213,9 +226,14 @@ struct documentation_generator
new_text += token_text;
break;
case ::EOLIAN_DOC_TOKEN_REF:
ref = ref_conversion(&token, state, name_tail);
ref = ref_conversion(&token, state, name_tail, want_beta);
if (ref != "")
new_text += "<see cref=\"" + ref + "\"/>";
{
if (utils::ends_with(ref, BETA_REF_SUFFIX))
new_text += "<span class=\"text-muted\">" + ref + "</span>";
else
new_text += "<see cref=\"" + ref + "\"/>";
}
else
// Unresolved references are passed through.
// They will appear in the docs as plain text, without link,
@ -264,7 +282,8 @@ struct documentation_generator
std::string new_text;
if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context))
return false;
new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state );
auto options = context_find_tag<options_context>(context);
new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, options.want_beta);
std::string tabs;
as_generator(scope_tab(scope_size) << "/// ").generate (std::back_inserter(tabs), attributes::unused, context);
@ -486,8 +505,18 @@ struct documentation_generator
for (auto &&param : ctor.function.parameters)
{
auto ref = function_conversion(func);
if (!context_find_tag<options_context>(context).want_beta && func.is_beta)
{
ref += BETA_REF_SUFFIX;
ref = "<span class=\"text-muted\">" + ref + "</span>";
}
else
ref = "<see cref=\"" + ref + "\" />";
if (!as_generator(
scope_tab << "/// <param name=\"" << constructor_parameter_name(ctor) << "\">" << summary << " See <see cref=\"" << function_conversion(func) << "\"/></param>\n"
scope_tab << "/// <param name=\"" << constructor_parameter_name(ctor) << "\">" << summary << " See " << ref << "</param>\n"
).generate(sink, param, context))
return false;
}

View File

@ -25,6 +25,7 @@ struct enum_definition_generator
if(!as_generator
(
"[Efl.Eo.BindingEntity]\n"
"public enum " << string << "\n{\n"
)
.generate(sink, name_helpers::typedecl_managed_name(enum_), context))

View File

@ -1,5 +1,5 @@
#ifndef EOLIAN_MONO_EVENTS_HH
#define EOLINA_MONO_EVENTS_HH
#define EOLIAN_MONO_EVENTS_HH
#include <iterator>
@ -250,6 +250,7 @@ struct event_argument_wrapper_generator
return as_generator("///<summary>Event argument wrapper for event <see cref=\""
<< join_namespaces(evt.klass.namespaces, '.', managed_namespace)
<< klass_interface_name(evt.klass) << "." << evt_name << "\"/>.</summary>\n"
<< "[Efl.Eo.BindingEntity]\n"
<< "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
<< scope_tab << "///<summary>Actual event payload.</summary>\n"
<< scope_tab << "public " << type << " arg { get; set; }\n"

View File

@ -44,6 +44,7 @@ struct function_pointer {
// C# visible delegate
if (!as_generator(documentation
<< "[Efl.Eo.BindingEntity]\n"
<< "public delegate " << type << " " << string
<< "(" << (parameter % ", ") << ");\n")
.generate(sink, std::make_tuple(f, f.return_type, f_name, f.parameters), funcptr_ctx))

View File

@ -21,6 +21,16 @@ struct class_context
};
wrapper_kind current_wrapper_kind;
std::string name;
class_context(wrapper_kind current_wrapper_kind)
: current_wrapper_kind(current_wrapper_kind)
, name()
{}
class_context(wrapper_kind current_wrapper_kind, std::string const& name)
: current_wrapper_kind(current_wrapper_kind)
, name(name)
{}
};
struct indentation_context

View File

@ -3,6 +3,7 @@
#include "grammar/klass_def.hpp"
#include "blacklist.hh"
#include "generation_contexts.hh"
#include "name_helpers.hh"
namespace eolian_mono {
@ -165,11 +166,19 @@ bool has_regular_ancestor(attributes::klass_def const& cls)
/*
* Gets all methods that this class should implement (i.e. that come from an unimplemented interface/mixin and the class itself)
*/
std::vector<attributes::function_def> get_all_implementable_methods(attributes::klass_def const& cls)
template<typename Context>
std::vector<attributes::function_def> get_all_implementable_methods(attributes::klass_def const& cls, Context const& context)
{
bool want_beta = efl::eolian::grammar::context_find_tag<options_context>(context).want_beta;
std::vector<attributes::function_def> ret;
auto filter_beta = [&want_beta](attributes::function_def const& func) {
if (!want_beta)
return !func.is_beta;
else
return true;
};
std::copy(cls.functions.begin(), cls.functions.end(), std::back_inserter(ret));
std::copy_if(cls.functions.begin(), cls.functions.end(), std::back_inserter(ret), filter_beta);
// Non implemented interfaces
std::set<attributes::klass_name, attributes::compare_klass_name_by_name> implemented_interfaces;
@ -206,7 +215,7 @@ std::vector<attributes::function_def> get_all_implementable_methods(attributes::
for (auto&& inherit : interfaces)
{
attributes::klass_def klass(get_klass(inherit, cls.unit), cls.unit);
std::copy(klass.functions.cbegin(), klass.functions.cend(), std::back_inserter(ret));
std::copy_if(klass.functions.cbegin(), klass.functions.cend(), std::back_inserter(ret), filter_beta);
}
return ret;

View File

@ -36,7 +36,7 @@ template<typename Context>
static std::size_t
get_implementable_function_count(grammar::attributes::klass_def const& cls, Context context)
{
auto methods = helpers::get_all_implementable_methods(cls);
auto methods = helpers::get_all_implementable_methods(cls, context);
return std::count_if(methods.cbegin(), methods.cend(), [&context](grammar::attributes::function_def const& func)
{
return !blacklist::is_function_blacklisted(func, context) && !func.is_static;
@ -106,6 +106,9 @@ struct klass
.generate(sink, attributes::unused, iface_cxt))
return false;
if(!as_generator("[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt))
return false;
if(!as_generator
(
"public " /*<< class_type*/ "interface" /*<<*/ " " << string << " : "
@ -115,6 +118,9 @@ struct klass
for(auto first = std::begin(cls.immediate_inherits)
, last = std::end(cls.immediate_inherits); first != last; ++first)
{
if (!context_find_tag<options_context>(iface_cxt).want_beta && first->is_beta)
continue;
if(first->type != attributes::class_type::regular && first->type != attributes::class_type::abstract_)
if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt))
return false;
@ -230,7 +236,7 @@ struct klass
.generate(sink, cls.parts, concrete_cxt)) return false;
// Concrete function definitions
auto implemented_methods = helpers::get_all_implementable_methods(cls);
auto implemented_methods = helpers::get_all_implementable_methods(cls, concrete_cxt);
if(!as_generator(*(function_definition))
.generate(sink, implemented_methods, concrete_cxt)) return false;
@ -276,6 +282,7 @@ struct klass
(
documentation
<< "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
<< "[Efl.Eo.BindingEntity]\n"
<< "public " << class_type << " " << name_helpers::klass_concrete_name(cls) << " : "
<< (klass_full_concrete_or_interface_name % ",") // classes
<< (root ? "Efl.Eo.EoWrapper" : "") // ... or root
@ -302,7 +309,7 @@ struct klass
.generate(sink, cls.parts, inherit_cxt)) return false;
// Inherit function definitions
auto implemented_methods = helpers::get_all_implementable_methods(cls);
auto implemented_methods = helpers::get_all_implementable_methods(cls, inherit_cxt);
if(!as_generator(*(function_definition(true)))
.generate(sink, implemented_methods, inherit_cxt)) return false;
@ -354,7 +361,7 @@ struct klass
context);
auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
auto inherit_name = name_helpers::klass_inherit_name(cls);
auto implementable_methods = helpers::get_all_implementable_methods(cls);
auto implementable_methods = helpers::get_all_implementable_methods(cls, context);
bool root = !helpers::has_regular_ancestor(cls);
auto const& indent = current_indentation(inative_cxt);
@ -499,7 +506,7 @@ struct klass
// For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
<< scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null") << "\n"
<< scope_tab << scope_tab << scope_tab << *(", " << constructor_param ) << ") : "
<< "base(" << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent)\n"
<< "base(" << name_helpers::klass_get_name(cls) << "(), parent)\n"
<< scope_tab << "{\n"
<< (*(scope_tab << scope_tab << constructor_invocation << "\n"))
<< scope_tab << scope_tab << "FinishInstantiation();\n"
@ -539,9 +546,8 @@ struct klass
scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
<< scope_tab << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.</summary>\n"
<< scope_tab << "/// <param name=\"baseKlass\">The pointer to the base native Eo class.</param>\n"
<< scope_tab << "/// <param name=\"managedType\">The managed type of the public constructor that originated this call.</param>\n"
<< scope_tab << "/// <param name=\"parent\">The Efl.Object parent of this instance.</param>\n"
<< scope_tab << "protected " << inherit_name << "(IntPtr baseKlass, System.Type managedType, Efl.Object parent) : base(baseKlass, managedType, parent)\n"
<< scope_tab << "protected " << inherit_name << "(IntPtr baseKlass, Efl.Object parent) : base(baseKlass, parent)\n"
<< scope_tab << "{\n"
<< scope_tab << "}\n\n"
).generate(sink, attributes::unused, context);

View File

@ -183,6 +183,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(r);
}
@ -195,6 +196,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(regular);
}
@ -208,6 +210,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(klass_name);
}
@ -253,7 +256,7 @@ struct marshall_type_visitor_generate
auto default_match = [&] (attributes::complex_type_def const& complex)
{
regular_type_def no_pointer_regular = complex.outer;
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
return visitor_type{sink, context, c_type, false, false, false, false}(no_pointer_regular)
&& as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context);
};
@ -286,6 +289,7 @@ struct marshall_type_visitor_generate
, is_out
, is_return
, is_ptr
, false
, is_special_subtype
}(complex);
}

View File

@ -396,6 +396,7 @@ struct struct_definition_generator
if(!as_generator
(
indent << "[StructLayout(LayoutKind.Sequential)]\n"
<< indent << "[Efl.Eo.BindingEntity]\n"
<< indent << "public struct " << string << "\n"
<< indent << "{\n"
)

View File

@ -412,7 +412,7 @@ struct visitor_generate
// pointers.swap(no_pointer_regular.pointers);
// if(is_out)
// pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
return visitor_type{sink, context, c_type, false, false, false, false, false}(no_pointer_regular)
&& as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context)
;
// && detail::generate_pointers(sink, pointers, *context, false);

View File

@ -387,7 +387,15 @@ private:
void _construct(U&& object)
{
assert(!is_engaged());
// NOTE: the buffer memory is intended to be in an
// uninitialized state here.
// So this warning can be disabled.
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
new (&buffer) T(std::forward<U>(object));
#pragma GCC diagnostic pop
engaged = true;
}

View File

@ -293,11 +293,23 @@ void _create_methods_specification_impl(Method const& method, Eldbus_Method2& el
eldbus::_fill_methods(*out_params, method.outs);
// NOTE: C pointer magic performed under the hood requires this conversion
// between incompatible function pointer types.
// C++ always raises a warning for such conversions, so this warning
// can be disabled just here.
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
Eldbus_Method_Cb method_cb =
reinterpret_cast<Eldbus_Method_Cb>
(static_cast<Eldbus_Method_Data_Cb>
(&_method_callback<typename Method::function_type
, typename Method::ins_type, typename Method::outs_type>));
#pragma GCC diagnostic pop
eldbus_method = {{method.name, &(*in_params)[0], &(*out_params)[0]
, reinterpret_cast<Eldbus_Method_Cb>
(static_cast<Eldbus_Method_Data_Cb>
(&_method_callback<typename Method::function_type
, typename Method::ins_type, typename Method::outs_type>))
, method_cb
, ELDBUS_METHOD_FLAG_HAS_DATA}
, new std::tuple<typename Method::function_type
, typename Method::ins_type, typename Method::outs_type

View File

@ -3,6 +3,7 @@
#define CODE_ANALYSIS
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Security.Permissions;
@ -719,6 +720,8 @@ static class ValueTypeBridge
{
private static Dictionary<ValueType, IntPtr> ManagedToNative = new Dictionary<ValueType, IntPtr>();
private static Dictionary<IntPtr, ValueType> NativeToManaged = new Dictionary<IntPtr, ValueType>();
private static Dictionary<System.Type, ValueType> StandardToManaged = new Dictionary<System.Type, ValueType>();
private static Dictionary<ValueType, System.Type> ManagedToStandard = new Dictionary<ValueType, System.Type>();
private static bool TypesLoaded; // CLR defaults to false;
public static ValueType GetManaged(IntPtr native)
@ -750,48 +753,106 @@ static class ValueTypeBridge
return ManagedToNative[valueType];
}
/// <summary>Returns the Eina.Value type associated with the given C# type.</summary>
public static ValueType GetManaged(System.Type type)
{
ValueType v;
if (StandardToManaged.TryGetValue(type, out v))
{
return v;
}
else
{
if (typeof(Efl.Object).IsAssignableFrom(type))
{
return ValueType.Object;
}
throw new Efl.EflException($"Unknown value type mapping for C# type {type}");
}
}
/// <summary>Returns the System.Type associated with the given Eina.Value type.</summary>
/// <param name="valueType">The intermediate type as returned by <see cref="Eina.Value.GetValueType()" />.</param>
/// <returns>The associated C# type with this value type.</returns>
public static System.Type GetStandard(ValueType valueType)
{
System.Type ret = null;
if (ManagedToStandard.TryGetValue(valueType, out ret))
{
return ret;
}
else
{
throw new Efl.EflException($"Unknown C# type mapping for value type {valueType}");
}
}
private static void LoadTypes()
{
Eina.Config.Init(); // Make sure eina is initialized.
ManagedToNative.Add(ValueType.SByte, type_sbyte());
NativeToManaged.Add(type_sbyte(), ValueType.SByte);
StandardToManaged.Add(typeof(sbyte), ValueType.SByte);
ManagedToStandard.Add(ValueType.SByte, typeof(sbyte));
ManagedToNative.Add(ValueType.Byte, type_byte());
NativeToManaged.Add(type_byte(), ValueType.Byte);
StandardToManaged.Add(typeof(byte), ValueType.Byte);
ManagedToStandard.Add(ValueType.Byte, typeof(byte));
ManagedToNative.Add(ValueType.Short, type_short());
NativeToManaged.Add(type_short(), ValueType.Short);
StandardToManaged.Add(typeof(short), ValueType.Short);
ManagedToStandard.Add(ValueType.Short, typeof(short));
ManagedToNative.Add(ValueType.UShort, type_ushort());
NativeToManaged.Add(type_ushort(), ValueType.UShort);
StandardToManaged.Add(typeof(ushort), ValueType.UShort);
ManagedToStandard.Add(ValueType.UShort, typeof(ushort));
ManagedToNative.Add(ValueType.Int32, type_int32());
NativeToManaged.Add(type_int32(), ValueType.Int32);
StandardToManaged.Add(typeof(int), ValueType.Int32);
ManagedToStandard.Add(ValueType.Int32, typeof(int));
ManagedToNative.Add(ValueType.UInt32, type_uint32());
NativeToManaged.Add(type_uint32(), ValueType.UInt32);
StandardToManaged.Add(typeof(uint), ValueType.UInt32);
ManagedToStandard.Add(ValueType.UInt32, typeof(uint));
ManagedToNative.Add(ValueType.Long, type_long());
NativeToManaged.Add(type_long(), ValueType.Long);
ManagedToStandard.Add(ValueType.Long, typeof(long));
ManagedToNative.Add(ValueType.ULong, type_ulong());
NativeToManaged.Add(type_ulong(), ValueType.ULong);
ManagedToStandard.Add(ValueType.ULong, typeof(ulong));
ManagedToNative.Add(ValueType.Int64, type_int64());
NativeToManaged.Add(type_int64(), ValueType.Int64);
StandardToManaged.Add(typeof(long), ValueType.Int64);
ManagedToStandard.Add(ValueType.Int64, typeof(long));
ManagedToNative.Add(ValueType.UInt64, type_uint64());
NativeToManaged.Add(type_uint64(), ValueType.UInt64);
StandardToManaged.Add(typeof(ulong), ValueType.UInt64);
ManagedToStandard.Add(ValueType.UInt64, typeof(ulong));
ManagedToNative.Add(ValueType.Float, type_float());
NativeToManaged.Add(type_float(), ValueType.Float);
StandardToManaged.Add(typeof(float), ValueType.Float);
ManagedToStandard.Add(ValueType.Float, typeof(float));
ManagedToNative.Add(ValueType.Double, type_double());
NativeToManaged.Add(type_double(), ValueType.Double);
StandardToManaged.Add(typeof(double), ValueType.Double);
ManagedToStandard.Add(ValueType.Double, typeof(double));
ManagedToNative.Add(ValueType.String, type_string());
NativeToManaged.Add(type_string(), ValueType.String);
StandardToManaged.Add(typeof(string), ValueType.String);
ManagedToStandard.Add(ValueType.String, typeof(string));
ManagedToNative.Add(ValueType.Array, type_array());
NativeToManaged.Add(type_array(), ValueType.Array);
@ -804,9 +865,15 @@ static class ValueTypeBridge
ManagedToNative.Add(ValueType.Error, type_error());
NativeToManaged.Add(type_error(), ValueType.Error);
StandardToManaged.Add(typeof(Eina.Error), ValueType.Error);
ManagedToStandard.Add(ValueType.Error, typeof(Eina.Error));
ManagedToNative.Add(ValueType.Object, type_object());
NativeToManaged.Add(type_object(), ValueType.Object);
// We don't use `typeof(Efl.Object)` directly in the StandartToManaged dictionary as typeof(myobj) may
// return a different type. For ManagedToStandard, we make use of C# generics covariance to create
// an collection of Efl.Objects when unwrapping.
ManagedToStandard.Add(ValueType.Object, typeof(Efl.Object));
ManagedToNative.Add(ValueType.Empty, IntPtr.Zero);
NativeToManaged.Add(IntPtr.Zero, ValueType.Empty);
@ -916,7 +983,108 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
private Value()
{
this.Handle = Alloc();
if (this.Handle == IntPtr.Zero)
{
throw new OutOfMemoryException("Failed to allocate memory for Eina.Value");
}
this.Ownership = Ownership.Managed;
MemoryNative.Memset(this.Handle, 0, eina_value_sizeof());
}
/// <summary>Creates a new Value from the given C# value.</summary>
/// <param name="obj">The object to be wrapped.</param>
public Value(object obj) : this()
{
var objType = obj.GetType();
if (objType == typeof(sbyte))
{
Setup(ValueType.SByte);
Set((sbyte)obj);
}
else if (objType == typeof(byte))
{
Setup(ValueType.Byte);
Set((byte)obj);
}
else if (objType == typeof(short))
{
Setup(ValueType.Short);
Set((short)obj);
}
else if (objType == typeof(ushort))
{
Setup(ValueType.UShort);
Set((ushort)obj);
}
else if (objType == typeof(int))
{
Setup(ValueType.Int32);
Set((int)obj);
}
else if (objType == typeof(uint))
{
Setup(ValueType.UInt32);
Set((uint)obj);
}
else if (objType == typeof(long))
{
Setup(ValueType.Int64);
Set((long)obj);
}
else if (objType == typeof(ulong))
{
Setup(ValueType.UInt64);
Set((ulong)obj);
}
else if (objType == typeof(float))
{
Setup(ValueType.Float);
Set((float)obj);
}
else if (objType == typeof(double))
{
Setup(ValueType.Double);
Set((double)obj);
}
else if (objType == typeof(string))
{
Setup(ValueType.String);
Set(obj as string);
}
else if (typeof(Efl.Object).IsAssignableFrom(objType))
{
Setup(ValueType.Object);
Set(obj as Efl.Object);
}
else
{
// Container type conversion is supported only from IEnumerable<T>
if (!obj.GetType().GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
{
throw new ArgumentException($"Unsupported type for direct construction: {objType}");
}
Type[] genericArguments = objType.GetGenericArguments();
if (genericArguments.Count() != 1)
{
throw new ArgumentException($"Unsupported type for direct construction: {objType}");
}
var genericArg = genericArguments[0];
var argValueType = ValueTypeBridge.GetManaged(genericArg);
Setup(ValueType.Array, argValueType);
foreach (var item in obj as System.Collections.IEnumerable)
{
Append(item);
}
}
}
public Value(IntPtr handle, Ownership ownership = Ownership.Managed)
@ -1390,6 +1558,121 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
return b;
}
/// <summary>Unwrap the value into its underlying C# value.
///
/// <para>Useful for methods like <see crev="PropertyInfo.SetValue(object, object)" />
/// as it will unpack the value to it correct C# type.</para>
/// </summary>
/// <returns>The C# value wrapped by this value.</returns>
public object Unwrap()
{
switch (GetValueType())
{
case ValueType.SByte:
{
sbyte o;
Get(out o);
return o;
}
case ValueType.Byte:
{
byte o;
Get(out o);
return o;
}
case ValueType.Short:
{
short o;
Get(out o);
return o;
}
case ValueType.UShort:
{
ushort o;
Get(out o);
return o;
}
case ValueType.Int32:
{
int o;
Get(out o);
return o;
}
case ValueType.UInt32:
{
uint o;
Get(out o);
return o;
}
case ValueType.Int64:
case ValueType.Long:
{
long o;
Get(out o);
return o;
}
case ValueType.UInt64:
case ValueType.ULong:
{
ulong o;
Get(out o);
return o;
}
case ValueType.Float:
{
float o;
Get(out o);
return o;
}
case ValueType.Double:
{
double o;
Get(out o);
return o;
}
case ValueType.String:
{
string o;
Get(out o);
return o;
}
case ValueType.Object:
{
Efl.Object o;
Get(out o);
return o;
}
case ValueType.Array:
case ValueType.List:
{
// Eina Array and Lists will be unwrapped into a System.Collections.Generic.List<T>
// usually to be handled as IEnumerable<T> through LINQ.
var genericType = ValueTypeBridge.GetStandard(GetValueSubType());
Type[] typeArgs = { genericType };
var containerType = typeof(System.Collections.Generic.List<>);
var retType = containerType.MakeGenericType(typeArgs);
object ret = Activator.CreateInstance(retType);
var addMeth = retType.GetMethod("Add");
if (addMeth == null)
{
throw new InvalidOperationException("Failed to get Add() method of container to wrap value");
}
for (int i = 0; i < Count(); i++)
{
object[] args = new object[]{ this[i] };
addMeth.Invoke(ret, args);
}
return ret;
}
default:
throw new InvalidOperationException($"Unsupported value type to unwrap: {GetValueType()}");
}
}
// Efl.Object conversions are made explicit to avoid ambiguity between
// Set(Efl.Object) and Set(Value) when dealing with classes derived from
// Efl.Object.
@ -1828,7 +2111,7 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
if (!GetValueType().IsString())
{
throw (new ArgumentException(
"Trying to set non-string value on a string Eina.Value"));
"Trying to set string value on a non-string Eina.Value"));
}
// No need to worry about ownership as eina_value_set will copy the passed string.

View File

@ -67,15 +67,14 @@ public abstract class EoWrapper : IWrapper, IDisposable
/// Internal usage: Constructor to actually call the native library constructors. C# subclasses
/// must use the public constructor only.</summary>
/// <param name="baseKlass">The pointer to the base native Eo class.</param>
/// <param name="managedType">The managed type of the public constructor that originated this call.</param>
/// <param name="parent">The Efl.Object parent of this instance.</param>
/// <param name="file">Name of the file from where the constructor is called.</param>
/// <param name="line">Number of the line from where the constructor is called.</param>
protected EoWrapper(IntPtr baseKlass, System.Type managedType, Efl.Object parent,
protected EoWrapper(IntPtr baseKlass, Efl.Object parent,
[CallerFilePath] string file = null,
[CallerLineNumber] int line = 0)
{
generated = ((object)this).GetType() == managedType;
generated = Efl.Eo.BindingEntity.IsBindingEntity(((object)this).GetType());
IntPtr actual_klass = baseKlass;
if (!generated)
{

View File

@ -775,6 +775,22 @@ public class PrivateNativeClass : NativeClass
}
}
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Interface |
System.AttributeTargets.Enum |
System.AttributeTargets.Delegate |
System.AttributeTargets.Struct,
AllowMultiple = false,
Inherited = false)
]
public class BindingEntity: System.Attribute
{
public static bool IsBindingEntity(System.Type t)
{
return Attribute.GetCustomAttribute(t, typeof(BindingEntity), false) != null;
}
}
public interface IWrapper
{
/// <summary>Pointer to internal Eo instance.</summary>

View File

@ -48,7 +48,8 @@ edje/swallow.edc \
edje/table.edc \
edje/text.edc \
edje/textblock-hyphen.edc \
edje/toggle_using_filter.edc
edje/toggle_using_filter.edc \
edje/center_zoom.edc
MULTISENSE_EDCS = edje/multisense.edc
if ENABLE_MULTISENSE

View File

@ -0,0 +1,105 @@
collections {
group { name: "center_zoom_example";
min: 360 360;
max: 360 360;
parts {
part {
name: "bg";
type: RECT;
description {
state: "default" 0.0;
color: 0 0 0 255;
}
}
part {
name: "center_part";
type: RECT;
description {
state: "default" 0.0;
min: 25 25;
max: 25 25;
rel1.to:"bg";
rel2 {
relative: 1.0 0.5;
to: "bg";
}
}
}
part {
name: "rectangle";
type: RECT;
description {
state: "default" 0.0;
color: 0 0 255 128;
max: 150 150;
rel1 {
to: "bg";
}
rel2 {
to: "bg";
}
map {
on: 1;
zoom {
center: "center_part";
x: 0.0;
y: 0.0;
}
}
}
description {
state: "zoom" 0.0;
inherit: "default" 0.0;
map {
on: 1;
zoom {
center: "center_part";
x: 1;
y: 1;
}
}
}
}
part {
name: "title";
type: TEXT;
description {
state: "default" 0.0;
color: 200 200 200 255;
align: 0.5 0.0;
rel1.to:"bg";
rel2 {
relative: 1.0 0.0;
to: "bg";
}
text {
text: "Center Zoom Example";
font: "Sans";
size: 16;
min: 1 1;
}
}
}
part {
name: "event";
type: RECT;
mouse_events: 1;
description {
state: "default" 0.0;
color: 0 0 0 0;
}
}
}
programs {
program {
name: "move,bottom";
signal: "mouse,up,1";
source: "event";
action: STATE_SET "zoom" 0.0;
transition: LINEAR 1.0;
target: "rectangle";
}
}
}
}

View File

@ -44,6 +44,7 @@ edc_files = [
'textblock-hyphen.edc',
'toggle_using_filter.edc',
'multisense.edc',
'center_zoom.edc',
]
if (get_option('physics'))

View File

@ -77,6 +77,8 @@ static void _ecore_evas_animator_freeze(Ecore_Animator *animator);
static void _ecore_evas_animator_thaw(Ecore_Animator *animator);
static void *_ecore_evas_animator_del(Ecore_Animator *animator);
static void _ecore_evas_event_del(void *data, const Efl_Event *ev EINA_UNUSED);
static void
_ecore_evas_focus_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *seat)
{
@ -3432,6 +3434,12 @@ _ecore_evas_free(Ecore_Evas *ee)
Efl_Input_Device *dev;
Ecore_Evas_Interface *iface;
if (ee->self_del)
{
efl_event_callback_del(ee->evas, EFL_EVENT_INVALIDATE, _ecore_evas_event_del, ee);
ee->self_del = EINA_FALSE;
}
ee->deleted = EINA_TRUE;
if (ee->refcount > 0) return;
@ -3494,7 +3502,7 @@ _ecore_evas_free(Ecore_Evas *ee)
ee->prop.wm_rot.manual_mode.timer = NULL;
eina_hash_free(ee->prop.cursors);
ee->prop.cursors = NULL;
evas_free(ee->evas);
if (!ee->evas_dying) evas_free(ee->evas);
ee->evas = NULL;
ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE);
ee->driver = NULL;
@ -5264,6 +5272,15 @@ ecore_evas_evas_new(Ecore_Evas *ee, int w, int h)
return e;
}
static void
_ecore_evas_event_del(void *data, const Efl_Event *ev EINA_UNUSED)
{
Ecore_Evas *ee = data;
ee->evas_dying = EINA_TRUE;
ecore_evas_free(ee);
}
EAPI void
ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window)
{
@ -5277,6 +5294,9 @@ ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window)
if (single_window)
evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
efl_event_callback_add(ee->evas, EFL_EVENT_INVALIDATE, _ecore_evas_event_del, ee);
ee->self_del = EINA_TRUE;
}
static Ecore_Animator *

View File

@ -385,6 +385,8 @@ struct _Ecore_Evas
unsigned char animator_ticked : 1;
unsigned char animator_ran : 1;
unsigned char first_frame : 1;
unsigned char self_del : 1;
unsigned char evas_dying : 1;
};
struct _Ecore_Evas_Aux_Hint

View File

@ -8,8 +8,11 @@ static void _edje_part_make_rtl(Edje_Part_Description_C
static Edje_Part_Description_Common *_edje_get_description_by_orientation(Edje *ed, Edje_Part_Description_Common *src, Edje_Part_Description_Common **dst, unsigned char type);
static void _edje_part_recalc_single(Edje *ed, Edje_Real_Part *ep,
Edje_Part_Description_Common *desc, Edje_Part_Description_Common *chosen_desc,
Edje_Real_Part *center, Edje_Real_Part *light, Edje_Real_Part *persp,
Edje_Part_Description_Common *desc,
Edje_Part_Description_Common *chosen_desc,
Edje_Real_Part *center,
Edje_Real_Part *zoom_center,
Edje_Real_Part *light, Edje_Real_Part *persp,
Edje_Real_Part *rel1_to_x, Edje_Real_Part *rel1_to_y,
Edje_Real_Part *rel2_to_x, Edje_Real_Part *rel2_to_y,
Edje_Real_Part *clip_to,
@ -2279,6 +2282,7 @@ static void
_edje_part_recalc_single_map(Edje *ed,
Edje_Real_Part *ep EINA_UNUSED,
Edje_Real_Part *center,
Edje_Real_Part *zoom_center,
Edje_Real_Part *light,
Edje_Real_Part *persp,
Edje_Part_Description_Common *desc,
@ -2293,6 +2297,7 @@ _edje_part_recalc_single_map(Edje *ed,
EINA_COW_CALC_MAP_BEGIN(params, params_write)
{
//rotation center
if (center)
{
params_write->center.x = ed->x + center->x + (center->w / 2);
@ -2304,6 +2309,17 @@ _edje_part_recalc_single_map(Edje *ed,
params_write->center.y = ed->y + params->final.y + (params->final.h / 2);
}
params_write->center.z = 0;
//zoom center
if (zoom_center)
{
params_write->zoom_center.x = ed->x + zoom_center->x + (zoom_center->w / 2);
params_write->zoom_center.y = ed->y + zoom_center->y + (zoom_center->h / 2);
}
else
{
params_write->zoom_center.x = ed->x + params->final.x + (params->final.w / 2);
params_write->zoom_center.y = ed->y + params->final.y + (params->final.h / 2);
}
params_write->rotation.x = desc->map.rot.x;
params_write->rotation.y = desc->map.rot.y;
@ -2680,6 +2696,7 @@ _edje_part_recalc_single(Edje *ed,
Edje_Part_Description_Common *desc,
Edje_Part_Description_Common *chosen_desc,
Edje_Real_Part *center,
Edje_Real_Part *zoom_center,
Edje_Real_Part *light,
Edje_Real_Part *persp,
Edje_Real_Part *rel1_to_x,
@ -3056,7 +3073,7 @@ _edje_part_recalc_single(Edje *ed,
EINA_COW_CALC_PHYSICS_END(params, params_write);
}
#endif
_edje_part_recalc_single_map(ed, ep, center, light, persp, desc, chosen_desc, params);
_edje_part_recalc_single_map(ed, ep, center, zoom_center, light, persp, desc, chosen_desc, params);
}
static void
@ -3757,7 +3774,7 @@ _edje_map_prop_set(Evas_Map *map, const Edje_Calc_Params *pf,
//zoom
evas_map_util_zoom(map,
pf->ext->map->zoom.x, pf->ext->map->zoom.y,
pf->ext->map->center.x, pf->ext->map->center.y);
pf->ext->map->zoom_center.x, pf->ext->map->zoom_center.y);
//rotate
evas_map_util_3d_rotate(map,
@ -3994,6 +4011,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
int statep2 = -1;
int statecl = -1;
Edje_Real_Part *center[2] = { NULL, NULL };
Edje_Real_Part *zoom_center[2] = { NULL, NULL };
Edje_Real_Part *light[2] = { NULL, NULL };
Edje_Real_Part *persp[2] = { NULL, NULL };
Edje_Real_Part *rp1[4] = { NULL, NULL, NULL, NULL };
@ -4313,6 +4331,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
if (ep->param1.description->map.on)
{
center[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.rot.id_center, &statec1);
zoom_center[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.zoom.id_center, &statec1);
light[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.id_light, &statel1);
if (chosen_desc->map.persp_on)
@ -4324,6 +4343,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
if (ep->param2 && ep->param2->description->map.on)
{
center[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.rot.id_center, &statec2);
zoom_center[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.zoom.id_center, &statec2);
light[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.id_light, &statel2);
if (chosen_desc->map.persp_on)
@ -4359,7 +4379,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
#endif
{
_edje_part_recalc_single(ed, ep, ep->param1.description,
chosen_desc, center[0], light[0],
chosen_desc, center[0], zoom_center[0], light[0],
persp[0], rp1[Rel1X], rp1[Rel1Y],
rp1[Rel2X], rp1[Rel2Y], clip1, confine_to,
threshold, p1, mmw, mmh,
@ -4405,7 +4425,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
#endif
{
_edje_part_recalc_single(ed, ep, ep->param2->description,
chosen_desc, center[1], light[1],
chosen_desc, center[1], zoom_center[1], light[1],
persp[1], rp2[Rel1X], rp2[Rel1Y],
rp2[Rel2X], rp2[Rel2Y], clip2, confine_to,
threshold, p2, mmw, mmh,
@ -4690,6 +4710,8 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
p3_write->center.x = INTP(p1->ext->map->center.x, p2->ext->map->center.x, pos);
p3_write->center.y = INTP(p1->ext->map->center.y, p2->ext->map->center.y, pos);
p3_write->center.z = INTP(p1->ext->map->center.z, p2->ext->map->center.z, pos);
p3_write->zoom_center.x = INTP(p1->ext->map->zoom_center.x, p2->ext->map->zoom_center.x, pos);
p3_write->zoom_center.y = INTP(p1->ext->map->zoom_center.y, p2->ext->map->zoom_center.y, pos);
p3_write->rotation.x = FFP(p1->ext->map->rotation.x, p2->ext->map->rotation.x, pos);
p3_write->rotation.y = FFP(p1->ext->map->rotation.y, p2->ext->map->rotation.y, pos);
p3_write->rotation.z = FFP(p1->ext->map->rotation.z, p2->ext->map->rotation.z, pos);

View File

@ -798,6 +798,7 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.id_persp", map.id_persp, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.id_light", map.id_light, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.id_center", map.rot.id_center, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.zoom.id_center", map.zoom.id_center, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.x", map.rot.x, EDJE_T_FLOAT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.y", map.rot.y, EDJE_T_FLOAT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.z", map.rot.z, EDJE_T_FLOAT); \
@ -892,6 +893,7 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.id_persp", Dec.map.id_persp, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.id_light", Dec.map.id_light, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.id_center", Dec.map.rot.id_center, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.zoom.id_center", Dec.map.zoom.id_center, EET_T_INT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.x", Dec.map.rot.x, EDJE_T_FLOAT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.y", Dec.map.rot.y, EDJE_T_FLOAT); \
EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "map.rot.z", Dec.map.rot.z, EDJE_T_FLOAT); \

View File

@ -16,7 +16,7 @@ Eina_Cow *_edje_calc_params_physics_cow = NULL;
Edje_Global *_edje_global_obj = NULL;
static const Edje_Calc_Params_Map default_calc_map = {
{ 0, 0, 0 }, { 0.0, 0.0, 0.0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0.0, 0.0 }, NULL, 0
{ 0, 0, 0 }, { 0, 0 }, { 0.0, 0.0, 0.0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0.0, 0.0 }, NULL, 0
};
static const Edje_Calc_Params_Physics default_calc_physics = {

View File

@ -1310,6 +1310,7 @@ struct _Edje_Part_Description_Common
} rot;
struct {
FLOAT_T x, y;
int id_center;
} zoom;
Edje_Map_Color **colors; /* List of the Edje_Map_Color */
unsigned int colors_count;
@ -1812,6 +1813,9 @@ struct _Edje_Calc_Params_Map
struct {
int x, y, z;
} center; // 12
struct {
int x, y;
} zoom_center; // 12
struct {
FLOAT_T x, y, z;
} rotation; // 24

View File

@ -40,6 +40,17 @@ enum @beta Efl.Gfx.Image_Scale_Type
none [[Not scale the image]]
}
struct Efl.Gfx.Image.Stretch_Region
{
[[This struct holds the description of a stretchable region in one dimension (vertical or horizontal).
Used when scaling an image.
$offset + $length should be smaller than image size in that dimension.
]]
offset: uint; [[First pixel of the stretchable region, starting at 0.]]
length: uint; [[Length of the stretchable region in pixels.]]
}
interface @beta Efl.Gfx.Image
{
[[Common APIs for all 2D images that can be rendered on the canvas.]]
@ -76,6 +87,22 @@ interface @beta Efl.Gfx.Image
ratio: double; [[The image's ratio.]]
}
}
@property content_region {
[[Return the relative area enclosed inside the image where content is expected.
We do expect content to be inside the limit defined by the border or inside the
stretch region. If a stretch region is provided, the content region will encompass the
non strechable area that are surrounded by stretchable area. If no border and no
stretch region is set, they are assumed to be zero and the full object geometry is
where content can be layout on top. The area size change with the object size.
The geometry of the area is expressed relative to the geometry of the object.
]]
get { }
values {
region: Eina.Rect; [[A rectangle inside the object boundary that where content is expected.]]
}
}
@property border {
[[Dimensions of this image's border, a region that does not scale
with the center area.
@ -140,6 +167,26 @@ interface @beta Efl.Gfx.Image
fill: Efl.Gfx.Border_Fill_Mode; [[Fill mode of the center region.]]
}
}
@property stretch_region {
[[This property defines the stretchable pixels region of an image.
When the regions are set by the user, the method will walk the iterators
once and then destroy them. When the regions are retrieved by the user,
it is his responsibility to destroy the iterators.. It will remember the
information for the lifetime of the object. It will ignore all value
of @.border, @.border_scale and @.border_center_fill . To reset the object
you can just pass $null to both horizontal and vertical at the same
time.
]]
set {
return: Eina.Error; [[return an error code if the stretch_region provided are incorrect.]]
}
get {}
values {
horizontal: iterator<ptr(Efl.Gfx.Image.Stretch_Region)>; [[Representation of area that are stretchable in the image horizontal space.]]
vertical: iterator<ptr(Efl.Gfx.Image.Stretch_Region)>; [[Representation of area that are stretchable in the image vertical space.]]
}
}
@property image_size {
[[This represents the size of the original image in pixels.

View File

@ -1,6 +1,6 @@
parse efl_ui_layout_orientable;
enum @beta Efl.Gfx.Image_Orientation
enum Efl.Gfx.Image_Orientation
{
[[An orientation type, to rotate and flip images.
@ -25,12 +25,12 @@ enum @beta Efl.Gfx.Image_Orientation
flip_bitmask = 12 [[Bitmask that can be used to isolate flipping values, that is, $flip_vertical and $flip_horizontal.]]
}
interface @beta Efl.Gfx.Image_Orientable
interface Efl.Gfx.Image_Orientable
{
[[Interface for objects which can be oriented.]]
c_prefix: efl_gfx_image;
c_prefix: efl_gfx;
methods {
@property orientation {
@property image_orientation {
[[Control the orientation (rotation and flipping) of a visual object.
This can be used to set the rotation on an image or a window, for

View File

@ -1,4 +1,4 @@
enum @beta Efl.Input.Device_Type
enum Efl.Input.Device_Type
{
[[General type of input device.
@ -19,7 +19,7 @@ enum @beta Efl.Input.Device_Type
@property canvas { values { canvas: Efl.Canvas; } }
*/
class @beta Efl.Input.Device extends Efl.Object
class Efl.Input.Device extends Efl.Object
{
[[Represents a pointing device such as a touch finger, pen or mouse.
]]

View File

@ -1,4 +1,4 @@
enum @beta Efl.Pointer.Action
enum Efl.Pointer.Action
{
[[Pointer event type. Represents which kind of event this is.
@ -18,7 +18,7 @@ enum @beta Efl.Pointer.Action
axis, [[Axis event (pen, stick, ...).]]
}
enum @beta Efl.Pointer.Flags
enum Efl.Pointer.Flags
{
[[Pointer flags indicating whether a double or triple click is under way.
@ -29,7 +29,7 @@ enum @beta Efl.Pointer.Flags
triple_click = (1 << 1), [[This mouse button press was the 3rd press of a triple click]]
}
enum @beta Efl.Input.Flags
enum Efl.Input.Flags
{
[[Special flags set during an input event propagation.
@ -74,7 +74,7 @@ enum @beta Efl.Input.Object_Pointer_Mode {
]]
}
enum @beta Efl.Input.Value {
enum @beta Efl.Input.Value {
[[Keys for the generic values of all events.
@since 1.19

View File

@ -1,4 +1,4 @@
interface @beta Efl.Pack extends Efl.Container
interface Efl.Pack extends Efl.Container
{
[[Common interface for objects (containers) with multiple contents
(sub-objects) which can be added and removed at runtime.

View File

@ -1,4 +1,4 @@
interface @beta Efl.Pack_Linear extends Efl.Pack
interface Efl.Pack_Linear extends Efl.Pack
{
[[Common interface for objects (containers) with multiple contents
(sub-objects) which can be added and removed at runtime in a linear fashion.

View File

@ -1,4 +1,4 @@
interface @beta Efl.Ui.Autorepeat {
interface Efl.Ui.Autorepeat {
[[Interface for autorepeating clicks.
This interface abstracts functions for enabling / disabling this feature.

View File

@ -1,6 +1,6 @@
parse efl_gfx_image_orientable;
enum @beta Efl.Ui.Layout_Orientation
enum Efl.Ui.Layout_Orientation
{
[[Orientation for UI objects and layouts that can have multiple configurations.
@ -24,10 +24,10 @@ enum @beta Efl.Ui.Layout_Orientation
along the selected axis.]]
}
interface @beta Efl.Ui.Layout_Orientable
interface Efl.Ui.Layout_Orientable
{
[[Interface for UI objects which can have more than one orientation.
For example, sliders, which can be horizontal or vertical, or container
boxes, which can arrange their elements in a horizontal or vertical fashion.
]]

View File

@ -1,4 +1,4 @@
class @beta Efl.Ui.Box extends Efl.Ui.Widget implements Efl.Pack_Linear, Efl.Pack_Layout,
class Efl.Ui.Box extends Efl.Ui.Widget implements Efl.Pack_Linear, Efl.Pack_Layout,
Efl.Ui.Layout_Orientable, Efl.Gfx.Arrangement
{
[[A container that arranges children widgets in a vertical or horizontal fashion.

View File

@ -1,4 +1,4 @@
class @beta Efl.Ui.Button extends Efl.Ui.Layout_Base implements Efl.Ui.Clickable, Efl.Ui.Autorepeat,
class Efl.Ui.Button extends Efl.Ui.Layout_Base implements Efl.Ui.Clickable, Efl.Ui.Autorepeat,
Efl.Text, Efl.Content,
Efl.Access.Widget.Action
{

View File

@ -1,4 +1,4 @@
struct Efl.Ui.Clickable_Clicked {
struct @beta Efl.Ui.Clickable_Clicked {
[[A struct that expresses a click in elementary.]]
repeated : int; [[The amount of how often the clicked event was repeated in a certain amount of time]]
button : int; [[The Button that is pressed]]

View File

@ -746,12 +746,7 @@ _grid_item_process(Eo *obj, Efl_Ui_Grid_Data *pd, EINA_UNUSED Efl_Ui_Grid_Item *
if (!efl_ui_widget_sub_object_add(obj, it))
return EINA_FALSE;
//FIXME: This is tricky workaround for set select mode and parent value.
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(it, gd, EINA_FALSE);
EFL_UI_ITEM_DATA_GET_OR_RETURN(it, id, EINA_FALSE);
id->select_mode = &(pd->select_mode);
id->parent = obj;
gd->parent = obj;
efl_ui_item_container_set(it, obj);
efl_canvas_group_member_add(pd->pan, it);
efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
@ -769,11 +764,7 @@ static void
_grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *it)
{
EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it);
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(it, gd);
EFL_UI_ITEM_DATA_GET_OR_RETURN(it, id);
id->select_mode = NULL;
id->parent = NULL;
gd->parent = NULL;
efl_ui_item_container_set(it, NULL);
pd->items = eina_list_remove(pd->items, it);
if (efl_ui_item_selected_get(it))

View File

@ -7,7 +7,6 @@ typedef struct _Efl_Ui_Grid_Item_Data
{
// Eo Objects
Eo *obj; /* Self-Object */
Eo *parent; /* Parent Widget */
Eina_Rect geo;
int index;
struct {

View File

@ -1362,7 +1362,7 @@ _efl_ui_image_efl_gfx_image_load_controller_load_size_get(const Eo *obj EINA_UNU
}
EOLIAN static void
_efl_ui_image_efl_gfx_image_orientable_orientation_set(Eo *obj, Efl_Ui_Image_Data *sd, Efl_Gfx_Image_Orientation orient)
_efl_ui_image_efl_gfx_image_orientable_image_orientation_set(Eo *obj, Efl_Ui_Image_Data *sd, Efl_Gfx_Image_Orientation orient)
{
if (sd->edje) return;
if (sd->orient == orient) return;
@ -1372,7 +1372,7 @@ _efl_ui_image_efl_gfx_image_orientable_orientation_set(Eo *obj, Efl_Ui_Image_Dat
}
EOLIAN static Efl_Gfx_Image_Orientation
_efl_ui_image_efl_gfx_image_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *sd)
_efl_ui_image_efl_gfx_image_orientable_image_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *sd)
{
return sd->orient;
}

View File

@ -100,7 +100,7 @@ class @beta Efl.Ui.Image extends Efl.Ui.Widget implements Efl.Ui.Clickable, Efl.
Efl.Gfx.Image_Load_Controller.load_size { get; set; }
Efl.Gfx.Image.smooth_scale { get; set; }
Efl.Gfx.Image.scale_type { get; set; }
Efl.Gfx.Image_Orientable.orientation { get; set; }
Efl.Gfx.Image_Orientable.image_orientation { get; set; }
Efl.Player.playable { get; }
Efl.Player.play { get; set; }
Efl.Layout.Signal.signal_emit;

View File

@ -1331,7 +1331,7 @@ _orient_apply(Eo *obj, Efl_Ui_Image_Zoomable_Data *sd)
}
EOLIAN static void
_efl_ui_image_zoomable_efl_gfx_image_orientable_orientation_set(Eo *obj, Efl_Ui_Image_Zoomable_Data *sd,
_efl_ui_image_zoomable_efl_gfx_image_orientable_image_orientation_set(Eo *obj, Efl_Ui_Image_Zoomable_Data *sd,
Efl_Gfx_Image_Orientation orient)
{
if (sd->orient == orient) return;
@ -1341,7 +1341,7 @@ _efl_ui_image_zoomable_efl_gfx_image_orientable_orientation_set(Eo *obj, Efl_Ui_
}
EOLIAN static Efl_Gfx_Image_Orientation
_efl_ui_image_zoomable_efl_gfx_image_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Image_Zoomable_Data *sd)
_efl_ui_image_zoomable_efl_gfx_image_orientable_image_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Image_Zoomable_Data *sd)
{
return sd->orient;
}

View File

@ -65,7 +65,7 @@ class @beta Efl.Ui.Image_Zoomable extends Efl.Ui.Image implements Efl.Ui.Zoom,
Efl.Access.Widget.Action.elm_actions { get; }
Efl.File.load;
Efl.File.file { get; set; }
Efl.Gfx.Image_Orientable.orientation { get; set; }
Efl.Gfx.Image_Orientable.image_orientation { get; set; }
Efl.Layout.Group.group_size_min { get; }
Efl.Layout.Group.group_size_max { get; }
Efl.Layout.Signal.signal_callback_add;

View File

@ -143,10 +143,12 @@ _efl_ui_item_part_content_efl_content_content_unset(Eo *obj, void *pd EINA_UNUSE
static void
_item_select(Eo *obj, Efl_Ui_Item_Data *pd)
{
if (pd->selected &&
(*(pd->select_mode) != EFL_UI_SELECT_MODE_SINGLE_ALWAYS))
Efl_Ui_Select_Mode m;
if (!pd->parent)
return;
m = efl_ui_select_mode_get(pd->parent);
if (m == EFL_UI_SELECT_MODE_NONE || (pd->selected && m != EFL_UI_SELECT_MODE_SINGLE_ALWAYS))
return;
if (*(pd->select_mode) == EFL_UI_SELECT_MODE_NONE) return;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@ -206,6 +208,10 @@ _item_mouse_up(void *data,
{
Evas_Event_Mouse_Up *ev = event_info;
Eo *item = data;
Efl_Ui_Select_Mode m;
if (!efl_ui_item_container_get(item))
return;
EFL_UI_ITEM_DATA_GET_OR_RETURN(item, pd);
ELM_WIDGET_DATA_GET_OR_RETURN(item, wd);
if (wd->disabled) return;
@ -226,9 +232,10 @@ _item_mouse_up(void *data,
edje_object_signal_emit(wd->resize_obj, "efl,state,unpressed", "efl");
efl_event_callback_call(item, EFL_UI_EVENT_UNPRESSED, NULL);
if ((*(pd->select_mode) != EFL_UI_SELECT_MODE_SINGLE_ALWAYS) && (pd->selected))
m = efl_ui_select_mode_get(efl_ui_item_container_get(item));
if ((m != EFL_UI_SELECT_MODE_SINGLE_ALWAYS) && (pd->selected))
_item_unselect(item, pd);
else if (*(pd->select_mode) != EFL_UI_SELECT_MODE_NONE)
else if (m != EFL_UI_SELECT_MODE_NONE)
_item_select(item, pd);
}
@ -380,6 +387,19 @@ _efl_ui_item_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
return pd->selected;
}
EOLIAN static void
_efl_ui_item_container_set(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd, Efl_Ui_Widget *container)
{
pd->parent = container;
}
EOLIAN static Efl_Ui_Widget*
_efl_ui_item_container_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
{
return pd->parent;
}
/* Internal EO APIs and hidden overrides */
#define EFL_UI_ITEM_EXTRA_OPS \

View File

@ -18,6 +18,15 @@ abstract @beta Efl.Ui.Item extends Efl.Ui.Layout_Base implements Efl.Ui.Selectab
select: bool;
}
}
@property container {
[[The container this object is part of.
You should never use this property yourself, the container will set it. Unsetting this while the item is packed into a container does not have an impact on its state in the container.
]]
values {
container : Efl.Ui.Widget; [[The container this item is in.]]
}
}
}
implements {
//Efl.Object

View File

@ -9,7 +9,6 @@ typedef struct _Efl_Ui_Item_Data
Eo *obj; /* Self-Object */
Eo *parent; /* Parent Widget */
Efl_Ui_Select_Mode *select_mode; /* Select Mdoe of parent widget */
Ecore_Timer *longpress_timer; /* Timer for longpress handle */
// Boolean Data

View File

@ -667,16 +667,11 @@ _list_item_unselected(void *data, const Efl_Event *event)
}
static Eina_Bool
_list_item_process(Eo *obj, Efl_Ui_List_Data *pd, EINA_UNUSED Efl_Ui_List_Item *it)
_list_item_process(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_List_Item *it)
{
EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
//FIXME: This is tricky workaround for set select mode and parent value.
EFL_UI_LIST_ITEM_DATA_GET_OR_RETURN(it, ld, EINA_FALSE);
EFL_UI_ITEM_DATA_GET_OR_RETURN(it, id, EINA_FALSE);
id->select_mode = &(pd->select_mode);
id->parent = obj;
ld->parent = obj;
efl_ui_item_container_set(it, obj);
efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
@ -692,11 +687,7 @@ static void
_list_item_clear(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, EINA_UNUSED Efl_Ui_List_Item *it)
{
EFL_UI_LIST_ITEM_CHECK_OR_RETURN(it);
EFL_UI_LIST_ITEM_DATA_GET_OR_RETURN(it, ld);
EFL_UI_ITEM_DATA_GET_OR_RETURN(it, id);
id->select_mode = NULL;
id->parent = NULL;
ld->parent = NULL;
efl_ui_item_container_set(it, NULL);
efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _list_item_pressed, obj);
efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _list_item_unpressed, obj);

View File

@ -7,7 +7,6 @@ typedef struct _Efl_Ui_List_Item_Data
{
// Eo Objects
Eo *obj; /* Self-Object */
Eo *parent; /* Parent Widget */
Eina_Bool needs_size_calc : 1; /* Flag for Size calculation */
} Efl_Ui_List_Item_Data;

View File

@ -593,23 +593,24 @@ _progressbar_part_value_get(Efl_Ui_Progressbar_Data *sd, const char* part)
EOLIAN static void
_efl_ui_progressbar_efl_ui_range_display_range_value_set(Eo *obj, Efl_Ui_Progressbar_Data *sd, double val)
{
if (val < sd->val_min)
{
ERR("Error, value is less than minimum");
return;
}
if (val > sd->val_max)
{
ERR("Error, value is greater than maximum");
return;
}
if (EINA_DBL_EQ(sd->val, val)) return;
if (elm_widget_is_legacy(obj))
_progressbar_part_value_set(obj, sd, "elm.cur.progressbar", val);
else
_progressbar_part_value_set(obj, sd, "efl.cur.progressbar", val);
{
if (val < sd->val_min)
{
ERR("Error, value is less than minimum");
return;
}
if (val > sd->val_max)
{
ERR("Error, value is greater than maximum");
return;
}
_progressbar_part_value_set(obj, sd, "efl.cur.progressbar", val);
}
}
EOLIAN static double
@ -1052,7 +1053,7 @@ elm_progressbar_unit_format_set(Evas_Object *obj, const char *units)
EAPI const char *
elm_progressbar_unit_format_get(const Evas_Object *obj)
{
const char *fmt;
const char *fmt = NULL;
efl_ui_format_string_get(obj, &fmt, NULL);
return fmt;
}

View File

@ -748,16 +748,18 @@ _efl_ui_slider_efl_ui_range_display_range_limits_get(const Eo *obj EINA_UNUSED,
EOLIAN static void
_efl_ui_slider_efl_ui_range_display_range_value_set(Eo *obj, Efl_Ui_Slider_Data *sd, double val)
{
if (val < sd->val_min)
if (!elm_widget_is_legacy(obj))
{
ERR("Error, value is less than minimum");
return;
}
if (val > sd->val_max)
{
ERR("Error, value is greater than maximum");
return;
if (val < sd->val_min)
{
ERR("Error, value is less than minimum");
return;
}
if (val > sd->val_max)
{
ERR("Error, value is greater than maximum");
return;
}
}
if (EINA_DBL_EQ(val, sd->val)) return;

View File

@ -1,8 +1,8 @@
class @beta Efl.Ui.Table extends Efl.Ui.Widget implements Efl.Pack_Table, Efl.Pack_Layout,
class Efl.Ui.Table extends Efl.Ui.Widget implements Efl.Pack_Table, Efl.Pack_Layout,
Efl.Ui.Layout_Orientable, Efl.Gfx.Arrangement
{
[[Widget container that arranges its elements in a grid.
The amount of rows and columns can be controlled with @Efl.Pack_Table.table_rows
and @Efl.Pack_Table.table_columns, and elements can be manually positioned with
@Efl.Pack_Table.pack_table.

View File

@ -1427,7 +1427,6 @@ _long_press_cb(void *data, const Efl_Event *ev EINA_UNUSED)
sd->long_pressed = EINA_TRUE;
sd->longpress_timer = NULL;
efl_event_callback_call(data, EFL_UI_EVENT_LONGPRESSED, NULL);
}
static void

View File

@ -15,7 +15,7 @@ enum @beta Elm.Code_Widget_Scroller_Policy
struct @extern Elm.Code; [[Elementary code main data structure]] /* The main interface currently defined in code */
struct @extern Elm.Code_Line; [[Elementary code line data structure]] /* Parts of the interface currently defined in code */
class @beta Elm.Code_Widget extends Efl.Ui.Layout_Base
class @beta Elm.Code_Widget extends Efl.Ui.Layout
{
[[Elementary code widget]]
c_prefix: efl_ui_code_widget;

View File

@ -1124,7 +1124,7 @@ _indi_default_format_free_cb(void *data)
}
EOLIAN static void
_elm_slider_part_indicator_efl_ui_format_format_string_set(Eo *obj, void *_pd EINA_UNUSED, const char *template)
_elm_slider_part_indicator_efl_ui_format_format_string_set(Eo *obj, void *_pd EINA_UNUSED, const char *template, Efl_Ui_Format_String_Type type EINA_UNUSED)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
Elm_Slider_Data *sd = efl_data_scope_get(pd->obj, ELM_SLIDER_CLASS);
@ -1135,13 +1135,13 @@ _elm_slider_part_indicator_efl_ui_format_format_string_set(Eo *obj, void *_pd EI
efl_ui_format_func_set(efl_part(pd->obj, "indicator"), pd->obj, _indi_default_format_cb, _indi_default_format_free_cb);
}
EOLIAN static const char *
_elm_slider_part_indicator_efl_ui_format_format_string_get(const Eo *obj, void *_pd EINA_UNUSED)
EOLIAN static void
_elm_slider_part_indicator_efl_ui_format_format_string_get(const Eo *obj, void *_pd EINA_UNUSED, const char **template, Efl_Ui_Format_String_Type *type EINA_UNUSED)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
Elm_Slider_Data *sd = efl_data_scope_get(pd->obj, ELM_SLIDER_CLASS);
return sd->indi_template;
if (template) *template = sd->indi_template;
}
EOLIAN static void
@ -1207,7 +1207,7 @@ elm_slider_unit_format_set(Evas_Object *obj, const char *units)
EAPI const char *
elm_slider_unit_format_get(const Evas_Object *obj)
{
const char* fmt;
const char* fmt = NULL;
efl_ui_format_string_get(obj, &fmt, NULL);
return fmt;
}
@ -1386,7 +1386,7 @@ elm_slider_indicator_format_set(Evas_Object *obj, const char *indicator)
EAPI const char *
elm_slider_indicator_format_get(const Evas *obj)
{
const char *fmt;
const char *fmt = NULL;
efl_ui_format_string_get(efl_part(obj, "indicator"), &fmt, NULL);
return fmt;
}

View File

@ -9,11 +9,9 @@ EOAPI EFL_FUNC_BODY_CONST(elm_slider_part_indicator_visible_mode_get, Elm_Slider
void _elm_slider_part_indicator_efl_ui_format_format_cb_set(Eo *obj, void *pd, void *func_data, Efl_Ui_Format_Func func, Eina_Free_Cb func_free_cb);
void _elm_slider_part_indicator_efl_ui_format_format_string_set(Eo *obj, void *_pd, const char *template, Efl_Ui_Format_String_Type type);
void _elm_slider_part_indicator_efl_ui_format_format_string_set(Eo *obj, void *pd, const char *units);
const char *_elm_slider_part_indicator_efl_ui_format_format_string_get(const Eo *obj, void *pd);
void _elm_slider_part_indicator_efl_ui_format_format_string_get (const Eo *obj, void *_pd, const char **template, Efl_Ui_Format_String_Type *type);
void _elm_slider_part_indicator_efl_ui_format_apply_formatted_value(Eo *obj, Elm_Part_Data *pd);

View File

@ -9,7 +9,10 @@ namespace efl { namespace eolian { namespace grammar {
namespace attributes {
struct unused_type {};
struct unused_type {
unused_type() = default;
unused_type(std::nullptr_t) {}
};
unused_type const unused = {};
template <int N, typename Tuple, typename Enable = void>

View File

@ -15,6 +15,7 @@
#include "grammar/type_impl.hpp"
#include "grammar/attribute_reorder.hpp"
#include "grammar/part_implementation.hpp"
#include "grammar/ignore_warning.hpp"
namespace efl { namespace eolian { namespace grammar {
@ -42,6 +43,9 @@ struct class_implementation_generator
.generate(sink, std::make_tuple(cls.namespaces, cls.cxx_name), add_lower_case_context(ctx)))
return false;
if(!as_generator(ignore_warning_begin).generate(sink, nullptr, ctx))
return false;
#ifndef USE_EOCXX_INHERIT_ONLY
if(!as_generator(
(namespaces
@ -71,6 +75,9 @@ struct class_implementation_generator
)).generate(sink, std::make_tuple(cls.namespaces, cls.functions, cpp_namespaces, cls.cxx_name, cls.parts), ctx))
return false;
if(!as_generator(ignore_warning_end).generate(sink, nullptr, ctx))
return false;
if(!as_generator("#endif\n").generate(sink, std::make_tuple(), ctx))
return false;

View File

@ -46,7 +46,7 @@ struct is_eager_generator<T volatile const&> : is_eager_generator<T> {};
// struct is_generator<T> : is_eager_generator<T> {};
template <typename G, typename Enable = typename std::enable_if<is_eager_generator<G>::value>::type>
G as_generator(G&& g) { return g; }
G as_generator(G g) { return g; }
} } }

View File

@ -11,6 +11,7 @@
#include "class_definition.hpp"
#include "class_declaration.hpp"
#include "implementation_include_directive.hpp"
#include "ignore_warning.hpp"
namespace efl { namespace eolian { namespace grammar {
@ -27,11 +28,13 @@ auto class_header =
<< *class_declaration // sequence<class> | class
<< *class_forward_declaration // sequence<class> | class
<< string // extra header <string>
<< ignore_warning_begin
<< "\nnamespace eo_cxx {\n"
<< *base_class_definition // sequence<class> | class
<< "}\n"
<< *class_definition // sequence<class> | class
// << *implementation_include_directive
<< ignore_warning_end
]
;

View File

@ -0,0 +1,48 @@
#ifndef EOLIAN_CXX_IGNORE_WARNING_HH
#define EOLIAN_CXX_IGNORE_WARNING_HH
#include "grammar/generator.hpp"
namespace efl { namespace eolian { namespace grammar {
struct ignore_warning_begin_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::unused_type, Context const& context) const
{
return as_generator(
"\n"
"#pragma GCC diagnostic push\n"
"#pragma GCC diagnostic ignored \"-Wignored-qualifiers\"\n"
"\n"
).generate(sink, nullptr, context);
}
};
struct ignore_warning_end_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::unused_type, Context const& context) const
{
return as_generator(
"\n#pragma GCC diagnostic pop\n\n"
).generate(sink, nullptr, context);
}
};
template <>
struct is_eager_generator<ignore_warning_begin_generator> : std::true_type {};
template <>
struct is_generator<ignore_warning_begin_generator> : std::true_type {};
template <>
struct is_eager_generator<ignore_warning_end_generator> : std::true_type {};
template <>
struct is_generator<ignore_warning_end_generator> : std::true_type {};
ignore_warning_begin_generator constexpr ignore_warning_begin = {};
ignore_warning_end_generator constexpr ignore_warning_end = {};
} } }
#endif

View File

@ -348,7 +348,7 @@ struct visitor_generate
// pointers.swap(no_pointer_regular.pointers);
// if(is_out)
// pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
return visitor_type{sink, context, c_type, false, false}(no_pointer_regular)
&& as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context)
;
// && detail::generate_pointers(sink, pointers, *context, false);

View File

@ -126,7 +126,6 @@ ephysics_quaternion_euler_set(EPhysics_Quaternion *quat, double yaw, double pitc
return;
}
bt_quat = btQuaternion();
bt_quat.setEuler(yaw / RAD_TO_DEG, pitch / RAD_TO_DEG, roll / RAD_TO_DEG);
_ephysics_quaternion_update(quat, &bt_quat);
}

View File

@ -70,7 +70,7 @@ extern "C" {
#endif
/* the module api version */
#define EVAS_MODULE_API_VERSION 2
#define EVAS_MODULE_API_VERSION 3
/* the module types */
typedef enum _Evas_Module_Type
@ -130,7 +130,25 @@ struct _Evas_Image_Load_Opts
};
typedef Emile_Image_Animated Evas_Image_Animated;
typedef Emile_Image_Property Evas_Image_Property;
typedef struct _Evas_Image_Property Evas_Image_Property;
struct _Evas_Image_Property
{
Emile_Image_Property info;
// Stretch region are directly encoded the way Evas excpect them internally
// 8bits is used for each step. The lower bits indicate how long the stretch region
// span. Masking with 0x80 will be true if the region is stretchable. If false, it
// will be fixed size.
struct {
struct {
uint8_t *region;
} horizontal, vertical;
} stretch;
// Where inside the image are we supposed to overlay data
Eina_Rectangle content;
// need_data is set to True when to get accurate property, data need to be loaded
Eina_Bool need_data;
};
typedef struct _Evas_Image_Load_Func Evas_Image_Load_Func;
@ -186,8 +204,11 @@ typedef Emile_Colorspace Evas_Colorspace; /**< Colorspaces for pixel data suppor
#define EVAS_COLORSPACE_RGBA_S3TC_DXT4 EMILE_COLORSPACE_RGBA_S3TC_DXT4
#define EVAS_COLORSPACE_RGBA_S3TC_DXT5 EMILE_COLORSPACE_RGBA_S3TC_DXT5
#define EVAS_IMAGE_LOAD_VERSION 2
struct _Evas_Image_Load_Func
{
int version;
void *(*file_open) (Eina_File *f, Eina_Stringshare *key,
Evas_Image_Load_Opts *opts,
Evas_Image_Animated *animated,
@ -195,11 +216,14 @@ struct _Evas_Image_Load_Func
void (*file_close) (void *loader_data);
Eina_Bool (*file_head) (void *loader_data,
Evas_Image_Property *prop,
int *error);
Evas_Image_Property *prop,
int *error);
Eina_Bool (*file_head_with_data) (void *loader_data,
Evas_Image_Property *prop,
void *pixels, int *error);
Eina_Bool (*file_data) (void *loader_data,
Evas_Image_Property *prop,
void *pixels, int *error);
Evas_Image_Property *prop,
void *pixels, int *error);
double (*frame_duration) (void *loader_data,
int start, int frame_num);
@ -240,6 +264,32 @@ EAPI Eina_Bool evas_module_task_cancelled (void); /**< @since 1.19 */
EINA_MODULE_INIT(evas_##Tn##_##Name##_init); \
EINA_MODULE_SHUTDOWN(evas_##Tn##_##Name##_shutdown);
static inline Eina_Bool
evas_loader_helper_stretch_region_push(uint8_t **region,
uint8_t *offset,
Eina_Bool stretchable)
{
uint32_t length = 0;
void *tmp;
if (*offset == 0) return EINA_TRUE;
while (*region && (*region)[length] != 0)
length++;
// +1 for termination and +1 for the region being pushed
tmp = realloc(*region, sizeof (uint8_t) * (length + 2));
if (!tmp) return EINA_FALSE;
*region = (uint8_t *) tmp;
(*region)[length] = (*offset) | (stretchable ? 0x80 : 0);
(*region)[length + 1] = 0;
*offset = 0;
return EINA_TRUE;
}
#ifdef __cplusplus
}
#endif

View File

@ -11,12 +11,14 @@ abstract @beta Efl.Canvas.Image_Internal extends Efl.Canvas.Object implements Ef
Efl.Object.finalize;
Efl.Object.debug_name_override;
Efl.File_Save.save;
Efl.Gfx.Image_Orientable.orientation { get; set; }
Efl.Gfx.Image_Orientable.image_orientation { get; set; }
Efl.Gfx.Image.smooth_scale { get; set; }
Efl.Gfx.Image.ratio { get; }
Efl.Gfx.Image.content_region { get; }
Efl.Gfx.Image.border { get; set; }
Efl.Gfx.Image.border_scale { get; set; }
Efl.Gfx.Image.border_center_fill { get; set; }
Efl.Gfx.Image.stretch_region { get; set; }
Efl.Gfx.Image.scale_hint { get; set; }
Efl.Gfx.Image.content_hint { get; set; }
Efl.Gfx.Image.image_size { get; }

View File

@ -1,6 +1,6 @@
import efl_input_types;
mixin @beta Efl.Input.Event requires Efl.Object extends Efl.Duplicate
mixin Efl.Input.Event requires Efl.Object extends Efl.Duplicate
{
[[Represents a generic event data.

View File

@ -1,4 +1,4 @@
class @beta Efl.Input.Hold extends Efl.Object implements Efl.Input.Event
class Efl.Input.Hold extends Efl.Object implements Efl.Input.Event
{
[[Event data sent when inputs are put on hold or resumed.]]
methods {

View File

@ -1,4 +1,4 @@
interface @beta Efl.Input.Interface
interface Efl.Input.Interface
{
[[An object implementing this interface can send pointer events.

View File

@ -1,4 +1,4 @@
class @beta Efl.Input.Key extends Efl.Object implements Efl.Input.Event, Efl.Input.State
class Efl.Input.Key extends Efl.Object implements Efl.Input.Event, Efl.Input.State
{
[[Represents a single key event from a keyboard or similar device.
]]

View File

@ -1,6 +1,6 @@
import efl_input_types;
class @beta Efl.Input.Pointer extends Efl.Object implements Efl.Input.Event, Efl.Input.State
class Efl.Input.Pointer extends Efl.Object implements Efl.Input.Event, Efl.Input.State
{
[[Event data carried over with any pointer event (mouse, touch, pen, ...)
]]
@ -11,7 +11,7 @@ class @beta Efl.Input.Pointer extends Efl.Object implements Efl.Input.Event, Efl
act: Efl.Pointer.Action; [[Event action]]
}
}
@property value_has {
@property value_has @beta {
[[$true if this event carries a valid value for the specified $key.]]
get {}
keys {
@ -21,7 +21,7 @@ class @beta Efl.Input.Pointer extends Efl.Object implements Efl.Input.Event, Efl
has: bool; [[$true if input value is valid, $false otherwise]]
}
}
@property value {
@property value @beta {
[[Represents a generic value for this event.
Refer to the documentation of @Efl.Input.Value for each value's

View File

@ -1851,6 +1851,38 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data
_evas_event_source_mouse_up_events(eo_obj, eo_e, evt, pdata, event_id, cancel);
if (e->delete_me) break;
}
else if (evas_event_freezes_through(eo_obj, obj) &&
(obj->proxy->is_proxy) && (obj->proxy->src_events))
{
Evas_Object *eo_src = _evas_object_image_source_get(eo_obj);
Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
Evas_Object_Protected_Data *child;
Evas_Object *eo_child;
Eina_List *copy_events;
if (src->delete_me) continue;
copy_events = evas_event_list_copy(src->proxy->src_event_in);
EINA_LIST_FREE(copy_events, eo_child)
{
Evas_Object_Pointer_Data *obj_pdata;
child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
obj_pdata = _evas_object_pointer_data_get(pdata, child);
if (!obj_pdata)
{
ERR("Could not find the object pointer data for device %p",
ev->device);
continue;
}
if (((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) ||
(obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) &&
(obj_pdata->mouse_grabbed > 0))
{
obj_pdata->mouse_grabbed--;
pdata->seat->mouse_grabbed--;
}
}
}
if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
{
if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--;

View File

@ -75,6 +75,13 @@ struct _Evas_Object_Image_State
short l, r, t, b;
unsigned char fill;
} border;
struct {
struct {
uint8_t *region;
uint32_t stretchable;
uint32_t total;
} horizontal, vertical;
} stretch;
Evas_Object *source;
Evas_Map *defmap;
@ -91,6 +98,9 @@ struct _Evas_Object_Image_State
Eina_Bool has_alpha :1;
Eina_Bool opaque_valid : 1;
Eina_Bool opaque : 1;
Eina_Bool free_stretch : 1; // Should we free stretch region?
Eina_Bool stretch_loaded : 1; // Is the stretch region loaded from file?
};
#define EVAS_IMAGE_PRELOAD_NONE 0x00

View File

@ -14,6 +14,9 @@ static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *eo_obj, Evas_Ob
static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
static void evas_object_image_init(Evas_Object *eo_obj);
static inline uint32_t _stretch_region_accumulate(uint8_t *stretch_region, Eina_Bool mask, uint32_t *i);
static void evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
void *type_private_data,
void *engine, void *output, void *context, void *surface,
@ -92,6 +95,7 @@ static const Evas_Object_Image_State default_state = {
{ 0, 0, 0, 0 }, // fill
{ 0, 0, 0 }, // image
{ 1.0, 0, 0, 0, 0, 1 }, // border
{ { NULL, 0, 0 }, { NULL, 0, 0 } },
NULL, NULL, NULL, //source, defmap, scene
NULL, //f
NULL, //key
@ -412,7 +416,7 @@ _evas_image_orientation_set(Eo *eo_obj, Evas_Image_Data *o, Evas_Image_Orient or
}
EOLIAN static void
_efl_canvas_image_internal_efl_gfx_image_orientable_orientation_set(Eo *obj, Evas_Image_Data *o, Efl_Gfx_Image_Orientation efl_orient)
_efl_canvas_image_internal_efl_gfx_image_orientable_image_orientation_set(Eo *obj, Evas_Image_Data *o, Efl_Gfx_Image_Orientation efl_orient)
{
// This array takes an Efl_Gfx_Image_Orientation and turns it into an Elm_Image_Orient
static const Evas_Image_Orient evas_orient[16] = {
@ -440,7 +444,7 @@ _efl_canvas_image_internal_efl_gfx_image_orientable_orientation_set(Eo *obj, Eva
}
EOLIAN static Efl_Gfx_Image_Orientation
_efl_canvas_image_internal_efl_gfx_image_orientable_orientation_get(const Eo *obj EINA_UNUSED, Evas_Image_Data *o)
_efl_canvas_image_internal_efl_gfx_image_orientable_image_orientation_get(const Eo *obj EINA_UNUSED, Evas_Image_Data *o)
{
return o->orient_value;
}
@ -461,6 +465,130 @@ _efl_canvas_image_internal_efl_object_dbg_info_get(Eo *eo_obj, Evas_Image_Data *
(uint64_t)(uintptr_t)evas_object_image_source_get(eo_obj));
}
static void
_stretch_region_load(Evas_Object_Protected_Data *obj, Evas_Image_Data *o)
{
unsigned int i;
uint8_t *horizontal = NULL;
uint8_t *vertical = NULL;
uint32_t total, stretchable;
if (o->cur->stretch_loaded == EINA_TRUE ||
(o->cur->stretch.horizontal.region && o->cur->stretch.vertical.region))
return ;
ENFN->image_stretch_region_get(ENC, o->engine_data,
&horizontal,
&vertical);
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
{
state_write->stretch.horizontal.region = horizontal;
state_write->stretch.vertical.region = vertical;
state_write->free_stretch = EINA_FALSE;
state_write->stretch_loaded = EINA_TRUE;
}
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
if (!o->cur->stretch.horizontal.region || !o->cur->stretch.vertical.region)
return ;
stretchable = 0;
total = 0;
for (i = 0; o->cur->stretch.horizontal.region[i]; i++)
{
total += o->cur->stretch.horizontal.region[i] & 0x7F;
if (o->cur->stretch.horizontal.region[i] & 0x80)
stretchable += o->cur->stretch.horizontal.region[i] & 0x7F;
}
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
{
state_write->stretch.horizontal.stretchable = stretchable;
state_write->stretch.horizontal.total = total;
}
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
stretchable = 0;
total = 0;
for (i = 0; o->cur->stretch.vertical.region[i]; i++)
{
total += o->cur->stretch.vertical.region[i] & 0x7F;
if (o->cur->stretch.vertical.region[i] & 0x80)
stretchable += o->cur->stretch.vertical.region[i] & 0x7F;
}
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
{
state_write->stretch.vertical.stretchable = stretchable;
state_write->stretch.vertical.total = total;
}
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
}
static Eina_Rect
_efl_canvas_image_internal_efl_gfx_image_content_region_get(const Eo *eo_obj, Evas_Image_Data *o)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Eina_Rect r;
if (!o->cur->stretch.horizontal.region &&
!o->cur->stretch.vertical.region)
_stretch_region_load(obj, o);
if (o->cur->stretch.horizontal.region &&
o->cur->stretch.vertical.region)
{
uint32_t acc;
uint32_t hi = 0;
uint32_t vi = 0;
// If the file come with a defined content zone, then return it
if (ENFN->image_content_region_get(ENC, o->engine_data, &r.rect))
{
// Correct bottom right corner coordinate to be resized with object size
r.w = obj->cur->geometry.w - (o->cur->image.w - r.w);
r.h = obj->cur->geometry.h - (o->cur->image.h - r.h);
return r;
}
r.x = _stretch_region_accumulate(o->cur->stretch.horizontal.region, 0, &hi);
r.w = o->cur->stretch.horizontal.stretchable + obj->cur->geometry.w - o->cur->image.w;
// Accumulate all the non stretch zone, except the first one and the last one
acc = 0;
while (o->cur->stretch.horizontal.region[hi])
{
// We are just ignoring all the stretchable zone as we know them already
_stretch_region_accumulate(o->cur->stretch.horizontal.region, 0x80, &hi);
r.w += acc;
acc = _stretch_region_accumulate(o->cur->stretch.horizontal.region, 0, &hi);
}
r.y = _stretch_region_accumulate(o->cur->stretch.vertical.region, 0, &vi);
r.h = o->cur->stretch.vertical.stretchable + obj->cur->geometry.h - o->cur->image.h;
// Accumulate all the stretch zone, except the last non stretching one
acc = 0;
while (o->cur->stretch.vertical.region[vi])
{
// We are just ignoring all the stretchable zone as we know them already
_stretch_region_accumulate(o->cur->stretch.vertical.region, 0x80, &vi);
r.h += acc;
acc = _stretch_region_accumulate(o->cur->stretch.vertical.region, 0, &vi);
}
}
else
{
r.x = o->cur->border.l;
r.y = o->cur->border.t;
r.w = obj->cur->geometry.w - o->cur->border.l - o->cur->border.r;
r.h = obj->cur->geometry.h - o->cur->border.t - o->cur->border.b;
}
return r;
}
EOLIAN static void
_efl_canvas_image_internal_efl_gfx_image_border_set(Eo *eo_obj, Evas_Image_Data *o, int l, int r, int t, int b)
{
@ -531,6 +659,276 @@ _toggle_fill_listener(Eo *eo_obj, Evas_Image_Data *o)
NULL);
}
static inline Eina_Bool
_efl_canvas_image_internal_stretch_region_push(uint8_t **stretch_region,
uint32_t *stretch_region_length,
const uint8_t region)
{
uint8_t *tmp;
tmp = realloc(*stretch_region, (*stretch_region_length + 1) * sizeof (uint8_t));
if (!tmp) return EINA_FALSE;
*stretch_region = tmp;
(*stretch_region)[*stretch_region_length] = region;
(*stretch_region_length) += 1;
return EINA_TRUE;
}
static inline Eina_Error
_efl_canvas_image_internal_stretch_region_build(uint8_t **stretch_region,
uint32_t *stretch_region_length,
uint32_t value, uint8_t mask)
{
while (value > 0x7F)
{
if (!_efl_canvas_image_internal_stretch_region_push(stretch_region,
stretch_region_length,
mask | 0x7F))
{
free(*stretch_region);
return ENOMEM;
}
value -= 0x7F;
}
if (!value) return 0;
if (!_efl_canvas_image_internal_stretch_region_push(stretch_region,
stretch_region_length,
mask | value))
{
free(*stretch_region);
return ENOMEM;
}
return 0;
}
static inline uint8_t *
_efl_canvas_image_internal_stretch_region_iterate(Eina_Iterator *it)
{
Efl_Gfx_Image_Stretch_Region sz;
uint8_t *stretch_region = NULL;
uint32_t stretch_region_length = 0;
EINA_ITERATOR_FOREACH(it, sz)
{
if (_efl_canvas_image_internal_stretch_region_build(&stretch_region,
&stretch_region_length,
sz.offset, 0))
return NULL;
// The upper bit means stretchable region if set
if (_efl_canvas_image_internal_stretch_region_build(&stretch_region,
&stretch_region_length,
sz.length, 0x80))
return NULL;
}
if (!_efl_canvas_image_internal_stretch_region_push(&stretch_region,
&stretch_region_length,
0))
{
free(stretch_region);
return NULL;
}
return stretch_region;
}
static Eina_Error
_efl_canvas_image_internal_efl_gfx_image_stretch_region_set(Eo *eo_obj, Evas_Image_Data *pd,
Eina_Iterator *horizontal,
Eina_Iterator *vertical)
{
uint8_t *fhsz = NULL, *fvsz = NULL, *walk;
uint32_t hstretch = 0, vstretch = 0;
uint32_t htotal = 0, vtotal = 0;
Eina_Error err = EINVAL;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
// We do not duplicate the stretch region in memory, just move pointer. So when
// we do change it, we have to make sure nobody is accessing them anymore by
// blocking rendering.
evas_object_async_block(obj);
EINA_COW_IMAGE_STATE_WRITE_BEGIN(pd, state_write)
{
if (state_write->free_stretch) free(state_write->stretch.horizontal.region);
state_write->stretch.horizontal.region = NULL;
if (state_write->free_stretch) free(state_write->stretch.vertical.region);
state_write->stretch.vertical.region = NULL;
state_write->free_stretch = EINA_FALSE;
state_write->stretch_loaded = EINA_FALSE;
}
EINA_COW_IMAGE_STATE_WRITE_END(pd, state_write);
if (!horizontal && !vertical) return 0;
if (!horizontal || !vertical) goto on_error;
err = ENOMEM;
fhsz = _efl_canvas_image_internal_stretch_region_iterate(horizontal);
if (!fhsz) goto on_error;
fvsz = _efl_canvas_image_internal_stretch_region_iterate(vertical);
if (!fvsz) goto on_error;
for (walk = fhsz; *walk; walk++)
{
if ((*walk & 0x80)) hstretch += *walk & 0x7F;
htotal += *walk & 0x7F;
}
for (walk = fvsz; *walk; walk++)
{
if ((*walk & 0x80)) vstretch += *walk & 0x7F;
vtotal += *walk & 0x7F;
}
eina_iterator_free(horizontal);
eina_iterator_free(vertical);
EINA_COW_IMAGE_STATE_WRITE_BEGIN(pd, state_write)
{
state_write->stretch.horizontal.region = fhsz;
state_write->stretch.horizontal.stretchable = hstretch;
state_write->stretch.horizontal.total = htotal;
state_write->stretch.vertical.region = fvsz;
state_write->stretch.vertical.stretchable = vstretch;
state_write->stretch.vertical.total = vtotal;
state_write->free_stretch = EINA_TRUE;
state_write->stretch_loaded = EINA_TRUE;
}
EINA_COW_IMAGE_STATE_WRITE_END(pd, state_write);
return 0;
on_error:
eina_iterator_free(horizontal);
eina_iterator_free(vertical);
free(fhsz);
free(fvsz);
return err;
}
typedef struct _Efl_Gfx_Image_Stretch_Region_Iterator Efl_Gfx_Image_Stretch_Region_Iterator;
struct _Efl_Gfx_Image_Stretch_Region_Iterator
{
Eina_Iterator iterator;
Efl_Gfx_Image_Stretch_Region sz;
uint8_t *stretch_region;
unsigned int next;
};
static Eina_Bool
_efl_gfx_image_stretch_region_iterator_next(Eina_Iterator *iterator, void **data)
{
Efl_Gfx_Image_Stretch_Region_Iterator *it = (Efl_Gfx_Image_Stretch_Region_Iterator*) iterator;
*data = &it->sz;
if (!it->stretch_region[it->next]) return EINA_FALSE;
it->sz.offset = 0;
it->sz.length = 0;
// Count offset before next stretch region
while (!(it->stretch_region[it->next] & 0x80) && it->stretch_region[it->next])
{
it->sz.offset += it->stretch_region[it->next] & 0x7F;
it->next++;
}
// Count length of the stretch region
while ((it->stretch_region[it->next] & 0x80) && it->stretch_region[it->next])
{
it->sz.length += it->stretch_region[it->next] & 0x7F;
it->next++;
}
return EINA_TRUE;
}
static void *
_efl_gfx_image_stretch_region_iterator_container(Eina_Iterator *it EINA_UNUSED)
{
return NULL;
}
static void
_efl_gfx_image_stretch_region_iterator_free(Eina_Iterator *it)
{
free(it);
}
static void
_efl_canvas_image_internal_efl_gfx_image_stretch_region_get(const Eo *eo_obj,
Evas_Image_Data *pd,
Eina_Iterator **horizontal,
Eina_Iterator **vertical)
{
Efl_Gfx_Image_Stretch_Region_Iterator *it;
if (!pd->cur->stretch.vertical.region &&
!pd->cur->stretch.horizontal.region)
{
Evas_Object_Protected_Data *obj;
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
_stretch_region_load(obj, pd);
}
if (!horizontal) goto vertical_only;
if (!pd->cur->stretch.horizontal.region)
{
*horizontal = NULL;
goto vertical_only;
}
it = calloc(1, sizeof (Efl_Gfx_Image_Stretch_Region_Iterator));
if (!it) return;
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->stretch_region = pd->cur->stretch.horizontal.region;
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_efl_gfx_image_stretch_region_iterator_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
_efl_gfx_image_stretch_region_iterator_container);
it->iterator.free = FUNC_ITERATOR_FREE(_efl_gfx_image_stretch_region_iterator_free);
*horizontal = &it->iterator;
vertical_only:
if (!vertical) return;
if (!pd->cur->stretch.vertical.region)
{
*vertical = NULL;
return;
}
it = calloc(1, sizeof (Efl_Gfx_Image_Stretch_Region_Iterator));
if (!it) return;
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->stretch_region = pd->cur->stretch.vertical.region;
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_efl_gfx_image_stretch_region_iterator_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
_efl_gfx_image_stretch_region_iterator_container);
it->iterator.free = FUNC_ITERATOR_FREE(_efl_gfx_image_stretch_region_iterator_free);
*vertical = &it->iterator;
}
EOLIAN static void
_efl_canvas_image_internal_efl_gfx_fill_fill_auto_set(Eo *eo_obj, Evas_Image_Data *o, Eina_Bool setting)
{
@ -1286,6 +1684,7 @@ _efl_canvas_image_internal_efl_object_destructor(Eo *eo_obj, Evas_Image_Data *o
if (obj->legacy.ctor)
evas_object_image_video_surface_set(eo_obj, NULL);
evas_object_image_free(eo_obj, obj);
efl_gfx_image_stretch_region_set(eo_obj, NULL, NULL);
efl_destructor(efl_super(eo_obj, MY_CLASS));
}
@ -1966,6 +2365,84 @@ _evas_image_pixels_get(Eo *eo_obj, Evas_Object_Protected_Data *obj,
return pixels;
}
static inline uint32_t
_stretch_region_accumulate(uint8_t *stretch_region, Eina_Bool mask, uint32_t *i)
{
uint32_t acc;
for (acc = 0;
((stretch_region[*i] & 0x80) == mask) && stretch_region[*i];
(*i)++)
acc += stretch_region[*i] & 0x7F;
return acc;
}
static void
_evas_image_render_hband(Evas_Object_Protected_Data *obj, Evas_Image_Data *o,
void *engine, void *output, void *context,
void *surface, void *pixels,
const int *imw, const int *imh EINA_UNUSED,
int stretchw, int stretchh EINA_UNUSED,
int *inx, int *iny, int *inw, int *inh,
int *outx, int *outy, int *outw, int *outh,
Eina_Bool do_async)
{
uint32_t hacc;
uint32_t hi;
if (*inh == 0 || *outh == 0) goto end;
hi = 0;
while (o->cur->stretch.horizontal.region[hi])
{
// Not stretched horizontal
hacc = _stretch_region_accumulate(o->cur->stretch.horizontal.region,
0, &hi);
*inw = hacc;
*outw = hacc;
if (*inw && *outw)
_draw_image(obj, engine, output, context, surface, pixels,
*inx, *iny, *inw, *inh,
*outx, *outy, *outw, *outh,
o->cur->smooth_scale, do_async);
// We always step before starting the new region
*inx += *inw;
*outx += *outw;
// Horizontal stretched
hacc = _stretch_region_accumulate(o->cur->stretch.horizontal.region,
0x80, &hi);
*inw = hacc;
*outw = hacc * stretchw / o->cur->stretch.horizontal.stretchable;
if (*inw)
_draw_image(obj, engine, output, context, surface, pixels,
*inx, *iny, *inw, *inh,
*outx, *outy, *outw, *outh,
o->cur->smooth_scale, do_async);
// We always step before starting the new region
*inx += *inw;
*outx += *outw;
}
// Finish end of image, not horizontally stretched
*inw = *imw - *inx;
*outw = *inw; // If my math are correct, this should be equal
if (*inw)
_draw_image(obj, engine, output, context, surface, pixels,
*inx, *iny, *inw, *inh,
*outx, *outy, *outw, *outh,
o->cur->smooth_scale, do_async);
end:
*iny += *inh; // We always step before starting the next region
*outy += *outh;
}
static void
_evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
void *engine, void *output, void *context, void *surface, int x, int y,
@ -1996,6 +2473,8 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
return;
}
_stretch_region_load(obj, o);
ENFN->image_scale_hint_set(engine, pixels, o->scale_hint);
idx = evas_object_image_figure_x_fill(eo_obj, obj, o->cur->fill.x, o->cur->fill.w, &idw);
idy = evas_object_image_figure_y_fill(eo_obj, obj, o->cur->fill.y, o->cur->fill.h, &idh);
@ -2050,7 +2529,82 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
if (ih <= 0) break;
}
if ((o->cur->border.l == 0) && (o->cur->border.r == 0) &&
if (o->cur->stretch.horizontal.region &&
o->cur->stretch.vertical.region)
{
int inx, iny, inw, inh, outx, outy, outw, outh;
int ox, oy;
int imw, imh;
int stretchh, stretchw;
uint32_t vacc;
uint32_t vi;
imw = imagew;
imh = imageh;
ox = offx + ix;
oy = offy + iy;
iny = 0;
outy = oy;
// Check that the image is something we can deal with
if (imw < (int) o->cur->stretch.horizontal.total ||
imh < (int) o->cur->stretch.vertical.total)
break;
// Calculate the amount to stretch, by removing from the targetted size
// the amount that should not stretch from the source image
stretchw = iw - (imw - o->cur->stretch.horizontal.stretchable);
stretchh = ih - (imh - o->cur->stretch.vertical.stretchable);
// Check we have room to stretch
if (stretchh < 0) stretchh = 0;
if (stretchw < 0) stretchw = 0;
for (vi = 0; o->cur->stretch.vertical.region[vi]; )
{
vacc = _stretch_region_accumulate(o->cur->stretch.vertical.region, 0, &vi);
inx = 0;
outx = ox;
// Not stretching vertically step
inh = vacc;
outh = vacc;
_evas_image_render_hband(obj, o, engine, output, context,
surface, pixels,
&imw, &imh, stretchw, stretchh,
&inx, &iny, &inw, &inh,
&outx, &outy, &outw, &outh,
do_async);
// Stretching vertically step
vacc = _stretch_region_accumulate(o->cur->stretch.vertical.region, 0x80, &vi);
inx = 0;
outx = ox;
inh = vacc;
outh = vacc * stretchh / o->cur->stretch.vertical.stretchable;
_evas_image_render_hband(obj, o, engine, output, context,
surface, pixels,
&imw, &imh, stretchw, stretchh,
&inx, &iny, &inw, &inh,
&outx, &outy, &outw, &outh,
do_async);
}
// Finish end of image, not stretched vertical, not stretched horizontal
inx = 0;
outx = ox;
inh = imh - iny;
outh = inh; // Again, if my math are correct, this should be the same
_evas_image_render_hband(obj, o, engine, output, context,
surface, pixels,
&imw, &imh, stretchw, stretchh,
&inx, &iny, &inw, &inh,
&outx, &outy, &outw, &outh,
do_async);
}
else if ((o->cur->border.l == 0) && (o->cur->border.r == 0) &&
(o->cur->border.t == 0) && (o->cur->border.b == 0) &&
(o->cur->border.fill != 0))
{

View File

@ -3625,11 +3625,16 @@ evas_render_updates_internal(Evas *eo_e,
obj = eina_array_data_get(&e->pending_objects, i);
if (obj->smart.parent)
{
/* these are all objects which could not be rendered because they were
* added to their smart parent in this cycle and the parent was not changed
*/
Evas_Object_Protected_Data *smart_parent;
smart_parent = efl_data_scope_get(obj->smart.parent,
EFL_CANVAS_OBJECT_CLASS);
evas_object_change(obj->smart.parent, smart_parent);
/* render cache must be invalidated to correctly render subobj on next pass */
evas_object_smart_render_cache_clear(obj->smart.parent);
}
obj->changed = EINA_TRUE;
}

View File

@ -183,7 +183,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
evas_image_load_func = em->functions;
evas_module_use(em);
*error = EVAS_LOAD_ERROR_NONE;
if (evas_image_load_func)
if (evas_image_load_func && evas_image_load_func->version == EVAS_IMAGE_LOAD_VERSION)
{
Evas_Image_Property property;
const char *file;
@ -215,17 +215,18 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
DBG("loaded file head using module '%s' (%p): %s",
em->definition->name, em, file);
ie->w = property.w;
ie->h = property.h;
ie->borders.l = property.borders.l;
ie->borders.r = property.borders.r;
ie->borders.t = property.borders.t;
ie->borders.b = property.borders.b;
ie->scale = property.scale;
ie->flags.alpha = property.alpha;
if (property.cspaces) ie->cspaces = property.cspaces;
ie->flags.rotated = property.rotated;
ie->flags.flipped = property.flipped;
ie->w = property.info.w;
ie->h = property.info.h;
ie->borders.l = property.info.borders.l;
ie->borders.r = property.info.borders.r;
ie->borders.t = property.info.borders.t;
ie->borders.b = property.info.borders.b;
ie->scale = property.info.scale;
ie->flags.alpha = property.info.alpha;
ie->need_data = property.need_data;
if (property.info.cspaces) ie->cspaces = property.info.cspaces;
ie->flags.rotated = property.info.rotated;
ie->flags.flipped = property.info.flipped;
r = EINA_FALSE;
}
else
@ -448,20 +449,20 @@ end:
_timestamp_build(&(ie->tstamp), &st);
memset(&property, 0, sizeof (property));
property.w = ie->w;
property.h = ie->h;
property.scale = ie->scale;
property.rotated = ie->flags.rotated;
property.flipped = ie->flags.flipped;
property.premul = EINA_FALSE;
property.alpha_sparse = EINA_FALSE;
property.cspace = ie->space;
property.info.w = ie->w;
property.info.h = ie->h;
property.info.scale = ie->scale;
property.info.rotated = ie->flags.rotated;
property.info.flipped = ie->flags.flipped;
property.info.premul = EINA_FALSE;
property.info.alpha_sparse = EINA_FALSE;
property.info.cspace = ie->space;
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
property.borders.l = ie->borders.l;
property.borders.r = ie->borders.r;
property.borders.t = ie->borders.t;
property.borders.b = ie->borders.b;
property.info.borders.l = ie->borders.l;
property.info.borders.r = ie->borders.r;
property.info.borders.t = ie->borders.t;
property.info.borders.b = ie->borders.b;
pixels = evas_cache_image_pixels(ie);
if (!pixels)
@ -470,11 +471,21 @@ end:
return EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
}
evas_image_load_func->file_data(ie->loader_data, &property, pixels, &ret);
if (ie->need_data)
{
evas_image_load_func->file_head_with_data(ie->loader_data, &property, pixels, &ret);
memcpy(&ie->content, &property.content, sizeof (Eina_Rectangle));
ie->stretch.horizontal.region = property.stretch.horizontal.region;
ie->stretch.vertical.region = property.stretch.vertical.region;
}
else
{
evas_image_load_func->file_data(ie->loader_data, &property, pixels, &ret);
}
ie->flags.alpha_sparse = property.alpha_sparse;
ie->flags.alpha_sparse = property.info.alpha_sparse;
if (property.premul) evas_common_image_premul(ie);
if (property.info.premul) evas_common_image_premul(ie);
return ret;
}

View File

@ -598,6 +598,7 @@ struct _Image_Entry
unsigned char need_unload : 1;
unsigned char load_failed : 1;
unsigned char need_data : 1;
struct
{
@ -633,6 +634,14 @@ struct _Image_Entry
int connect_num;
int channel;
Evas_Load_Error load_error;
struct {
struct {
uint8_t *region;
} horizontal, vertical;
} stretch;
Eina_Rectangle content;
};
struct _Engine_Image_Entry

View File

@ -1354,6 +1354,8 @@ struct _Evas_Func
Eina_Bool (*image_data_map) (void *engine, void **image, Eina_Rw_Slice *slice, int *stride, int x, int y, int w, int h, Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode, int plane);
Eina_Bool (*image_data_unmap) (void *engine, void *image, const Eina_Rw_Slice *slice);
int (*image_data_maps_get) (void *engine, const void *image, const Eina_Rw_Slice **slices);
Eina_Bool (*image_content_region_get) (void *engine, void *image, Eina_Rectangle *content);
Eina_Bool (*image_stretch_region_get) (void *engine, void *image, uint8_t **horizontal, uint8_t **vertical);
/* new api for direct data set (not put) */
void *(*image_data_slice_add) (void *engine, void *image, const Eina_Slice *slice, Eina_Bool copy, int w, int h, int stride, Evas_Colorspace space, int plane, Eina_Bool alpha);

View File

@ -299,7 +299,6 @@ text_input_commit_string(void *data,
if (old_preedit)
{
ecore_imf_context_preedit_end_event_add(imcontext->ctx);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_PREEDIT_END,
NULL);
@ -331,7 +330,6 @@ text_input_commit_string(void *data,
if (surrounding)
free(surrounding);
ecore_imf_context_delete_surrounding_event_add(imcontext->ctx, ev.offset, ev.n_chars);
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
}
}
@ -341,7 +339,6 @@ text_input_commit_string(void *data,
imcontext->pending_commit.cursor = 0;
imcontext->pending_commit.anchor = 0;
ecore_imf_context_commit_event_add(imcontext->ctx, text);
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)text);
}
@ -354,17 +351,13 @@ commit_preedit(WaylandIMContext *imcontext)
if (!imcontext->ctx)
return;
ecore_imf_context_preedit_changed_event_add(imcontext->ctx);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
NULL);
ecore_imf_context_preedit_end_event_add(imcontext->ctx);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
ecore_imf_context_commit_event_add(imcontext->ctx,
imcontext->preedit_commit);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_COMMIT,
(void *)imcontext->preedit_commit);
@ -458,20 +451,17 @@ text_input_preedit_string(void *data,
if (!old_preedit)
{
ecore_imf_context_preedit_start_event_add(imcontext->ctx);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_PREEDIT_START,
NULL);
}
ecore_imf_context_preedit_changed_event_add(imcontext->ctx);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
NULL);
if (imcontext->preedit_text && strlen(imcontext->preedit_text) == 0)
{
ecore_imf_context_preedit_end_event_add(imcontext->ctx);
ecore_imf_context_event_callback_call(imcontext->ctx,
ECORE_IMF_CALLBACK_PREEDIT_END,
NULL);
@ -492,7 +482,6 @@ text_input_delete_surrounding_text(void *data,
imcontext->pending_commit.delete_index = ev.offset = index;
imcontext->pending_commit.delete_length = ev.n_chars = length;
ecore_imf_context_delete_surrounding_event_add(imcontext->ctx, ev.offset, ev.n_chars);
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
}

View File

@ -1050,6 +1050,48 @@ eng_image_file_colorspace_get(void *data EINA_UNUSED, void *image)
return im->cache_entry.space;
}
static Eina_Bool
eng_image_content_region_get(void *engine EINA_UNUSED, void *image, Eina_Rectangle *content)
{
RGBA_Image *im = image;
if (!im) return EINA_FALSE;
if (!im->cache_entry.need_data) return EINA_FALSE;
if (!im->image.data) evas_cache_image_load_data(&im->cache_entry);
if (!im->cache_entry.content.w ||
!im->cache_entry.content.h)
return EINA_FALSE;
if (!content) return EINA_FALSE;
memcpy(content, &im->cache_entry.content, sizeof (Eina_Rectangle));
return EINA_TRUE;
}
static Eina_Bool
eng_image_stretch_region_get(void *engine EINA_UNUSED, void *image,
uint8_t **horizontal, uint8_t **vertical)
{
RGBA_Image *im = image;
if (!im) return EINA_FALSE;
if (!im->cache_entry.need_data) return EINA_FALSE;
if (!im->image.data) evas_cache_image_load_data(&im->cache_entry);
if (!im->cache_entry.stretch.horizontal.region ||
!im->cache_entry.stretch.vertical.region)
return EINA_FALSE;
*horizontal = im->cache_entry.stretch.horizontal.region;
*vertical = im->cache_entry.stretch.vertical.region;
return EINA_TRUE;
}
static Eina_Bool
eng_image_data_direct_get(void *data EINA_UNUSED, void *image, int plane,
Eina_Slice *slice, Evas_Colorspace *cspace,
@ -4611,6 +4653,8 @@ static Evas_Func func =
eng_image_data_map,
eng_image_data_unmap,
eng_image_data_maps_get,
eng_image_content_region_get,
eng_image_stretch_region_get,
eng_image_data_slice_add,
eng_image_prepare,
eng_image_surface_noscale_new,

View File

@ -319,7 +319,7 @@ evas_image_load_file_close_bmp(void *loader_data)
static Eina_Bool
evas_image_load_file_head_bmp(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader;
@ -454,7 +454,7 @@ evas_image_load_file_head_bmp(void *loader_data,
static Eina_Bool
evas_image_load_file_data_bmp(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -1429,10 +1429,12 @@ evas_image_load_file_data_bmp(void *loader_data,
static Evas_Image_Load_Func evas_image_load_bmp_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_bmp,
evas_image_load_file_close_bmp,
evas_image_load_file_head_bmp,
evas_image_load_file_data_bmp,
(void*) evas_image_load_file_head_bmp,
NULL,
(void*) evas_image_load_file_data_bmp,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -161,7 +161,7 @@ _dword_read(const char **m)
static Eina_Bool
evas_image_load_file_head_dds(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
static const unsigned int base_flags = /* 0x1007 */
@ -313,7 +313,7 @@ on_error:
}
static Eina_Bool
_dds_data_load(Evas_Loader_Internal *loader, Evas_Image_Property *prop,
_dds_data_load(Evas_Loader_Internal *loader, Emile_Image_Property *prop,
unsigned char *map, void *pixels, int *error)
{
const unsigned char *src;
@ -442,7 +442,7 @@ on_error:
Eina_Bool
evas_image_load_file_data_dds(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -529,10 +529,12 @@ on_error:
Evas_Image_Load_Func evas_image_load_dds_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_dds,
evas_image_load_file_close_dds,
evas_image_load_file_head_dds,
evas_image_load_file_data_dds,
(void*) evas_image_load_file_head_dds,
NULL,
(void*) evas_image_load_file_data_dds,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -95,7 +95,7 @@ static const Evas_Colorspace cspaces_etc2_rgba[] = {
static Eina_Bool
evas_image_load_file_head_eet(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
@ -163,7 +163,7 @@ evas_image_load_file_head_eet(void *loader_data,
Eina_Bool
evas_image_load_file_data_eet(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -224,10 +224,12 @@ evas_image_load_file_data_eet(void *loader_data,
Evas_Image_Load_Func evas_image_load_eet_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_eet,
evas_image_load_file_close_eet,
evas_image_load_file_head_eet,
evas_image_load_file_data_eet,
(void*) evas_image_load_file_head_eet,
NULL,
(void*) evas_image_load_file_data_eet,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -101,7 +101,7 @@ dotcat(char *dest, const char *src)
static Eina_Bool
_load(Eina_File *ef, const char *key,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
Evas_Image_Load_Opts *opts,
void *pixels,
int *error, Eina_Bool get_data)
@ -422,7 +422,7 @@ evas_image_load_file_close_generic(void *loader_data)
static Eina_Bool
evas_image_load_file_head_generic(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
@ -432,7 +432,7 @@ evas_image_load_file_head_generic(void *loader_data,
static Eina_Bool
evas_image_load_file_data_generic(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -443,10 +443,12 @@ evas_image_load_file_data_generic(void *loader_data,
Evas_Image_Load_Func evas_image_load_generic_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_generic,
evas_image_load_file_close_generic,
evas_image_load_file_head_generic,
evas_image_load_file_data_generic,
(void*) evas_image_load_file_head_generic,
NULL,
(void*) evas_image_load_file_data_generic,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -399,7 +399,7 @@ _file_read(GifFileType *gft, GifByteType *buf, int len)
static Eina_Bool
evas_image_load_file_head_gif2(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Loader_Info *loader = loader_data;
@ -569,7 +569,7 @@ on_error: // jump here on any errors to clean up
static Eina_Bool
evas_image_load_file_data_gif2(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -905,10 +905,12 @@ evas_image_load_file_close_gif2(void *loader_data)
// general module delcaration stuff
static Evas_Image_Load_Func evas_image_load_gif_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_gif2,
evas_image_load_file_close_gif2,
evas_image_load_file_head_gif2,
evas_image_load_file_data_gif2,
(void*) evas_image_load_file_head_gif2,
NULL,
(void*) evas_image_load_file_data_gif2,
evas_image_load_frame_duration_gif2,
EINA_TRUE,
EINA_FALSE

View File

@ -111,7 +111,7 @@ evas_image_load_file_close_ico(void *loader_data)
static Eina_Bool
evas_image_load_file_head_ico(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
@ -340,7 +340,7 @@ evas_image_load_file_head_ico(void *loader_data,
static Eina_Bool
evas_image_load_file_data_ico(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -792,10 +792,12 @@ evas_image_load_file_data_ico(void *loader_data,
static Evas_Image_Load_Func evas_image_load_ico_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_ico,
evas_image_load_file_close_ico,
evas_image_load_file_head_ico,
evas_image_load_file_data_ico,
(void*) evas_image_load_file_head_ico,
NULL,
(void*) evas_image_load_file_data_ico,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -403,7 +403,7 @@ evas_image_load_file_close_jp2k(void *loader_data)
static Eina_Bool
evas_image_load_file_head_jp2k(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
@ -432,7 +432,7 @@ evas_image_load_file_head_jp2k(void *loader_data,
static Eina_Bool
evas_image_load_file_data_jp2k(void *loader_data,
Evas_Image_Property *prop EINA_UNUSED,
Emile_Image_Property *prop EINA_UNUSED,
void *pixels,
int *error)
{
@ -462,10 +462,12 @@ evas_image_load_file_data_jp2k(void *loader_data,
static Evas_Image_Load_Func evas_image_load_jp2k_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_jp2k,
evas_image_load_file_close_jp2k,
evas_image_load_file_head_jp2k,
evas_image_load_file_data_jp2k,
(void*) evas_image_load_file_head_jp2k,
NULL,
(void*) evas_image_load_file_data_jp2k,
NULL,
EINA_TRUE,
EINA_TRUE

View File

@ -70,7 +70,7 @@ evas_image_load_file_close_jpeg(void *loader_data)
static Eina_Bool
evas_image_load_file_head_jpeg(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
@ -95,7 +95,7 @@ _evas_image_load_jpeg_cancelled(void *data EINA_UNUSED,
Eina_Bool
evas_image_load_file_data_jpeg(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -116,10 +116,12 @@ evas_image_load_file_data_jpeg(void *loader_data,
Evas_Image_Load_Func evas_image_load_jpeg_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_jpeg,
evas_image_load_file_close_jpeg,
evas_image_load_file_head_jpeg,
evas_image_load_file_data_jpeg,
(void*) evas_image_load_file_head_jpeg,
NULL,
(void*) evas_image_load_file_data_jpeg,
NULL,
EINA_TRUE,
EINA_TRUE

View File

@ -67,7 +67,7 @@ evas_image_load_file_close_pmaps(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_pmaps(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -95,7 +95,7 @@ evas_image_load_file_head_pmaps(void *loader_data,
static Eina_Bool
evas_image_load_file_data_pmaps(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -551,10 +551,12 @@ pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *val)
/* external functions */
Evas_Image_Load_Func evas_image_load_pmaps_func = {
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_pmaps,
evas_image_load_file_close_pmaps,
evas_image_load_file_head_pmaps,
evas_image_load_file_data_pmaps,
(void*) evas_image_load_file_head_pmaps,
NULL,
(void*) evas_image_load_file_data_pmaps,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -10,6 +10,8 @@
#include "evas_private.h"
#define PNG_BYTES_TO_CHECK 4
#define WHITE 0xFFFFFFFF
#define BLACK 0xFF000000
typedef struct _Evas_PNG_Info Evas_PNG_Info;
struct _Evas_PNG_Info
@ -17,6 +19,13 @@ struct _Evas_PNG_Info
unsigned char *map;
size_t length;
size_t position;
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 w32, h32;
int bit_depth, color_type, interlace_type;
volatile Eina_Bool hasa;
};
typedef struct _Evas_Loader_Internal Evas_Loader_Internal;
@ -36,6 +45,34 @@ static const Evas_Colorspace cspace_grey_alpha[2] = {
EVAS_COLORSPACE_ARGB8888
};
static void
_evas_image_png_update_x_content(Eina_Rectangle *r, int index)
{
if (r->x == 0)
{
r->x = index;
r->w = 1;
}
else
{
r->w = index - r->x;
}
}
static void
_evas_image_png_update_y_content(Eina_Rectangle *r, int index)
{
if (r->y == 0)
{
r->y = index;
r->h = 1;
}
else
{
r->h = index - r->y;
}
}
static void
_evas_image_png_read(png_structp png_ptr, png_bytep out, png_size_t count)
{
@ -76,77 +113,65 @@ evas_image_load_file_close_png(void *loader_data)
}
static Eina_Bool
evas_image_load_file_head_png(void *loader_data,
Evas_Image_Property *prop,
int *error)
_evas_image_load_file_internal_head_png(Evas_Loader_Internal *loader,
Evas_Image_Property *prop,
Evas_PNG_Info *epi,
int *error, Eina_Bool close_file)
{
Evas_Loader_Internal *loader = loader_data;
Evas_Image_Load_Opts *opts;
Eina_File *f;
Evas_PNG_Info epi;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_uint_32 w32, h32;
int bit_depth, color_type, interlace_type;
volatile char hasa;
Evas_Image_Load_Opts *opts = loader->opts;
Eina_File *f = loader->f;
volatile Eina_Bool r = EINA_FALSE;
opts = loader->opts;
f = loader->f;
*error = EVAS_LOAD_ERROR_NONE;
hasa = 0;
epi.map = eina_file_map_all(f, EINA_FILE_RANDOM);
if (!epi.map)
epi->hasa = 0;
epi->map = eina_file_map_all(f, EINA_FILE_RANDOM);
if (!epi->map)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
epi.length = eina_file_size_get(f);
epi.position = 0;
epi->length = eina_file_size_get(f);
epi->position = 0;
if (epi.length < PNG_BYTES_TO_CHECK)
if (epi->length < PNG_BYTES_TO_CHECK)
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
if (png_sig_cmp(epi->map, 0, PNG_BYTES_TO_CHECK))
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
epi->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!epi->png_ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
epi->info_ptr = png_create_info_struct(epi->png_ptr);
if (!epi->info_ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
png_set_read_fn(epi->png_ptr, epi, _evas_image_png_read);
if (setjmp(png_jmpbuf(epi->png_ptr)))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
if (png_sig_cmp(epi.map, 0, PNG_BYTES_TO_CHECK))
png_read_info(epi->png_ptr, epi->info_ptr);
png_get_IHDR(epi->png_ptr, epi->info_ptr, (png_uint_32 *) (&epi->w32),
(png_uint_32 *) (&epi->h32), &epi->bit_depth, &epi->color_type,
&epi->interlace_type, NULL, NULL);
if ((epi->w32 < 1) || (epi->h32 < 1) ||
(epi->w32 > IMG_MAX_SIZE) || (epi->h32 > IMG_MAX_SIZE) ||
IMG_TOO_BIG(epi->w32, epi->h32))
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
png_set_read_fn(png_ptr, &epi, _evas_image_png_read);
if (setjmp(png_jmpbuf(png_ptr)))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
(png_uint_32 *) (&h32), &bit_depth, &color_type,
&interlace_type, NULL, NULL);
if ((w32 < 1) || (h32 < 1) || (w32 > IMG_MAX_SIZE) || (h32 > IMG_MAX_SIZE) ||
IMG_TOO_BIG(w32, h32))
{
if (IMG_TOO_BIG(w32, h32))
if (IMG_TOO_BIG(epi->w32, epi->h32))
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
else
*error = EVAS_LOAD_ERROR_GENERIC;
@ -155,28 +180,28 @@ evas_image_load_file_head_png(void *loader_data,
if (opts->emile.region.w > 0 && opts->emile.region.h > 0)
{
if (((int) w32 < opts->emile.region.x + opts->emile.region.w) ||
((int) h32 < opts->emile.region.y + opts->emile.region.h))
if (((int) epi->w32 < opts->emile.region.x + opts->emile.region.w) ||
((int) epi->h32 < opts->emile.region.y + opts->emile.region.h))
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
if(opts->emile.scale_down_by > 1)
{
prop->w = opts->emile.region.w / opts->emile.scale_down_by;
prop->h = opts->emile.region.h / opts->emile.scale_down_by;
prop->info.w = opts->emile.region.w / opts->emile.scale_down_by;
prop->info.h = opts->emile.region.h / opts->emile.scale_down_by;
}
else
{
prop->w = opts->emile.region.w;
prop->h = opts->emile.region.h;
prop->info.w = opts->emile.region.w;
prop->info.h = opts->emile.region.h;
}
}
else if (opts->emile.scale_down_by > 1)
{
prop->w = (int) w32 / opts->emile.scale_down_by;
prop->h = (int) h32 / opts->emile.scale_down_by;
if ((prop->w < 1) || (prop->h < 1))
prop->info.w = (int) epi->w32 / opts->emile.scale_down_by;
prop->info.h = (int) epi->h32 / opts->emile.scale_down_by;
if ((prop->info.w < 1) || (prop->info.h < 1))
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
@ -184,34 +209,365 @@ evas_image_load_file_head_png(void *loader_data,
}
else
{
prop->w = (int) w32;
prop->h = (int) h32;
prop->info.w = (int) epi->w32;
prop->info.h = (int) epi->h32;
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
switch (color_type)
if (png_get_valid(epi->png_ptr, epi->info_ptr, PNG_INFO_tRNS)) epi->hasa = 1;
switch (epi->color_type)
{
case PNG_COLOR_TYPE_RGB_ALPHA:
hasa = 1;
epi->hasa = 1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
hasa = 1;
prop->cspaces = cspace_grey_alpha;
epi->hasa = 1;
prop->info.cspaces = cspace_grey_alpha;
break;
case PNG_COLOR_TYPE_GRAY:
if (!hasa) prop->cspaces = cspace_grey;
if (!epi->hasa) prop->info.cspaces = cspace_grey;
break;
}
if (hasa) prop->alpha = 1;
if (epi->hasa) prop->info.alpha = 1;
prop->need_data = eina_str_has_extension(eina_file_filename_get(f), ".9.png");
if (prop->need_data)
{
// Adjust size to take into account the 9 patch pixels information
prop->info.w -= 2;
prop->info.h -= 2;
}
r = EINA_TRUE;
if (!close_file) return r;
close_file:
if (epi->png_ptr) png_destroy_read_struct(&epi->png_ptr,
epi->info_ptr ? &epi->info_ptr : NULL,
NULL);
if (epi->map) eina_file_map_free(f, epi->map);
memset(epi, 0, sizeof (Evas_PNG_Info));
return r;
}
static Eina_Bool
evas_image_load_file_head_png(void *loader_data,
Evas_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
Evas_PNG_Info epi;
memset(&epi, 0, sizeof (Evas_PNG_Info));
if (!_evas_image_load_file_internal_head_png(loader, prop, &epi, error, EINA_TRUE))
return EINA_FALSE;
return EINA_TRUE;
}
static inline Eina_Bool
_is_black(DATA32 *ptr)
{
if (*ptr == BLACK) return EINA_TRUE;
return EINA_FALSE;
}
static Eina_Bool
evas_image_load_file_head_with_data_png(void *loader_data,
Evas_Image_Property *prop,
void *pixels,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
Evas_Image_Load_Opts *opts;
Eina_File *f;
unsigned char *src_ptr;
unsigned char *pixels2;
unsigned char *surface;
Evas_PNG_Info epi;
Eina_Rectangle region;
unsigned int pack_offset;
int w, h;
char passes;
int i, j, p, k;
volatile int scale_ratio = 1;
int image_w = 0, image_h = 0;
volatile Eina_Bool r = EINA_FALSE;
Eina_Bool nine_patch = EINA_FALSE;
opts = loader->opts;
f = loader->f;
memset(&epi, 0, sizeof (Evas_PNG_Info));
region = opts->emile.region;
if (!_evas_image_load_file_internal_head_png(loader, prop, &epi, error, EINA_FALSE))
return EINA_FALSE;
image_w = epi.w32;
image_h = epi.h32;
// We are leveragging region code to not load the border information pixels
// from 9patch files into the surface used by Evas
if (prop->need_data)
{
nine_patch = EINA_TRUE;
region.x += 1;
region.y += 1;
if (region.w > 0 && region.h > 0)
{
if (region.x + region.w + 1 < image_w) region.w += 1;
else region.w = image_w - region.x - 1;
if (region.y + region.h + 1 < image_h) region.h += 1;
else region.h = image_h - region.y - 1;
}
else
{
region.w = image_w - region.x - 1;
region.h = image_h - region.y - 1;
}
}
surface = pixels;
/* Prep for transformations... ultimately we want ARGB */
/* expand palette -> RGB if necessary */
if (epi.color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(epi.png_ptr);
/* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
if ((epi.color_type == PNG_COLOR_TYPE_GRAY) ||
(epi.color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
{
if (prop->info.cspace == EVAS_COLORSPACE_ARGB8888)
png_set_gray_to_rgb(epi.png_ptr);
if (epi.bit_depth < 8) png_set_expand_gray_1_2_4_to_8(epi.png_ptr);
}
/* reduce 16bit color -> 8bit color if necessary */
if (epi.bit_depth > 8) png_set_strip_16(epi.png_ptr);
/* pack all pixels to byte boundaries */
png_set_packing(epi.png_ptr);
w = prop->info.w;
h = prop->info.h;
switch (prop->info.cspace)
{
case EVAS_COLORSPACE_ARGB8888:
/* we want ARGB */
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha(epi.png_ptr);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
png_set_bgr(epi.png_ptr);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_AFTER);
#endif
pack_offset = sizeof(DATA32);
break;
case EVAS_COLORSPACE_AGRY88:
/* we want AGRY */
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha(epi.png_ptr);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_AFTER);
#endif
pack_offset = sizeof(DATA16);
break;
case EVAS_COLORSPACE_GRY8: pack_offset = sizeof(DATA8); break;
default: abort();
}
passes = png_set_interlace_handling(epi.png_ptr);
/* we read image line by line in all case because of .9.png */
pixels2 = malloc(image_w * image_h * pack_offset);
if (!pixels2)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
for (p = 0; p < passes; p++)
{
for (i = 0; i < image_h; i++)
png_read_row(epi.png_ptr, pixels2 + (i * image_w * pack_offset), NULL);
}
png_read_end(epi.png_ptr, epi.info_ptr);
if (nine_patch && pack_offset != sizeof (DATA32))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
if (nine_patch)
{
DATA32 *src_ptr1;
DATA32 *src_ptr2;
Eina_Bool stretchable = EINA_FALSE;
Eina_Rectangle optional_content = { 0 };
uint8_t current = 0;
memset(&prop->content, 0, sizeof (Eina_Rectangle));
// Top line of the image
src_ptr1 = (DATA32*) pixels2 + 1;
// Bottom line of the image
src_ptr2 = src_ptr1 + (image_h - 1) * image_w;
// Extract top stretch zone and horizontal content area
for (i = 1; i < image_w - 1;
i++, src_ptr1++, src_ptr2++)
{
Eina_Bool bp1 = _is_black(src_ptr1);
Eina_Bool bp2 = _is_black(src_ptr2);
// Updating horizontal area where content can be located
if (bp2)
_evas_image_png_update_x_content(&prop->content, i);
// In case no content area is provided, let's make it up
if (bp1)
_evas_image_png_update_x_content(&optional_content, i);
// Switching from a non stretchable to a stretchable zone or the opposite
if (!((stretchable && (bp1)) ||
(!stretchable && (!bp1))))
{
evas_loader_helper_stretch_region_push(&prop->stretch.horizontal.region,
&current, stretchable);
stretchable = !stretchable;
}
// Keep counting in the area we are in
current++;
if (current != 0x7F) continue;
// The bucket is full
evas_loader_helper_stretch_region_push(&prop->stretch.horizontal.region,
&current, stretchable);
}
current = 0;
// Left border of the image
src_ptr1 = (DATA32*) pixels2 + image_w;
// Right border of the image
src_ptr2 = src_ptr1 + (image_w - 1);
for (i = 1; i < image_h - 1;
i++, src_ptr1 += image_w, src_ptr2 += image_w)
{
Eina_Bool bp1 = _is_black(src_ptr1);
Eina_Bool bp2 = _is_black(src_ptr2);
// Updating vertical area where content can be located
if (bp2)
_evas_image_png_update_y_content(&prop->content, i);
// In case no content area is provided, let's make it up
if (bp1)
_evas_image_png_update_y_content(&optional_content, i);
// Switching from a non stretchable to a stretchable zone or the opposite
if (!((stretchable && (bp1)) ||
(!stretchable && (!bp1))))
{
evas_loader_helper_stretch_region_push(&prop->stretch.vertical.region,
&current, stretchable);
stretchable = !stretchable;
}
// Keep counting in the area we are in
current++;
if (current != 0x7F) continue;
// The bucket is full
evas_loader_helper_stretch_region_push(&prop->stretch.vertical.region,
&current, stretchable);
}
// Content zone is optional, if not provided, we should use the one we guessed
if (prop->content.x == 0 || prop->content.y == 0)
memcpy(&prop->content, &optional_content, sizeof (Eina_Rectangle));
// Check that the limit of our content zone are correct
// This could be handled as an incorrect file completly,
// but let's try to recover
if (prop->content.x == 0 || prop->content.y == 0)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
if ((prop->content.x + prop->content.w >= image_w - 1) &&
(prop->content.y + prop->content.h >= image_h - 1))
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
// Correct the work space to be the same as the image one for intersection
// with region and correct back afterward.
prop->content.x++;
prop->content.y++;
if (eina_rectangle_intersection(&prop->content, &region))
{
prop->content.x--;
prop->content.y--;
}
}
src_ptr = pixels2 + (region.y * image_w * pack_offset) + region.x * pack_offset;
//general case: 4 bytes pixel.
if (pack_offset == sizeof(DATA32))
{
DATA32 *dst_ptr = (DATA32 *) surface;
DATA32 *src_ptr2 = (DATA32 *) src_ptr;
for (i = 0; i < h; i++)
{
for (j = 0; j < w; j++)
{
*dst_ptr = *src_ptr2;
++dst_ptr;
src_ptr2 += scale_ratio;
}
src_ptr2 += scale_ratio * (image_w - w);
}
}
else
{
unsigned char *dst_ptr = surface;
for (i = 0; i < h; i++)
{
for (j = 0; j < w; j++)
{
for (k = 0; k < (int)pack_offset; k++)
dst_ptr[k] = src_ptr[k + scale_ratio * j * pack_offset];
dst_ptr += pack_offset;
}
src_ptr += scale_ratio * (image_w - w) * pack_offset;
}
}
free(pixels2);
prop->info.premul = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE;
close_file:
if (png_ptr) png_destroy_read_struct(&png_ptr,
info_ptr ? &info_ptr : NULL,
NULL);
if (epi.map) eina_file_map_free(f, epi. map);
if (epi.png_ptr) png_destroy_read_struct(&epi.png_ptr,
epi.info_ptr ? &epi.info_ptr : NULL,
NULL);
if (epi.map) eina_file_map_free(f, epi.map);
return r;
}
@ -226,14 +582,9 @@ evas_image_load_file_data_png(void *loader_data,
Eina_File *f;
unsigned char *surface;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
Evas_PNG_Info epi;
png_uint_32 w32, h32;
unsigned int pack_offset;
int w, h;
int bit_depth, color_type, interlace_type;
volatile char hasa;
char passes;
int i, j, p, k;
volatile int scale_ratio = 1;
@ -244,131 +595,76 @@ evas_image_load_file_data_png(void *loader_data,
opts = loader->opts;
f = loader->f;
hasa = 0;
memset(&epi, 0, sizeof (Evas_PNG_Info));
epi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
if (!epi.map)
{
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
epi.length = eina_file_size_get(f);
epi.position = 0;
if (!_evas_image_load_file_internal_head_png(loader, prop, &epi, error, EINA_FALSE))
return EINA_FALSE;
if (epi.length < PNG_BYTES_TO_CHECK)
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
/* if we havent read the header before, set the header data */
if (png_sig_cmp(epi.map, 0, PNG_BYTES_TO_CHECK))
{
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
goto close_file;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
png_set_read_fn(png_ptr, &epi, _evas_image_png_read);
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
goto close_file;
}
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
(png_uint_32 *) (&h32), &bit_depth, &color_type,
&interlace_type, NULL, NULL);
image_w = w32;
image_h = h32;
image_w = epi.w32;
image_h = epi.h32;
if (opts->emile.scale_down_by > 1)
{
scale_ratio = opts->emile.scale_down_by;
w32 /= scale_ratio;
h32 /= scale_ratio;
epi.w32 /= scale_ratio;
epi.h32 /= scale_ratio;
}
if ((opts->emile.region.w > 0 && opts->emile.region.h > 0) &&
(opts->emile.region.w != image_w || opts->emile.region.h != image_h))
{
w32 = opts->emile.region.w / scale_ratio;
h32 = opts->emile.region.h / scale_ratio;
epi.w32 = opts->emile.region.w / scale_ratio;
epi.h32 = opts->emile.region.h / scale_ratio;
region_set = 1;
}
if (prop->w != w32 ||
prop->h != h32)
if (prop->info.w != epi.w32 ||
prop->info.h != epi.h32)
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
surface = pixels;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
{
/* expand transparency entry -> alpha channel if present */
png_set_tRNS_to_alpha(png_ptr);
hasa = 1;
}
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
if (hasa) prop->alpha = 1;
/* Prep for transformations... ultimately we want ARGB */
/* expand palette -> RGB if necessary */
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
if (epi.color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(epi.png_ptr);
/* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
if ((color_type == PNG_COLOR_TYPE_GRAY) ||
(color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
if ((epi.color_type == PNG_COLOR_TYPE_GRAY) ||
(epi.color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
{
if (prop->cspace == EVAS_COLORSPACE_ARGB8888)
png_set_gray_to_rgb(png_ptr);
if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
if (prop->info.cspace == EVAS_COLORSPACE_ARGB8888)
png_set_gray_to_rgb(epi.png_ptr);
if (epi.bit_depth < 8) png_set_expand_gray_1_2_4_to_8(epi.png_ptr);
}
/* reduce 16bit color -> 8bit color if necessary */
if (bit_depth > 8) png_set_strip_16(png_ptr);
if (epi.bit_depth > 8) png_set_strip_16(epi.png_ptr);
/* pack all pixels to byte boundaries */
png_set_packing(png_ptr);
png_set_packing(epi.png_ptr);
w = w32;
h = h32;
w = epi.w32;
h = epi.h32;
switch (prop->cspace)
switch (prop->info.cspace)
{
case EVAS_COLORSPACE_ARGB8888:
/* we want ARGB */
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha(png_ptr);
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
png_set_swap_alpha(epi.png_ptr);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
png_set_bgr(png_ptr);
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
png_set_bgr(epi.png_ptr);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_AFTER);
#endif
pack_offset = sizeof(DATA32);
break;
case EVAS_COLORSPACE_AGRY88:
/* we want AGRY */
#ifdef WORDS_BIGENDIAN
png_set_swap_alpha(png_ptr);
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
png_set_swap_alpha(epi.png_ptr);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
if (!epi.hasa) png_set_filler(epi.png_ptr, 0xff, PNG_FILLER_AFTER);
#endif
pack_offset = sizeof(DATA16);
break;
@ -376,7 +672,7 @@ evas_image_load_file_data_png(void *loader_data,
default: abort();
}
passes = png_set_interlace_handling(png_ptr);
passes = png_set_interlace_handling(epi.png_ptr);
/* we read image line by line if scale down was set */
if (scale_ratio == 1 && region_set == 0)
@ -384,9 +680,9 @@ evas_image_load_file_data_png(void *loader_data,
for (p = 0; p < passes; p++)
{
for (i = 0; i < h; i++)
png_read_row(png_ptr, surface + (i * w * pack_offset), NULL);
png_read_row(epi.png_ptr, surface + (i * w * pack_offset), NULL);
}
png_read_end(png_ptr, info_ptr);
png_read_end(epi.png_ptr, epi.info_ptr);
}
else
{
@ -409,9 +705,9 @@ evas_image_load_file_data_png(void *loader_data,
unsigned short *pbuf;
for (skip_row = 0; skip_row < region_y; skip_row++)
png_read_row(png_ptr, tmp_line, NULL);
png_read_row(epi.png_ptr, tmp_line, NULL);
png_read_row(png_ptr, tmp_line, NULL);
png_read_row(epi.png_ptr, tmp_line, NULL);
src_ptr = tmp_line + (region_x * pack_offset);
//The first pixel, of the first line
@ -450,7 +746,7 @@ evas_image_load_file_data_png(void *loader_data,
//vertical interpolation.
for (j = 0; j < scale_ratio; j++)
{
png_read_row(png_ptr, tmp_line, NULL);
png_read_row(epi.png_ptr, tmp_line, NULL);
src_ptr = tmp_line + (region_x * pack_offset);
for (p = 0; p < line_size; ++p)
@ -486,7 +782,7 @@ evas_image_load_file_data_png(void *loader_data,
}
for (skip_row = region_y + h * scale_ratio; skip_row < image_h; skip_row++)
png_read_row(png_ptr, tmp_line, NULL);
png_read_row(epi.png_ptr, tmp_line, NULL);
}
else
{
@ -499,8 +795,9 @@ evas_image_load_file_data_png(void *loader_data,
for (p = 0; p < passes; p++)
{
for (i = 0; i < image_h; i++)
png_read_row(png_ptr, pixels2 + (i * image_w * pack_offset), NULL);
png_read_row(epi.png_ptr, pixels2 + (i * image_w * pack_offset), NULL);
}
png_read_end(epi.png_ptr, epi.info_ptr);
src_ptr = pixels2 + (region_y * image_w * pack_offset) + region_x * pack_offset;
@ -541,24 +838,26 @@ evas_image_load_file_data_png(void *loader_data,
}
}
prop->premul = EINA_TRUE;
prop->info.premul = EINA_TRUE;
*error = EVAS_LOAD_ERROR_NONE;
r = EINA_TRUE;
close_file:
if (png_ptr) png_destroy_read_struct(&png_ptr,
info_ptr ? &info_ptr : NULL,
NULL);
if (epi.png_ptr) png_destroy_read_struct(&epi.png_ptr,
epi.info_ptr ? &epi.info_ptr : NULL,
NULL);
if (epi.map) eina_file_map_free(f, epi.map);
return r;
}
static Evas_Image_Load_Func evas_image_load_png_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_png,
evas_image_load_file_close_png,
evas_image_load_file_head_png,
evas_image_load_file_head_with_data_png,
evas_image_load_file_data_png,
NULL,
EINA_TRUE,

View File

@ -147,7 +147,7 @@ evas_image_load_file_close_psd(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_psd(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -691,7 +691,7 @@ read_psd_rgb(void *pixels, PSD_Header *head, const unsigned char *map, size_t le
}
Eina_Bool
read_psd_cmyk(Evas_Image_Property *prop, void *pixels, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
read_psd_cmyk(Emile_Image_Property *prop, void *pixels, PSD_Header *head, const unsigned char *map, size_t length, size_t *position, int *error)
{
unsigned int color_mode, resource_size, misc_info, size, j, data_size;
unsigned short compressed;
@ -797,7 +797,7 @@ read_psd_cmyk(Evas_Image_Property *prop, void *pixels, PSD_Header *head, const u
static Eina_Bool
evas_image_load_file_data_psd(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -882,10 +882,12 @@ get_compressed_channels_length(PSD_Header *head,
}
static const Evas_Image_Load_Func evas_image_load_psd_func = {
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_psd,
evas_image_load_file_close_psd,
evas_image_load_file_head_psd,
evas_image_load_file_data_psd,
(void*) evas_image_load_file_head_psd,
NULL,
(void*) evas_image_load_file_data_psd,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -68,7 +68,7 @@ evas_image_load_file_close_tga(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_tga(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -164,7 +164,7 @@ close_file:
static Eina_Bool
evas_image_load_file_data_tga(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -563,10 +563,12 @@ evas_image_load_file_data_tga(void *loader_data,
static Evas_Image_Load_Func evas_image_load_tga_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_tga,
evas_image_load_file_close_tga,
evas_image_load_file_head_tga,
evas_image_load_file_data_tga,
(void*) evas_image_load_file_head_tga,
NULL,
(void*) evas_image_load_file_data_tga,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -70,7 +70,7 @@ evas_image_load_file_close_tgv(void *loader_data)
static Eina_Bool
evas_image_load_file_head_tgv(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Evas_Loader_Internal *loader = loader_data;
@ -87,7 +87,7 @@ evas_image_load_file_head_tgv(void *loader_data,
Eina_Bool
evas_image_load_file_data_tgv(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -105,10 +105,12 @@ evas_image_load_file_data_tgv(void *loader_data,
Evas_Image_Load_Func evas_image_load_tgv_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_tgv,
evas_image_load_file_close_tgv,
evas_image_load_file_head_tgv,
evas_image_load_file_data_tgv,
(void*) evas_image_load_file_head_tgv,
NULL,
(void*) evas_image_load_file_data_tgv,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -103,7 +103,7 @@ evas_image_load_file_close_tiff(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_tiff(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -186,7 +186,7 @@ evas_image_load_file_head_tiff(void *loader_data,
static Eina_Bool
evas_image_load_file_data_tiff(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -332,10 +332,12 @@ evas_image_load_file_data_tiff(void *loader_data,
static Evas_Image_Load_Func evas_image_load_tiff_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_tiff,
evas_image_load_file_close_tiff,
evas_image_load_file_head_tiff,
evas_image_load_file_data_tiff,
(void*) evas_image_load_file_head_tiff,
NULL,
(void*) evas_image_load_file_data_tiff,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -41,7 +41,7 @@ evas_image_load_file_close_wbmp(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_wbmp(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -98,7 +98,7 @@ evas_image_load_file_head_wbmp(void *loader_data,
static Eina_Bool
evas_image_load_file_data_wbmp(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -181,10 +181,12 @@ evas_image_load_file_data_wbmp(void *loader_data,
static Evas_Image_Load_Func evas_image_load_wbmp_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_wbmp,
evas_image_load_file_close_wbmp,
evas_image_load_file_head_wbmp,
evas_image_load_file_data_wbmp,
(void*) evas_image_load_file_head_wbmp,
NULL,
(void*) evas_image_load_file_data_wbmp,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -52,7 +52,7 @@ evas_image_load_file_close_webp(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_webp(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -73,7 +73,7 @@ evas_image_load_file_head_webp(void *loader_data,
static Eina_Bool
evas_image_load_file_data_webp(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -112,10 +112,12 @@ evas_image_load_file_data_webp(void *loader_data,
static Evas_Image_Load_Func evas_image_load_webp_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_webp,
evas_image_load_file_close_webp,
evas_image_load_file_head_webp,
evas_image_load_file_data_webp,
(void*) evas_image_load_file_head_webp,
NULL,
(void*) evas_image_load_file_data_webp,
NULL,
EINA_TRUE,
EINA_FALSE

View File

@ -1688,7 +1688,7 @@ _cmap_cmp_key_cb(const Eina_Rbtree *node, const void *key, int length EINA_UNUSE
/** FIXME: clean this up and make more efficient **/
static Eina_Bool
evas_image_load_file_xpm(Eina_File *f, Evas_Image_Property *prop, void *pixels, int load_data, int *error)
evas_image_load_file_xpm(Eina_File *f, Emile_Image_Property *prop, void *pixels, int load_data, int *error)
{
DATA32 *ptr, *end, *head = NULL;
const char *map = NULL;
@ -2193,7 +2193,7 @@ evas_image_load_file_close_xpm(void *loader_data EINA_UNUSED)
static Eina_Bool
evas_image_load_file_head_xpm(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
int *error)
{
Eina_File *f = loader_data;
@ -2203,7 +2203,7 @@ evas_image_load_file_head_xpm(void *loader_data,
static Eina_Bool
evas_image_load_file_data_xpm(void *loader_data,
Evas_Image_Property *prop,
Emile_Image_Property *prop,
void *pixels,
int *error)
{
@ -2214,10 +2214,12 @@ evas_image_load_file_data_xpm(void *loader_data,
static Evas_Image_Load_Func evas_image_load_xpm_func =
{
EVAS_IMAGE_LOAD_VERSION,
evas_image_load_file_open_xpm,
evas_image_load_file_close_xpm,
evas_image_load_file_head_xpm,
evas_image_load_file_data_xpm,
(void*) evas_image_load_file_head_xpm,
NULL,
(void*) evas_image_load_file_data_xpm,
NULL,
EINA_FALSE,
EINA_FALSE

View File

@ -9,7 +9,7 @@ draw_src = [
draw_opt_lib = [ ]
if cpu_sse3 == true and sys_windows == false
if cpu_sse3 == true
draw_opt = static_library('draw_opt',
sources: [ 'draw_main_sse2.c' ],
include_directories: config_dir + [include_directories(join_paths('..', '..', 'lib'))],

View File

@ -14,7 +14,7 @@ void call_async(efl::eina::mutex& mutex, efl::eina::condition_variable& cond, in
{
efl::ecore::main_loop_thread_safe_call_async
(
[&mutex,&cond,&done]
[&mutex,&done]
{
std::cout << "yeah" << std::endl;
efl::eina::unique_lock<efl::eina::mutex> l(mutex);

View File

@ -120,7 +120,7 @@ class TestEoInherit
public static void inherited_collected()
{
var wref = CreateCollectableInherited();
Test.CollectAndIterate();
Test.CollectAndIterate(300, 10);
Test.AssertNull(wref.Target);
}

View File

@ -171,9 +171,7 @@ class TestFunctionPointers
// Should release the handle to the wrapper allocated when calling set_callback from C.
obj.SetCallback(twice);
GC.Collect();
GC.WaitForPendingFinalizers();
Efl.App.AppMain.Iterate();
Test.CollectAndIterate(300, 10);
Test.Assert(obj.set_called, "set_callback override must have been called");
Test.Assert(!obj.invoke_called, "invoke_callback must not have been called");

View File

@ -200,14 +200,17 @@ public static class Test
/// <summary>Runs a number of garbage collections and iterate the main loop.
/// The iteration is needed to make sure objects collected in the GC thread
/// are efl_unref'd in the main thread.</summary>
public static void CollectAndIterate(int iterations=1000)
public static void CollectAndIterate(int iterations=1000, int global_iterations=1)
{
for (int i = 0; i < iterations; i++)
for (int g = 0; g < global_iterations; ++g)
{
System.GC.Collect();
for (int i = 0; i < iterations; ++i)
{
System.GC.Collect();
}
System.GC.WaitForPendingFinalizers();
Efl.App.AppMain.Iterate();
}
System.GC.WaitForPendingFinalizers();
Efl.App.AppMain.Iterate();
}
}

Some files were not shown because too many files have changed in this diff Show More