@@ -68,6 +68,18 @@ static inline uint32_t INTERPOLATE_PIXEL_255(uint32_t x, uint32_t a, uint32_t y,
6868 return x ;
6969}
7070
71+ static inline uint32_t INTERPOLATE_PIXEL_256 (uint32_t x , uint32_t a , uint32_t y , uint32_t b )
72+ {
73+ uint32_t t = (x & 0xff00ff ) * a + (y & 0xff00ff ) * b ;
74+ t >>= 8 ;
75+ t &= 0xff00ff ;
76+
77+ x = ((x >> 8 ) & 0xff00ff ) * a + ((y >> 8 ) & 0xff00ff ) * b ;
78+ x &= 0xff00ff00 ;
79+ x |= t ;
80+ return x ;
81+ }
82+
7183static inline uint32_t BYTE_MUL (uint32_t x , uint32_t a )
7284{
7385 uint32_t t = (x & 0xff00ff ) * a ;
@@ -854,14 +866,23 @@ static void blend_untransformed_tiled_argb(plutovg_surface_t* surface, plutovg_o
854866 }
855867}
856868
869+ static inline uint32_t interpolate_4_pixels (uint32_t tl , uint32_t tr , uint32_t bl , uint32_t br , uint32_t distx , uint32_t disty )
870+ {
871+ uint32_t idistx = 256 - distx ;
872+ uint32_t idisty = 256 - disty ;
873+ uint32_t xtop = INTERPOLATE_PIXEL_256 (tl , idistx , tr , distx );
874+ uint32_t xbot = INTERPOLATE_PIXEL_256 (bl , idistx , br , distx );
875+ return INTERPOLATE_PIXEL_256 (xtop , idisty , xbot , disty );
876+ }
877+
878+ #define HALF_POINT (1 << 15)
857879static void blend_transformed_tiled_argb (plutovg_surface_t * surface , plutovg_operator_t op , const texture_data_t * texture , const plutovg_span_buffer_t * span_buffer )
858880{
859881 composition_function_t func = composition_table [op ];
860882 uint32_t buffer [BUFFER_SIZE ];
861883
862884 int image_width = texture -> width ;
863885 int image_height = texture -> height ;
864- const int scanline_offset = texture -> stride / 4 ;
865886
866887 int fdx = (int )(texture -> matrix .a * FIXED_SCALE );
867888 int fdy = (int )(texture -> matrix .b * FIXED_SCALE );
@@ -870,35 +891,46 @@ static void blend_transformed_tiled_argb(plutovg_surface_t* surface, plutovg_ope
870891 const plutovg_span_t * spans = span_buffer -> spans .data ;
871892 while (count -- ) {
872893 uint32_t * target = (uint32_t * )(surface -> data + spans -> y * surface -> stride ) + spans -> x ;
873- const uint32_t * image_bits = (const uint32_t * )texture -> data ;
874894
875895 const float cx = spans -> x + 0.5f ;
876896 const float cy = spans -> y + 0.5f ;
877897
878- int x = (int )((texture -> matrix .c * cy + texture -> matrix .a * cx + texture -> matrix .e ) * FIXED_SCALE );
879- int y = (int )((texture -> matrix .d * cy + texture -> matrix .b * cx + texture -> matrix .f ) * FIXED_SCALE );
898+ int fx = (int )((texture -> matrix .c * cy + texture -> matrix .a * cx + texture -> matrix .e ) * FIXED_SCALE );
899+ int fy = (int )((texture -> matrix .d * cy + texture -> matrix .b * cx + texture -> matrix .f ) * FIXED_SCALE );
900+
901+ fx -= HALF_POINT ;
902+ fy -= HALF_POINT ;
880903
881904 const int coverage = (spans -> coverage * texture -> const_alpha ) >> 8 ;
882905 int length = spans -> len ;
883906 while (length ) {
884907 int l = plutovg_min (length , BUFFER_SIZE );
885908 const uint32_t * end = buffer + l ;
886909 uint32_t * b = buffer ;
887- while (b < end ) {
888- int px = x >> 16 ;
889- int py = y >> 16 ;
890- px %= image_width ;
891- py %= image_height ;
892- if (px < 0 ) px += image_width ;
893- if (py < 0 ) py += image_height ;
894- int y_offset = py * scanline_offset ;
910+ while (b < end ) {
911+ int x1 = (fx >> 16 ) % image_width ;
912+ int y1 = (fy >> 16 ) % image_height ;
895913
896- assert ( px >= 0 && px < image_width ) ;
897- assert ( py >= 0 && py < image_height ) ;
914+ if ( x1 < 0 ) x1 += image_width ;
915+ if ( y1 < 0 ) y1 += image_height ;
898916
899- * b = image_bits [y_offset + px ];
900- x += fdx ;
901- y += fdy ;
917+ int x2 = (x1 + 1 ) % image_width ;
918+ int y2 = (y1 + 1 ) % image_height ;
919+
920+ const uint32_t * s1 = (const uint32_t * )(texture -> data + y1 * texture -> stride );
921+ const uint32_t * s2 = (const uint32_t * )(texture -> data + y2 * texture -> stride );
922+
923+ uint32_t tl = s1 [x1 ];
924+ uint32_t tr = s1 [x2 ];
925+ uint32_t bl = s2 [x1 ];
926+ uint32_t br = s2 [x2 ];
927+
928+ int distx = (fx & 0x0000ffff ) >> 8 ;
929+ int disty = (fy & 0x0000ffff ) >> 8 ;
930+ * b = interpolate_4_pixels (tl , tr , bl , br , distx , disty );
931+
932+ fx += fdx ;
933+ fy += fdy ;
902934 ++ b ;
903935 }
904936
0 commit comments