altos/draw: Add damage tracking
[fw/altos] / src / draw / ao_draw_int.h
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #ifndef _AO_DRAW_INT_H_
16 #define _AO_DRAW_INT_H_
17
18 static inline uint32_t
19 ao_expand(uint32_t bits)
20 {
21         return ~((bits & 1)-1);
22 }
23
24 static inline uint32_t
25 ao_xor(uint8_t rop, uint32_t fg)
26 {
27         fg = ao_expand(fg);
28
29         return (fg & ao_expand(rop >> 1)) |
30                 (~fg & ao_expand(rop >> 3));
31 }
32
33 static inline uint32_t
34 ao_and(uint8_t rop, uint32_t fg)
35 {
36         fg = ao_expand(fg);
37
38         return (fg & ao_expand(rop ^ (rop >> 1))) |
39                 (~fg & ao_expand((rop>>2) ^ (rop>>3)));
40 }
41
42 static inline uint32_t
43 ao_left(uint32_t bits, int16_t shift) {
44         return bits >> shift;
45 }
46
47 static inline uint32_t
48 ao_right(uint32_t bits, int16_t shift) {
49         return bits << shift;
50 }
51
52 static inline uint32_t
53 ao_right_mask(int16_t x) {
54         if ((AO_UNIT - x) & AO_MASK)
55                 return ao_left(AO_ALLONES,(AO_UNIT - x) & AO_MASK);
56         else
57                 return 0;
58 }
59
60 static inline uint32_t
61 ao_left_mask(int16_t x) {
62         if (x & AO_MASK)
63                 return ao_right(AO_ALLONES, x & AO_MASK);
64         else
65                 return 0;
66 }
67
68 static inline uint32_t
69 ao_bits_mask(int16_t x, int16_t w) {
70         return ao_right(AO_ALLONES, x & AO_MASK) &
71                 ao_left(AO_ALLONES,(AO_UNIT - (x + w)) & AO_MASK);
72 }
73
74 #define ao_mask_bits(x,w,l,n,r) { \
75     n = (w); \
76     r = ao_right_mask((x)+n); \
77     l = ao_left_mask(x); \
78     if (l) { \
79         n -= (int16_t) (AO_UNIT - ((x) & AO_MASK));     \
80         if (n < 0) { \
81             n = 0; \
82             l &= r; \
83             r = 0; \
84         } \
85     } \
86     n >>= AO_SHIFT; \
87 }
88
89 #define ao_clip(val,min,max) do {               \
90                 if (val < min) {                \
91                         val = min;              \
92                 } else if (val > max) {         \
93                         val = max;              \
94                 }                               \
95         } while (0)
96
97 static inline int16_t
98 ao_min16(int16_t a, int16_t b)
99 {
100         return a < b ? a : b;
101 }
102
103 static inline int16_t
104 ao_max16(int16_t a, int16_t b)
105 {
106         return a > b ? a : b;
107 }
108
109 static inline uint32_t
110 ao_do_mask_rrop(uint32_t dst, uint32_t and, uint32_t xor, uint32_t mask) {
111         return (dst & (and | ~mask)) ^ (xor & mask);
112 }
113
114 static inline uint32_t
115 ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) {
116         return (dst & and) ^ xor;
117 }
118
119 static inline void
120 ao_damage(struct ao_bitmap      *dst,
121           int16_t               x1,
122           int16_t               y1,
123           int16_t               x2,
124           int16_t               y2)
125 {
126         ao_box_union(&dst->damage, x1, y1, x2, y2);
127 }
128
129 void
130 ao_blt(uint32_t         *src_line,
131        int16_t          src_stride,
132        int16_t          src_x,
133        uint32_t         *dst_line,
134        int16_t          dst_stride,
135        int16_t          dst_x,
136        int16_t          width,
137        int16_t          height,
138        uint8_t          rop,
139        uint8_t          reverse,
140        uint8_t          upsidedown);
141
142 void
143 ao_solid(uint32_t       and,
144          uint32_t       xor,
145          uint32_t       *dst,
146          int16_t        dst_stride,
147          int16_t        dst_x,
148          int16_t        width,
149          int16_t        height);
150
151 int16_t
152 ao_glyph(const struct ao_bitmap *dst,
153          int16_t                x,
154          int16_t                y,
155          uint8_t                c,
156          uint8_t                rop);
157
158 #endif /* _AO_DRAW_INT_H_ */