[GX] Hook up feature variations
Shape-plan caching is not implemented.
This commit is contained in:
parent
ec87ba9ba3
commit
72ada4f0c6
|
@ -288,7 +288,9 @@ struct hb_coretext_shaper_shape_plan_data_t {};
|
|||
hb_coretext_shaper_shape_plan_data_t *
|
||||
_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
@ -1280,7 +1282,9 @@ struct hb_coretext_aat_shaper_shape_plan_data_t {};
|
|||
hb_coretext_aat_shaper_shape_plan_data_t *
|
||||
_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
|
|
@ -259,7 +259,9 @@ struct hb_directwrite_shaper_shape_plan_data_t {};
|
|||
hb_directwrite_shaper_shape_plan_data_t *
|
||||
_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,9 @@ struct hb_fallback_shaper_shape_plan_data_t {};
|
|||
hb_fallback_shaper_shape_plan_data_t *
|
||||
_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
|
|
@ -1253,7 +1253,6 @@ hb_font_destroy (hb_font_t *font)
|
|||
hb_face_destroy (font->face);
|
||||
hb_font_funcs_destroy (font->klass);
|
||||
|
||||
if (font->coords)
|
||||
free (font->coords);
|
||||
|
||||
free (font);
|
||||
|
@ -1561,7 +1560,6 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
|
|||
if (unlikely (coords_length && !copy))
|
||||
return;
|
||||
|
||||
if (font->coords)
|
||||
free (font->coords);
|
||||
|
||||
if (coords_length)
|
||||
|
|
|
@ -195,7 +195,9 @@ struct hb_graphite2_shaper_shape_plan_data_t {};
|
|||
hb_graphite2_shaper_shape_plan_data_t *
|
||||
_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
|
|
@ -176,7 +176,9 @@ struct hb_ot_map_builder_t
|
|||
inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
|
||||
{ add_pause (1, pause_func); }
|
||||
|
||||
HB_INTERNAL void compile (hb_ot_map_t &m);
|
||||
HB_INTERNAL void compile (hb_ot_map_t &m,
|
||||
const int *coords,
|
||||
unsigned int num_coords);
|
||||
|
||||
inline void finish (void) {
|
||||
feature_infos.finish ();
|
||||
|
@ -192,6 +194,7 @@ struct hb_ot_map_builder_t
|
|||
hb_face_t *face,
|
||||
unsigned int table_index,
|
||||
unsigned int feature_index,
|
||||
unsigned int variations_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwj);
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
|
|||
hb_face_t *face,
|
||||
unsigned int table_index,
|
||||
unsigned int feature_index,
|
||||
unsigned int variations_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwj)
|
||||
{
|
||||
|
@ -95,9 +96,10 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
|
|||
offset = 0;
|
||||
do {
|
||||
len = ARRAY_LENGTH (lookup_indices);
|
||||
hb_ot_layout_feature_get_lookups (face,
|
||||
hb_ot_layout_feature_with_variations_get_lookups (face,
|
||||
table_tags[table_index],
|
||||
feature_index,
|
||||
variations_index,
|
||||
offset, &len,
|
||||
lookup_indices);
|
||||
|
||||
|
@ -130,7 +132,9 @@ void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::paus
|
|||
}
|
||||
|
||||
void
|
||||
hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
||||
hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||
const int *coords,
|
||||
unsigned int num_coords)
|
||||
{
|
||||
m.global_mask = 1;
|
||||
|
||||
|
@ -264,6 +268,13 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||
{
|
||||
/* Collect lookup indices for features */
|
||||
|
||||
unsigned int variations_index;
|
||||
hb_ot_layout_table_find_feature_variations (face,
|
||||
table_tags[table_index],
|
||||
coords,
|
||||
num_coords,
|
||||
&variations_index);
|
||||
|
||||
unsigned int stage_index = 0;
|
||||
unsigned int last_num_lookups = 0;
|
||||
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
||||
|
@ -272,6 +283,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||
required_feature_stage[table_index] == stage)
|
||||
add_lookups (m, face, table_index,
|
||||
required_feature_index[table_index],
|
||||
variations_index,
|
||||
1 /* mask */,
|
||||
true /* auto_zwj */);
|
||||
|
||||
|
@ -279,6 +291,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||
if (m.features[i].stage[table_index] == stage)
|
||||
add_lookups (m, face, table_index,
|
||||
m.features[i].index[table_index],
|
||||
variations_index,
|
||||
m.features[i].mask,
|
||||
m.features[i].auto_zwj);
|
||||
|
||||
|
|
|
@ -77,11 +77,13 @@ struct hb_ot_shape_planner_t
|
|||
map (face, &props) {}
|
||||
~hb_ot_shape_planner_t (void) { map.finish (); }
|
||||
|
||||
inline void compile (hb_ot_shape_plan_t &plan)
|
||||
inline void compile (hb_ot_shape_plan_t &plan,
|
||||
const int *coords,
|
||||
unsigned int num_coords)
|
||||
{
|
||||
plan.props = props;
|
||||
plan.shaper = shaper;
|
||||
map.compile (plan.map);
|
||||
map.compile (plan.map, coords, num_coords);
|
||||
|
||||
plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
|
||||
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
|
||||
|
|
|
@ -163,7 +163,9 @@ _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
|
|||
hb_ot_shaper_shape_plan_data_t *
|
||||
_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features)
|
||||
unsigned int num_user_features,
|
||||
const int *coords,
|
||||
unsigned int num_coords)
|
||||
{
|
||||
hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
|
||||
if (unlikely (!plan))
|
||||
|
@ -173,9 +175,10 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
|||
|
||||
planner.shaper = hb_ot_shape_complex_categorize (&planner);
|
||||
|
||||
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
|
||||
hb_ot_shape_collect_features (&planner, &shape_plan->props,
|
||||
user_features, num_user_features);
|
||||
|
||||
planner.compile (*plan);
|
||||
planner.compile (*plan, coords, num_coords);
|
||||
|
||||
if (plan->shaper->data_create) {
|
||||
plan->data = plan->shaper->data_create (plan);
|
||||
|
|
|
@ -47,12 +47,17 @@ struct hb_shape_plan_t
|
|||
hb_feature_t *user_features;
|
||||
unsigned int num_user_features;
|
||||
|
||||
int *coords;
|
||||
unsigned int num_coords;
|
||||
|
||||
struct hb_shaper_data_t shaper_data;
|
||||
};
|
||||
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
|
||||
, const hb_feature_t *user_features \
|
||||
, unsigned int num_user_features
|
||||
, unsigned int num_user_features \
|
||||
, const int *coords \
|
||||
, unsigned int num_coords
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
|
|
@ -46,11 +46,14 @@ static void
|
|||
hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const int *coords,
|
||||
unsigned int num_coords,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
|
||||
"num_features=%d shaper_list=%p",
|
||||
"num_features=%d num_coords=%d shaper_list=%p",
|
||||
num_user_features,
|
||||
num_coords,
|
||||
shaper_list);
|
||||
|
||||
const hb_shaper_pair_t *shapers = _hb_shapers_get ();
|
||||
|
@ -59,7 +62,9 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
|
|||
HB_STMT_START { \
|
||||
if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
|
||||
HB_SHAPER_DATA (shaper, shape_plan) = \
|
||||
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
|
||||
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \
|
||||
user_features, num_user_features, \
|
||||
coords, num_coords); \
|
||||
shape_plan->shaper_func = _hb_##shaper##_shape; \
|
||||
shape_plan->shaper_name = #shaper; \
|
||||
return; \
|
||||
|
@ -114,15 +119,32 @@ hb_shape_plan_create (hb_face_t *face,
|
|||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
return hb_shape_plan_create2 (face, props,
|
||||
user_features, num_user_features,
|
||||
NULL, 0,
|
||||
shaper_list);
|
||||
}
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_create2 (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const int *orig_coords,
|
||||
unsigned int num_coords,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
|
||||
"face=%p num_features=%d shaper_list=%p",
|
||||
"face=%p num_features=%d num_coords=%d shaper_list=%p",
|
||||
face,
|
||||
num_user_features,
|
||||
num_coords,
|
||||
shaper_list);
|
||||
|
||||
hb_shape_plan_t *shape_plan;
|
||||
hb_feature_t *features = NULL;
|
||||
int *coords = NULL;
|
||||
|
||||
if (unlikely (!face))
|
||||
face = hb_face_get_empty ();
|
||||
|
@ -130,7 +152,14 @@ hb_shape_plan_create (hb_face_t *face,
|
|||
return hb_shape_plan_get_empty ();
|
||||
if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
|
||||
return hb_shape_plan_get_empty ();
|
||||
if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
|
||||
if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int))))
|
||||
{
|
||||
free (features);
|
||||
return hb_shape_plan_get_empty ();
|
||||
}
|
||||
if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
|
||||
{
|
||||
free (coords);
|
||||
free (features);
|
||||
return hb_shape_plan_get_empty ();
|
||||
}
|
||||
|
@ -145,8 +174,15 @@ hb_shape_plan_create (hb_face_t *face,
|
|||
shape_plan->user_features = features;
|
||||
if (num_user_features)
|
||||
memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
|
||||
shape_plan->num_coords = num_coords;
|
||||
shape_plan->coords = coords;
|
||||
if (num_coords)
|
||||
memcpy (coords, orig_coords, num_coords * sizeof (int));
|
||||
|
||||
hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
|
||||
hb_shape_plan_plan (shape_plan,
|
||||
user_features, num_user_features,
|
||||
coords, num_coords,
|
||||
shaper_list);
|
||||
|
||||
return shape_plan;
|
||||
}
|
||||
|
@ -176,6 +212,9 @@ hb_shape_plan_get_empty (void)
|
|||
NULL, /* user_features */
|
||||
0, /* num_user_featurs */
|
||||
|
||||
NULL, /* coords */
|
||||
0, /* num_coords */
|
||||
|
||||
{
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
|
||||
#include "hb-shaper-list.hh"
|
||||
|
@ -220,6 +259,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
|
|||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
free (shape_plan->user_features);
|
||||
free (shape_plan->coords);
|
||||
|
||||
free (shape_plan);
|
||||
}
|
||||
|
@ -351,6 +391,8 @@ struct hb_shape_plan_proposal_t
|
|||
const char * const *shaper_list;
|
||||
const hb_feature_t *user_features;
|
||||
unsigned int num_user_features;
|
||||
const int *coords;
|
||||
unsigned int num_coords;
|
||||
hb_shape_func_t *shaper_func;
|
||||
};
|
||||
|
||||
|
@ -358,12 +400,26 @@ static inline hb_bool_t
|
|||
hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
|
||||
const hb_shape_plan_proposal_t *proposal)
|
||||
{
|
||||
if (proposal->num_user_features != shape_plan->num_user_features) return false;
|
||||
if (proposal->num_user_features != shape_plan->num_user_features)
|
||||
return false;
|
||||
for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
|
||||
if (proposal->user_features[i].tag != shape_plan->user_features[i].tag ||
|
||||
proposal->user_features[i].value != shape_plan->user_features[i].value ||
|
||||
proposal->user_features[i].start != shape_plan->user_features[i].start ||
|
||||
proposal->user_features[i].end != shape_plan->user_features[i].end) return false;
|
||||
proposal->user_features[i].end != shape_plan->user_features[i].end)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan,
|
||||
const hb_shape_plan_proposal_t *proposal)
|
||||
{
|
||||
if (proposal->num_coords != shape_plan->num_coords)
|
||||
return false;
|
||||
for (unsigned int i = 0, n = proposal->num_coords; i < n; i++)
|
||||
if (proposal->coords[i] != shape_plan->coords[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -373,6 +429,7 @@ hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
|
|||
{
|
||||
return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
|
||||
hb_shape_plan_user_features_match (shape_plan, proposal) &&
|
||||
hb_shape_plan_coords_match (shape_plan, proposal) &&
|
||||
((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
|
||||
(shape_plan->shaper_func == proposal->shaper_func));
|
||||
}
|
||||
|
@ -389,6 +446,13 @@ hb_non_global_user_features_present (const hb_feature_t *user_features,
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
hb_coords_present (const int *coords,
|
||||
unsigned int num_coords)
|
||||
{
|
||||
return num_coords != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_shape_plan_create_cached:
|
||||
* @face:
|
||||
|
@ -409,6 +473,21 @@ hb_shape_plan_create_cached (hb_face_t *face,
|
|||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
return hb_shape_plan_create_cached2 (face, props,
|
||||
user_features, num_user_features,
|
||||
NULL, 0,
|
||||
shaper_list);
|
||||
}
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_create_cached2 (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const int *coords,
|
||||
unsigned int num_coords,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
|
||||
"face=%p num_features=%d shaper_list=%p",
|
||||
|
@ -456,16 +535,21 @@ retry:
|
|||
|
||||
/* Not found. */
|
||||
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props,
|
||||
user_features, num_user_features,
|
||||
coords, num_coords,
|
||||
shaper_list);
|
||||
|
||||
/* Don't add to the cache if face is inert. */
|
||||
if (unlikely (hb_object_is_inert (face)))
|
||||
return shape_plan;
|
||||
|
||||
/* Don't add the plan to the cache if there were user features with non-global ranges */
|
||||
|
||||
if (hb_non_global_user_features_present (user_features, num_user_features))
|
||||
return shape_plan;
|
||||
/* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */
|
||||
if (hb_coords_present (coords, num_coords))
|
||||
return shape_plan;
|
||||
|
||||
hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
|
||||
if (unlikely (!node))
|
||||
|
|
|
@ -52,6 +52,25 @@ hb_shape_plan_create_cached (hb_face_t *face,
|
|||
unsigned int num_user_features,
|
||||
const char * const *shaper_list);
|
||||
|
||||
HB_EXTERN hb_shape_plan_t *
|
||||
hb_shape_plan_create2 (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const int *coords,
|
||||
unsigned int num_coords,
|
||||
const char * const *shaper_list);
|
||||
|
||||
HB_EXTERN hb_shape_plan_t *
|
||||
hb_shape_plan_create_cached2 (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const int *coords,
|
||||
unsigned int num_coords,
|
||||
const char * const *shaper_list);
|
||||
|
||||
|
||||
HB_EXTERN hb_shape_plan_t *
|
||||
hb_shape_plan_get_empty (void);
|
||||
|
||||
|
|
|
@ -373,7 +373,10 @@ hb_shape_full (hb_font_t *font,
|
|||
unsigned int num_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props,
|
||||
features, num_features,
|
||||
font->coords, font->num_coords,
|
||||
shaper_list);
|
||||
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
|
||||
hb_shape_plan_destroy (shape_plan);
|
||||
|
||||
|
|
|
@ -587,7 +587,9 @@ struct hb_uniscribe_shaper_shape_plan_data_t {};
|
|||
hb_uniscribe_shaper_shape_plan_data_t *
|
||||
_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue