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 * IntArgbAlphaMaskFill()
34 * FourByteAbgrAlphaMaskFill()
35 */
36
37#define MASK_FILL(rr, pathA, dstA, dstARGB)                    \
38{                                                              \
39    mlib_d64 t0, t1;                                           \
40    mlib_s32 srcF, dstF, srcA;                                 \
41                                                               \
42    srcF = ((dstA & SrcOpAnd) ^ SrcOpXor) + SrcOpAdd;          \
43                                                               \
44    srcF = MUL8_INT(srcF, pathA);                              \
45    dstF = mul8_dstF[pathA] + (0xff - pathA);                  \
46                                                               \
47    srcA = mul8_cnstA[srcF];                                   \
48    dstA = MUL8_INT(dstF, dstA);                               \
49                                                               \
50    t0 = MUL8_VIS(cnstARGB0, srcF);                            \
51    t1 = MUL8_VIS(dstARGB, dstA);                              \
52    rr = vis_fpadd16(t0, t1);                                  \
53                                                               \
54    dstA += srcA;                                              \
55    DIV_ALPHA(rr, dstA);                                       \
56}
57
58/***************************************************************/
59
60static void IntArgbAlphaMaskFill_line(mlib_f32 *dst_ptr,
61                                      mlib_u8  *pMask,
62                                      mlib_s32 width,
63                                      mlib_f32 cnstARGB0,
64                                      mlib_s32 *log_val,
65                                      mlib_u8  *mul8_cnstA,
66                                      mlib_u8  *mul8_dstF,
67                                      mlib_u8  *mul8_tbl)
68{
69    mlib_s32 i, i0;
70    mlib_s32 pathA0, pathA1, dstA0, dstA1, msk;
71    mlib_d64 res0, res1, dstARGB;
72    mlib_f32 dstARGB0;
73    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
74
75    SrcOpAnd = log_val[0];
76    SrcOpXor = log_val[1];
77    SrcOpAdd = log_val[2];
78
79    i = i0 = 0;
80
81    if ((mlib_s32)dst_ptr & 7) {
82        pathA0 = pMask[i];
83
84        if (pathA0) {
85            dstA0 = *(mlib_u8*)(dst_ptr + i);
86            dstARGB0 = dst_ptr[i];
87            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
88            dst_ptr[i] = vis_fpack16(res0);
89            *(mlib_u8*)(dst_ptr + i) = dstA0;
90        }
91
92        i0 = 1;
93    }
94
95#pragma pipeloop(0)
96    for (i = i0; i <= width - 2; i += 2) {
97        pathA0 = pMask[i];
98        pathA1 = pMask[i + 1];
99        dstA0 = *(mlib_u8*)(dst_ptr + i);
100        dstA1 = *(mlib_u8*)(dst_ptr + i + 1);
101        dstARGB = *(mlib_d64*)(dst_ptr + i);
102
103        MASK_FILL(res0, pathA0, dstA0, vis_read_hi(dstARGB));
104        MASK_FILL(res1, pathA1, dstA1, vis_read_lo(dstARGB));
105
106        res0 = vis_fpack16_pair(res0, res1);
107
108        msk = (((-pathA0) & (1 << 11)) | ((-pathA1) & (1 << 10))) >> 10;
109        vis_pst_32(res0, dst_ptr + i, msk);
110
111        *(mlib_u8*)(dst_ptr + i    ) = dstA0;
112        *(mlib_u8*)(dst_ptr + i + 1) = dstA1;
113    }
114
115    if (i < width) {
116        pathA0 = pMask[i];
117
118        if (pathA0) {
119            dstA0 = *(mlib_u8*)(dst_ptr + i);
120            dstARGB0 = dst_ptr[i];
121            MASK_FILL(res0, pathA0, dstA0, dstARGB0);
122            dst_ptr[i] = vis_fpack16(res0);
123            *(mlib_u8*)(dst_ptr + i) = dstA0;
124        }
125    }
126}
127
128/***************************************************************/
129
130#undef  MASK_FILL
131#define MASK_FILL(rr, pathA, dstA, dstARGB)                    \
132{                                                              \
133    mlib_d64 t0, t1;                                           \
134    mlib_s32 srcA, alp1;                                       \
135                                                               \
136    srcA = ((dstA & SrcOpAnd) ^ SrcOpXor) + SrcOpAdd;          \
137    alp1 = mul8_dstF[dstA];                                    \
138    dstA = mul8_cnstA[srcA] + alp1;                            \
139                                                               \
140    t0 = MUL8_VIS(cnstARGB0, srcA);                            \
141    t1 = MUL8_VIS(dstARGB, alp1);                              \
142    rr = vis_fpadd16(t0, t1);                                  \
143                                                               \
144    DIV_ALPHA(rr, dstA);                                       \
145}
146
147/***************************************************************/
148
149static void IntArgbAlphaMaskFill_A1_line(mlib_f32 *dst_ptr,
150                                         mlib_u8  *pMask,
151                                         mlib_s32 width,
152                                         mlib_f32 cnstARGB0,
153                                         mlib_s32 *log_val,
154                                         mlib_u8  *mul8_cnstA,
155                                         mlib_u8  *mul8_dstF,
156                                         mlib_u8  *mul8_tbl)
157{
158    mlib_s32 i;
159    mlib_s32 dstA0;
160    mlib_d64 res0;
161    mlib_f32 dstARGB0;
162    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
163
164    SrcOpAnd = log_val[0];
165    SrcOpXor = log_val[1];
166    SrcOpAdd = log_val[2];
167
168#pragma pipeloop(0)
169    for (i = 0; i < width; i++) {
170        dstA0 = *(mlib_u8*)(dst_ptr + i);
171        dstARGB0 = dst_ptr[i];
172        MASK_FILL(res0, pathA0, dstA0, dstARGB0);
173        dst_ptr[i] = vis_fpack16(res0);
174        *(mlib_u8*)(dst_ptr + i) = dstA0;
175    }
176}
177
178/***************************************************************/
179
180void ADD_SUFF(IntArgbAlphaMaskFill)(void *rasBase,
181                                    jubyte *pMask,
182                                    jint maskOff,
183                                    jint maskScan,
184                                    jint width,
185                                    jint height,
186                                    jint fgColor,
187                                    SurfaceDataRasInfo *pRasInfo,
188                                    NativePrimitive *pPrim,
189                                    CompositeInfo *pCompInfo)
190{
191    mlib_s32 cnstA, cnstR, cnstG, cnstB;
192    mlib_s32 rasScan = pRasInfo->scanStride;
193    mlib_f32 cnstARGB0;
194    mlib_u8  *mul8_cnstA, *mul8_dstF;
195    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
196    mlib_s32 DstOpAnd, DstOpXor, DstOpAdd;
197    mlib_s32 dstF;
198    mlib_s32 log_val[3];
199    mlib_s32 j;
200
201    cnstA = (fgColor >> 24) & 0xff;
202    cnstR = (fgColor >> 16) & 0xff;
203    cnstG = (fgColor >>  8) & 0xff;
204    cnstB = (fgColor      ) & 0xff;
205
206    if (cnstA != 0xff) {
207        cnstR = mul8table[cnstA][cnstR];
208        cnstG = mul8table[cnstA][cnstG];
209        cnstB = mul8table[cnstA][cnstB];
210    }
211
212    cnstARGB0 = F32_FROM_U8x4(cnstA, cnstR, cnstG, cnstB);
213
214    SrcOpAnd = (AlphaRules[pCompInfo->rule].srcOps).andval;
215    SrcOpXor = (AlphaRules[pCompInfo->rule].srcOps).xorval;
216    SrcOpAdd = (AlphaRules[pCompInfo->rule].srcOps).addval;
217    SrcOpAdd -= SrcOpXor;
218
219    log_val[0] = SrcOpAnd;
220    log_val[1] = SrcOpXor;
221    log_val[2] = SrcOpAdd;
222
223    DstOpAnd = (AlphaRules[pCompInfo->rule].dstOps).andval;
224    DstOpXor = (AlphaRules[pCompInfo->rule].dstOps).xorval;
225    DstOpAdd = (AlphaRules[pCompInfo->rule].dstOps).addval;
226    DstOpAdd -= DstOpXor;
227
228    dstF = (((cnstA) & DstOpAnd) ^ DstOpXor) + DstOpAdd;
229
230    mul8_cnstA = mul8table[cnstA];
231    mul8_dstF = mul8table[dstF];
232
233    vis_write_gsr(7 << 3);
234
235    if (pMask != NULL) {
236        pMask += maskOff;
237
238        if (rasScan == 4*width && maskScan == width) {
239            width *= height;
240            height = 1;
241        }
242
243        for (j = 0; j < height; j++) {
244            IntArgbAlphaMaskFill_line(rasBase, pMask, width, cnstARGB0,
245                                      log_val, mul8_cnstA, mul8_dstF,
246                                      (void*)mul8table);
247
248            PTR_ADD(rasBase, rasScan);
249            PTR_ADD(pMask, maskScan);
250        }
251    } else {
252        if (rasScan == 4*width) {
253            width *= height;
254            height = 1;
255        }
256
257        for (j = 0; j < height; j++) {
258            IntArgbAlphaMaskFill_A1_line(rasBase, pMask, width, cnstARGB0,
259                                         log_val, mul8_cnstA, mul8_dstF,
260                                         (void*)mul8table);
261
262            PTR_ADD(rasBase, rasScan);
263        }
264    }
265}
266
267/***************************************************************/
268
269void ADD_SUFF(FourByteAbgrAlphaMaskFill)(void *rasBase,
270                                         jubyte *pMask,
271                                         jint maskOff,
272                                         jint maskScan,
273                                         jint width,
274                                         jint height,
275                                         jint fgColor,
276                                         SurfaceDataRasInfo *pRasInfo,
277                                         NativePrimitive *pPrim,
278                                         CompositeInfo *pCompInfo)
279{
280    mlib_d64 buff[BUFF_SIZE/2];
281    void     *pbuff = buff;
282    mlib_s32 cnstA, cnstR, cnstG, cnstB;
283    mlib_s32 rasScan = pRasInfo->scanStride;
284    mlib_f32 cnstARGB0;
285    mlib_u8  *mul8_cnstA, *mul8_dstF;
286    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
287    mlib_s32 DstOpAnd, DstOpXor, DstOpAdd;
288    mlib_s32 dstF;
289    mlib_s32 log_val[3];
290    mlib_s32 j;
291
292    cnstA = (mlib_u32)fgColor >> 24;
293    cnstR = (fgColor >> 16) & 0xff;
294    cnstG = (fgColor >>  8) & 0xff;
295    cnstB = (fgColor      ) & 0xff;
296
297    if (cnstA != 0xff) {
298        cnstR = mul8table[cnstA][cnstR];
299        cnstG = mul8table[cnstA][cnstG];
300        cnstB = mul8table[cnstA][cnstB];
301    }
302
303    cnstARGB0 = F32_FROM_U8x4(cnstA, cnstB, cnstG, cnstR);
304
305    SrcOpAnd = (AlphaRules[pCompInfo->rule].srcOps).andval;
306    SrcOpXor = (AlphaRules[pCompInfo->rule].srcOps).xorval;
307    SrcOpAdd = (AlphaRules[pCompInfo->rule].srcOps).addval;
308    SrcOpAdd -= SrcOpXor;
309
310    log_val[0] = SrcOpAnd;
311    log_val[1] = SrcOpXor;
312    log_val[2] = SrcOpAdd;
313
314    DstOpAnd = (AlphaRules[pCompInfo->rule].dstOps).andval;
315    DstOpXor = (AlphaRules[pCompInfo->rule].dstOps).xorval;
316    DstOpAdd = (AlphaRules[pCompInfo->rule].dstOps).addval;
317    DstOpAdd -= DstOpXor;
318
319    dstF = (((cnstA) & DstOpAnd) ^ DstOpXor) + DstOpAdd;
320
321    mul8_cnstA = mul8table[cnstA];
322    mul8_dstF = mul8table[dstF];
323
324    vis_write_gsr(7 << 3);
325
326    if (pMask != NULL) {
327        pMask += maskOff;
328
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 && maskScan == width) {
333                width *= height;
334                height = 1;
335            }
336        }
337
338        for (j = 0; j < height; j++) {
339            if (!((mlib_s32)rasBase & 3)) {
340                IntArgbAlphaMaskFill_line(rasBase, pMask, width, cnstARGB0,
341                                          log_val, mul8_cnstA, mul8_dstF,
342                                          (void*)mul8table);
343            } else {
344                mlib_ImageCopy_na(rasBase, pbuff, width*sizeof(mlib_s32));
345                IntArgbAlphaMaskFill_line(pbuff, pMask, width, cnstARGB0,
346                                          log_val, mul8_cnstA, mul8_dstF,
347                                          (void*)mul8table);
348                mlib_ImageCopy_na(pbuff, rasBase, width*sizeof(mlib_s32));
349            }
350
351            PTR_ADD(rasBase, rasScan);
352            PTR_ADD(pMask, maskScan);
353        }
354    } else {
355        if (((mlib_s32)rasBase | rasScan) & 3) {
356            if (width > BUFF_SIZE) pbuff = mlib_malloc(width*sizeof(mlib_s32));
357        } else {
358            if (rasScan == 4*width) {
359                width *= height;
360                height = 1;
361            }
362        }
363
364        for (j = 0; j < height; j++) {
365            if (!((mlib_s32)rasBase & 3)) {
366                IntArgbAlphaMaskFill_A1_line(rasBase, pMask, width, cnstARGB0,
367                                             log_val, mul8_cnstA, mul8_dstF,
368                                             (void*)mul8table);
369            } else {
370                mlib_ImageCopy_na(rasBase, pbuff, width*sizeof(mlib_s32));
371                IntArgbAlphaMaskFill_A1_line(pbuff, pMask, width, cnstARGB0,
372                                             log_val, mul8_cnstA, mul8_dstF,
373                                             (void*)mul8table);
374                mlib_ImageCopy_na(pbuff, rasBase, width*sizeof(mlib_s32));
375            }
376
377            PTR_ADD(rasBase, rasScan);
378        }
379    }
380
381    if (pbuff != buff) {
382        mlib_free(pbuff);
383    }
384}
385
386/***************************************************************/
387
388/* ##############################################################
389 * IntRgbAlphaMaskFill()
390 * IntBgrAlphaMaskFill()
391 */
392
393#undef  MASK_FILL
394#define MASK_FILL(rr, pathA, dstA, dstARGB)                    \
395{                                                              \
396    mlib_d64 t0, t1;                                           \
397    mlib_s32 srcF, srcA;                                       \
398                                                               \
399    srcF = mul8_srcF[pathA];                                   \
400    srcA = mul8_cnstA[srcF];                                   \
401    dstA = mul8_dstF[pathA] + (0xff - pathA);                  \
402                                                               \
403    t0 = MUL8_VIS(cnstARGB0, srcF);                            \
404    t1 = MUL8_VIS(dstARGB, dstA);                              \
405    rr = vis_fpadd16(t0, t1);                                  \
406                                                               \
407    dstA += srcA;                                              \
408    DIV_ALPHA_RGB(rr, dstA);                                   \
409                                                               \
410    pathA = dstA - 0xff - srcF;                                \
411    /* (pathA == 0) if (dstA == 0xFF && srcF == 0) */          \
412}
413
414/***************************************************************/
415
416static void IntRgbAlphaMaskFill_line(mlib_f32 *dst_ptr,
417                                     mlib_u8  *pMask,
418                                     mlib_s32 width,
419                                     mlib_f32 cnstARGB0,
420                                     mlib_u8  *mul8_cnstA,
421                                     mlib_u8  *mul8_dstF,
422                                     mlib_u8  *mul8_srcF,
423                                     mlib_u8  *mul8_tbl)
424{
425    mlib_s32 i, i0;
426    mlib_s32 pathA0, pathA1, dstA0, dstA1, msk;
427    mlib_d64 res0, res1, dstARGB;
428    mlib_f32 dstARGB0;
429
430    i = i0 = 0;
431
432    if ((mlib_s32)dst_ptr & 7) {
433        pathA0 = pMask[i];
434
435        dstARGB0 = dst_ptr[i];
436        MASK_FILL(res0, pathA0, dstA0, dstARGB0);
437        if (pathA0) {
438            dst_ptr[i] = vis_fpack16(res0);
439        }
440
441        i0 = 1;
442    }
443
444#pragma pipeloop(0)
445    for (i = i0; i <= width - 2; i += 2) {
446        pathA0 = pMask[i];
447        pathA1 = pMask[i + 1];
448        dstARGB = *(mlib_d64*)(dst_ptr + i);
449
450        MASK_FILL(res0, pathA0, dstA0, vis_read_hi(dstARGB));
451        MASK_FILL(res1, pathA1, dstA1, vis_read_lo(dstARGB));
452
453        res0 = vis_fpack16_pair(res0, res1);
454
455        msk = (((pathA0) & (1 << 11)) | ((pathA1) & (1 << 10))) >> 10;
456        vis_pst_32(res0, dst_ptr + i, msk);
457    }
458
459    if (i < width) {
460        pathA0 = pMask[i];
461
462        dstARGB0 = dst_ptr[i];
463        MASK_FILL(res0, pathA0, dstA0, dstARGB0);
464        if (pathA0) {
465            dst_ptr[i] = vis_fpack16(res0);
466        }
467    }
468}
469
470/***************************************************************/
471
472#undef  MASK_FILL
473#define MASK_FILL(rr, pathA, _dstA_, dstARGB)          \
474{                                                      \
475    rr = MUL8_VIS(dstARGB, dstF);                      \
476    rr = vis_fpadd16(rr, cnstARGB);                    \
477                                                       \
478    DIV_ALPHA_RGB(rr, dstA);                           \
479}
480
481/***************************************************************/
482
483static void IntRgbAlphaMaskFill_A1_line(mlib_f32 *dst_ptr,
484                                         mlib_u8  *pMask,
485                                         mlib_s32 width,
486                                         mlib_d64 cnstARGB,
487                                         mlib_s32 dstF,
488                                         mlib_s32 dstA)
489{
490    mlib_s32 i;
491    mlib_d64 res0;
492    mlib_f32 dstARGB0;
493
494#pragma pipeloop(0)
495    for (i = 0; i < width; i++) {
496        dstARGB0 = dst_ptr[i];
497        MASK_FILL(res0, pathA0, dstA0, dstARGB0);
498        dst_ptr[i] = vis_fpack16(res0);
499    }
500}
501
502/***************************************************************/
503
504void ADD_SUFF(IntRgbAlphaMaskFill)(void *rasBase,
505                                    jubyte *pMask,
506                                    jint maskOff,
507                                    jint maskScan,
508                                    jint width,
509                                    jint height,
510                                    jint fgColor,
511                                    SurfaceDataRasInfo *pRasInfo,
512                                    NativePrimitive *pPrim,
513                                    CompositeInfo *pCompInfo)
514{
515    mlib_s32 cnstA, cnstR, cnstG, cnstB;
516    mlib_s32 rasScan = pRasInfo->scanStride;
517    mlib_f32 cnstARGB0;
518    mlib_u8  *mul8_cnstA, *mul8_dstF, *mul8_srcF;
519    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
520    mlib_s32 DstOpAnd, DstOpXor, DstOpAdd;
521    mlib_s32 srcF, dstF;
522    mlib_s32 log_val[3];
523    mlib_s32 j;
524
525    cnstA = (fgColor >> 24) & 0xff;
526    cnstR = (fgColor >> 16) & 0xff;
527    cnstG = (fgColor >>  8) & 0xff;
528    cnstB = (fgColor      ) & 0xff;
529
530    if (cnstA != 0xff) {
531        cnstR = mul8table[cnstA][cnstR];
532        cnstG = mul8table[cnstA][cnstG];
533        cnstB = mul8table[cnstA][cnstB];
534    }
535
536    cnstARGB0 = F32_FROM_U8x4(cnstA, cnstR, cnstG, cnstB);
537
538    SrcOpAnd = (AlphaRules[pCompInfo->rule].srcOps).andval;
539    SrcOpXor = (AlphaRules[pCompInfo->rule].srcOps).xorval;
540    SrcOpAdd = (AlphaRules[pCompInfo->rule].srcOps).addval;
541    SrcOpAdd -= SrcOpXor;
542
543    log_val[0] = SrcOpAnd;
544    log_val[1] = SrcOpXor;
545    log_val[2] = SrcOpAdd;
546
547    DstOpAnd = (AlphaRules[pCompInfo->rule].dstOps).andval;
548    DstOpXor = (AlphaRules[pCompInfo->rule].dstOps).xorval;
549    DstOpAdd = (AlphaRules[pCompInfo->rule].dstOps).addval;
550    DstOpAdd -= DstOpXor;
551
552    dstF = (((cnstA) & DstOpAnd) ^ DstOpXor) + DstOpAdd;
553    srcF = (((  255) & SrcOpAnd) ^ SrcOpXor) + SrcOpAdd;
554
555    vis_write_gsr(7 << 3);
556
557    mul8_cnstA = mul8table[cnstA];
558
559    if (pMask != NULL) {
560        pMask += maskOff;
561
562        mul8_dstF  = mul8table[dstF];
563        mul8_srcF  = mul8table[srcF];
564
565        if (rasScan == 4*width && maskScan == width) {
566            width *= height;
567            height = 1;
568        }
569
570        for (j = 0; j < height; j++) {
571            IntRgbAlphaMaskFill_line(rasBase, pMask, width, cnstARGB0,
572                                     mul8_cnstA, mul8_dstF, mul8_srcF,
573                                     (void*)mul8table);
574
575            PTR_ADD(rasBase, rasScan);
576            PTR_ADD(pMask, maskScan);
577        }
578    } else {
579        mlib_s32 dstA;
580        mlib_d64 cnstARGB;
581
582        if (dstF == 0xFF && srcF == 0) return;
583
584        cnstARGB = MUL8_VIS(cnstARGB0, srcF);
585        dstA = dstF + mul8_cnstA[srcF];
586
587        if (rasScan == 4*width) {
588            width *= height;
589            height = 1;
590        }
591
592        for (j = 0; j < height; j++) {
593            IntRgbAlphaMaskFill_A1_line(rasBase, pMask, width, cnstARGB,
594                                        dstF, dstA);
595
596            PTR_ADD(rasBase, rasScan);
597        }
598    }
599}
600
601/***************************************************************/
602
603void ADD_SUFF(IntBgrAlphaMaskFill)(void *rasBase,
604                                   jubyte *pMask,
605                                   jint maskOff,
606                                   jint maskScan,
607                                   jint width,
608                                   jint height,
609                                   jint fgColor,
610                                   SurfaceDataRasInfo *pRasInfo,
611                                   NativePrimitive *pPrim,
612                                   CompositeInfo *pCompInfo)
613{
614    mlib_s32 cnstA, cnstR, cnstG, cnstB;
615    mlib_s32 rasScan = pRasInfo->scanStride;
616    mlib_f32 cnstARGB0;
617    mlib_u8  *mul8_cnstA, *mul8_dstF, *mul8_srcF;
618    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
619    mlib_s32 DstOpAnd, DstOpXor, DstOpAdd;
620    mlib_s32 srcF, dstF;
621    mlib_s32 log_val[3];
622    mlib_s32 j;
623
624    cnstA = (fgColor >> 24) & 0xff;
625    cnstR = (fgColor >> 16) & 0xff;
626    cnstG = (fgColor >>  8) & 0xff;
627    cnstB = (fgColor      ) & 0xff;
628
629    if (cnstA != 0xff) {
630        cnstR = mul8table[cnstA][cnstR];
631        cnstG = mul8table[cnstA][cnstG];
632        cnstB = mul8table[cnstA][cnstB];
633    }
634
635    cnstARGB0 = F32_FROM_U8x4(cnstA, cnstB, cnstG, cnstR);
636
637    SrcOpAnd = (AlphaRules[pCompInfo->rule].srcOps).andval;
638    SrcOpXor = (AlphaRules[pCompInfo->rule].srcOps).xorval;
639    SrcOpAdd = (AlphaRules[pCompInfo->rule].srcOps).addval;
640    SrcOpAdd -= SrcOpXor;
641
642    log_val[0] = SrcOpAnd;
643    log_val[1] = SrcOpXor;
644    log_val[2] = SrcOpAdd;
645
646    DstOpAnd = (AlphaRules[pCompInfo->rule].dstOps).andval;
647    DstOpXor = (AlphaRules[pCompInfo->rule].dstOps).xorval;
648    DstOpAdd = (AlphaRules[pCompInfo->rule].dstOps).addval;
649    DstOpAdd -= DstOpXor;
650
651    dstF = (((cnstA) & DstOpAnd) ^ DstOpXor) + DstOpAdd;
652    srcF = (((  255) & SrcOpAnd) ^ SrcOpXor) + SrcOpAdd;
653
654    vis_write_gsr(7 << 3);
655
656    mul8_cnstA = mul8table[cnstA];
657
658    if (pMask != NULL) {
659        pMask += maskOff;
660
661        mul8_dstF  = mul8table[dstF];
662        mul8_srcF  = mul8table[srcF];
663
664        if (rasScan == 4*width && maskScan == width) {
665            width *= height;
666            height = 1;
667        }
668
669        for (j = 0; j < height; j++) {
670            IntRgbAlphaMaskFill_line(rasBase, pMask, width, cnstARGB0,
671                                     mul8_cnstA, mul8_dstF, mul8_srcF,
672                                     (void*)mul8table);
673
674            PTR_ADD(rasBase, rasScan);
675            PTR_ADD(pMask, maskScan);
676        }
677    } else {
678        mlib_s32 dstA;
679        mlib_d64 cnstARGB;
680
681        if (dstF == 0xFF && srcF == 0) return;
682
683        cnstARGB = MUL8_VIS(cnstARGB0, srcF);
684        dstA = dstF + mul8_cnstA[srcF];
685
686        if (rasScan == 4*width) {
687            width *= height;
688            height = 1;
689        }
690
691        for (j = 0; j < height; j++) {
692            IntRgbAlphaMaskFill_A1_line(rasBase, pMask, width, cnstARGB,
693                                        dstF, dstA);
694
695            PTR_ADD(rasBase, rasScan);
696        }
697    }
698}
699
700/***************************************************************/
701
702void ADD_SUFF(ThreeByteBgrAlphaMaskFill)(void *rasBase,
703                                         jubyte *pMask,
704                                         jint maskOff,
705                                         jint maskScan,
706                                         jint width,
707                                         jint height,
708                                         jint fgColor,
709                                         SurfaceDataRasInfo *pRasInfo,
710                                         NativePrimitive *pPrim,
711                                         CompositeInfo *pCompInfo)
712{
713    mlib_d64 buff[BUFF_SIZE/2];
714    void     *pbuff = buff;
715    mlib_s32 cnstA, cnstR, cnstG, cnstB;
716    mlib_s32 rasScan = pRasInfo->scanStride;
717    mlib_f32 cnstARGB0;
718    mlib_u8  *mul8_cnstA, *mul8_dstF, *mul8_srcF;
719    mlib_s32 SrcOpAnd, SrcOpXor, SrcOpAdd;
720    mlib_s32 DstOpAnd, DstOpXor, DstOpAdd;
721    mlib_s32 srcF, dstF;
722    mlib_s32 log_val[3];
723    mlib_s32 j;
724
725    if (width > BUFF_SIZE) pbuff = mlib_malloc(width*sizeof(mlib_s32));
726
727    cnstA = (fgColor >> 24) & 0xff;
728    cnstR = (fgColor >> 16) & 0xff;
729    cnstG = (fgColor >>  8) & 0xff;
730    cnstB = (fgColor      ) & 0xff;
731
732    if (cnstA != 0xff) {
733        cnstR = mul8table[cnstA][cnstR];
734        cnstG = mul8table[cnstA][cnstG];
735        cnstB = mul8table[cnstA][cnstB];
736    }
737
738    cnstARGB0 = F32_FROM_U8x4(cnstA, cnstR, cnstG, cnstB);
739
740    SrcOpAnd = (AlphaRules[pCompInfo->rule].srcOps).andval;
741    SrcOpXor = (AlphaRules[pCompInfo->rule].srcOps).xorval;
742    SrcOpAdd = (AlphaRules[pCompInfo->rule].srcOps).addval;
743    SrcOpAdd -= SrcOpXor;
744
745    log_val[0] = SrcOpAnd;
746    log_val[1] = SrcOpXor;
747    log_val[2] = SrcOpAdd;
748
749    DstOpAnd = (AlphaRules[pCompInfo->rule].dstOps).andval;
750    DstOpXor = (AlphaRules[pCompInfo->rule].dstOps).xorval;
751    DstOpAdd = (AlphaRules[pCompInfo->rule].dstOps).addval;
752    DstOpAdd -= DstOpXor;
753
754    dstF = (((cnstA) & DstOpAnd) ^ DstOpXor) + DstOpAdd;
755    srcF = (((  255) & SrcOpAnd) ^ SrcOpXor) + SrcOpAdd;
756
757    vis_write_gsr(7 << 3);
758
759    mul8_cnstA = mul8table[cnstA];
760
761    if (pMask != NULL) {
762        pMask += maskOff;
763
764        mul8_dstF  = mul8table[dstF];
765        mul8_srcF  = mul8table[srcF];
766
767        for (j = 0; j < height; j++) {
768            ADD_SUFF(ThreeByteBgrToIntArgbConvert)(rasBase, pbuff, width, 1,
769                                                   pRasInfo, pRasInfo,
770                                                   pPrim, pCompInfo);
771
772            IntRgbAlphaMaskFill_line(pbuff, pMask, width, cnstARGB0,
773                                     mul8_cnstA, mul8_dstF, mul8_srcF,
774                                     (void*)mul8table);
775
776            IntArgbToThreeByteBgrConvert(pbuff, rasBase, width, 1,
777                                         pRasInfo, pRasInfo, pPrim, pCompInfo);
778
779            PTR_ADD(rasBase, rasScan);
780            PTR_ADD(pMask, maskScan);
781        }
782    } else {
783        mlib_s32 dstA;
784        mlib_d64 cnstARGB;
785
786        if (dstF == 0xFF && srcF == 0) return;
787
788        cnstARGB = MUL8_VIS(cnstARGB0, srcF);
789        dstA = dstF + mul8_cnstA[srcF];
790
791        for (j = 0; j < height; j++) {
792            ADD_SUFF(ThreeByteBgrToIntArgbConvert)(rasBase, pbuff, width, 1,
793                                                   pRasInfo, pRasInfo,
794                                                   pPrim, pCompInfo);
795
796            IntRgbAlphaMaskFill_A1_line(pbuff, pMask, width, cnstARGB,
797                                        dstF, dstA);
798
799            IntArgbToThreeByteBgrConvert(pbuff, rasBase, width, 1,
800                                         pRasInfo, pRasInfo, pPrim, pCompInfo);
801
802            PTR_ADD(rasBase, rasScan);
803        }
804    }
805
806    if (pbuff != buff) {
807        mlib_free(pbuff);
808    }
809}
810
811/***************************************************************/
812
813#endif /* JAVA2D_NO_MLIB */
814