@@ -63,7 +63,7 @@ typedef struct {
63
63
} Edge ;
64
64
65
65
/* Type used in "polygon*" functions */
66
- typedef void (* hline_handler )(Imaging , int , int , int , int );
66
+ typedef void (* hline_handler )(Imaging , int , int , int , int , Imaging );
67
67
68
68
static inline void
69
69
point8 (Imaging im , int x , int y , int ink ) {
@@ -103,7 +103,7 @@ point32rgba(Imaging im, int x, int y, int ink) {
103
103
}
104
104
105
105
static inline void
106
- hline8 (Imaging im , int x0 , int y0 , int x1 , int ink ) {
106
+ hline8 (Imaging im , int x0 , int y0 , int x1 , int ink , Imaging mask ) {
107
107
int pixelwidth ;
108
108
109
109
if (y0 >= 0 && y0 < im -> ysize ) {
@@ -119,15 +119,30 @@ hline8(Imaging im, int x0, int y0, int x1, int ink) {
119
119
}
120
120
if (x0 <= x1 ) {
121
121
pixelwidth = strncmp (im -> mode , "I;16" , 4 ) == 0 ? 2 : 1 ;
122
- memset (
123
- im -> image8 [y0 ] + x0 * pixelwidth , (UINT8 )ink , (x1 - x0 + 1 ) * pixelwidth
124
- );
122
+ if (mask == NULL ) {
123
+ memset (
124
+ im -> image8 [y0 ] + x0 * pixelwidth ,
125
+ (UINT8 )ink ,
126
+ (x1 - x0 + 1 ) * pixelwidth
127
+ );
128
+ } else {
129
+ UINT8 * p = im -> image8 [y0 ];
130
+ while (x0 <= x1 ) {
131
+ if (mask -> image8 [y0 ][x0 ]) {
132
+ p [x0 * pixelwidth ] = ink ;
133
+ if (pixelwidth == 2 ) {
134
+ p [x0 * pixelwidth + 1 ] = ink ;
135
+ }
136
+ }
137
+ x0 ++ ;
138
+ }
139
+ }
125
140
}
126
141
}
127
142
}
128
143
129
144
static inline void
130
- hline32 (Imaging im , int x0 , int y0 , int x1 , int ink ) {
145
+ hline32 (Imaging im , int x0 , int y0 , int x1 , int ink , Imaging mask ) {
131
146
INT32 * p ;
132
147
133
148
if (y0 >= 0 && y0 < im -> ysize ) {
@@ -143,13 +158,16 @@ hline32(Imaging im, int x0, int y0, int x1, int ink) {
143
158
}
144
159
p = im -> image32 [y0 ];
145
160
while (x0 <= x1 ) {
146
- p [x0 ++ ] = ink ;
161
+ if (mask == NULL || mask -> image8 [y0 ][x0 ]) {
162
+ p [x0 ] = ink ;
163
+ }
164
+ x0 ++ ;
147
165
}
148
166
}
149
167
}
150
168
151
169
static inline void
152
- hline32rgba (Imaging im , int x0 , int y0 , int x1 , int ink ) {
170
+ hline32rgba (Imaging im , int x0 , int y0 , int x1 , int ink , Imaging mask ) {
153
171
unsigned int tmp ;
154
172
155
173
if (y0 >= 0 && y0 < im -> ysize ) {
@@ -167,9 +185,11 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink) {
167
185
UINT8 * out = (UINT8 * )im -> image [y0 ] + x0 * 4 ;
168
186
UINT8 * in = (UINT8 * )& ink ;
169
187
while (x0 <= x1 ) {
170
- out [0 ] = BLEND (in [3 ], out [0 ], in [0 ], tmp );
171
- out [1 ] = BLEND (in [3 ], out [1 ], in [1 ], tmp );
172
- out [2 ] = BLEND (in [3 ], out [2 ], in [2 ], tmp );
188
+ if (mask == NULL || mask -> image8 [y0 ][x0 ]) {
189
+ out [0 ] = BLEND (in [3 ], out [0 ], in [0 ], tmp );
190
+ out [1 ] = BLEND (in [3 ], out [1 ], in [1 ], tmp );
191
+ out [2 ] = BLEND (in [3 ], out [2 ], in [2 ], tmp );
192
+ }
173
193
x0 ++ ;
174
194
out += 4 ;
175
195
}
@@ -407,7 +427,14 @@ x_cmp(const void *x0, const void *x1) {
407
427
408
428
static void
409
429
draw_horizontal_lines (
410
- Imaging im , int n , Edge * e , int ink , int * x_pos , int y , hline_handler hline
430
+ Imaging im ,
431
+ int n ,
432
+ Edge * e ,
433
+ int ink ,
434
+ int * x_pos ,
435
+ int y ,
436
+ hline_handler hline ,
437
+ Imaging mask
411
438
) {
412
439
int i ;
413
440
for (i = 0 ; i < n ; i ++ ) {
@@ -429,7 +456,7 @@ draw_horizontal_lines(
429
456
}
430
457
}
431
458
432
- (* hline )(im , xmin , e [i ].ymin , xmax , ink );
459
+ (* hline )(im , xmin , e [i ].ymin , xmax , ink , mask );
433
460
* x_pos = xmax + 1 ;
434
461
}
435
462
}
@@ -439,7 +466,9 @@ draw_horizontal_lines(
439
466
* Filled polygon draw function using scan line algorithm.
440
467
*/
441
468
static inline int
442
- polygon_generic (Imaging im , int n , Edge * e , int ink , int eofill , hline_handler hline ) {
469
+ polygon_generic (
470
+ Imaging im , int n , Edge * e , int ink , int eofill , hline_handler hline , Imaging mask
471
+ ) {
443
472
Edge * * edge_table ;
444
473
float * xx ;
445
474
int edge_count = 0 ;
@@ -469,7 +498,7 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler h
469
498
}
470
499
if (e [i ].ymin == e [i ].ymax ) {
471
500
if (hasAlpha != 1 ) {
472
- (* hline )(im , e [i ].xmin , e [i ].ymin , e [i ].xmax , ink );
501
+ (* hline )(im , e [i ].xmin , e [i ].ymin , e [i ].xmax , ink , mask );
473
502
}
474
503
continue ;
475
504
}
@@ -557,7 +586,7 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler h
557
586
// Line would be before the current position
558
587
continue ;
559
588
}
560
- draw_horizontal_lines (im , n , e , ink , & x_pos , ymin , hline );
589
+ draw_horizontal_lines (im , n , e , ink , & x_pos , ymin , hline , mask );
561
590
if (x_end < x_pos ) {
562
591
// Line would be before the current position
563
592
continue ;
@@ -573,13 +602,13 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler h
573
602
continue ;
574
603
}
575
604
}
576
- (* hline )(im , x_start , ymin , x_end , ink );
605
+ (* hline )(im , x_start , ymin , x_end , ink , mask );
577
606
x_pos = x_end + 1 ;
578
607
}
579
- draw_horizontal_lines (im , n , e , ink , & x_pos , ymin , hline );
608
+ draw_horizontal_lines (im , n , e , ink , & x_pos , ymin , hline , mask );
580
609
} else {
581
610
for (i = 1 ; i < j ; i += 2 ) {
582
- (* hline )(im , ROUND_UP (xx [i - 1 ]), ymin , ROUND_DOWN (xx [i ]), ink );
611
+ (* hline )(im , ROUND_UP (xx [i - 1 ]), ymin , ROUND_DOWN (xx [i ]), ink , mask );
583
612
}
584
613
}
585
614
}
@@ -623,7 +652,7 @@ add_edge(Edge *e, int x0, int y0, int x1, int y1) {
623
652
624
653
typedef struct {
625
654
void (* point )(Imaging im , int x , int y , int ink );
626
- void (* hline )(Imaging im , int x0 , int y0 , int x1 , int ink );
655
+ void (* hline )(Imaging im , int x0 , int y0 , int x1 , int ink , Imaging mask );
627
656
void (* line )(Imaging im , int x0 , int y0 , int x1 , int y1 , int ink );
628
657
} DRAW ;
629
658
@@ -674,7 +703,15 @@ ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink_, in
674
703
675
704
int
676
705
ImagingDrawWideLine (
677
- Imaging im , int x0 , int y0 , int x1 , int y1 , const void * ink_ , int width , int op
706
+ Imaging im ,
707
+ int x0 ,
708
+ int y0 ,
709
+ int x1 ,
710
+ int y1 ,
711
+ const void * ink_ ,
712
+ int width ,
713
+ int op ,
714
+ Imaging mask
678
715
) {
679
716
DRAW * draw ;
680
717
INT32 ink ;
@@ -714,7 +751,7 @@ ImagingDrawWideLine(
714
751
add_edge (e + 2 , vertices [2 ][0 ], vertices [2 ][1 ], vertices [3 ][0 ], vertices [3 ][1 ]);
715
752
add_edge (e + 3 , vertices [3 ][0 ], vertices [3 ][1 ], vertices [0 ][0 ], vertices [0 ][1 ]);
716
753
717
- polygon_generic (im , 4 , e , ink , 0 , draw -> hline );
754
+ polygon_generic (im , 4 , e , ink , 0 , draw -> hline , mask );
718
755
}
719
756
return 0 ;
720
757
}
@@ -757,7 +794,7 @@ ImagingDrawRectangle(
757
794
}
758
795
759
796
for (y = y0 ; y <= y1 ; y ++ ) {
760
- draw -> hline (im , x0 , y , x1 , ink );
797
+ draw -> hline (im , x0 , y , x1 , ink , NULL );
761
798
}
762
799
763
800
} else {
@@ -766,8 +803,8 @@ ImagingDrawRectangle(
766
803
width = 1 ;
767
804
}
768
805
for (i = 0 ; i < width ; i ++ ) {
769
- draw -> hline (im , x0 , y0 + i , x1 , ink );
770
- draw -> hline (im , x0 , y1 - i , x1 , ink );
806
+ draw -> hline (im , x0 , y0 + i , x1 , ink , NULL );
807
+ draw -> hline (im , x0 , y1 - i , x1 , ink , NULL );
771
808
draw -> line (im , x1 - i , y0 + width , x1 - i , y1 - width + 1 , ink );
772
809
draw -> line (im , x0 + i , y0 + width , x0 + i , y1 - width + 1 , ink );
773
810
}
@@ -778,7 +815,14 @@ ImagingDrawRectangle(
778
815
779
816
int
780
817
ImagingDrawPolygon (
781
- Imaging im , int count , int * xy , const void * ink_ , int fill , int width , int op
818
+ Imaging im ,
819
+ int count ,
820
+ int * xy ,
821
+ const void * ink_ ,
822
+ int fill ,
823
+ int width ,
824
+ int op ,
825
+ Imaging mask
782
826
) {
783
827
int i , n , x0 , y0 , x1 , y1 ;
784
828
DRAW * draw ;
@@ -822,7 +866,7 @@ ImagingDrawPolygon(
822
866
if (xy [i * 2 ] != xy [0 ] || xy [i * 2 + 1 ] != xy [1 ]) {
823
867
add_edge (& e [n ++ ], xy [i * 2 ], xy [i * 2 + 1 ], xy [0 ], xy [1 ]);
824
868
}
825
- polygon_generic (im , n , e , ink , 0 , draw -> hline );
869
+ polygon_generic (im , n , e , ink , 0 , draw -> hline , mask );
826
870
free (e );
827
871
828
872
} else {
@@ -844,11 +888,12 @@ ImagingDrawPolygon(
844
888
xy [i * 2 + 3 ],
845
889
ink_ ,
846
890
width ,
847
- op
891
+ op ,
892
+ mask
848
893
);
849
894
}
850
895
ImagingDrawWideLine (
851
- im , xy [i * 2 ], xy [i * 2 + 1 ], xy [0 ], xy [1 ], ink_ , width , op
896
+ im , xy [i * 2 ], xy [i * 2 + 1 ], xy [0 ], xy [1 ], ink_ , width , op , mask
852
897
);
853
898
}
854
899
}
@@ -1519,7 +1564,9 @@ ellipseNew(
1519
1564
ellipse_init (& st , a , b , width );
1520
1565
int32_t X0 , Y , X1 ;
1521
1566
while (ellipse_next (& st , & X0 , & Y , & X1 ) != -1 ) {
1522
- draw -> hline (im , x0 + (X0 + a ) / 2 , y0 + (Y + b ) / 2 , x0 + (X1 + a ) / 2 , ink );
1567
+ draw -> hline (
1568
+ im , x0 + (X0 + a ) / 2 , y0 + (Y + b ) / 2 , x0 + (X1 + a ) / 2 , ink , NULL
1569
+ );
1523
1570
}
1524
1571
return 0 ;
1525
1572
}
@@ -1554,7 +1601,9 @@ clipEllipseNew(
1554
1601
int32_t X0 , Y , X1 ;
1555
1602
int next_code ;
1556
1603
while ((next_code = clip_ellipse_next (& st , & X0 , & Y , & X1 )) >= 0 ) {
1557
- draw -> hline (im , x0 + (X0 + a ) / 2 , y0 + (Y + b ) / 2 , x0 + (X1 + a ) / 2 , ink );
1604
+ draw -> hline (
1605
+ im , x0 + (X0 + a ) / 2 , y0 + (Y + b ) / 2 , x0 + (X1 + a ) / 2 , ink , NULL
1606
+ );
1558
1607
}
1559
1608
clip_ellipse_free (& st );
1560
1609
return next_code == -1 ? 0 : -1 ;
@@ -1972,7 +2021,7 @@ ImagingDrawOutline(
1972
2021
1973
2022
DRAWINIT ();
1974
2023
1975
- polygon_generic (im , outline -> count , outline -> edges , ink , 0 , draw -> hline );
2024
+ polygon_generic (im , outline -> count , outline -> edges , ink , 0 , draw -> hline , NULL );
1976
2025
1977
2026
return 0 ;
1978
2027
}
0 commit comments