@@ -1060,369 +1060,3 @@ bool MCBitmapEffectsSetProperty(MCExecContext& ctxt, MCBitmapEffectsRef& self, M
10601060}
10611061
10621062// //////////////////////////////////////////////////////////////////////////////
1063-
1064- #ifdef OLD_GRAPHICS
1065- PACKED_INLINE uint8_t _scale_bounded (uint8_t a, uint8_t b)
1066- {
1067- uint32_t u;
1068- u = a * b + 0x80 ;
1069- return (u + (u >> 8 )) >> 8 ;
1070- }
1071-
1072-
1073- static void MCBitmapEffectCompositeNormal (uint32_t *dst, uint32_t color, uint8_t *mask, int32_t count)
1074- {
1075- for (int32_t x = 0 ; x < count; x++)
1076- {
1077- if (mask[x] == 0 )
1078- continue ;
1079-
1080- uint32_t src;
1081- src = packed_scale_bounded (color, mask[x]);
1082- dst[x] = packed_scale_bounded (dst[x], 255 - (src >> 24 )) + src;
1083- }
1084- }
1085-
1086- static void MCBitmapEffectCompositeMultiply (uint32_t *dst, uint32_t color, uint8_t *mask, int32_t count)
1087- {
1088- for (int32_t x = 0 ; x < count; x++)
1089- {
1090- if (mask[x] == 0 )
1091- continue ;
1092-
1093- uint32_t src;
1094- src = packed_scale_bounded (color, mask[x]);
1095- dst[x] = packed_multiply_bounded (src, dst[x]) + packed_bilinear_bounded (src, 255 - (dst[x] >> 24 ), dst[x], 255 - (src >> 24 ));
1096- }
1097- }
1098-
1099- static void MCBitmapEffectCompositeMultiplyOpaque (uint32_t *dst, uint32_t color, uint8_t *mask, int32_t count)
1100- {
1101- for (int32_t x = 0 ; x < count; x++)
1102- {
1103- if (mask[x] == 0 )
1104- continue ;
1105-
1106- uint32_t src;
1107- src = packed_scale_bounded (color, mask[x]);
1108- dst[x] = packed_multiply_bounded (src, dst[x]) + packed_scale_bounded (dst[x], 255 - (src >> 24 ));
1109- }
1110- }
1111-
1112- static void MCBitmapEffectCompositeColorDodge (uint32_t *dst, uint32_t color, uint8_t *mask, int32_t count)
1113- {
1114- for (int32_t x = 0 ; x < count; x++)
1115- {
1116- if (mask[x] == 0 )
1117- continue ;
1118-
1119- uint32_t srcv;
1120- // I.M. 2009-08-26 - color dodge works best blending from white -> black
1121- // rather than opaque -> transparent so retain the color alpha value
1122- srcv = (packed_scale_bounded (color, mask[x]) & 0x00FFFFFF ) | (color & 0xFF000000 );
1123- // srcv = packed_scale_bounded(color, mask[x]);
1124-
1125- uint32_t dstv;
1126- dstv = dst[x];
1127-
1128- uint8_t sr, sg, sb;
1129- sr = srcv & 0xff ;
1130- sg = (srcv >> 8 ) & 0xff ;
1131- sb = (srcv >> 16 ) & 0xff ;
1132-
1133- uint8_t dr, dg, db;
1134- dr = dstv & 0xff ;
1135- dg = (dstv >> 8 ) & 0xff ;
1136- db = (dstv >> 16 ) & 0xff ;
1137-
1138- uint8_t sa, da;
1139- sa = srcv >> 24 ;
1140- da = dstv >> 24 ;
1141-
1142- uint32_t r, g, b;
1143- uint32_t tr,tg,tb;
1144- r = (sa - sr) * da;
1145- tr = dr * sa;
1146- r = (r > tr) ? 255 * tr / r : (dr == 0 ? 0 : 255 );
1147- g = (sa - sg) * da;
1148- tg = dg * sa;
1149- g = (g > tg) ? 255 * tg / g : (dg == 0 ? 0 : 255 );
1150- b = (sa - sb) * da;
1151- tb = (db * sa);
1152- b = (b > tb) ? 255 * tb / b : (db == 0 ? 0 : 255 );
1153-
1154- uint32_t f;
1155- f = 0xff000000 | r | (g << 8 ) | (b << 16 );
1156-
1157- dst[x] =
1158- packed_scale_bounded (f, _scale_bounded (sa, da)) +
1159- packed_scale_bounded (srcv, 255 - da) +
1160- packed_scale_bounded (dstv, 255 - sa);
1161- }
1162- }
1163-
1164- // //////////////////////////////////////////////////////////////////////////////
1165-
1166- static void MCBitmapEffectAttenuateInner (uint8_t *mask, uint32_t *src, int32_t count)
1167- {
1168- for (int32_t x = 0 ; x < count; x++)
1169- mask[x] = _scale_bounded (mask[x], src[x] >> 24 );
1170- }
1171-
1172- static void MCBitmapEffectAttenuateInvertedInner (uint8_t *mask, uint32_t *src, int32_t count)
1173- {
1174- for (int32_t x = 0 ; x < count; x++)
1175- mask[x] = _scale_bounded (255 - mask[x], src[x] >> 24 );
1176- }
1177-
1178- static void MCBitmapEffectAttenuateOuter (uint8_t *mask, uint32_t *src, int32_t count)
1179- {
1180- for (int32_t x = 0 ; x < count; x++)
1181- mask[x] = _scale_bounded (mask[x], 255 - (src[x] >> 24 ));
1182- }
1183-
1184- // //////////////////////////////////////////////////////////////////////////////
1185-
1186- typedef void (*MCBitmapEffectAttenuateCallback)(uint8_t *mask, uint32_t *src, int32_t count);
1187- typedef void (*MCBitmapEffectCompositeCallback)(uint32_t *dst, uint32_t src, uint8_t *mask, int32_t count);
1188-
1189- struct MCBitmapEffectRenderState
1190- {
1191- // The region we are rendering
1192- MCRectangle region;
1193-
1194- // The source color
1195- uint32_t color;
1196-
1197- // The blur parameters (if needed)
1198- MCBitmapEffectFilter blur_filter;
1199- uint32_t blur_size;
1200- uint8_t blur_spread;
1201- MCRectangle blur_rect;
1202-
1203- // The mask attenuation callback (if needed)
1204- MCBitmapEffectAttenuateCallback attenuate;
1205- MCBitmapEffectCompositeCallback composite;
1206- };
1207-
1208- static MCBitmapEffectCompositeCallback MCBitmapEffectChooseCompositer (MCBitmapEffectBlendMode p_mode, bool p_has_dst_alpha)
1209- {
1210- switch (p_mode)
1211- {
1212- case kMCBitmapEffectBlendModeNormal :
1213- return MCBitmapEffectCompositeNormal;
1214-
1215- case kMCBitmapEffectBlendModeMultiply :
1216- return p_has_dst_alpha ? MCBitmapEffectCompositeMultiply : MCBitmapEffectCompositeMultiplyOpaque;
1217-
1218- case kMCBitmapEffectBlendModeColorDodge :
1219- return MCBitmapEffectCompositeColorDodge;
1220-
1221- default :
1222- break ;
1223- }
1224-
1225- return NULL ;
1226- }
1227-
1228- static void MCBitmapEffectRender (MCBitmapEffectRenderState& state, MCBitmapEffectLayer& dst, MCBitmapEffectLayer& src)
1229- {
1230- // Compute the dst ptr/stride in pixels.
1231- uint32_t t_dst_stride, *t_dst_pixels;
1232- t_dst_stride = dst . stride / 4 ;
1233- t_dst_pixels = (uint4 *)dst . bits + t_dst_stride * (state . region . y - dst . bounds . y) + (state . region . x - dst . bounds . x);
1234-
1235- // Compute the blur src ptr/stride in pixels.
1236- uint32_t t_blur_src_stride, *t_blur_src_pixels;
1237- t_blur_src_stride = src . stride / 4 ;
1238- t_blur_src_pixels = (uint4 *)src . bits + t_blur_src_stride * (state . blur_rect . y - src . bounds . y) + (state . blur_rect . x - src . bounds . x);
1239-
1240- // Compute the src ptr/stride in pixels.
1241- uint32_t t_src_stride, *t_src_pixels;
1242- t_src_stride = src . stride / 4 ;
1243- t_src_pixels = (uint4 *)src . bits + t_src_stride * (state . region . y - src . bounds . y) + (state . region . x - src . bounds . x);
1244-
1245- // Compute the pre-multiplied color.
1246- uint32_t t_color;
1247- t_color = packed_scale_bounded (state . color | 0xff000000 , state . color >> 24 );
1248-
1249- // Ensure the color format is correct for the target context (Android is 0xAABBGGRR rather than 0xAARRGGBB)
1250- #ifdef _ANDROID_MOBILE
1251- t_color = (t_color & 0xff00ff00 ) | ((t_color & 0x00ff0000 ) >> 16 ) | ((t_color & 0x000000ff ) << 16 );
1252- #endif
1253-
1254- // Allocate a run of mask pixels
1255- uint8_t *t_mask_pixels;
1256- t_mask_pixels = new (nothrow) uint8_t [dst . bounds . width];
1257-
1258- // Calculate the attenuation bounds
1259- int32_t t_left, t_top, t_right, t_bottom, t_count;
1260- t_left = MCU_max (state . region . x, src . bounds . x) - state . region . x;
1261- t_top = src . bounds . y - state . region . y;
1262- t_right = MCU_min (state . region . x + state . region . width, src . bounds . x + src . bounds . width) - state . region . x;
1263- t_bottom = src . bounds . y + src . bounds . height - state . region . y;
1264- t_count = MCU_max (t_right - t_left, 0 );
1265-
1266- // Initialize the blur
1267- MCBitmapEffectBlurRef t_blur;
1268- MCBitmapEffectBlurParameters t_blur_params;
1269- t_blur_params . radius = state . blur_size;
1270- t_blur_params . spread = state . blur_spread;
1271- t_blur_params . filter = state . blur_filter;
1272-
1273- if (MCBitmapEffectBlurBegin (t_blur_params, src . bounds, state . blur_rect, t_blur_src_pixels, t_blur_src_stride, t_blur))
1274- {
1275- for (int32_t y = 0 ; y < state . region . height; y++, t_dst_pixels += t_dst_stride, t_src_pixels += t_src_stride)
1276- {
1277- // Fetch the next line of blur
1278- MCBitmapEffectBlurContinue (t_blur, t_mask_pixels);
1279-
1280- // Attenuate the mask pixels appropriately.
1281- if (state . attenuate && y >= t_top && y < t_bottom)
1282- state . attenuate (t_mask_pixels + t_left, t_src_pixels + t_left, t_count);
1283-
1284- // Composite the src with dst
1285- state . composite (t_dst_pixels, t_color, t_mask_pixels, state . region . width);
1286- }
1287- MCBitmapEffectBlurEnd (t_blur);
1288- }
1289-
1290- delete[] t_mask_pixels;
1291- }
1292-
1293- static void MCShadowEffectRender (MCShadowEffect* self, bool p_inner, const MCRectangle& p_shape, MCBitmapEffectLayer& dst, MCBitmapEffectLayer& src)
1294- {
1295- // We fill in this structure and defer to the main rendering routine.
1296- MCBitmapEffectRenderState t_state;
1297-
1298- // Compute the displacement of the shadow from the shape
1299- int32_t t_delta_x, t_delta_y;
1300- t_delta_x = (int32_t )floor (0.5 + self -> distance * cos (self -> angle * M_PI / 180.0 ));
1301- t_delta_y = (int32_t )floor (0.5 + self -> distance * sin (self -> angle * M_PI / 180.0 ));
1302-
1303- if (p_inner)
1304- t_state . region = MCU_intersect_rect (dst . bounds, p_shape);
1305- else
1306- t_state . region = MCU_intersect_rect (dst . bounds, MCU_offset_rect (MCU_reduce_rect (p_shape, -(signed )self -> size), t_delta_x, t_delta_y));
1307-
1308- t_state . blur_filter = (MCBitmapEffectFilter)self -> filter;
1309- t_state . blur_size = self -> size;
1310- t_state . blur_spread = self -> spread;
1311- t_state . blur_rect = MCU_offset_rect (t_state . region, -t_delta_x, -t_delta_y);
1312-
1313- t_state . color = self -> color;
1314-
1315- if (p_inner)
1316- t_state . attenuate = MCBitmapEffectAttenuateInvertedInner;
1317- else if (self -> knockout)
1318- t_state . attenuate = MCBitmapEffectAttenuateOuter;
1319- else
1320- t_state . attenuate = NULL ;
1321-
1322- t_state . composite = MCBitmapEffectChooseCompositer ((MCBitmapEffectBlendMode)self -> blend_mode, dst . has_alpha);
1323-
1324- MCBitmapEffectRender (t_state, dst, src);
1325- }
1326-
1327- static void MCGlowEffectRender (MCGlowEffect* self, bool p_inner, const MCRectangle& p_shape, MCBitmapEffectLayer& p_dst, MCBitmapEffectLayer& p_src)
1328- {
1329- // We fill in this structure and defer to the main rendering routine.
1330- MCBitmapEffectRenderState t_state;
1331-
1332- // There is nothing to do if the glow radius is 0
1333- if (self -> size == 0 )
1334- return ;
1335-
1336- if (p_inner)
1337- t_state . region = MCU_intersect_rect (p_shape, p_dst . bounds);
1338- else
1339- t_state . region = MCU_intersect_rect (MCU_reduce_rect (p_shape, -(signed )self -> size), p_dst . bounds);
1340-
1341- t_state . blur_filter = (MCBitmapEffectFilter)self -> filter;
1342- t_state . blur_size = self -> size;
1343- t_state . blur_spread = self -> spread;
1344- t_state . blur_rect = t_state . region;
1345-
1346- t_state . color = self -> color;
1347-
1348- if (p_inner)
1349- {
1350- if (self -> source == kMCBitmapEffectSourceEdge )
1351- t_state . attenuate = MCBitmapEffectAttenuateInvertedInner;
1352- else
1353- t_state . attenuate = MCBitmapEffectAttenuateInner;
1354- }
1355- else
1356- t_state . attenuate = NULL ;// MCBitmapEffectAttenuateOuter;
1357-
1358- t_state . composite = MCBitmapEffectChooseCompositer ((MCBitmapEffectBlendMode)self -> blend_mode, p_dst . has_alpha);
1359-
1360- MCBitmapEffectRender (t_state, p_dst, p_src);
1361- }
1362-
1363- static void MCColorOverlayEffectRender (MCLayerEffect *self, const MCRectangle& p_shape, MCBitmapEffectLayer& p_dst, MCBitmapEffectLayer& p_src)
1364- {
1365- MCBitmapEffectRenderState t_state;
1366- t_state . region = MCU_intersect_rect (p_shape, p_dst . bounds);
1367- t_state . blur_filter = kMCBitmapEffectFilterOnePassBox ;
1368- t_state . blur_size = 0 ;
1369- t_state . blur_spread = 0 ;
1370- t_state . blur_rect = t_state . region;
1371- t_state . color = self -> color;
1372- t_state . attenuate = NULL ;
1373- t_state . composite = MCBitmapEffectChooseCompositer ((MCBitmapEffectBlendMode)self -> blend_mode, p_dst . has_alpha);
1374- MCBitmapEffectRender (t_state, p_dst, p_src);
1375- }
1376-
1377- extern void surface_combine_blendSrcOver (void *p_dst, int32_t p_dst_stride, const void *p_src, uint32_t p_src_stride, uint32_t p_width, uint32_t p_height, uint1 opacity);
1378- void MCFilterEffectRender (MCBitmapEffect* self, const MCRectangle& p_shape, MCBitmapEffectLayer& p_dst, MCBitmapEffectLayer& p_src)
1379- {
1380- // Compute the output region - the output rect is goverened by the shape
1381- // and what bits we have in the src and dst.
1382- MCRectangle t_region;
1383- t_region = MCU_intersect_rect (p_shape, p_dst . bounds);
1384-
1385- surface_combine_blendSrcOver (
1386- (char *)p_dst . bits + (t_region . y - p_dst . bounds . y) * p_dst . stride + (t_region . x - p_dst . bounds . x) * 4 , p_dst . stride,
1387- (char *)p_src . bits + (t_region . y - p_src . bounds . y) * p_src . stride + (t_region . x - p_src . bounds . x) * 4 , p_src . stride,
1388- t_region . width, t_region . height, 255 );
1389- }
1390-
1391- // The order of the layers we render are as follows:
1392- // 1) Drop Shadow
1393- // 2) Image
1394- // 3) Inner Shadow
1395- // 4) Inner/Outer Glows
1396- // 5) Color Overlay
1397- //
1398- // This method assumes that the dst and src are set up correctly. That is that
1399- // the 'dst' bounds represent the dirty area to be redrawn, and the 'src'
1400- // bounds are as least as big as that returned by ComputeClip for the given
1401- // 'dst' bounds.
1402- //
1403- void MCBitmapEffectsRender (MCBitmapEffectsRef self, const MCRectangle& shape, MCBitmapEffectLayer& dst, MCBitmapEffectLayer& src)
1404- {
1405- // Render the drop shadow
1406- if ((self -> mask & kMCBitmapEffectTypeDropShadowBit ) != 0 )
1407- MCShadowEffectRender (&self -> effects[kMCBitmapEffectTypeDropShadow ] . shadow, false , shape, dst, src);
1408-
1409- // Render the outer glow
1410- if ((self -> mask & kMCBitmapEffectTypeOuterGlowBit ) != 0 )
1411- MCGlowEffectRender (&self -> effects[kMCBitmapEffectTypeOuterGlow ] . glow, false , shape, dst, src);
1412-
1413- // Render the image
1414- MCFilterEffectRender (NULL , shape, dst, src);
1415-
1416- // Render the inner shadow
1417- if ((self -> mask & kMCBitmapEffectTypeInnerShadowBit ) != 0 )
1418- MCShadowEffectRender (&self -> effects[kMCBitmapEffectTypeInnerShadow ] . shadow, true , shape, dst, src);
1419-
1420- // Render the inner glow
1421- if ((self -> mask & kMCBitmapEffectTypeInnerGlowBit ) != 0 )
1422- MCGlowEffectRender (&self -> effects[kMCBitmapEffectTypeInnerGlow ] . glow, true , shape, dst, src);
1423-
1424- // Render the color overlay
1425- if ((self -> mask & kMCBitmapEffectTypeColorOverlayBit ) != 0 )
1426- MCColorOverlayEffectRender (&self -> effects[kMCBitmapEffectTypeColorOverlay ] . layer, shape, dst, src);
1427- }
1428- #endif
0 commit comments