@@ -92,13 +92,23 @@ point32(Imaging im, int x, int y, int ink) {
9292static inline void
9393point32rgba (Imaging im , int x , int y , int ink ) {
9494 unsigned int tmp ;
95+ UINT8 * in = (UINT8 * )& ink ;
96+ int a = in [3 ];
97+ if (a == 0 ) { // Transparent ink. Nothing to paint.
98+ return ;
99+ }
95100
96101 if (x >= 0 && x < im -> xsize && y >= 0 && y < im -> ysize ) {
97102 UINT8 * out = (UINT8 * )im -> image [y ] + x * 4 ;
98- UINT8 * in = (UINT8 * )& ink ;
99- out [0 ] = BLEND (in [3 ], out [0 ], in [0 ], tmp );
100- out [1 ] = BLEND (in [3 ], out [1 ], in [1 ], tmp );
101- out [2 ] = BLEND (in [3 ], out [2 ], in [2 ], tmp );
103+ if (a == 255 ) { // Solid ink, no need to blend.
104+ out [0 ] = in [0 ];
105+ out [1 ] = in [1 ];
106+ out [2 ] = in [2 ];
107+ } else {
108+ out [0 ] = BLEND (in [3 ], out [0 ], in [0 ], tmp );
109+ out [1 ] = BLEND (in [3 ], out [1 ], in [1 ], tmp );
110+ out [2 ] = BLEND (in [3 ], out [2 ], in [2 ], tmp );
111+ }
102112 }
103113}
104114
@@ -188,32 +198,52 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
188198 UINT8 b = ((UINT8 * )& ink )[2 ];
189199 UINT8 a = ((UINT8 * )& ink )[3 ];
190200
191- if (y0 >= 0 && y0 < im -> ysize ) {
192- if (x0 < 0 ) {
193- x0 = 0 ;
194- } else if (x0 >= im -> xsize ) {
195- return ;
196- }
197- if (x1 < 0 ) {
198- return ;
199- } else if (x1 >= im -> xsize ) {
200- x1 = im -> xsize - 1 ;
201- }
202- if (x0 > x1 ) {
203- return ;
204- }
201+ if (a == 0 ) { // Transparent ink. Nothing to paint.
202+ return ;
203+ }
205204
206- UINT8 * restrict out = (UINT8 * )im -> image [y0 ] + x0 * 4 ;
207- if (mask == NULL ) {
205+ int xsize = im -> xsize , ysize = im -> ysize ;
206+ if (y0 < 0 || y0 >= ysize || x0 >= xsize || x1 < 0 ) {
207+ // Painting outside the canvas.
208+ return ;
209+ }
210+
211+ x0 = x0 < 0 ? 0 : x0 ;
212+ x1 = x1 >= xsize ? xsize - 1 : x1 ;
213+
214+ UINT8 * restrict out = (UINT8 * )im -> image [y0 ] + x0 * 4 ;
215+
216+ if (mask == NULL ) {
217+ if (a == 255 ) { // Solid ink, no need to blend.
218+ for (; x0 <= x1 ; x0 ++ , out += 4 ) {
219+ out [0 ] = r ;
220+ out [1 ] = g ;
221+ out [2 ] = b ;
222+ // No-op, but allows the compiler to vectorize the loop:
223+ out [3 ] = BLEND (255 , out [3 ], out [3 ], tmp );
224+ }
225+ } else {
208226 for (; x0 <= x1 ; x0 ++ , out += 4 ) {
209227 out [0 ] = BLEND (a , out [0 ], r , tmp );
210228 out [1 ] = BLEND (a , out [1 ], g , tmp );
211229 out [2 ] = BLEND (a , out [2 ], b , tmp );
212230 // No-op, but allows the compiler to vectorize the loop:
213231 out [3 ] = BLEND (a , out [3 ], out [3 ], tmp );
214232 }
233+ }
234+ } else {
235+ UINT8 * mask_row = mask -> image8 [y0 ];
236+ if (a == 255 ) { // Solid paint, no need to blend.
237+ for (; x0 <= x1 ; x0 ++ , out += 4 ) {
238+ if (mask_row [x0 ]) {
239+ out [0 ] = r ;
240+ out [1 ] = g ;
241+ out [2 ] = b ;
242+ // Not touching out[3] here, since the mask check prevents
243+ // vectorization anyway.
244+ }
245+ }
215246 } else {
216- UINT8 * mask_row = mask -> image8 [y0 ];
217247 for (; x0 <= x1 ; x0 ++ , out += 4 ) {
218248 if (mask_row [x0 ]) {
219249 out [0 ] = BLEND (a , out [0 ], r , tmp );
@@ -377,6 +407,11 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) {
377407 int dx , dy ;
378408 int xs , ys ;
379409
410+ UINT8 a = ((UINT8 * )& ink )[3 ];
411+ if (a == 0 ) { // Transparent ink. Nothing to paint.
412+ return ;
413+ }
414+
380415 /* normalize coordinates */
381416 dx = x1 - x0 ;
382417 if (dx < 0 ) {
0 commit comments