summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Antognolli <antognolli@gmail.com>2011-09-15 18:51:33 +0000
committerRafael Antognolli <antognolli@gmail.com>2011-09-15 18:51:33 +0000
commit0c4dd42a0aa82aabdca48c6efd377af3312a1382 (patch)
treeca5573bb39bd2216bc51e123bb8a5288bb9298b0
parent5c3474beedf7618b927844b699b5e38ad62548b0 (diff)
emotion/aspect: Add API to configure the aspect ratio policy.
The new function emotion_object_keep_aspect_set() allow to set a policy that will automatically change the emotion object border property, based on the video aspect ratio and object current aspect ratio. Possible values are: * EMOTION_ASPECT_KEEP_NONE * EMOTION_ASPECT_KEEP_WIDTH * EMOTION_ASPECT_KEEP_HEIGHT * EMOTION_ASPECT_KEEP_BOTH * EMOTION_ASPECT_CROP * EMOTION_ASPECT_CUSTOM SVN revision: 63416
-rw-r--r--legacy/emotion/src/examples/emotion_border_example.c26
-rw-r--r--legacy/emotion/src/lib/Emotion.h64
-rw-r--r--legacy/emotion/src/lib/emotion_smart.c177
3 files changed, 238 insertions, 29 deletions
diff --git a/legacy/emotion/src/examples/emotion_border_example.c b/legacy/emotion/src/examples/emotion_border_example.c
index f83790a7d7..6772b0b836 100644
--- a/legacy/emotion/src/examples/emotion_border_example.c
+++ b/legacy/emotion/src/examples/emotion_border_example.c
@@ -70,6 +70,30 @@ _on_key_down(void *data, Evas *e, Evas_Object *o, void *event_info)
70 fprintf(stderr, "playing next file: %s\n", file); 70 fprintf(stderr, "playing next file: %s\n", file);
71 emotion_object_file_set(em, file); 71 emotion_object_file_set(em, file);
72 } 72 }
73 else if (!strcmp(ev->keyname, "b"))
74 {
75 emotion_object_border_set(em, 0, 0, 50, 50);
76 }
77 else if (!strcmp(ev->keyname, "0"))
78 {
79 emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_NONE);
80 }
81 else if (!strcmp(ev->keyname, "w"))
82 {
83 emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_WIDTH);
84 }
85 else if (!strcmp(ev->keyname, "h"))
86 {
87 emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_HEIGHT);
88 }
89 else if (!strcmp(ev->keyname, "2"))
90 {
91 emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_BOTH);
92 }
93 else if (!strcmp(ev->keyname, "c"))
94 {
95 emotion_object_keep_aspect_set(em, EMOTION_ASPECT_CROP);
96 }
73 else 97 else
74 { 98 {
75 fprintf(stderr, "unhandled key: %s\n", ev->keyname); 99 fprintf(stderr, "unhandled key: %s\n", ev->keyname);
@@ -179,7 +203,7 @@ main(int argc, const char *argv[])
179 evas_object_move(em, 10, 10); 203 evas_object_move(em, 10, 10);
180 evas_object_resize(em, WIDTH, HEIGHT); 204 evas_object_resize(em, WIDTH, HEIGHT);
181 evas_object_resize(em, WIDTH - 20, HEIGHT - 20); 205 evas_object_resize(em, WIDTH - 20, HEIGHT - 20);
182 emotion_object_border_set(em, 0, 0, 50, 50); 206 emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_BOTH);
183 emotion_object_bg_color_set(em, 0, 128, 0, 255); 207 emotion_object_bg_color_set(em, 0, 128, 0, 255);
184 evas_object_show(em); 208 evas_object_show(em);
185 209
diff --git a/legacy/emotion/src/lib/Emotion.h b/legacy/emotion/src/lib/Emotion.h
index ba2f15c955..0483bebba7 100644
--- a/legacy/emotion/src/lib/Emotion.h
+++ b/legacy/emotion/src/lib/Emotion.h
@@ -210,10 +210,21 @@ typedef enum
210 EMOTION_HIBERNATE 210 EMOTION_HIBERNATE
211} Emotion_Suspend; 211} Emotion_Suspend;
212 212
213enum _Emotion_Aspect
214{
215 EMOTION_ASPECT_KEEP_NONE, /**< ignore video aspect ratio */
216 EMOTION_ASPECT_KEEP_WIDTH, /**< respect video aspect, fitting its width inside the object width */
217 EMOTION_ASPECT_KEEP_HEIGHT, /**< respect video aspect, fitting its height inside the object height */
218 EMOTION_ASPECT_KEEP_BOTH, /**< respect video aspect, fitting it inside the object area */
219 EMOTION_ASPECT_CROP, /**< respect video aspect, cropping exceding area */
220 EMOTION_ASPECT_CUSTOM, /**< use custom borders/crop for the video */
221};
222
213typedef enum _Emotion_Module Emotion_Module; 223typedef enum _Emotion_Module Emotion_Module;
214typedef enum _Emotion_Event Emotion_Event; 224typedef enum _Emotion_Event Emotion_Event;
215typedef enum _Emotion_Meta_Info Emotion_Meta_Info; /**< Meta info type to be retrieved. */ 225typedef enum _Emotion_Meta_Info Emotion_Meta_Info; /**< Meta info type to be retrieved. */
216typedef enum _Emotion_Vis Emotion_Vis; /**< Type of visualization. */ 226typedef enum _Emotion_Vis Emotion_Vis; /**< Type of visualization. */
227typedef enum _Emotion_Aspect Emotion_Aspect; /**< Aspect ratio option. */
217 228
218#define EMOTION_CHANNEL_AUTO -1 229#define EMOTION_CHANNEL_AUTO -1
219#define EMOTION_CHANNEL_DEFAULT 0 230#define EMOTION_CHANNEL_DEFAULT 0
@@ -449,6 +460,59 @@ EAPI void emotion_object_bg_color_set(Evas_Object *obj, int r, int g, int b, int
449EAPI void emotion_object_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a); 460EAPI void emotion_object_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a);
450 461
451/** 462/**
463 * @brief Set whether emotion should keep the aspect ratio of the video.
464 *
465 * @param obj The emotion object where to set the aspect.
466 * @param a The aspect ratio policy.
467 *
468 * Instead of manually calculating the required border to set with
469 * emotion_object_border_set(), and using this to fix the aspect ratio of the
470 * video when the emotion object has a different aspect, it's possible to just
471 * set the policy to be used.
472 *
473 * The options are:
474 *
475 * - @b #EMOTION_ASPECT_KEEP_NONE - ignore the video aspect ratio, and reset any
476 * border set to 0, stretching the video inside the emotion object area. This
477 * option is similar to EVAS_ASPECT_CONTROL_NONE size hint.
478 * - @b #EMOTION_ASPECT_KEEP_WIDTH - respect the video aspect ratio, fitting the
479 * video width inside the object width. This option is similar to
480 * EVAS_ASPECT_CONTROL_HORIZONTAL size hint.
481 * - @b #EMOTION_ASPECT_KEEP_HEIGHT - respect the video aspect ratio, fitting
482 * the video height inside the object height. This option is similar to
483 * EVAS_ASPECT_CONTROL_VERTIAL size hint.
484 * - @b #EMOTION_ASPECT_KEEP_BOTH - respect the video aspect ratio, fitting both
485 * its width and height inside the object area. This option is similar to
486 * EVAS_ASPECT_CONTROL_BOTH size hint. It's the effect called letterboxing.
487 * - @b #EMOTION_ASPECT_CROP - respect the video aspect ratio, fitting the width
488 * or height inside the object area, and cropping the exceding areas of the
489 * video in height or width. It's the effect called pan-and-scan.
490 * - @b #EMOTION_ASPECT_CUSTOM - ignore the video aspect ratio, and use the
491 * current set from emotion_object_border_set().
492 *
493 * @note Calling this function with any value except #EMOTION_ASPECT_CUSTOM will
494 * invalidate borders set with emotion_object_border_set().
495 *
496 * @note Calling emotion_object_border_set() will automatically set the aspect
497 * policy to #EMOTION_ASPECT_CUSTOM.
498 *
499 * @see emotion_object_border_set()
500 * @see emotion_object_keep_aspect_get()
501 */
502EAPI void emotion_object_keep_aspect_set(Evas_Object *obj, Emotion_Aspect a);
503
504/**
505 * @brief Get the current emotion aspect ratio policy.
506 *
507 * @param obj The emotion object from which we are fetching the aspect ratio
508 * policy.
509 * @return The current aspect ratio policy.
510 *
511 * @see emotion_object_keep_aspect_set()
512 */
513EAPI Emotion_Aspect emotion_object_keep_aspect_get(const Evas_Object *obj);
514
515/**
452 * @brief Set the file to be played in the Emotion object. 516 * @brief Set the file to be played in the Emotion object.
453 * 517 *
454 * @param obj The emotion object where the file is being loaded. 518 * @param obj The emotion object where the file is being loaded.
diff --git a/legacy/emotion/src/lib/emotion_smart.c b/legacy/emotion/src/lib/emotion_smart.c
index f9882b096c..cde9351980 100644
--- a/legacy/emotion/src/lib/emotion_smart.c
+++ b/legacy/emotion/src/lib/emotion_smart.c
@@ -94,6 +94,7 @@ struct _Smart_Data
94 Emotion_Module_Options module_options; 94 Emotion_Module_Options module_options;
95 95
96 Emotion_Suspend state; 96 Emotion_Suspend state;
97 Emotion_Aspect aspect;
97 98
98 Eina_Bool open : 1; 99 Eina_Bool open : 1;
99 Eina_Bool play : 1; 100 Eina_Bool play : 1;
@@ -289,16 +290,15 @@ _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **
289} 290}
290 291
291static void 292static void
292_clipper_position_size_update(Evas_Object *obj, int vid_w, int vid_h) 293_clipper_position_size_update(Evas_Object *obj, int w, int h, int vid_w, int vid_h)
293{ 294{
294 Smart_Data *sd; 295 Smart_Data *sd;
295 double scale_w, scale_h; 296 double scale_w, scale_h;
296 int x, y; 297 int x, y;
297 int w, h;
298 298
299 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); 299 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
300 300
301 evas_object_geometry_get(obj, &x, &y, &w, &h); 301 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
302 evas_object_move(sd->crop.clipper, x, y); 302 evas_object_move(sd->crop.clipper, x, y);
303 scale_w = (double)w / (double)(vid_w - sd->crop.l - sd->crop.r); 303 scale_w = (double)w / (double)(vid_w - sd->crop.l - sd->crop.r);
304 scale_h = (double)h / (double)(vid_h - sd->crop.t - sd->crop.b); 304 scale_h = (double)h / (double)(vid_h - sd->crop.t - sd->crop.b);
@@ -450,30 +450,25 @@ emotion_object_file_get(const Evas_Object *obj)
450 return sd->file; 450 return sd->file;
451} 451}
452 452
453EAPI void 453static void
454emotion_object_border_set(Evas_Object *obj, int l, int r, int t, int b) 454_emotion_aspect_borders_apply(Evas_Object *obj, Smart_Data *sd, int w, int h, int iw, int ih)
455{ 455{
456 Smart_Data *sd; 456 /* applying calculated borders */
457 457 if (sd->crop.l == 0 && sd->crop.r == 0 &&
458 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); 458 sd->crop.t == 0 && sd->crop.b == 0)
459 sd->crop.l = -l;
460 sd->crop.r = -r;
461 sd->crop.t = -t;
462 sd->crop.b = -b;
463 if (l == 0 && r == 0 && t == 0 && b == 0)
464 { 459 {
465 Evas_Object *old_clipper; 460 Evas_Object *old_clipper;
466 if (!sd->crop.clipper) 461 if (sd->crop.clipper)
467 return; 462 {
468 old_clipper = evas_object_clip_get(sd->crop.clipper); 463 old_clipper = evas_object_clip_get(sd->crop.clipper);
469 evas_object_clip_unset(sd->obj); 464 evas_object_clip_unset(sd->obj);
470 evas_object_clip_set(sd->obj, old_clipper); 465 evas_object_clip_set(sd->obj, old_clipper);
471 evas_object_del(sd->crop.clipper); 466 evas_object_del(sd->crop.clipper);
472 sd->crop.clipper = NULL; 467 sd->crop.clipper = NULL;
468 }
473 } 469 }
474 else 470 else
475 { 471 {
476 int vid_w, vid_h;
477 if (!sd->crop.clipper) 472 if (!sd->crop.clipper)
478 { 473 {
479 Evas_Object *old_clipper; 474 Evas_Object *old_clipper;
@@ -487,9 +482,108 @@ emotion_object_border_set(Evas_Object *obj, int l, int r, int t, int b)
487 if (evas_object_visible_get(sd->obj)) 482 if (evas_object_visible_get(sd->obj))
488 evas_object_show(sd->crop.clipper); 483 evas_object_show(sd->crop.clipper);
489 } 484 }
490 sd->module->video_data_size_get(sd->video, &vid_w, &vid_h);
491 _clipper_position_size_update(obj, vid_w, vid_h);
492 } 485 }
486 _clipper_position_size_update(obj, w, h, iw, ih);
487}
488
489static void
490_emotion_object_aspect_border_apply(Evas_Object *obj, Smart_Data *sd, int w, int h)
491{
492 int iw, ih;
493 double ir;
494 double r;
495
496 int aspect_opt;
497 sd->module->video_data_size_get(sd->video, &iw, &ih);
498
499 ir = (double)iw / ih;
500 r = (double)w / h;
501
502 /* First check if we should fit the width or height of the video inside the
503 * width/height of the object. This check takes into account the original
504 * aspect ratio and the object aspect ratio, if we are keeping both sizes or
505 * cropping the exceding area.
506 */
507 if (sd->aspect == EMOTION_ASPECT_KEEP_NONE)
508 {
509 sd->crop.l = 0;
510 sd->crop.r = 0;
511 sd->crop.t = 0;
512 sd->crop.b = 0;
513 aspect_opt = 0; // just ignore keep_aspect
514 }
515 else if (sd->aspect == EMOTION_ASPECT_KEEP_WIDTH)
516 {
517 aspect_opt = 1;
518 }
519 else if (sd->aspect == EMOTION_ASPECT_KEEP_HEIGHT)
520 {
521 aspect_opt = 2;
522 }
523 else if (sd->aspect == EMOTION_ASPECT_KEEP_BOTH)
524 {
525 if (ir > r)
526 aspect_opt = 1;
527 else
528 aspect_opt = 2;
529 }
530 else if (sd->aspect == EMOTION_ASPECT_CROP)
531 {
532 if (ir > r)
533 aspect_opt = 2;
534 else
535 aspect_opt = 1;
536 }
537 else if (sd->aspect == EMOTION_ASPECT_CUSTOM)
538 {
539 // nothing to do, just respect the border settings
540 aspect_opt = 0;
541 }
542
543 /* updating borders based on keep_aspect settings */
544 if (aspect_opt == 1) // keep width
545 {
546 int th, dh;
547 double scale;
548
549 sd->crop.l = 0;
550 sd->crop.r = 0;
551 scale = (double)iw / w;
552 th = h * scale;
553 dh = ih - th;
554 sd->crop.t = sd->crop.b = dh / 2;
555 }
556 else if (aspect_opt == 2) // keep height
557 {
558 int tw, dw;
559 double scale;
560
561 sd->crop.t = 0;
562 sd->crop.b = 0;
563 scale = (double)ih / h;
564 tw = w * scale;
565 dw = iw - tw;
566 sd->crop.l = sd->crop.r = dw / 2;
567 }
568
569 _emotion_aspect_borders_apply(obj, sd, w, h, iw, ih);
570}
571
572EAPI void
573emotion_object_border_set(Evas_Object *obj, int l, int r, int t, int b)
574{
575 Smart_Data *sd;
576 int w, h;
577
578 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
579
580 sd->aspect = EMOTION_ASPECT_CUSTOM;
581 sd->crop.l = -l;
582 sd->crop.r = -r;
583 sd->crop.t = -t;
584 sd->crop.b = -b;
585 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
586 _emotion_object_aspect_border_apply(obj, sd, w, h);
493} 587}
494 588
495EAPI void 589EAPI void
@@ -532,6 +626,32 @@ emotion_object_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int
532} 626}
533 627
534EAPI void 628EAPI void
629emotion_object_keep_aspect_set(Evas_Object *obj, Emotion_Aspect a)
630{
631 Smart_Data *sd;
632 int w, h;
633
634 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
635
636 if (a == sd->aspect)
637 return;
638
639 sd->aspect = a;
640 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
641 _emotion_object_aspect_border_apply(obj, sd, w, h);
642}
643
644EAPI Emotion_Aspect
645emotion_object_keep_aspect_get(const Evas_Object *obj)
646{
647 Smart_Data *sd;
648
649 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_ASPECT_KEEP_NONE);
650
651 return sd->aspect;
652}
653
654EAPI void
535emotion_object_play_set(Evas_Object *obj, Eina_Bool play) 655emotion_object_play_set(Evas_Object *obj, Eina_Bool play)
536{ 656{
537 Smart_Data *sd; 657 Smart_Data *sd;
@@ -653,8 +773,6 @@ emotion_object_size_get(const Evas_Object *obj, int *iw, int *ih)
653 if (ih) *ih = 0; 773 if (ih) *ih = 0;
654 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); 774 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
655 evas_object_image_size_get(sd->obj, iw, ih); 775 evas_object_image_size_get(sd->obj, iw, ih);
656 *iw -= (sd->crop.l + sd->crop.r);
657 *ih -= (sd->crop.t + sd->crop.b);
658} 776}
659 777
660EAPI void 778EAPI void
@@ -1364,7 +1482,8 @@ _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio)
1364 { 1482 {
1365 evas_object_size_hint_request_set(obj, w, h); 1483 evas_object_size_hint_request_set(obj, w, h);
1366 evas_object_smart_callback_call(obj, SIG_FRAME_RESIZE, NULL); 1484 evas_object_smart_callback_call(obj, SIG_FRAME_RESIZE, NULL);
1367 _clipper_position_size_update(obj, w, h); 1485 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1486 _emotion_object_aspect_border_apply(obj, sd, w, h);
1368 } 1487 }
1369} 1488}
1370 1489
@@ -1750,7 +1869,8 @@ _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y)
1750 1869
1751 int vid_w, vid_h, w, h; 1870 int vid_w, vid_h, w, h;
1752 sd->module->video_data_size_get(sd->video, &vid_w, &vid_h); 1871 sd->module->video_data_size_get(sd->video, &vid_w, &vid_h);
1753 _clipper_position_size_update(obj, vid_w, vid_h); 1872 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1873 _clipper_position_size_update(obj, w, h, vid_w, vid_h);
1754 evas_object_move(sd->bg, x, y); 1874 evas_object_move(sd->bg, x, y);
1755} 1875}
1756 1876
@@ -1765,7 +1885,8 @@ _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h)
1765 int vid_w, vid_h; 1885 int vid_w, vid_h;
1766 1886
1767 sd->module->video_data_size_get(sd->video, &vid_w, &vid_h); 1887 sd->module->video_data_size_get(sd->video, &vid_w, &vid_h);
1768 _clipper_position_size_update(obj, vid_w, vid_h); 1888 fprintf(stderr, "smart resize: %dx%d\n", w, h);
1889 _emotion_object_aspect_border_apply(obj, sd, w, h);
1769 evas_object_resize(sd->bg, w, h); 1890 evas_object_resize(sd->bg, w, h);
1770} 1891}
1771 1892