1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Copyright © 2000 SuSE, Inc.
4*4882a593Smuzhiyun * Copyright © 2007 Red Hat, Inc.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Permission to use, copy, modify, distribute, and sell this software and its
7*4882a593Smuzhiyun * documentation for any purpose is hereby granted without fee, provided that
8*4882a593Smuzhiyun * the above copyright notice appear in all copies and that both that
9*4882a593Smuzhiyun * copyright notice and this permission notice appear in supporting
10*4882a593Smuzhiyun * documentation, and that the name of SuSE not be used in advertising or
11*4882a593Smuzhiyun * publicity pertaining to distribution of the software without specific,
12*4882a593Smuzhiyun * written prior permission. SuSE makes no representations about the
13*4882a593Smuzhiyun * suitability of this software for any purpose. It is provided "as is"
14*4882a593Smuzhiyun * without express or implied warranty.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17*4882a593Smuzhiyun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18*4882a593Smuzhiyun * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*4882a593Smuzhiyun * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20*4882a593Smuzhiyun * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21*4882a593Smuzhiyun * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * Author: Keith Packard, SuSE, Inc.
24*4882a593Smuzhiyun */
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
27*4882a593Smuzhiyun #include <dix-config.h>
28*4882a593Smuzhiyun #endif
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include <string.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include "fb.h"
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include "picturestr.h"
35*4882a593Smuzhiyun #include "mipict.h"
36*4882a593Smuzhiyun #include "fbpict.h"
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun void
fbComposite(CARD8 op,PicturePtr pSrc,PicturePtr pMask,PicturePtr pDst,INT16 xSrc,INT16 ySrc,INT16 xMask,INT16 yMask,INT16 xDst,INT16 yDst,CARD16 width,CARD16 height)39*4882a593Smuzhiyun fbComposite(CARD8 op,
40*4882a593Smuzhiyun PicturePtr pSrc,
41*4882a593Smuzhiyun PicturePtr pMask,
42*4882a593Smuzhiyun PicturePtr pDst,
43*4882a593Smuzhiyun INT16 xSrc,
44*4882a593Smuzhiyun INT16 ySrc,
45*4882a593Smuzhiyun INT16 xMask,
46*4882a593Smuzhiyun INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun pixman_image_t *src, *mask, *dest;
49*4882a593Smuzhiyun int src_xoff, src_yoff;
50*4882a593Smuzhiyun int msk_xoff, msk_yoff;
51*4882a593Smuzhiyun int dst_xoff, dst_yoff;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun miCompositeSourceValidate(pSrc);
54*4882a593Smuzhiyun if (pMask)
55*4882a593Smuzhiyun miCompositeSourceValidate(pMask);
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff);
58*4882a593Smuzhiyun mask = image_from_pict(pMask, FALSE, &msk_xoff, &msk_yoff);
59*4882a593Smuzhiyun dest = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff);
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun if (src && dest && !(pMask && !mask)) {
62*4882a593Smuzhiyun pixman_image_composite(op, src, mask, dest,
63*4882a593Smuzhiyun xSrc + src_xoff, ySrc + src_yoff,
64*4882a593Smuzhiyun xMask + msk_xoff, yMask + msk_yoff,
65*4882a593Smuzhiyun xDst + dst_xoff, yDst + dst_yoff, width, height);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun free_pixman_pict(pSrc, src);
69*4882a593Smuzhiyun free_pixman_pict(pMask, mask);
70*4882a593Smuzhiyun free_pixman_pict(pDst, dest);
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun static pixman_glyph_cache_t *glyphCache;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun void
fbDestroyGlyphCache(void)76*4882a593Smuzhiyun fbDestroyGlyphCache(void)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun if (glyphCache)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun pixman_glyph_cache_destroy (glyphCache);
81*4882a593Smuzhiyun glyphCache = NULL;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun static void
fbUnrealizeGlyph(ScreenPtr pScreen,GlyphPtr pGlyph)86*4882a593Smuzhiyun fbUnrealizeGlyph(ScreenPtr pScreen,
87*4882a593Smuzhiyun GlyphPtr pGlyph)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun if (glyphCache)
90*4882a593Smuzhiyun pixman_glyph_cache_remove (glyphCache, pGlyph, NULL);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun void
fbGlyphs(CARD8 op,PicturePtr pSrc,PicturePtr pDst,PictFormatPtr maskFormat,INT16 xSrc,INT16 ySrc,int nlist,GlyphListPtr list,GlyphPtr * glyphs)94*4882a593Smuzhiyun fbGlyphs(CARD8 op,
95*4882a593Smuzhiyun PicturePtr pSrc,
96*4882a593Smuzhiyun PicturePtr pDst,
97*4882a593Smuzhiyun PictFormatPtr maskFormat,
98*4882a593Smuzhiyun INT16 xSrc,
99*4882a593Smuzhiyun INT16 ySrc, int nlist,
100*4882a593Smuzhiyun GlyphListPtr list,
101*4882a593Smuzhiyun GlyphPtr *glyphs)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun #define N_STACK_GLYPHS 512
104*4882a593Smuzhiyun ScreenPtr pScreen = pDst->pDrawable->pScreen;
105*4882a593Smuzhiyun pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
106*4882a593Smuzhiyun pixman_glyph_t *pglyphs = stack_glyphs;
107*4882a593Smuzhiyun pixman_image_t *srcImage, *dstImage;
108*4882a593Smuzhiyun int srcXoff, srcYoff, dstXoff, dstYoff;
109*4882a593Smuzhiyun GlyphPtr glyph;
110*4882a593Smuzhiyun int n_glyphs;
111*4882a593Smuzhiyun int x, y;
112*4882a593Smuzhiyun int i, n;
113*4882a593Smuzhiyun int xDst = list->xOff, yDst = list->yOff;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun miCompositeSourceValidate(pSrc);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun n_glyphs = 0;
118*4882a593Smuzhiyun for (i = 0; i < nlist; ++i)
119*4882a593Smuzhiyun n_glyphs += list[i].len;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun if (!glyphCache)
122*4882a593Smuzhiyun glyphCache = pixman_glyph_cache_create();
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun pixman_glyph_cache_freeze (glyphCache);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun if (n_glyphs > N_STACK_GLYPHS) {
127*4882a593Smuzhiyun if (!(pglyphs = xallocarray(n_glyphs, sizeof(pixman_glyph_t))))
128*4882a593Smuzhiyun goto out;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun i = 0;
132*4882a593Smuzhiyun x = y = 0;
133*4882a593Smuzhiyun while (nlist--) {
134*4882a593Smuzhiyun x += list->xOff;
135*4882a593Smuzhiyun y += list->yOff;
136*4882a593Smuzhiyun n = list->len;
137*4882a593Smuzhiyun while (n--) {
138*4882a593Smuzhiyun const void *g;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun glyph = *glyphs++;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
143*4882a593Smuzhiyun pixman_image_t *glyphImage;
144*4882a593Smuzhiyun PicturePtr pPicture;
145*4882a593Smuzhiyun int xoff, yoff;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun pPicture = GetGlyphPicture(glyph, pScreen);
148*4882a593Smuzhiyun if (!pPicture) {
149*4882a593Smuzhiyun n_glyphs--;
150*4882a593Smuzhiyun goto next;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
154*4882a593Smuzhiyun goto out;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
157*4882a593Smuzhiyun glyph->info.x,
158*4882a593Smuzhiyun glyph->info.y,
159*4882a593Smuzhiyun glyphImage);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun free_pixman_pict(pPicture, glyphImage);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun if (!g)
164*4882a593Smuzhiyun goto out;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun pglyphs[i].x = x;
168*4882a593Smuzhiyun pglyphs[i].y = y;
169*4882a593Smuzhiyun pglyphs[i].glyph = g;
170*4882a593Smuzhiyun i++;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun next:
173*4882a593Smuzhiyun x += glyph->info.xOff;
174*4882a593Smuzhiyun y += glyph->info.yOff;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun list++;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
180*4882a593Smuzhiyun goto out;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
183*4882a593Smuzhiyun goto out_free_src;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (maskFormat) {
186*4882a593Smuzhiyun pixman_format_code_t format;
187*4882a593Smuzhiyun pixman_box32_t extents;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun format = maskFormat->format | (maskFormat->depth << 24);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun pixman_composite_glyphs(op, srcImage, dstImage, format,
194*4882a593Smuzhiyun xSrc + srcXoff + extents.x1 - xDst, ySrc + srcYoff + extents.y1 - yDst,
195*4882a593Smuzhiyun extents.x1, extents.y1,
196*4882a593Smuzhiyun extents.x1 + dstXoff, extents.y1 + dstYoff,
197*4882a593Smuzhiyun extents.x2 - extents.x1,
198*4882a593Smuzhiyun extents.y2 - extents.y1,
199*4882a593Smuzhiyun glyphCache, n_glyphs, pglyphs);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun else {
202*4882a593Smuzhiyun pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
203*4882a593Smuzhiyun xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
204*4882a593Smuzhiyun dstXoff, dstYoff,
205*4882a593Smuzhiyun glyphCache, n_glyphs, pglyphs);
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun free_pixman_pict(pDst, dstImage);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun out_free_src:
211*4882a593Smuzhiyun free_pixman_pict(pSrc, srcImage);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun out:
214*4882a593Smuzhiyun pixman_glyph_cache_thaw(glyphCache);
215*4882a593Smuzhiyun if (pglyphs != stack_glyphs)
216*4882a593Smuzhiyun free(pglyphs);
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun static pixman_image_t *
create_solid_fill_image(PicturePtr pict)220*4882a593Smuzhiyun create_solid_fill_image(PicturePtr pict)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun PictSolidFill *solid = &pict->pSourcePict->solidFill;
223*4882a593Smuzhiyun /* pixman_color_t and xRenderColor have the same layout */
224*4882a593Smuzhiyun pixman_color_t *color = (pixman_color_t *)&solid->fullcolor;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun return pixman_image_create_solid_fill(color);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun static pixman_image_t *
create_linear_gradient_image(PictGradient * gradient)230*4882a593Smuzhiyun create_linear_gradient_image(PictGradient * gradient)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun PictLinearGradient *linear = (PictLinearGradient *) gradient;
233*4882a593Smuzhiyun pixman_point_fixed_t p1;
234*4882a593Smuzhiyun pixman_point_fixed_t p2;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun p1.x = linear->p1.x;
237*4882a593Smuzhiyun p1.y = linear->p1.y;
238*4882a593Smuzhiyun p2.x = linear->p2.x;
239*4882a593Smuzhiyun p2.y = linear->p2.y;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun return pixman_image_create_linear_gradient(&p1, &p2,
242*4882a593Smuzhiyun (pixman_gradient_stop_t *)
243*4882a593Smuzhiyun gradient->stops,
244*4882a593Smuzhiyun gradient->nstops);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun static pixman_image_t *
create_radial_gradient_image(PictGradient * gradient)248*4882a593Smuzhiyun create_radial_gradient_image(PictGradient * gradient)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun PictRadialGradient *radial = (PictRadialGradient *) gradient;
251*4882a593Smuzhiyun pixman_point_fixed_t c1;
252*4882a593Smuzhiyun pixman_point_fixed_t c2;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun c1.x = radial->c1.x;
255*4882a593Smuzhiyun c1.y = radial->c1.y;
256*4882a593Smuzhiyun c2.x = radial->c2.x;
257*4882a593Smuzhiyun c2.y = radial->c2.y;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun return pixman_image_create_radial_gradient(&c1, &c2, radial->c1.radius,
260*4882a593Smuzhiyun radial->c2.radius,
261*4882a593Smuzhiyun (pixman_gradient_stop_t *)
262*4882a593Smuzhiyun gradient->stops,
263*4882a593Smuzhiyun gradient->nstops);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun static pixman_image_t *
create_conical_gradient_image(PictGradient * gradient)267*4882a593Smuzhiyun create_conical_gradient_image(PictGradient * gradient)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun PictConicalGradient *conical = (PictConicalGradient *) gradient;
270*4882a593Smuzhiyun pixman_point_fixed_t center;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun center.x = conical->center.x;
273*4882a593Smuzhiyun center.y = conical->center.y;
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun return pixman_image_create_conical_gradient(¢er, conical->angle,
276*4882a593Smuzhiyun (pixman_gradient_stop_t *)
277*4882a593Smuzhiyun gradient->stops,
278*4882a593Smuzhiyun gradient->nstops);
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun static pixman_image_t *
create_bits_picture(PicturePtr pict,Bool has_clip,int * xoff,int * yoff)282*4882a593Smuzhiyun create_bits_picture(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun PixmapPtr pixmap;
285*4882a593Smuzhiyun FbBits *bits;
286*4882a593Smuzhiyun FbStride stride;
287*4882a593Smuzhiyun int bpp;
288*4882a593Smuzhiyun pixman_image_t *image;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun fbGetDrawablePixmap(pict->pDrawable, pixmap, *xoff, *yoff);
291*4882a593Smuzhiyun fbGetPixmapBitsData(pixmap, bits, stride, bpp);
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun image = pixman_image_create_bits((pixman_format_code_t) pict->format,
294*4882a593Smuzhiyun pixmap->drawable.width,
295*4882a593Smuzhiyun pixmap->drawable.height, (uint32_t *) bits,
296*4882a593Smuzhiyun stride * sizeof(FbStride));
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun if (!image)
299*4882a593Smuzhiyun return NULL;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun #ifdef FB_ACCESS_WRAPPER
302*4882a593Smuzhiyun pixman_image_set_accessors(image,
303*4882a593Smuzhiyun (pixman_read_memory_func_t) wfbReadMemory,
304*4882a593Smuzhiyun (pixman_write_memory_func_t) wfbWriteMemory);
305*4882a593Smuzhiyun #endif
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun /* pCompositeClip is undefined for source pictures, so
308*4882a593Smuzhiyun * only set the clip region for pictures with drawables
309*4882a593Smuzhiyun */
310*4882a593Smuzhiyun if (has_clip) {
311*4882a593Smuzhiyun if (pict->clientClip)
312*4882a593Smuzhiyun pixman_image_set_has_client_clip(image, TRUE);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun if (*xoff || *yoff)
315*4882a593Smuzhiyun pixman_region_translate(pict->pCompositeClip, *xoff, *yoff);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun pixman_image_set_clip_region(image, pict->pCompositeClip);
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (*xoff || *yoff)
320*4882a593Smuzhiyun pixman_region_translate(pict->pCompositeClip, -*xoff, -*yoff);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun /* Indexed table */
324*4882a593Smuzhiyun if (pict->pFormat->index.devPrivate)
325*4882a593Smuzhiyun pixman_image_set_indexed(image, pict->pFormat->index.devPrivate);
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun /* Add in drawable origin to position within the image */
328*4882a593Smuzhiyun *xoff += pict->pDrawable->x;
329*4882a593Smuzhiyun *yoff += pict->pDrawable->y;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun return image;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun static pixman_image_t *image_from_pict_internal(PicturePtr pict, Bool has_clip,
335*4882a593Smuzhiyun int *xoff, int *yoff,
336*4882a593Smuzhiyun Bool is_alpha_map);
337*4882a593Smuzhiyun
image_destroy(pixman_image_t * image,void * data)338*4882a593Smuzhiyun static void image_destroy(pixman_image_t *image, void *data)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun fbFinishAccess((DrawablePtr)data);
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun static void
set_image_properties(pixman_image_t * image,PicturePtr pict,Bool has_clip,int * xoff,int * yoff,Bool is_alpha_map)344*4882a593Smuzhiyun set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
345*4882a593Smuzhiyun int *xoff, int *yoff, Bool is_alpha_map)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun pixman_repeat_t repeat;
348*4882a593Smuzhiyun pixman_filter_t filter;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun if (pict->transform) {
351*4882a593Smuzhiyun /* For source images, adjust the transform to account
352*4882a593Smuzhiyun * for the drawable offset within the pixman image,
353*4882a593Smuzhiyun * then set the offset to 0 as it will be used
354*4882a593Smuzhiyun * to compute positions within the transformed image.
355*4882a593Smuzhiyun */
356*4882a593Smuzhiyun if (!has_clip) {
357*4882a593Smuzhiyun struct pixman_transform adjusted;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun adjusted = *pict->transform;
360*4882a593Smuzhiyun pixman_transform_translate(&adjusted,
361*4882a593Smuzhiyun NULL,
362*4882a593Smuzhiyun pixman_int_to_fixed(*xoff),
363*4882a593Smuzhiyun pixman_int_to_fixed(*yoff));
364*4882a593Smuzhiyun pixman_image_set_transform(image, &adjusted);
365*4882a593Smuzhiyun *xoff = 0;
366*4882a593Smuzhiyun *yoff = 0;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun else
369*4882a593Smuzhiyun pixman_image_set_transform(image, pict->transform);
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun switch (pict->repeatType) {
373*4882a593Smuzhiyun default:
374*4882a593Smuzhiyun case RepeatNone:
375*4882a593Smuzhiyun repeat = PIXMAN_REPEAT_NONE;
376*4882a593Smuzhiyun break;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun case RepeatPad:
379*4882a593Smuzhiyun repeat = PIXMAN_REPEAT_PAD;
380*4882a593Smuzhiyun break;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun case RepeatNormal:
383*4882a593Smuzhiyun repeat = PIXMAN_REPEAT_NORMAL;
384*4882a593Smuzhiyun break;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun case RepeatReflect:
387*4882a593Smuzhiyun repeat = PIXMAN_REPEAT_REFLECT;
388*4882a593Smuzhiyun break;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun pixman_image_set_repeat(image, repeat);
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun /* Fetch alpha map unless 'pict' is being used
394*4882a593Smuzhiyun * as the alpha map for this operation
395*4882a593Smuzhiyun */
396*4882a593Smuzhiyun if (pict->alphaMap && !is_alpha_map) {
397*4882a593Smuzhiyun int alpha_xoff, alpha_yoff;
398*4882a593Smuzhiyun pixman_image_t *alpha_map =
399*4882a593Smuzhiyun image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff,
400*4882a593Smuzhiyun &alpha_yoff, TRUE);
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x,
403*4882a593Smuzhiyun pict->alphaOrigin.y);
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun free_pixman_pict(pict->alphaMap, alpha_map);
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun pixman_image_set_component_alpha(image, pict->componentAlpha);
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun switch (pict->filter) {
411*4882a593Smuzhiyun default:
412*4882a593Smuzhiyun case PictFilterNearest:
413*4882a593Smuzhiyun case PictFilterFast:
414*4882a593Smuzhiyun filter = PIXMAN_FILTER_NEAREST;
415*4882a593Smuzhiyun break;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun case PictFilterBilinear:
418*4882a593Smuzhiyun case PictFilterGood:
419*4882a593Smuzhiyun filter = PIXMAN_FILTER_BILINEAR;
420*4882a593Smuzhiyun break;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun case PictFilterConvolution:
423*4882a593Smuzhiyun filter = PIXMAN_FILTER_CONVOLUTION;
424*4882a593Smuzhiyun break;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun if (pict->pDrawable)
428*4882a593Smuzhiyun pixman_image_set_destroy_function(image, &image_destroy,
429*4882a593Smuzhiyun pict->pDrawable);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun pixman_image_set_filter(image, filter,
432*4882a593Smuzhiyun (pixman_fixed_t *) pict->filter_params,
433*4882a593Smuzhiyun pict->filter_nparams);
434*4882a593Smuzhiyun pixman_image_set_source_clipping(image, TRUE);
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun static pixman_image_t *
image_from_pict_internal(PicturePtr pict,Bool has_clip,int * xoff,int * yoff,Bool is_alpha_map)438*4882a593Smuzhiyun image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
439*4882a593Smuzhiyun Bool is_alpha_map)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun pixman_image_t *image = NULL;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun if (!pict)
444*4882a593Smuzhiyun return NULL;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun if (pict->pDrawable) {
447*4882a593Smuzhiyun image = create_bits_picture(pict, has_clip, xoff, yoff);
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun else if (pict->pSourcePict) {
450*4882a593Smuzhiyun SourcePict *sp = pict->pSourcePict;
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun if (sp->type == SourcePictTypeSolidFill) {
453*4882a593Smuzhiyun image = create_solid_fill_image(pict);
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun else {
456*4882a593Smuzhiyun PictGradient *gradient = &pict->pSourcePict->gradient;
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun if (sp->type == SourcePictTypeLinear)
459*4882a593Smuzhiyun image = create_linear_gradient_image(gradient);
460*4882a593Smuzhiyun else if (sp->type == SourcePictTypeRadial)
461*4882a593Smuzhiyun image = create_radial_gradient_image(gradient);
462*4882a593Smuzhiyun else if (sp->type == SourcePictTypeConical)
463*4882a593Smuzhiyun image = create_conical_gradient_image(gradient);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun *xoff = *yoff = 0;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun if (image)
469*4882a593Smuzhiyun set_image_properties(image, pict, has_clip, xoff, yoff, is_alpha_map);
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun return image;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun pixman_image_t *
image_from_pict(PicturePtr pict,Bool has_clip,int * xoff,int * yoff)475*4882a593Smuzhiyun image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun return image_from_pict_internal(pict, has_clip, xoff, yoff, FALSE);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun void
free_pixman_pict(PicturePtr pict,pixman_image_t * image)481*4882a593Smuzhiyun free_pixman_pict(PicturePtr pict, pixman_image_t * image)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun if (image)
484*4882a593Smuzhiyun pixman_image_unref(image);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun Bool
fbPictureInit(ScreenPtr pScreen,PictFormatPtr formats,int nformats)488*4882a593Smuzhiyun fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun PictureScreenPtr ps;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (!miPictureInit(pScreen, formats, nformats))
494*4882a593Smuzhiyun return FALSE;
495*4882a593Smuzhiyun ps = GetPictureScreen(pScreen);
496*4882a593Smuzhiyun ps->Composite = fbComposite;
497*4882a593Smuzhiyun ps->Glyphs = fbGlyphs;
498*4882a593Smuzhiyun ps->UnrealizeGlyph = fbUnrealizeGlyph;
499*4882a593Smuzhiyun ps->CompositeRects = miCompositeRects;
500*4882a593Smuzhiyun ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
501*4882a593Smuzhiyun ps->Trapezoids = fbTrapezoids;
502*4882a593Smuzhiyun ps->AddTraps = fbAddTraps;
503*4882a593Smuzhiyun ps->AddTriangles = fbAddTriangles;
504*4882a593Smuzhiyun ps->Triangles = fbTriangles;
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun return TRUE;
507*4882a593Smuzhiyun }
508