Rename pixman-pict.c to pixman.c
[profile/ivi/pixman.git] / pixman / pixman.c
1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
2 /*
3  * Copyright © 2000 SuSE, Inc.
4  * Copyright © 2007 Red Hat, Inc.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of SuSE not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  SuSE makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author:  Keith Packard, SuSE, Inc.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 #include "pixman-private.h"
30
31 /*
32  * Operator optimizations based on source or destination opacity
33  */
34 typedef struct
35 {
36     pixman_op_t                 op;
37     pixman_op_t                 opSrcDstOpaque;
38     pixman_op_t                 opSrcOpaque;
39     pixman_op_t                 opDstOpaque;
40 } OptimizedOperatorInfo;
41
42 static const OptimizedOperatorInfo optimized_operators[] =
43 {
44     /* Input Operator           SRC&DST Opaque          SRC Opaque              DST Opaque      */
45     { PIXMAN_OP_OVER,           PIXMAN_OP_SRC,          PIXMAN_OP_SRC,          PIXMAN_OP_OVER },
46     { PIXMAN_OP_OVER_REVERSE,   PIXMAN_OP_DST,          PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST },
47     { PIXMAN_OP_IN,             PIXMAN_OP_SRC,          PIXMAN_OP_IN,           PIXMAN_OP_SRC },
48     { PIXMAN_OP_IN_REVERSE,     PIXMAN_OP_DST,          PIXMAN_OP_DST,          PIXMAN_OP_IN_REVERSE },
49     { PIXMAN_OP_OUT,            PIXMAN_OP_CLEAR,        PIXMAN_OP_OUT,          PIXMAN_OP_CLEAR },
50     { PIXMAN_OP_OUT_REVERSE,    PIXMAN_OP_CLEAR,        PIXMAN_OP_CLEAR,        PIXMAN_OP_OUT_REVERSE },
51     { PIXMAN_OP_ATOP,           PIXMAN_OP_SRC,          PIXMAN_OP_IN,           PIXMAN_OP_OVER },
52     { PIXMAN_OP_ATOP_REVERSE,   PIXMAN_OP_DST,          PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_IN_REVERSE },
53     { PIXMAN_OP_XOR,            PIXMAN_OP_CLEAR,        PIXMAN_OP_OUT,          PIXMAN_OP_OUT_REVERSE },
54     { PIXMAN_OP_SATURATE,       PIXMAN_OP_DST,          PIXMAN_OP_OVER_REVERSE, PIXMAN_OP_DST },
55     { PIXMAN_OP_NONE }
56 };
57
58 /*
59  * Check if the current operator could be optimized
60  */
61 static const OptimizedOperatorInfo*
62 pixman_operator_can_be_optimized(pixman_op_t op)
63 {
64     const OptimizedOperatorInfo *info;
65
66     for (info = optimized_operators; info->op != PIXMAN_OP_NONE; info++)
67     {
68         if(info->op == op)
69             return info;
70     }
71     return NULL;
72 }
73
74 /*
75  * Optimize the current operator based on opacity of source or destination
76  * The output operator should be mathematically equivalent to the source.
77  */
78 static pixman_op_t
79 pixman_optimize_operator(pixman_op_t op, pixman_image_t *pSrc, pixman_image_t *pMask, pixman_image_t *pDst )
80 {
81     pixman_bool_t is_source_opaque;
82     pixman_bool_t is_dest_opaque;
83     const OptimizedOperatorInfo *info = pixman_operator_can_be_optimized(op);
84
85     if(!info || pMask)
86         return op;
87
88     is_source_opaque = pixman_image_is_opaque(pSrc);
89     is_dest_opaque = pixman_image_is_opaque(pDst);
90
91     if(is_source_opaque == FALSE && is_dest_opaque == FALSE)
92         return op;
93
94     if(is_source_opaque && is_dest_opaque)
95         return info->opSrcDstOpaque;
96     else if(is_source_opaque)
97         return info->opSrcOpaque;
98     else if(is_dest_opaque)
99         return info->opDstOpaque;
100
101     return op;
102
103 }
104
105 static pixman_implementation_t *imp;
106
107 PIXMAN_EXPORT void
108 pixman_image_composite (pixman_op_t      op,
109                         pixman_image_t * src,
110                         pixman_image_t * mask,
111                         pixman_image_t * dest,
112                         int16_t      src_x,
113                         int16_t      src_y,
114                         int16_t      mask_x,
115                         int16_t      mask_y,
116                         int16_t      dest_x,
117                         int16_t      dest_y,
118                         uint16_t     width,
119                         uint16_t     height)
120 {
121     /*
122      * Check if we can replace our operator by a simpler one if the src or dest are opaque
123      * The output operator should be mathematically equivalent to the source.
124      */
125     op = pixman_optimize_operator(op, src, mask, dest);
126     if(op == PIXMAN_OP_DST)
127         return;
128
129     if (!imp)
130         imp = _pixman_choose_implementation();
131
132     _pixman_implementation_composite (imp, op,
133                                       src, mask, dest,
134                                       src_x, src_y,
135                                       mask_x, mask_y,
136                                       dest_x, dest_y,
137                                       width, height);
138 }
139
140 PIXMAN_EXPORT pixman_bool_t
141 pixman_blt (uint32_t *src_bits,
142             uint32_t *dst_bits,
143             int src_stride,
144             int dst_stride,
145             int src_bpp,
146             int dst_bpp,
147             int src_x, int src_y,
148             int dst_x, int dst_y,
149             int width, int height)
150 {
151     if (!imp)
152         imp = _pixman_choose_implementation();
153     
154     return _pixman_implementation_blt (imp, src_bits, dst_bits, src_stride, dst_stride,
155                                        src_bpp, dst_bpp,
156                                        src_x, src_y,
157                                        dst_x, dst_y,
158                                        width, height);
159 }
160
161 PIXMAN_EXPORT pixman_bool_t
162 pixman_fill (uint32_t *bits,
163              int stride,
164              int bpp,
165              int x,
166              int y,
167              int width,
168              int height,
169              uint32_t xor)
170 {
171     if (!imp)
172         imp = _pixman_choose_implementation();
173
174     return _pixman_implementation_fill (imp, bits, stride, bpp, x, y, width, height, xor);
175 }