Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-gdi / shape.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * GDI Shape Functions
4  *
5  * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <freerdp/freerdp.h>
24 #include <freerdp/gdi/gdi.h>
25
26 #include <freerdp/gdi/8bpp.h>
27 #include <freerdp/gdi/16bpp.h>
28 #include <freerdp/gdi/32bpp.h>
29 #include <freerdp/gdi/bitmap.h>
30
31 #include <freerdp/gdi/shape.h>
32
33 p_FillRect FillRect_[5] =
34 {
35         NULL,
36         FillRect_8bpp,
37         FillRect_16bpp,
38         NULL,
39         FillRect_32bpp
40 };
41
42 static void Ellipse_Bresenham(HGDI_DC hdc, int x1, int y1, int x2, int y2)
43 {
44         int i;
45         long e, e2;
46         long dx, dy;
47         int a, b, c;
48
49         HGDI_BITMAP bmp;
50         uint8 pixel8;
51         uint16 pixel16;
52         uint32 pixel32;
53         int bpp = hdc->bitsPerPixel;
54
55         a = (x1 < x2) ? x2 - x1 : x1 - x2;
56         b = (y1 < y2) ? y2 - y1 : y1 - y2;
57         c = b & 1;
58
59         dx = 4 * (1 - a) * b * b;
60         dy = 4 * (c + 1) * a * a;
61         e = dx + dy + c * a * a;
62
63         if (x1 > x2)
64         {
65                 x1 = x2;
66                 x2 += a;
67         }
68
69         if (y1 > y2)
70                 y1 = y2;
71
72         y1 += (b + 1) / 2;
73         y2 = y1 - c;
74
75         a *= 8 * a;
76         c = 8 * b * b;
77
78         pixel8 = 0;
79         pixel16 = 0;
80         pixel32 = 0;
81         bmp = (HGDI_BITMAP) hdc->selectedObject;
82
83         do
84         {
85                 if (bpp == 32)
86                 {
87                         gdi_SetPixel_32bpp(bmp, x2, y1, pixel32);
88                         gdi_SetPixel_32bpp(bmp, x1, y1, pixel32);
89                         gdi_SetPixel_32bpp(bmp, x1, y2, pixel32);
90                         gdi_SetPixel_32bpp(bmp, x2, y2, pixel32);
91                 }
92                 else if (bpp == 16)
93                 {
94                         gdi_SetPixel_16bpp(bmp, x2, y1, pixel16);
95                         gdi_SetPixel_16bpp(bmp, x1, y1, pixel16);
96                         gdi_SetPixel_16bpp(bmp, x1, y2, pixel16);
97                         gdi_SetPixel_16bpp(bmp, x2, y2, pixel16);
98                 }
99                 else if (bpp == 8)
100                 {
101                         for (i = x1; i < x2; i++)
102                         {
103                                 gdi_SetPixel_8bpp(bmp, i, y1, pixel8);
104                                 gdi_SetPixel_8bpp(bmp, i, y2, pixel8);
105                         }
106
107                         for (i = y1; i < y2; i++)
108                         {
109                                 gdi_SetPixel_8bpp(bmp, x1, i, pixel8);
110                                 gdi_SetPixel_8bpp(bmp, x2, i, pixel8);
111                         }
112                 }
113
114                 e2 = 2 * e;
115
116                 if (e2 >= dx)
117                 {
118                         x1++;
119                         x2--;
120                         e += dx += c;
121                 }
122
123                 if (e2 <= dy)
124                 {
125                         y1++;
126                         y2--;
127                         e += dy += a;
128                 }
129         }
130         while (x1 <= x2);
131
132         while (y1 - y2 < b)
133         {
134                 if (bpp == 32)
135                 {
136                         gdi_SetPixel_32bpp(bmp, x1 - 1, ++y1, pixel32);
137                         gdi_SetPixel_32bpp(bmp, x1 - 1, --y2, pixel32);
138                 }
139                 else if (bpp == 16)
140                 {
141                         gdi_SetPixel_16bpp(bmp, x1 - 1, ++y1, pixel16);
142                         gdi_SetPixel_16bpp(bmp, x1 - 1, --y2, pixel16);
143                 }
144                 else if (bpp == 8)
145                 {
146                         gdi_SetPixel_8bpp(bmp, x1 - 1, ++y1, pixel8);
147                         gdi_SetPixel_8bpp(bmp, x1 - 1, --y2, pixel8);
148                 }
149         }
150 }
151
152 /**
153  * Draw an ellipse
154  * @param hdc device context
155  * @param nLeftRect x1
156  * @param nTopRect y1
157  * @param nRightRect x2
158  * @param nBottomRect y2
159  * @return
160  */
161 int gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
162 {
163         Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
164         return 1;
165 }
166
167 /**
168  * Fill a rectangle with the given brush.\n
169  * @msdn{dd162719}
170  * @param hdc device context
171  * @param rect rectangle
172  * @param hbr brush
173  * @return 1 if successful, 0 otherwise
174  */
175
176 int gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
177 {
178         p_FillRect _FillRect = FillRect_[IBPP(hdc->bitsPerPixel)];
179
180         if (_FillRect != NULL)
181                 return _FillRect(hdc, rect, hbr);
182         else
183                 return 0;
184 }
185
186 /**
187  *
188  * @param hdc device context
189  * @param lpPoints array of points
190  * @param nCount number of points
191  * @return
192  */
193 int gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount)
194 {
195         return 1;
196 }
197
198 /**
199  * Draw a series of closed polygons
200  * @param hdc device context
201  * @param lpPoints array of series of points
202  * @param lpPolyCounts array of number of points in each series
203  * @param nCount count of number of points in lpPolyCounts
204  * @return
205  */
206 int gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount)
207 {
208         return 1;
209 }
210
211 /**
212  * Draw a rectangle
213  * @param hdc device context
214  * @param nLeftRect x1
215  * @param nTopRect y1
216  * @param nRightRect x2
217  * @param nBottomRect y2
218  * @return
219  */
220 int gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
221 {
222         return 1;
223 }