1/*
2 * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#if !defined(JAVA2D_NO_MLIB) || defined(MLIB_ADD_SUFF)
27
28#include <vis_AlphaMacros.h>
29
30/***************************************************************/
31
32/* ##############################################################
33 * IntArgbSrcOverMaskFill()
34 * FourByteAbgrSrcOverMaskFill()
35 */
36
37#define MASK_FILL(rr, pathA, dstA, dstARGB)    \
38{                                              \
39    mlib_d64 t0, t1;                           \
40    mlib_s32 alp0;                             \
41                                               \
42    alp0 = mul8_cnstA[pathA];                  \
43    dstA = MUL8_INT(dstA, 0xff - alp0);        \
44                                               \
45    t0 = MUL8_VIS(cnstARGB0, pathA);           \
46    t1 = MUL8_VIS(dstARGB, dstA);              \
47    rr = vis_fpadd16(t0, t1);                  \
48                                               \
49    dstA = dstA + alp0;                        \
50    DIV_ALPHA(rr, dstA);                       \
51}
52
53/***************************************************************/
54
55static void IntArgbSrcOverMaskFill_line(mlib_f32 *dst_ptr,
56                                        mlib_u8  *pMask,
57                                        mlib_s32 width,
58                                        mlib_f32 cnstARGB0,
59                                        mlib_u8  *mul8_cnstA,
60                                        mlib_u8  *mul8_tbl)
61{
62    mlib_s32 i, i0;
63    mlib_s32 pathA0, pathA1, dstA0, dstA1, msk;
64    mlib_d64 res0, res1, dstARGB;
65    mlib_f32 dstARGB0;
66
67    i = i0 = 0;
68
69    if ((mlib_s32)dst_ptr & 7) {
70        pathA0 = pMask[i];
71
72        if (pathA0) {
73            dstA0 = *(mlib_u8*)(dst_ptr + i);
74            dstARGB0 = dst_ptr[i];
75            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
76            dst_ptr[i] = vis_fpack16(res0);
77            *(mlib_u8*)(dst_ptr + i) = dstA0;
78        }
79
80        i0 = 1;
81    }
82
83#pragma pipeloop(0)
84    for (i = i0; i <= width - 2; i += 2) {
85        pathA0 = pMask[i];
86        pathA1 = pMask[i + 1];
87        dstA0 = *(mlib_u8*)(dst_ptr + i);
88        dstA1 = *(mlib_u8*)(dst_ptr + i + 1);
89        dstARGB = *(mlib_d64*)(dst_ptr + i);
90
91        MASK_FILL(res0, pathA0, dstA0, vis_read_hi(dstARGB));
92        MASK_FILL(res1, pathA1, dstA1, vis_read_lo(dstARGB));
93
94        res0 = vis_fpack16_pair(res0, res1);
95
96        msk = (((-pathA0) & (1 << 11)) | ((-pathA1) & (1 << 10))) >> 10;
97        vis_pst_32(res0, dst_ptr + i, msk);
98
99        *(mlib_u8*)(dst_ptr + i    ) = dstA0;
100        *(mlib_u8*)(dst_ptr + i + 1) = dstA1;
101    }
102
103    if (i < width) {
104        pathA0 = pMask[i];
105
106        if (pathA0) {
107            dstA0 = *(mlib_u8*)(dst_ptr + i);
108            dstARGB0 = dst_ptr[i];
109            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
110            dst_ptr[i] = vis_fpack16(res0);
111            *(mlib_u8*)(dst_ptr + i) = dstA0;
112        }
113    }
114}
115
116/***************************************************************/
117
118#undef  MASK_FILL
119#define MASK_FILL(rr, pathA, dstA, dstARGB)    \
120{                                              \
121    dstA = mul8_cnstA[dstA];                   \
122                                               \
123    rr = MUL8_VIS(dstARGB, dstA);              \
124    rr = vis_fpadd16(rr, cnstARGB);            \
125                                               \
126    dstA = dstA + cnstA;                       \
127    DIV_ALPHA(rr, dstA);                       \
128}
129
130/***************************************************************/
131
132static void IntArgbSrcOverMaskFill_A1_line(mlib_f32 *dst_ptr,
133                                           mlib_u8  *pMask,
134                                           mlib_s32 width,
135                                           mlib_d64 cnstARGB,
136                                           mlib_s32 cnstA,
137                                           mlib_u8  *mul8_cnstA,
138                                           mlib_u8  *mul8_tbl)
139{
140    mlib_s32 i, i0;
141    mlib_s32 dstA0, dstA1;
142    mlib_d64 res0, res1, dstARGB;
143    mlib_f32 dstARGB0;
144
145    i = i0 = 0;
146
147    if ((mlib_s32)dst_ptr & 7) {
148        {
149            dstA0 = *(mlib_u8*)(dst_ptr + i);
150            dstARGB0 = dst_ptr[i];
151            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
152            dst_ptr[i] = vis_fpack16(res0);
153            *(mlib_u8*)(dst_ptr + i) = dstA0;
154        }
155
156        i0 = 1;
157    }
158
159#pragma pipeloop(0)
160    for (i = i0; i <= width - 2; i += 2) {
161        dstA0 = *(mlib_u8*)(dst_ptr + i);
162        dstA1 = *(mlib_u8*)(dst_ptr + i + 1);
163        dstARGB = *(mlib_d64*)(dst_ptr + i);
164
165        MASK_FILL(res0, pathA0, dstA0, vis_read_hi(dstARGB));
166        MASK_FILL(res1, pathA1, dstA1, vis_read_lo(dstARGB));
167
168        res0 = vis_fpack16_pair(res0, res1);
169
170        *(mlib_d64*)(dst_ptr + i) = res0;
171
172        *(mlib_u8*)(dst_ptr + i    ) = dstA0;
173        *(mlib_u8*)(dst_ptr + i + 1) = dstA1;
174    }
175
176    if (i < width) {
177        {
178            dstA0 = *(mlib_u8*)(dst_ptr + i);
179            dstARGB0 = dst_ptr[i];
180            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
181            dst_ptr[i] = vis_fpack16(res0);
182            *(mlib_u8*)(dst_ptr + i) = dstA0;
183        }
184    }
185}
186
187/***************************************************************/
188
189void ADD_SUFF(IntArgbSrcOverMaskFill)(void *rasBase,
190                                      jubyte *pMask,
191                                      jint maskOff,
192                                      jint maskScan,
193                                      jint width,
194                                      jint height,
195                                      jint fgColor,
196                                      SurfaceDataRasInfo *pRasInfo,
197                                      NativePrimitive *pPrim,
198                                      CompositeInfo *pCompInfo)
199{
200    mlib_s32 cnstA, cnstR, cnstG, cnstB;
201    mlib_s32 rasScan = pRasInfo->scanStride;
202    mlib_f32 cnstARGB0;
203    mlib_d64 cnstARGB;
204    mlib_u8  *mul8_cnstA;
205    mlib_s32 j;
206
207    cnstA = (fgColor >> 24) & 0xff;
208    cnstR = (fgColor >> 16) & 0xff;
209    cnstG = (fgColor >>  8) & 0xff;
210    cnstB = (fgColor      ) & 0xff;
211
212    if (cnstA != 0xff) {
213        if (cnstA == 0) return;
214
215        cnstR = mul8table[cnstA][cnstR];
216        cnstG = mul8table[cnstA][cnstG];
217        cnstB = mul8table[cnstA][cnstB];
218    }
219
220    vis_write_gsr(7 << 3);
221
222    if (pMask != NULL) {
223        pMask += maskOff;
224
225        if (rasScan == 4*width && maskScan == width) {
226            width *= height;
227            height = 1;
228        }
229
230        mul8_cnstA = mul8table[cnstA];
231
232        cnstARGB0 = F32_FROM_U8x4(cnstA, cnstR, cnstG, cnstB);
233
234        for (j = 0; j < height; j++) {
235            IntArgbSrcOverMaskFill_line(rasBase, pMask, width, cnstARGB0,
236                                        mul8_cnstA, (void*)mul8table);
237
238            PTR_ADD(rasBase, rasScan);
239            PTR_ADD(pMask, maskScan);
240        }
241    } else {
242        if (rasScan == 4*width) {
243            width *= height;
244            height = 1;
245        }
246
247        mul8_cnstA = mul8table[255 - cnstA];
248
249        cnstARGB = vis_to_double((cnstA << 23) | (cnstR << 7),
250                                 (cnstG << 23) | (cnstB << 7));
251
252        for (j = 0; j < height; j++) {
253            IntArgbSrcOverMaskFill_A1_line(rasBase, pMask, width, cnstARGB,
254                                           cnstA,mul8_cnstA, (void*)mul8table);
255
256            PTR_ADD(rasBase, rasScan);
257        }
258    }
259}
260
261/***************************************************************/
262
263void ADD_SUFF(FourByteAbgrSrcOverMaskFill)(void *rasBase,
264                                           jubyte *pMask,
265                                           jint maskOff,
266                                           jint maskScan,
267                                           jint width,
268                                           jint height,
269                                           jint fgColor,
270                                           SurfaceDataRasInfo *pRasInfo,
271                                           NativePrimitive *pPrim,
272                                           CompositeInfo *pCompInfo)
273{
274    mlib_d64 buff[BUFF_SIZE/2];
275    void     *pbuff = buff;
276    mlib_s32 cnstA, cnstR, cnstG, cnstB;
277    mlib_s32 rasScan = pRasInfo->scanStride;
278    mlib_f32 cnstARGB0;
279    mlib_d64 cnstARGB;
280    mlib_u8  *mul8_cnstA;
281    mlib_s32 j;
282
283    cnstA = (mlib_u32)fgColor >> 24;
284    cnstR = (fgColor >> 16) & 0xff;
285    cnstG = (fgColor >>  8) & 0xff;
286    cnstB = (fgColor      ) & 0xff;
287
288    if (cnstA != 0xff) {
289        if (cnstA == 0) return;
290
291        cnstR = mul8table[cnstA][cnstR];
292        cnstG = mul8table[cnstA][cnstG];
293        cnstB = mul8table[cnstA][cnstB];
294    }
295
296    vis_write_gsr(7 << 3);
297
298    if (pMask != NULL) {
299        pMask += maskOff;
300
301        if (((mlib_s32)rasBase | rasScan) & 3) {
302            if (width > BUFF_SIZE) pbuff = mlib_malloc(width*sizeof(mlib_s32));
303        } else {
304            if (rasScan == 4*width && maskScan == width) {
305                width *= height;
306                height = 1;
307            }
308        }
309
310        mul8_cnstA = mul8table[cnstA];
311
312        cnstARGB0 = F32_FROM_U8x4(cnstA, cnstB, cnstG, cnstR);
313
314        for (j = 0; j < height; j++) {
315            if (!((mlib_s32)rasBase & 3)) {
316                IntArgbSrcOverMaskFill_line(rasBase, pMask, width, cnstARGB0,
317                                            mul8_cnstA, (void*)mul8table);
318            } else {
319                mlib_ImageCopy_na(rasBase, pbuff, width*sizeof(mlib_s32));
320                IntArgbSrcOverMaskFill_line(pbuff, pMask, width, cnstARGB0,
321                                            mul8_cnstA, (void*)mul8table);
322                mlib_ImageCopy_na(pbuff, rasBase, width*sizeof(mlib_s32));
323            }
324
325            PTR_ADD(rasBase, rasScan);
326            PTR_ADD(pMask, maskScan);
327        }
328    } else {
329        if (((mlib_s32)rasBase | rasScan) & 3) {
330            if (width > BUFF_SIZE) pbuff = mlib_malloc(width*sizeof(mlib_s32));
331        } else {
332            if (rasScan == 4*width) {
333                width *= height;
334                height = 1;
335            }
336        }
337
338        mul8_cnstA = mul8table[255 - cnstA];
339
340        cnstARGB = vis_to_double((cnstA << 23) | (cnstB << 7),
341                                 (cnstG << 23) | (cnstR << 7));
342
343        for (j = 0; j < height; j++) {
344            if (!((mlib_s32)rasBase & 3)) {
345                IntArgbSrcOverMaskFill_A1_line(rasBase, pMask, width, cnstARGB,
346                                               cnstA, mul8_cnstA,
347                                               (void*)mul8table);
348            } else {
349                mlib_ImageCopy_na(rasBase, pbuff, width*sizeof(mlib_s32));
350                IntArgbSrcOverMaskFill_A1_line(pbuff, pMask, width, cnstARGB,
351                                               cnstA, mul8_cnstA,
352                                               (void*)mul8table);
353                mlib_ImageCopy_na(pbuff, rasBase, width*sizeof(mlib_s32));
354            }
355
356            PTR_ADD(rasBase, rasScan);
357        }
358    }
359
360    if (pbuff != buff) {
361        mlib_free(pbuff);
362    }
363}
364
365/***************************************************************/
366
367/* ##############################################################
368 * IntRgbSrcOverMaskFill()
369 * IntBgrSrcOverMaskFill()
370 */
371
372#undef  MASK_FILL
373#define MASK_FILL(rr, pathA, dstA, dstARGB)    \
374{                                              \
375    mlib_d64 t0, t1;                           \
376    mlib_s32 srcA;                             \
377                                               \
378    srcA = mul8_cnstA[pathA];                  \
379    dstA  = 0xff - srcA;                       \
380                                               \
381    t0 = MUL8_VIS(cnstARGB0, pathA);           \
382    t1 = MUL8_VIS(dstARGB, dstA);              \
383    rr = vis_fpadd16(t0, t1);                  \
384    rr = vis_fand(rr, maskRGB);                \
385}
386
387/***************************************************************/
388
389static void IntRgbSrcOverMaskFill_line(mlib_f32 *dst_ptr,
390                                       mlib_u8  *pMask,
391                                       mlib_s32 width,
392                                       mlib_f32 cnstARGB0,
393                                       mlib_u8  *mul8_cnstA,
394                                       mlib_u8  *mul8_tbl)
395{
396    mlib_s32 i, i0;
397    mlib_s32 pathA0, pathA1, dstA0, dstA1, msk;
398    mlib_d64 res0, res1, dstARGB;
399    mlib_f32 dstARGB0;
400    /*mlib_d64 maskRGB = vis_to_double_dup(0x00FFFFFF);*/
401    mlib_d64 maskRGB = vis_to_double(0x0000FFFF, 0xFFFFFFFF);
402
403    i = i0 = 0;
404
405    if ((mlib_s32)dst_ptr & 7) {
406        pathA0 = pMask[i];
407
408        if (pathA0) {
409            dstARGB0 = dst_ptr[i];
410            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
411            dst_ptr[i] = vis_fpack16(res0);
412        }
413
414        i0 = 1;
415    }
416
417#pragma pipeloop(0)
418    for (i = i0; i <= width - 2; i += 2) {
419        pathA0 = pMask[i];
420        pathA1 = pMask[i + 1];
421        dstARGB = *(mlib_d64*)(dst_ptr + i);
422
423        MASK_FILL(res0, pathA0, dstA0, vis_read_hi(dstARGB));
424        MASK_FILL(res1, pathA1, dstA1, vis_read_lo(dstARGB));
425
426        res0 = vis_fpack16_pair(res0, res1);
427
428        msk = (((-pathA0) & (1 << 11)) | ((-pathA1) & (1 << 10))) >> 10;
429        vis_pst_32(res0, dst_ptr + i, msk);
430    }
431
432    if (i < width) {
433        pathA0 = pMask[i];
434
435        if (pathA0) {
436            dstARGB0 = dst_ptr[i];
437            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
438            dst_ptr[i] = vis_fpack16(res0);
439        }
440    }
441}
442
443/***************************************************************/
444
445#undef  MASK_FILL
446#define MASK_FILL(rr, pathA, dstA, dstARGB)    \
447{                                              \
448    rr = MUL8_VIS(dstARGB, cnstA);             \
449    rr = vis_fpadd16(rr, cnstARGB);            \
450    rr = vis_fand(rr, maskRGB);                \
451}
452
453/***************************************************************/
454
455static void IntRgbSrcOverMaskFill_A1_line(mlib_f32 *dst_ptr,
456                                          mlib_u8  *pMask,
457                                          mlib_s32 width,
458                                          mlib_d64 cnstARGB,
459                                          mlib_s32 cnstA,
460                                          mlib_u8  *mul8_tbl)
461{
462    mlib_s32 i, i0;
463    mlib_d64 res0, res1, dstARGB;
464    mlib_f32 dstARGB0;
465    mlib_d64 maskRGB = vis_to_double(0x0000FFFF, 0xFFFFFFFF);
466
467    i = i0 = 0;
468
469    if ((mlib_s32)dst_ptr & 7) {
470        dstARGB0 = dst_ptr[i];
471        MASK_FILL(res0, pathA0, dstA0, dstARGB0);
472        dst_ptr[i] = vis_fpack16(res0);
473
474        i0 = 1;
475    }
476
477#pragma pipeloop(0)
478    for (i = i0; i <= width - 2; i += 2) {
479        dstARGB = *(mlib_d64*)(dst_ptr + i);
480
481        MASK_FILL(res0, pathA0, dstA0, vis_read_hi(dstARGB));
482        MASK_FILL(res1, pathA1, dstA1, vis_read_lo(dstARGB));
483
484        res0 = vis_fpack16_pair(res0, res1);
485
486        *(mlib_d64*)(dst_ptr + i) = res0;
487    }
488
489    if (i < width) {
490        dstARGB0 = dst_ptr[i];
491        MASK_FILL(res0, pathA0, dstA0, dstARGB0);
492        dst_ptr[i] = vis_fpack16(res0);
493    }
494}
495
496/***************************************************************/
497
498void ADD_SUFF(IntRgbSrcOverMaskFill)(void *rasBase,
499                                     jubyte *pMask,
500                                     jint maskOff,
501                                     jint maskScan,
502                                     jint width,
503                                     jint height,
504                                     jint fgColor,
505                                     SurfaceDataRasInfo *pRasInfo,
506                                     NativePrimitive *pPrim,
507                                     CompositeInfo *pCompInfo)
508{
509    mlib_s32 cnstA, cnstR, cnstG, cnstB;
510    mlib_s32 rasScan = pRasInfo->scanStride;
511    mlib_f32 cnstARGB0;
512    mlib_d64 cnstARGB;
513    mlib_u8  *mul8_cnstA;
514    mlib_s32 j;
515
516    cnstA = (fgColor >> 24) & 0xff;
517    cnstR = (fgColor >> 16) & 0xff;
518    cnstG = (fgColor >>  8) & 0xff;
519    cnstB = (fgColor      ) & 0xff;
520
521    if (cnstA != 0xff) {
522        if (cnstA == 0) return;
523
524        cnstR = mul8table[cnstA][cnstR];
525        cnstG = mul8table[cnstA][cnstG];
526        cnstB = mul8table[cnstA][cnstB];
527    }
528
529    vis_write_gsr(0 << 3);
530
531    if (pMask != NULL) {
532        pMask += maskOff;
533
534        if (rasScan == 4*width && maskScan == width) {
535            width *= height;
536            height = 1;
537        }
538
539        mul8_cnstA = mul8table[cnstA];
540
541        cnstARGB0 = F32_FROM_U8x4(cnstA, cnstR, cnstG, cnstB);
542
543        for (j = 0; j < height; j++) {
544            IntRgbSrcOverMaskFill_line(rasBase, pMask, width, cnstARGB0,
545                                       mul8_cnstA, (void*)mul8table);
546
547            PTR_ADD(rasBase, rasScan);
548            PTR_ADD(pMask, maskScan);
549        }
550    } else {
551        if (rasScan == 4*width) {
552            width *= height;
553            height = 1;
554        }
555
556        cnstARGB = vis_to_double((cnstR << 7), (cnstG << 23) | (cnstB << 7));
557
558        cnstA = 255 - cnstA;
559
560        for (j = 0; j < height; j++) {
561            IntRgbSrcOverMaskFill_A1_line(rasBase, pMask, width, cnstARGB,
562                                          cnstA, (void*)mul8table);
563
564            PTR_ADD(rasBase, rasScan);
565        }
566    }
567}
568
569/***************************************************************/
570
571void ADD_SUFF(IntBgrSrcOverMaskFill)(void *rasBase,
572                                     jubyte *pMask,
573                                     jint maskOff,
574                                     jint maskScan,
575                                     jint width,
576                                     jint height,
577                                     jint fgColor,
578                                     SurfaceDataRasInfo *pRasInfo,
579                                     NativePrimitive *pPrim,
580                                     CompositeInfo *pCompInfo)
581{
582    mlib_s32 cnstA, cnstR, cnstG, cnstB;
583    mlib_s32 rasScan = pRasInfo->scanStride;
584    mlib_f32 cnstARGB0;
585    mlib_d64 cnstARGB;
586    mlib_u8  *mul8_cnstA;
587    mlib_s32 j;
588
589    cnstA = (fgColor >> 24) & 0xff;
590    cnstR = (fgColor >> 16) & 0xff;
591    cnstG = (fgColor >>  8) & 0xff;
592    cnstB = (fgColor      ) & 0xff;
593
594    if (cnstA != 0xff) {
595        if (cnstA == 0) return;
596
597        cnstR = mul8table[cnstA][cnstR];
598        cnstG = mul8table[cnstA][cnstG];
599        cnstB = mul8table[cnstA][cnstB];
600    }
601
602    vis_write_gsr(0 << 3);
603
604    if (pMask != NULL) {
605        pMask += maskOff;
606
607        if (rasScan == 4*width && maskScan == width) {
608            width *= height;
609            height = 1;
610        }
611
612        mul8_cnstA = mul8table[cnstA];
613
614        cnstARGB0 = F32_FROM_U8x4(cnstA, cnstB, cnstG, cnstR);
615
616        for (j = 0; j < height; j++) {
617            IntRgbSrcOverMaskFill_line(rasBase, pMask, width, cnstARGB0,
618                                       mul8_cnstA, (void*)mul8table);
619
620            PTR_ADD(rasBase, rasScan);
621            PTR_ADD(pMask, maskScan);
622        }
623    } else {
624        if (rasScan == 4*width) {
625            width *= height;
626            height = 1;
627        }
628
629        cnstARGB = vis_to_double((cnstB << 7), (cnstG << 23) | (cnstR << 7));
630
631        cnstA = 255 - cnstA;
632
633        for (j = 0; j < height; j++) {
634            IntRgbSrcOverMaskFill_A1_line(rasBase, pMask, width, cnstARGB,
635                                          cnstA, (void*)mul8table);
636
637            PTR_ADD(rasBase, rasScan);
638        }
639    }
640}
641
642/***************************************************************/
643
644void ADD_SUFF(ThreeByteBgrSrcOverMaskFill)(void *rasBase,
645                                           jubyte *pMask,
646                                           jint maskOff,
647                                           jint maskScan,
648                                           jint width,
649                                           jint height,
650                                           jint fgColor,
651                                           SurfaceDataRasInfo *pRasInfo,
652                                           NativePrimitive *pPrim,
653                                           CompositeInfo *pCompInfo)
654{
655    mlib_d64 buff[BUFF_SIZE/2];
656    void     *pbuff = buff;
657    mlib_s32 cnstA, cnstR, cnstG, cnstB;
658    mlib_s32 rasScan = pRasInfo->scanStride;
659    mlib_f32 cnstARGB0;
660    mlib_d64 cnstARGB;
661    mlib_u8  *mul8_cnstA;
662    mlib_s32 j;
663
664    if (width > BUFF_SIZE) pbuff = mlib_malloc(width*sizeof(mlib_s32));
665
666    cnstA = (fgColor >> 24) & 0xff;
667    cnstR = (fgColor >> 16) & 0xff;
668    cnstG = (fgColor >>  8) & 0xff;
669    cnstB = (fgColor      ) & 0xff;
670
671    if (cnstA != 0xff) {
672        if (cnstA == 0) return;
673
674        cnstR = mul8table[cnstA][cnstR];
675        cnstG = mul8table[cnstA][cnstG];
676        cnstB = mul8table[cnstA][cnstB];
677    }
678
679    vis_write_gsr(0 << 3);
680
681    if (pMask != NULL) {
682        pMask += maskOff;
683
684        mul8_cnstA = mul8table[cnstA];
685
686        cnstARGB0 = F32_FROM_U8x4(cnstA, cnstR, cnstG, cnstB);
687
688        for (j = 0; j < height; j++) {
689            ADD_SUFF(ThreeByteBgrToIntArgbConvert)(rasBase, pbuff, width, 1,
690                                                   pRasInfo, pRasInfo,
691                                                   pPrim, pCompInfo);
692
693            IntRgbSrcOverMaskFill_line(pbuff, pMask, width, cnstARGB0,
694                                       mul8_cnstA, (void*)mul8table);
695
696            IntArgbToThreeByteBgrConvert(pbuff, rasBase, width, 1,
697                                         pRasInfo, pRasInfo, pPrim, pCompInfo);
698
699            PTR_ADD(rasBase, rasScan);
700            PTR_ADD(pMask, maskScan);
701        }
702    } else {
703        cnstARGB = vis_to_double((cnstR << 7), (cnstG << 23) | (cnstB << 7));
704
705        cnstA = 255 - cnstA;
706
707        for (j = 0; j < height; j++) {
708            ADD_SUFF(ThreeByteBgrToIntArgbConvert)(rasBase, pbuff, width, 1,
709                                                   pRasInfo, pRasInfo,
710                                                   pPrim, pCompInfo);
711
712            IntRgbSrcOverMaskFill_A1_line(pbuff, pMask, width, cnstARGB,
713                                          cnstA, (void*)mul8table);
714
715            IntArgbToThreeByteBgrConvert(pbuff, rasBase, width, 1,
716                                         pRasInfo, pRasInfo, pPrim, pCompInfo);
717
718            PTR_ADD(rasBase, rasScan);
719        }
720    }
721
722    if (pbuff != buff) {
723        mlib_free(pbuff);
724    }
725}
726
727/***************************************************************/
728
729#endif
730