summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-01-12 11:28:13 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-01-12 11:31:43 +0900
commitd6f4040d0c62c220f2339d2a57126fde43e85e19 (patch)
tree9f9c541792d3f403b33816362d91c3c7170a5b19
parent3e013b392b2725a3490306a9bc39f45aaa687bde (diff)
elm - elm image orientation api fix - major bug in implementation
@fix The elm image orient_set api looks like it is a state, and it is documented to SET the orietnation, but the code actually DOEs that orientation when you set it. so docs and api name didnt match functionality at all. this was bad an an oversight. you didn't notice until you set orientation multiple times to an image. this fixes the implementation to be as documented - a state that is applied and remains that way until set to something else. setting to the same orientation has no efect as with color, size, etc. etc. in evas. you could look on this as an api break, but then either the docs change AND api name changes to match the code, or code changes to match the docs. we don't keep bug compatibility in efl and in this case i'm making the call to break the behavior of a function as it was broken already with respect to name and docs.
-rw-r--r--src/lib/elm_image.c456
-rw-r--r--src/lib/elm_image_common.h3
2 files changed, 286 insertions, 173 deletions
diff --git a/src/lib/elm_image.c b/src/lib/elm_image.c
index 7cf964447..ae8922e80 100644
--- a/src/lib/elm_image.c
+++ b/src/lib/elm_image.c
@@ -324,96 +324,6 @@ _elm_image_resize_down_get(Eo *obj EINA_UNUSED, Elm_Image_Data *sd)
324 return sd->resize_up; 324 return sd->resize_up;
325} 325}
326 326
327static void
328_elm_image_flip_horizontal(Evas_Object *obj, Elm_Image_Data *sd)
329{
330 unsigned int *p1, *p2, tmp;
331 unsigned int *data;
332 int x, y, iw, ih;
333
334 evas_object_image_size_get(sd->img, &iw, &ih);
335 data = evas_object_image_data_get(sd->img, EINA_TRUE);
336
337 for (y = 0; y < ih; y++)
338 {
339 p1 = data + (y * iw);
340 p2 = data + ((y + 1) * iw) - 1;
341 for (x = 0; x < (iw >> 1); x++)
342 {
343 tmp = *p1;
344 *p1 = *p2;
345 *p2 = tmp;
346 p1++;
347 p2--;
348 }
349 }
350
351 evas_object_image_data_set(sd->img, data);
352 evas_object_image_data_update_add(sd->img, 0, 0, iw, ih);
353
354 _elm_image_internal_sizing_eval(obj, sd);
355}
356
357static void
358_elm_image_flip_vertical(Evas_Object *obj, Elm_Image_Data *sd)
359{
360 unsigned int *p1, *p2, tmp;
361 unsigned int *data;
362 int x, y, iw, ih;
363
364 evas_object_image_size_get(sd->img, &iw, &ih);
365 data = evas_object_image_data_get(sd->img, EINA_TRUE);
366
367 for (y = 0; y < (ih >> 1); y++)
368 {
369 p1 = data + (y * iw);
370 p2 = data + ((ih - 1 - y) * iw);
371 for (x = 0; x < iw; x++)
372 {
373 tmp = *p1;
374 *p1 = *p2;
375 *p2 = tmp;
376 p1++;
377 p2++;
378 }
379 }
380
381 evas_object_image_data_set(sd->img, data);
382 evas_object_image_data_update_add(sd->img, 0, 0, iw, ih);
383
384 _elm_image_internal_sizing_eval(obj, sd);
385}
386
387static void
388_elm_image_smart_rotate_180(Evas_Object *obj, Elm_Image_Data *sd)
389{
390 unsigned int *p1, *p2, tmp;
391 unsigned int *data;
392 int x, hw, iw, ih;
393
394 evas_object_image_size_get(sd->img, &iw, &ih);
395 data = evas_object_image_data_get(sd->img, 1);
396
397 hw = iw * ih;
398 x = (hw / 2);
399 p1 = data;
400 p2 = data + hw - 1;
401
402 for (; --x > 0; )
403 {
404 tmp = *p1;
405 *p1 = *p2;
406 *p2 = tmp;
407 p1++;
408 p2--;
409 }
410
411 evas_object_image_data_set(sd->img, data);
412 evas_object_image_data_update_add(sd->img, 0, 0, iw, ih);
413
414 _elm_image_internal_sizing_eval(obj, sd);
415}
416
417static Eina_Bool 327static Eina_Bool
418_elm_image_drag_n_drop_cb(void *elm_obj, 328_elm_image_drag_n_drop_cb(void *elm_obj,
419 Evas_Object *obj, 329 Evas_Object *obj,
@@ -1090,116 +1000,316 @@ _elm_image_efl_image_load_size_get(Eo *obj EINA_UNUSED, Elm_Image_Data *sd, int
1090 if (h) *h = sd->load_size; 1000 if (h) *h = sd->load_size;
1091} 1001}
1092 1002
1093EOLIAN static void 1003static void
1094_elm_image_orient_set(Eo *obj, Elm_Image_Data *sd, Elm_Image_Orient orient) 1004_elm_image_flip_horizontal(Elm_Image_Data *sd)
1095{ 1005{
1006 unsigned int *p1, *p2, tmp;
1007 unsigned int *data;
1008 int x, y, iw, ih;
1096 1009
1097 unsigned int *data, *data2 = NULL, *to, *from; 1010 evas_object_image_size_get(sd->img, &iw, &ih);
1098 int x, y, w, hw, iw, ih; 1011 data = evas_object_image_data_get(sd->img, EINA_TRUE);
1099
1100 if (sd->edje)
1101 return;
1102 1012
1103 switch (orient) 1013 for (y = 0; y < ih; y++)
1104 { 1014 {
1105 case ELM_IMAGE_FLIP_HORIZONTAL: 1015 p1 = data + (y * iw);
1106 _elm_image_flip_horizontal(obj, sd); 1016 p2 = data + ((y + 1) * iw) - 1;
1107 sd->orient = orient; 1017 for (x = 0; x < (iw >> 1); x++)
1108 return; 1018 {
1109 1019 tmp = *p1;
1110 case ELM_IMAGE_FLIP_VERTICAL: 1020 *p1 = *p2;
1111 _elm_image_flip_vertical(obj, sd); 1021 *p2 = tmp;
1112 sd->orient = orient; 1022 p1++;
1113 return; 1023 p2--;
1114 1024 }
1115 case ELM_IMAGE_ROTATE_180:
1116 _elm_image_smart_rotate_180(obj, sd);
1117 sd->orient = orient;
1118 return;
1119
1120 case ELM_IMAGE_ORIENT_NONE:
1121 sd->orient = orient;
1122 return;
1123
1124 default:
1125 break;
1126 } 1025 }
1127 1026
1027 evas_object_image_data_set(sd->img, data);
1028}
1029
1030static void
1031_elm_image_flip_vertical(Elm_Image_Data *sd)
1032{
1033 unsigned int *p1, *p2, tmp;
1034 unsigned int *data;
1035 int x, y, iw, ih;
1036
1128 evas_object_image_size_get(sd->img, &iw, &ih); 1037 evas_object_image_size_get(sd->img, &iw, &ih);
1038 data = evas_object_image_data_get(sd->img, EINA_TRUE);
1129 1039
1130 /* we need separate destination memory if we want to rotate 90 or 1040 for (y = 0; y < (ih >> 1); y++)
1131 * 270 degree */ 1041 {
1132 data = evas_object_image_data_get(sd->img, EINA_FALSE); 1042 p1 = data + (y * iw);
1133 if (!data) return; 1043 p2 = data + ((ih - 1 - y) * iw);
1134 data2 = malloc(sizeof(unsigned int) * (iw * ih)); 1044 for (x = 0; x < iw; x++)
1135 if (!data2) return; 1045 {
1136 memcpy(data2, data, sizeof(unsigned int) * (iw * ih)); 1046 tmp = *p1;
1047 *p1 = *p2;
1048 *p2 = tmp;
1049 p1++;
1050 p2++;
1051 }
1052 }
1137 1053
1138 w = ih; 1054 evas_object_image_data_set(sd->img, data);
1139 ih = iw; 1055}
1140 iw = w;
1141 hw = w * ih;
1142 1056
1143 evas_object_image_size_set(sd->img, iw, ih); 1057static void
1144 data = evas_object_image_data_get(sd->img, EINA_TRUE); 1058_elm_image_smart_rotate_180(Elm_Image_Data *sd)
1145 if (!data) 1059{
1060 unsigned int *p1, *p2, tmp;
1061 unsigned int *data;
1062 int x, hw, iw, ih;
1063
1064 evas_object_image_size_get(sd->img, &iw, &ih);
1065 data = evas_object_image_data_get(sd->img, 1);
1066
1067 hw = iw * ih;
1068 x = (hw / 2);
1069 p1 = data;
1070 p2 = data + hw - 1;
1071
1072 for (; --x > 0; )
1146 { 1073 {
1147 free(data2); 1074 tmp = *p1;
1148 return; 1075 *p1 = *p2;
1076 *p2 = tmp;
1077 p1++;
1078 p2--;
1149 } 1079 }
1150 1080
1151 switch (orient) 1081 evas_object_image_data_set(sd->img, data);
1082}
1083
1084#define GETDAT(neww, newh) \
1085 unsigned int *data, *data2; \
1086 int iw, ih, w, h; \
1087 evas_object_image_size_get(sd->img, &iw, &ih); \
1088 data = evas_object_image_data_get(sd->img, EINA_FALSE); \
1089 if (!data) return; \
1090 data2 = malloc(iw * ih * sizeof(int)); \
1091 if (!data2) { \
1092 evas_object_image_data_set(sd->img, data); \
1093 return; \
1094 } \
1095 memcpy(data2, data, iw * ih * sizeof(int)); \
1096 evas_object_image_data_set(sd->img, data); \
1097 w = neww; h = newh; \
1098 evas_object_image_size_set(sd->img, w, h); \
1099 data = evas_object_image_data_get(sd->img, EINA_TRUE); \
1100 if (!data) return
1101
1102#define PUTDAT \
1103 evas_object_image_data_set(sd->img, data); \
1104 free(data2)
1105
1106#define TILE 32
1107
1108static void
1109_elm_image_smart_rotate_90(Elm_Image_Data *sd)
1110{
1111 GETDAT(ih, iw);
1112 int x, y, xx, yy, xx2, yy2;
1113 unsigned int *src, *dst;
1114
1115 for (y = 0; y < ih; y += TILE)
1152 { 1116 {
1153 case ELM_IMAGE_FLIP_TRANSPOSE: 1117 yy2 = y + TILE;
1154 to = data; 1118 if (yy2 > ih) yy2 = ih;
1155 hw = -hw + 1; 1119 for (x = 0; x < iw; x += TILE)
1156 sd->orient = orient; 1120 {
1157 break; 1121 xx2 = x + TILE;
1122 if (xx2 > iw) xx2 = iw;
1123 for (yy = y; yy < yy2; yy++)
1124 {
1125 src = data2 + (yy * iw) + x;
1126 dst = data + (x * w) + (w - yy - 1);
1127 for (xx = x; xx < xx2; xx++)
1128 {
1129 *dst = *src;
1130 src++;
1131 dst += w;
1132 }
1133 }
1134 }
1135 }
1136 PUTDAT;
1137}
1158 1138
1159 case ELM_IMAGE_FLIP_TRANSVERSE: 1139static void
1160 to = data + hw - 1; 1140_elm_image_smart_rotate_270(Elm_Image_Data *sd)
1161 w = -w; 1141{
1162 hw = hw - 1; 1142 GETDAT(ih, iw);
1163 sd->orient = orient; 1143 int x, y, xx, yy, xx2, yy2;
1164 break; 1144 unsigned int *src, *dst;
1165 1145
1166 case ELM_IMAGE_ROTATE_90: 1146 for (y = 0; y < ih; y += TILE)
1167 to = data + w - 1; 1147 {
1168 hw = -hw - 1; 1148 yy2 = y + TILE;
1169 sd->orient = orient; 1149 if (yy2 > ih) yy2 = ih;
1170 break; 1150 for (x = 0; x < iw; x += TILE)
1151 {
1152 xx2 = x + TILE;
1153 if (xx2 > iw) xx2 = iw;
1154 for (yy = y; yy < yy2; yy++)
1155 {
1156 src = data2 + (yy * iw) + x;
1157 dst = data + ((h - x - 1) * w) + yy;
1158 for (xx = x; xx < xx2; xx++)
1159 {
1160 *dst = *src;
1161 src++;
1162 dst -= w;
1163 }
1164 }
1165 }
1166 }
1167 PUTDAT;
1168}
1171 1169
1172 case ELM_IMAGE_ROTATE_270: 1170static void
1173 to = data + hw - w; 1171_elm_image_smart_flip_transverse(Elm_Image_Data *sd)
1174 w = -w; 1172{
1175 hw = hw + 1; 1173 GETDAT(ih, iw);
1176 sd->orient = orient; 1174 int x, y;
1177 break; 1175 unsigned int *src, *dst;
1176
1177 src = data2;
1178 for (y = 0; y < ih; y++)
1179 {
1180 dst = data + y;
1181 for (x = 0; x < iw; x++)
1182 {
1183 *dst = *src;
1184 src++;
1185 dst += w;
1186 }
1187 }
1188 PUTDAT;
1189}
1178 1190
1179 default: 1191static void
1180 ERR("unknown orient %d", orient); 1192_elm_image_smart_flip_transpose(Elm_Image_Data *sd)
1181 evas_object_image_data_set(sd->img, data); // give it back 1193{
1182 free(data2); 1194 GETDAT(ih, iw);
1195 int x, y;
1196 unsigned int *src, *dst;
1183 1197
1184 return; 1198 src = data2 + (iw * ih) - 1;
1199 for (y = 0; y < ih; y++)
1200 {
1201 dst = data + y;
1202 for (x = 0; x < iw; x++)
1203 {
1204 *dst = *src;
1205 src--;
1206 dst += w;
1207 }
1185 } 1208 }
1209 PUTDAT;
1210}
1211
1212EOLIAN static void
1213_elm_image_orient_set(Eo *obj, Elm_Image_Data *sd, Elm_Image_Orient orient)
1214{
1186 1215
1187 from = data2; 1216 int iw, ih;
1188 for (x = iw; --x >= 0; ) 1217
1218 if (sd->edje) return;
1219 if (sd->orient == orient) return;
1220
1221 evas_object_image_size_get(sd->img, &iw, &ih);
1222 if ((sd->orient >= ELM_IMAGE_ORIENT_0) &&
1223 (sd->orient <= ELM_IMAGE_ROTATE_270) &&
1224 (orient >= ELM_IMAGE_ORIENT_0) &&
1225 (orient <= ELM_IMAGE_ROTATE_270))
1189 { 1226 {
1190 for (y = ih; --y >= 0; ) 1227 // we are rotating from one anglee to another, so figure out delta
1228 // and apply that delta
1229 Elm_Image_Orient rot_delta = (4 + orient - sd->orient) % 4;
1230 switch (rot_delta)
1191 { 1231 {
1192 *to = *from; 1232 case ELM_IMAGE_ORIENT_0:
1193 from++; 1233 // this should never hppen
1194 to += w; 1234 break;
1235 case ELM_IMAGE_ORIENT_90:
1236 _elm_image_smart_rotate_90(sd);
1237 sd->orient = orient;
1238 break;
1239 case ELM_IMAGE_ORIENT_180:
1240 _elm_image_smart_rotate_180(sd);
1241 sd->orient = orient;
1242 break;
1243 case ELM_IMAGE_ORIENT_270:
1244 _elm_image_smart_rotate_270(sd);
1245 sd->orient = orient;
1246 break;
1247 default:
1248 // this should never hppen
1249 break;
1195 } 1250 }
1196 to += hw;
1197 } 1251 }
1198 free(data2); 1252 else if (((sd->orient == ELM_IMAGE_ORIENT_NONE) &&
1253 (orient == ELM_IMAGE_FLIP_HORIZONTAL)) ||
1254 ((sd->orient == ELM_IMAGE_FLIP_HORIZONTAL) &&
1255 (orient == ELM_IMAGE_ORIENT_NONE)))
1256 {
1257 // flip horizontally to get thew new orientation
1258 _elm_image_flip_horizontal(sd);
1259 sd->orient = orient;
1260 }
1261 else if (((sd->orient == ELM_IMAGE_ORIENT_NONE) &&
1262 (orient == ELM_IMAGE_FLIP_VERTICAL)) ||
1263 ((sd->orient == ELM_IMAGE_FLIP_VERTICAL) &&
1264 (orient == ELM_IMAGE_ORIENT_NONE)))
1265 {
1266 // flipvertically to get thew new orientation
1267 _elm_image_flip_vertical(sd);
1268 sd->orient = orient;
1269 }
1270 else
1271 {
1272 // generic solution - undo the previous orientation and then apply the
1273 // new one after that
1274 int i;
1199 1275
1200 evas_object_image_data_set(sd->img, data); 1276 for (i = 0; i < 2; i++)
1201 evas_object_image_data_update_add(sd->img, 0, 0, iw, ih); 1277 {
1278 switch (sd->orient)
1279 {
1280 case ELM_IMAGE_ORIENT_0:
1281 break;
1282 case ELM_IMAGE_ORIENT_90:
1283 _elm_image_smart_rotate_270(sd);
1284 break;
1285 case ELM_IMAGE_ORIENT_180:
1286 _elm_image_smart_rotate_180(sd);
1287 break;
1288 case ELM_IMAGE_ORIENT_270:
1289 _elm_image_smart_rotate_90(sd);
1290 break;
1291 case ELM_IMAGE_FLIP_HORIZONTAL:
1292 _elm_image_flip_horizontal(sd);
1293 break;
1294 case ELM_IMAGE_FLIP_VERTICAL:
1295 _elm_image_flip_vertical(sd);
1296 break;
1297 case ELM_IMAGE_FLIP_TRANSPOSE:
1298 _elm_image_smart_flip_transpose(sd);
1299 break;
1300 case ELM_IMAGE_FLIP_TRANSVERSE:
1301 _elm_image_smart_flip_transverse(sd);
1302 break;
1303 default:
1304 // this should never hppen
1305 break;
1306 }
1307 sd->orient = orient;
1308 }
1309 }
1202 1310
1311 evas_object_image_size_get(sd->img, &iw, &ih);
1312 evas_object_image_data_update_add(sd->img, 0, 0, iw, ih);
1203 _elm_image_internal_sizing_eval(obj, sd); 1313 _elm_image_internal_sizing_eval(obj, sd);
1204} 1314}
1205 1315
diff --git a/src/lib/elm_image_common.h b/src/lib/elm_image_common.h
index 7f4a3b804..a652f260c 100644
--- a/src/lib/elm_image_common.h
+++ b/src/lib/elm_image_common.h
@@ -15,8 +15,11 @@ typedef enum
15 ELM_IMAGE_ORIENT_NONE = 0, /**< no orientation change */ 15 ELM_IMAGE_ORIENT_NONE = 0, /**< no orientation change */
16 ELM_IMAGE_ORIENT_0 = 0, /**< no orientation change */ 16 ELM_IMAGE_ORIENT_0 = 0, /**< no orientation change */
17 ELM_IMAGE_ROTATE_90 = 1, /**< rotate 90 degrees clockwise */ 17 ELM_IMAGE_ROTATE_90 = 1, /**< rotate 90 degrees clockwise */
18 ELM_IMAGE_ORIENT_90 = 1, /**< rotate 90 degrees clockwise @since 1.13 */
18 ELM_IMAGE_ROTATE_180 = 2, /**< rotate 180 degrees clockwise */ 19 ELM_IMAGE_ROTATE_180 = 2, /**< rotate 180 degrees clockwise */
20 ELM_IMAGE_ORIENT_180 = 2, /**< rotate 180 degrees clockwise @since 1.13 */
19 ELM_IMAGE_ROTATE_270 = 3, /**< rotate 90 degrees counter-clockwise (i.e. 270 degrees clockwise) */ 21 ELM_IMAGE_ROTATE_270 = 3, /**< rotate 90 degrees counter-clockwise (i.e. 270 degrees clockwise) */
22 ELM_IMAGE_ORIENT_270 = 3, /**< rotate 90 degrees counter-clockwise (i.e. 270 degrees clockwise) @since 1.13 */
20 ELM_IMAGE_FLIP_HORIZONTAL = 4, /**< flip image horizontally */ 23 ELM_IMAGE_FLIP_HORIZONTAL = 4, /**< flip image horizontally */
21 ELM_IMAGE_FLIP_VERTICAL = 5, /**< flip image vertically */ 24 ELM_IMAGE_FLIP_VERTICAL = 5, /**< flip image vertically */
22 ELM_IMAGE_FLIP_TRANSPOSE = 6, /**< flip the image along the y = (width - x) line (bottom-left to top-right) */ 25 ELM_IMAGE_FLIP_TRANSPOSE = 6, /**< flip the image along the y = (width - x) line (bottom-left to top-right) */