1 /*
2  * Copyright (c) 2003, 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_proto.h>
29 #include "vis_AlphaMacros.h"
30 
31 /***************************************************************/
32 
33 #define STORE_INT      \
34     *dst = fgpixel
35 
36 #define STORE_D64(TSIZE, dst, mask)    \
37     vis_pst_##TSIZE(fgpixel_d, dst, mask)
38 
39 /***************************************************************/
40 
41 #define INIT_FG
42 
43 /***************************************************************/
44 
45 #define DEF_GLYPH(TSIZE)                                       \
46     const jubyte *pixels;                                      \
47     unsigned int rowBytes;                                     \
48     int left, top;                                             \
49     int width, height;                                         \
50     int right, bottom;                                         \
51                                                                \
52     pixels = (const jubyte *) glyphs[glyphCounter].pixels;     \
53                                                                \
54     if (!pixels) continue;                                     \
55                                                                \
56     left = glyphs[glyphCounter].x;                             \
57     top = glyphs[glyphCounter].y;                              \
58     width = glyphs[glyphCounter].width;                        \
59     height = glyphs[glyphCounter].height;                      \
60     rowBytes = width;                                          \
61     right = left + width;                                      \
62     bottom = top + height;                                     \
63     if (left < clipLeft) {                                     \
64         pixels += clipLeft - left;                             \
65         left = clipLeft;                                       \
66     }                                                          \
67     if (top < clipTop) {                                       \
68         pixels += (clipTop - top) * rowBytes;                  \
69         top = clipTop;                                         \
70     }                                                          \
71     if (right > clipRight) {                                   \
72         right = clipRight;                                     \
73     }                                                          \
74     if (bottom > clipBottom) {                                 \
75         bottom = clipBottom;                                   \
76     }                                                          \
77     if (right <= left || bottom <= top) {                      \
78         continue;                                              \
79     }                                                          \
80     width = right - left;                                      \
81     height = bottom - top;                                     \
82                                                                \
83     dstBase = pRasInfo->rasBase;                               \
84     PTR_ADD(dstBase, top*scan + TSIZE*left)
85 
86 /***************************************************************/
87 
ADD_SUFF(AnyByteDrawGlyphList)88 void ADD_SUFF(AnyByteDrawGlyphList)(GLYPH_LIST_PARAMS)
89 {
90     mlib_s32 glyphCounter;
91     mlib_s32 scan = pRasInfo->scanStride;
92     mlib_u8  *dstBase;
93     mlib_s32 j;
94     mlib_d64 fgpixel_d;
95     mlib_d64 dzero;
96     mlib_s32 pix, mask0, mask1, mask_h, mask_l, off;
97     mlib_f32 fzero;
98 
99     INIT_FG
100 
101     fzero = vis_fzeros();
102     dzero = vis_fzero();
103     D64_FROM_U8x8(fgpixel_d, fgpixel);
104 
105     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
106         DEF_GLYPH(1);
107 
108         for (j = 0; j < height; j++) {
109             mlib_u8 *src = (void*)pixels;
110             mlib_u8 *dst, *dst_end;
111             mlib_d64 ss, s0, s1;
112 
113             dst = (void*)dstBase;
114             dst_end = dst + width;
115 
116             while (((mlib_s32)dst & 7) && (dst < dst_end)) {
117                 pix = *src++;
118                 if (pix) STORE_INT;
119                 dst++;
120             }
121 
122             off = (mlib_s32)src & 7;
123             ss = *(mlib_d64*)(src - off);
124             mask_h = vis_fcmpne16(vis_fpmerge(vis_read_hi(ss), fzero), dzero);
125             mask_l = vis_fcmpne16(vis_fpmerge(vis_read_lo(ss), fzero), dzero);
126             mask1 = (mask_h << 4) | mask_l;
127 
128 #pragma pipeloop(0)
129             for (; dst <= (dst_end - 8); dst += 8) {
130                 mask0 = mask1;
131                 src += 8;
132                 ss = *(mlib_d64*)(src - off);
133                 s0 = vis_fpmerge(vis_read_hi(ss), fzero);
134                 s1 = vis_fpmerge(vis_read_lo(ss), fzero);
135                 mask_h = vis_fcmpne16(s0, dzero);
136                 mask_l = vis_fcmpne16(s1, dzero);
137                 mask1 = (mask_h << 4) | mask_l;
138                 STORE_D64(8, dst, (mask0 << off) | (mask1 >> (8 - off)));
139             }
140 
141             while (dst < dst_end) {
142                 pix = *src++;
143                 if (pix) STORE_INT;
144                 dst++;
145             }
146 
147             PTR_ADD(dstBase, scan);
148             pixels += rowBytes;
149         }
150     }
151 }
152 
153 /***************************************************************/
154 
ADD_SUFF(AnyShortDrawGlyphList)155 void ADD_SUFF(AnyShortDrawGlyphList)(GLYPH_LIST_PARAMS)
156 {
157     mlib_s32 glyphCounter;
158     mlib_s32 scan = pRasInfo->scanStride;
159     mlib_u8  *dstBase;
160     mlib_s32 j;
161     mlib_d64 fgpixel_d;
162     mlib_d64 dzero;
163     mlib_s32 pix, mask0, mask1, off;
164     mlib_f32 fzero;
165 
166     INIT_FG
167 
168     fzero = vis_fzeros();
169     dzero = vis_fzero();
170     D64_FROM_U16x4(fgpixel_d, fgpixel);
171 
172     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
173         DEF_GLYPH(2);
174 
175         for (j = 0; j < height; j++) {
176             mlib_u8 *src = (void*)pixels;
177             mlib_u16 *dst, *dst_end;
178             mlib_f32 ss;
179 
180             dst = (void*)dstBase;
181             dst_end = dst + width;
182 
183             while (((mlib_s32)dst & 7) && (dst < dst_end)) {
184                 pix = *src++;
185                 if (pix) STORE_INT;
186                 dst++;
187             }
188 
189             off = (mlib_s32)src & 3;
190             ss = *(mlib_f32*)(src - off);
191             mask1 = vis_fcmpne16(vis_fpmerge(ss, fzero), dzero);
192 
193 #pragma pipeloop(0)
194             for (; dst <= (dst_end - 4); dst += 4) {
195                 mask0 = mask1;
196                 src += 4;
197                 ss = *(mlib_f32*)(src - off);
198                 mask1 = vis_fcmpne16(vis_fpmerge(ss, fzero), dzero);
199                 STORE_D64(16, dst, (mask0 << off) | (mask1 >> (4 - off)));
200             }
201 
202             while (dst < dst_end) {
203                 pix = *src++;
204                 if (pix) STORE_INT;
205                 dst++;
206             }
207 
208             PTR_ADD(dstBase, scan);
209             pixels += rowBytes;
210         }
211     }
212 }
213 
214 /***************************************************************/
215 
ADD_SUFF(AnyIntDrawGlyphList)216 void ADD_SUFF(AnyIntDrawGlyphList)(GLYPH_LIST_PARAMS)
217 {
218     mlib_s32 glyphCounter;
219     mlib_s32 scan = pRasInfo->scanStride;
220     mlib_u8  *dstBase;
221     mlib_s32 j;
222     mlib_d64 fgpixel_d;
223     mlib_d64 dzero;
224     mlib_s32 pix, mask0, mask1, mask, off;
225     mlib_f32 fzero;
226 
227     INIT_FG
228 
229     fzero = vis_fzeros();
230     dzero = vis_fzero();
231     fgpixel_d = vis_to_double_dup(fgpixel);
232 
233     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
234         DEF_GLYPH(4);
235 
236         for (j = 0; j < height; j++) {
237             mlib_u8 *src = (void*)pixels;
238             mlib_u32 *dst, *dst_end;
239             mlib_f32 ss;
240 
241             dst = (void*)dstBase;
242             dst_end = dst + width;
243 
244             while (((mlib_s32)dst & 7) && (dst < dst_end)) {
245                 pix = *src++;
246                 if (pix) STORE_INT;
247                 dst++;
248             }
249 
250             off = (mlib_s32)src & 3;
251             ss = *(mlib_f32*)(src - off);
252             mask1 = vis_fcmpne16(vis_fpmerge(ss, fzero), dzero);
253 
254 #pragma pipeloop(0)
255             for (; dst <= (dst_end - 4); dst += 4) {
256                 mask0 = mask1;
257                 src += 4;
258                 ss = *(mlib_f32*)(src - off);
259                 mask1 = vis_fcmpne16(vis_fpmerge(ss, fzero), dzero);
260                 mask = (mask0 << off) | (mask1 >> (4 - off));
261                 STORE_D64(32, dst, mask >> 2);
262                 STORE_D64(32, dst + 2, mask);
263             }
264 
265             while (dst < dst_end) {
266                 pix = *src++;
267                 if (pix) STORE_INT;
268                 dst++;
269             }
270 
271             PTR_ADD(dstBase, scan);
272             pixels += rowBytes;
273         }
274     }
275 }
276 
277 /***************************************************************/
278 
ADD_SUFF(Any4ByteDrawGlyphList)279 void ADD_SUFF(Any4ByteDrawGlyphList)(GLYPH_LIST_PARAMS)
280 {
281     mlib_d64 buff[BUFF_SIZE/2];
282     void     *pbuff = buff;
283     mlib_s32 glyphCounter;
284     mlib_s32 scan = pRasInfo->scanStride;
285     mlib_u8  *dstBase;
286     mlib_s32 j;
287     mlib_d64 fgpixel_d;
288     mlib_d64 dzero;
289     mlib_s32 pix, mask0, mask1, mask, off;
290     mlib_f32 fzero, fgpixel_f;
291     mlib_s32 max_width = BUFF_SIZE;
292 
293     INIT_FG
294 
295     fzero = vis_fzeros();
296     dzero = vis_fzero();
297     fgpixel_f = vis_ldfa_ASI_PL(&fgpixel);
298     fgpixel_d = vis_freg_pair(fgpixel_f, fgpixel_f);
299     fgpixel = *(mlib_u32*)&fgpixel_f;
300 
301     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
302         DEF_GLYPH(4);
303 
304         if (((mlib_s32)dstBase | scan) & 3) {
305             if (width > max_width) {
306                 if (pbuff != buff) {
307                     mlib_free(pbuff);
308                 }
309                 pbuff = mlib_malloc(width*sizeof(mlib_s32));
310                 if (pbuff == NULL) return;
311                 max_width = width;
312             }
313         }
314 
315         for (j = 0; j < height; j++) {
316             mlib_u8 *src = (void*)pixels;
317             mlib_u32 *dst, *dst_end;
318             mlib_f32 ss;
319 
320             if ((mlib_s32)dstBase & 3) {
321                 COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32));
322                 dst = pbuff;
323             } else {
324                 dst = (void*)dstBase;
325             }
326             dst_end = dst + width;
327 
328             while (((mlib_s32)dst & 7) && (dst < dst_end)) {
329                 pix = *src++;
330                 if (pix) STORE_INT;
331                 dst++;
332             }
333 
334             off = (mlib_s32)src & 3;
335             ss = *(mlib_f32*)(src - off);
336             mask1 = vis_fcmpne16(vis_fpmerge(ss, fzero), dzero);
337 
338 #pragma pipeloop(0)
339             for (; dst <= (dst_end - 4); dst += 4) {
340                 mask0 = mask1;
341                 src += 4;
342                 ss = *(mlib_f32*)(src - off);
343                 mask1 = vis_fcmpne16(vis_fpmerge(ss, fzero), dzero);
344                 mask = (mask0 << off) | (mask1 >> (4 - off));
345                 STORE_D64(32, dst, mask >> 2);
346                 STORE_D64(32, dst + 2, mask);
347             }
348 
349             while (dst < dst_end) {
350                 pix = *src++;
351                 if (pix) STORE_INT;
352                 dst++;
353             }
354 
355             if ((mlib_s32)dstBase & 3) {
356                 COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32));
357             }
358 
359             PTR_ADD(dstBase, scan);
360             pixels += rowBytes;
361         }
362     }
363 
364     if (pbuff != buff) {
365         mlib_free(pbuff);
366     }
367 }
368 
369 /***************************************************************/
370 
371 #endif /* JAVA2D_NO_MLIB */
372