altos/draw: Add a reasonable API for drawing, add lines.
[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 -= 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 static inline uint32_t
90 ao_do_mask_rrop(uint32_t dst, uint32_t and, uint32_t xor, uint32_t mask) {
91         return (dst & (and | ~mask)) ^ (xor & mask);
92 }
93
94 static inline uint32_t
95 ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) {
96         return (dst & and) ^ xor;
97 }
98
99 void
100 ao_blt(uint32_t         *src_line,
101        int16_t          src_stride,
102        int16_t          src_x,
103        uint32_t         *dst_line,
104        int16_t          dst_stride,
105        int16_t          dst_x,
106        int16_t          width,
107        int16_t          height,
108        uint8_t          rop,
109        uint8_t          reverse,
110        uint8_t          upsidedown);
111
112 void
113 ao_solid(uint32_t       and,
114          uint32_t       xor,
115          uint32_t       *dst,
116          int16_t        dst_stride,
117          int16_t        dst_x,
118          int16_t        width,
119          int16_t        height);
120
121 int16_t
122 ao_glyph(const struct ao_bitmap *dst,
123          int16_t                x,
124          int16_t                y,
125          uint8_t                c,
126          uint8_t                rop);
127
128 #endif /* _AO_DRAW_INT_H_ */