Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-gdi / 16bpp.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * GDI 16bpp Internal Buffer Routines
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/api.h>
24 #include <freerdp/freerdp.h>
25 #include <freerdp/gdi/gdi.h>
26 #include <freerdp/codec/color.h>
27
28 #include <freerdp/gdi/pen.h>
29 #include <freerdp/gdi/bitmap.h>
30 #include <freerdp/gdi/region.h>
31 #include <freerdp/gdi/clipping.h>
32 #include <freerdp/gdi/drawing.h>
33
34 #include <freerdp/gdi/16bpp.h>
35
36 uint16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color)
37 {
38         uint8 r, g, b;
39         uint16 color16;
40
41         GetBGR32(r, g, b, color);
42
43         if (hdc->rgb555)
44         {
45                 if (hdc->invert)
46                 {
47                         color16 = BGR15(r, g, b);
48                 }
49                 else
50                 {
51                         color16 = RGB15(r, g, b);
52                 }
53         }
54         else
55         {
56                 if (hdc->invert)
57                 {
58                         color16 = BGR16(r, g, b);
59                 }
60                 else
61                 {
62                         color16 = RGB16(r, g, b);
63                 }
64         }
65
66         return color16;
67 }
68
69 int FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
70 {
71         int x, y;
72         uint16 *dstp;
73         int nXDest, nYDest;
74         int nWidth, nHeight;
75
76         uint16 color16;
77         
78         gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);
79         
80         if (gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
81                 return 0;
82
83         color16 = gdi_get_color_16bpp(hdc, hbr->color);
84
85         for (y = 0; y < nHeight; y++)
86         {
87                 dstp = (uint16*) gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
88
89                 if (dstp != 0)
90                 {
91                         for (x = 0; x < nWidth; x++)
92                         {
93                                 *dstp = color16;
94                                 dstp++;
95                         }
96                 }
97         }
98
99         gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight);
100         return 0;
101 }
102
103 static int BitBlt_BLACKNESS_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
104 {
105         int y;
106         uint8* dstp;
107
108         for (y = 0; y < nHeight; y++)
109         {
110                 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
111
112                 if (dstp != 0)
113                         memset(dstp, 0, nWidth * hdcDest->bytesPerPixel);
114         }
115
116         return 0;
117 }
118
119 static int BitBlt_WHITENESS_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
120 {
121         int y;
122         uint8* dstp;
123         
124         for (y = 0; y < nHeight; y++)
125         {
126                 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
127
128                 if (dstp != 0)
129                         memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel);
130         }
131
132         return 0;
133 }
134
135 static int BitBlt_SRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
136 {
137         int y;
138         uint8* srcp;
139         uint8* dstp;
140
141         if ((hdcDest->selectedObject != hdcSrc->selectedObject) ||
142             gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0)
143         {
144                 for (y = 0; y < nHeight; y++)
145                 {
146                         srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
147                         dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
148
149                         if (srcp != 0 && dstp != 0)
150                                 memcpy(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
151                 }
152
153                 return 0;
154         }
155         
156         if (nYSrc < nYDest)
157         {
158                 /* copy down (bottom to top) */
159                 for (y = nHeight - 1; y >= 0; y--)
160                 {
161                         srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
162                         dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
163
164                         if (srcp != 0 && dstp != 0)
165                                 memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
166                 }
167         }
168         else if (nYSrc > nYDest || nXSrc > nXDest)
169         {
170                 /* copy up or left (top top bottom) */
171                 for (y = 0; y < nHeight; y++)
172                 {
173                         srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
174                         dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
175
176                         if (srcp != 0 && dstp != 0)
177                                 memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
178                 }
179         }
180         else
181         {
182                 /* copy straight right */
183                 for (y = 0; y < nHeight; y++)
184                 {
185                         srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
186                         dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
187
188                         if (srcp != 0 && dstp != 0)
189                                 memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
190                 }
191         }
192         
193         return 0;
194 }
195
196 static int BitBlt_NOTSRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
197 {
198         int x, y;
199         uint16* srcp;
200         uint16* dstp;
201         
202         for (y = 0; y < nHeight; y++)
203         {
204                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
205                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
206
207                 if (dstp != 0)
208                 {
209                         for (x = 0; x < nWidth; x++)
210                         {
211                                 *dstp = ~(*srcp);
212                                 srcp++;
213                                 dstp++;
214                         }
215                 }
216         }
217
218         return 0;
219 }
220
221 static int BitBlt_DSTINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
222 {
223         int x, y;
224         uint16* dstp;
225                 
226         for (y = 0; y < nHeight; y++)
227         {
228                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
229
230                 if (dstp != 0)
231                 {
232                         for (x = 0; x < nWidth; x++)
233                         {
234                                 *dstp = ~(*dstp);
235                                 dstp++;
236                         }
237                 }
238         }
239
240         return 0;
241 }
242
243 static int BitBlt_SRCERASE_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
244 {
245         int x, y;
246         uint16* srcp;
247         uint16* dstp;
248                 
249         for (y = 0; y < nHeight; y++)
250         {
251                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
252                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
253
254                 if (dstp != 0)
255                 {
256                         for (x = 0; x < nWidth; x++)
257                         {
258                                 *dstp = *srcp & ~(*dstp);
259                                 srcp++;
260                                 dstp++;
261                         }
262                 }
263         }
264
265         return 0;
266 }
267
268 static int BitBlt_NOTSRCERASE_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
269 {
270         int x, y;
271         uint16* srcp;
272         uint16* dstp;
273                 
274         for (y = 0; y < nHeight; y++)
275         {
276                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
277                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
278
279                 if (dstp != 0)
280                 {
281                         for (x = 0; x < nWidth; x++)
282                         {
283                                 *dstp = ~(*srcp) & ~(*dstp);
284                                 srcp++;
285                                 dstp++;
286                         }
287                 }
288         }
289
290         return 0;
291 }
292
293 static int BitBlt_SRCINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
294 {
295         int x, y;
296         uint16* srcp;
297         uint16* dstp;
298                 
299         for (y = 0; y < nHeight; y++)
300         {
301                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
302                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
303
304                 if (dstp != 0)
305                 {
306                         for (x = 0; x < nWidth; x++)
307                         {
308                                 *dstp ^= *srcp;
309                                 srcp++;
310                                 dstp++;
311                         }
312                 }
313         }
314
315         return 0;
316 }
317
318 static int BitBlt_SRCAND_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
319 {
320         int x, y;
321         uint16* srcp;
322         uint16* dstp;
323                 
324         for (y = 0; y < nHeight; y++)
325         {
326                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
327                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
328
329                 if (dstp != 0)
330                 {
331                         for (x = 0; x < nWidth; x++)
332                         {
333                                 *dstp &= *srcp;
334                                 srcp++;
335                                 dstp++;
336                         }
337                 }
338         }
339
340         return 0;
341 }
342
343 static int BitBlt_SRCPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
344 {
345         int x, y;
346         uint16* srcp;
347         uint16* dstp;
348                 
349         for (y = 0; y < nHeight; y++)
350         {
351                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
352                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
353
354                 if (dstp != 0)
355                 {
356                         for (x = 0; x < nWidth; x++)
357                         {
358                                 *dstp |= *srcp;
359                                 srcp++;
360                                 dstp++;
361                         }
362                 }
363         }
364
365         return 0;
366 }
367
368 static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
369 {       
370         int x, y;
371         uint8* srcp;
372         uint16* dstp;
373         uint16 src16;
374         uint16 color16;
375         HGDI_BITMAP hSrcBmp;
376
377         /* D = (S & P) | (~S & D) */
378         /* DSPDxax, used to draw glyphs */
379
380         color16 = gdi_get_color_16bpp(hdcDest, hdcDest->textColor);
381
382         hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
383
384         if (hdcSrc->bytesPerPixel != 1)
385         {
386                 printf("BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel);
387                 return 0;
388         }
389         
390         for (y = 0; y < nHeight; y++)
391         {
392                 srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
393                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
394
395                 if (dstp != 0)
396                 {
397                         for (x = 0; x < nWidth; x++)
398                         {
399                                 src16 = (*srcp << 8) | *srcp;
400                                 *dstp = (src16 & color16) | (~src16 & *dstp);
401                                 srcp++;
402                                 dstp++;
403                         }
404                 }
405         }
406
407         return 0;
408 }
409
410 static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
411 {
412         int x, y;
413         uint16* srcp;
414         uint16* dstp;
415         uint16* patp;
416         
417         for (y = 0; y < nHeight; y++)
418         {
419                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
420                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
421
422                 if (dstp != 0)
423                 {
424                         for (x = 0; x < nWidth; x++)
425                         {
426                                 patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
427                                 *dstp = *srcp & ~(*patp);
428                                 srcp++;
429                                 dstp++;
430                         }
431                 }
432         }
433         
434         return 0;
435 }
436
437 static int BitBlt_PDxn_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
438 {
439         int x, y;
440         uint16* dstp;
441         uint16* patp;
442
443         for (y = 0; y < nHeight; y++)
444         {
445                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
446
447                 if (dstp != 0)
448                 {
449                         for (x = 0; x < nWidth; x++)
450                         {
451                                 patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
452                                 *dstp = *dstp ^ ~(*patp);
453                                 dstp++;
454                         }
455                 }
456         }
457
458         return 0;
459 }
460
461 static int BitBlt_DSna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
462 {
463         int x, y;
464         uint16* srcp;
465         uint16* dstp;
466
467         for (y = 0; y < nHeight; y++)
468         {
469                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
470                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
471
472                 if (dstp != 0)
473                 {
474                         for (x = 0; x < nWidth; x++)
475                         {
476                                 *dstp = ~(*srcp) & (*dstp);
477                                 srcp++;
478                                 dstp++;
479                         }
480                 }
481         }
482
483         return 0;
484 }
485
486
487 static int BitBlt_MERGECOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
488 {
489         int x, y;
490         uint16* srcp;
491         uint16* dstp;
492         uint16* patp;
493         
494         for (y = 0; y < nHeight; y++)
495         {
496                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
497                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
498
499                 if (dstp != 0)
500                 {
501                         for (x = 0; x < nWidth; x++)
502                         {
503                                 patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
504                                 *dstp = *srcp & *patp;
505                                 srcp++;
506                                 dstp++;
507                         }
508                 }
509         }
510         
511         return 0;
512 }
513
514 static int BitBlt_MERGEPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
515 {
516         int x, y;
517         uint16* srcp;
518         uint16* dstp;
519         
520         for (y = 0; y < nHeight; y++)
521         {
522                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
523                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
524
525                 if (dstp != 0)
526                 {
527                         for (x = 0; x < nWidth; x++)
528                         {                               
529                                 *dstp = ~(*srcp) | *dstp;
530                                 srcp++;
531                                 dstp++;
532                         }
533                 }
534         }
535         
536         return 0;
537 }
538
539 static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
540 {
541         int x, y;
542         uint16* dstp;
543         uint16* patp;
544         uint16 color16;
545
546         if (hdcDest->brush->style == GDI_BS_SOLID)
547         {
548                 color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color);
549
550                 for (y = 0; y < nHeight; y++)
551                 {
552                         dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
553
554                         if (dstp != 0)
555                         {
556                                 for (x = 0; x < nWidth; x++)
557                                 {
558                                         *dstp = color16;
559                                         dstp++;
560                                 }
561                         }
562                 }
563         }
564         else
565         {
566                 for (y = 0; y < nHeight; y++)
567                 {
568                         dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
569
570                         if (dstp != 0)
571                         {
572                                 for (x = 0; x < nWidth; x++)
573                                 {
574                                         patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
575                                         *dstp = *patp;
576                                         dstp++;
577                                 }
578                         }
579                 }
580         }
581
582         return 0;
583 }
584
585 static int BitBlt_PATINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
586 {
587         int x, y;
588         uint16* dstp;
589         uint16* patp;
590         uint16 color16;
591
592         if (hdcDest->brush->style == GDI_BS_SOLID)
593         {
594                 color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color);
595
596                 for (y = 0; y < nHeight; y++)
597                 {
598                         dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
599
600                         if (dstp != 0)
601                         {
602                                 for (x = 0; x < nWidth; x++)
603                                 {
604                                         *dstp ^= color16;
605                                         dstp++;
606                                 }
607                         }
608                 }
609         }
610         else
611         {
612                 for (y = 0; y < nHeight; y++)
613                 {
614                         dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
615
616                         if (dstp != 0)
617                         {
618                                 for (x = 0; x < nWidth; x++)
619                                 {
620                                         patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
621                                         *dstp = *patp ^ *dstp;
622                                         dstp++;
623                                 }
624                         }
625                 }
626         }
627         
628         return 0;
629 }
630
631 static int BitBlt_PATPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
632 {
633         int x, y;
634         uint16* srcp;
635         uint16* dstp;
636         uint16* patp;
637         
638         for (y = 0; y < nHeight; y++)
639         {
640                 srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
641                 dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
642
643                 if (dstp != 0)
644                 {
645                         for (x = 0; x < nWidth; x++)
646                         {
647                                 patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
648                                 *dstp = *dstp | (*patp | ~(*srcp));
649                                 srcp++;
650                                 dstp++;
651                         }
652                 }
653         }
654         
655         return 0;
656 }
657
658 int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
659 {
660         if (hdcSrc != NULL)
661         {
662                 if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0)
663                         return 0;
664         }
665         else
666         {
667                 if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
668                         return 0;
669         }
670         
671         gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
672         
673         switch (rop)
674         {
675                 case GDI_BLACKNESS:
676                         return BitBlt_BLACKNESS_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
677                         break;
678
679                 case GDI_WHITENESS:
680                         return BitBlt_WHITENESS_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
681                         break;
682
683                 case GDI_SRCCOPY:
684                         return BitBlt_SRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
685                         break;
686
687                 case GDI_SPna:
688                         return BitBlt_SPna_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
689                         break;
690
691                 case GDI_DSna:
692                         return BitBlt_DSna_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
693                         break;
694
695                 case GDI_DSPDxax:
696                         return BitBlt_DSPDxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
697                         break;
698                         
699                 case GDI_NOTSRCCOPY:
700                         return BitBlt_NOTSRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
701                         break;
702
703                 case GDI_DSTINVERT:
704                         return BitBlt_DSTINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
705                         break;
706
707                 case GDI_SRCERASE:
708                         return BitBlt_SRCERASE_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
709                         break;
710
711                 case GDI_NOTSRCERASE:
712                         return BitBlt_NOTSRCERASE_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
713                         break;
714
715                 case GDI_SRCINVERT:
716                         return BitBlt_SRCINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
717                         break;
718
719                 case GDI_SRCAND:
720                         return BitBlt_SRCAND_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
721                         break;
722
723                 case GDI_SRCPAINT:
724                         return BitBlt_SRCPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
725                         break;
726
727                 case GDI_MERGECOPY:
728                         return BitBlt_MERGECOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
729                         break;
730
731                 case GDI_MERGEPAINT:
732                         return BitBlt_MERGEPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
733                         break;
734
735                 case GDI_PATCOPY:
736                         return BitBlt_PATCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
737                         break;
738
739                 case GDI_PATINVERT:
740                         return BitBlt_PATINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
741                         break;
742
743                 case GDI_PATPAINT:
744                         return BitBlt_PATPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
745                         break;
746         }
747         
748         printf("BitBlt: unknown rop: 0x%08X\n", rop);
749         return 1;
750 }
751
752 int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
753 {
754         if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0)
755                 return 0;
756         
757         gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight);
758
759         switch (rop)
760         {
761                 case GDI_PATCOPY:
762                         return BitBlt_PATCOPY_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
763                         break;
764
765                 case GDI_PATINVERT:
766                         return BitBlt_PATINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
767                         break;
768                         
769                 case GDI_DSTINVERT:
770                         return BitBlt_DSTINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
771                         break;
772
773                 case GDI_BLACKNESS:
774                         return BitBlt_BLACKNESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
775                         break;
776
777                 case GDI_WHITENESS:
778                         return BitBlt_WHITENESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
779                         break;
780
781                 case GDI_PDxn:
782                         return BitBlt_PDxn_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
783                         break;
784
785                 default:
786                         break;
787         }
788         
789         printf("PatBlt: unknown rop: 0x%08X\n", rop);
790
791         return 1;
792 }
793
794 INLINE void SetPixel_BLACK_16bpp(uint16 *pixel, uint16 *pen)
795 {
796         /* D = 0 */
797         *pixel = 0;
798 }
799
800 INLINE void SetPixel_NOTMERGEPEN_16bpp(uint16 *pixel, uint16 *pen)
801 {
802         /* D = ~(D | P) */
803         *pixel = ~(*pixel | *pen);
804 }
805
806 INLINE void SetPixel_MASKNOTPEN_16bpp(uint16 *pixel, uint16 *pen)
807 {
808         /* D = D & ~P */
809         *pixel &= ~(*pen);
810 }
811
812 INLINE void SetPixel_NOTCOPYPEN_16bpp(uint16 *pixel, uint16 *pen)
813 {
814         /* D = ~P */
815         *pixel = ~(*pen);
816 }
817
818 INLINE void SetPixel_MASKPENNOT_16bpp(uint16 *pixel, uint16 *pen)
819 {
820         /* D = P & ~D */
821         *pixel = *pen & ~*pixel;
822 }
823
824 INLINE void SetPixel_NOT_16bpp(uint16 *pixel, uint16 *pen)
825 {
826         /* D = ~D */
827         *pixel = ~(*pixel);
828 }
829
830 INLINE void SetPixel_XORPEN_16bpp(uint16 *pixel, uint16 *pen)
831 {
832         /* D = D ^ P */
833         *pixel = *pixel ^ *pen;
834 }
835
836 INLINE void SetPixel_NOTMASKPEN_16bpp(uint16 *pixel, uint16 *pen)
837 {
838         /* D = ~(D & P) */
839         *pixel = ~(*pixel & *pen);
840 }
841
842 INLINE void SetPixel_MASKPEN_16bpp(uint16 *pixel, uint16 *pen)
843 {
844         /* D = D & P */
845         *pixel &= *pen;
846 }
847
848 INLINE void SetPixel_NOTXORPEN_16bpp(uint16 *pixel, uint16 *pen)
849 {
850         /* D = ~(D ^ P) */
851         *pixel = ~(*pixel ^ *pen);
852 }
853
854 INLINE void SetPixel_NOP_16bpp(uint16 *pixel, uint16 *pen)
855 {
856         /* D = D */
857 }
858
859 INLINE void SetPixel_MERGENOTPEN_16bpp(uint16 *pixel, uint16 *pen)
860 {
861         /* D = D | ~P */
862         *pixel |= ~(*pen);
863 }
864
865 INLINE void SetPixel_COPYPEN_16bpp(uint16 *pixel, uint16 *pen)
866 {
867         /* D = P */
868         *pixel = *pen;
869 }
870
871 INLINE void SetPixel_MERGEPENNOT_16bpp(uint16 *pixel, uint16 *pen)
872 {
873         /* D = P | ~D */
874         *pixel = *pen | ~(*pixel);
875 }
876
877 INLINE void SetPixel_MERGEPEN_16bpp(uint16 *pixel, uint16 *pen)
878 {
879         /* D = P | D */
880         *pixel |= *pen;
881 }
882
883 INLINE void SetPixel_WHITE_16bpp(uint16 *pixel, uint16 *pen)
884 {
885         /* D = 1 */
886         *pixel = 0xFFFF;
887 }
888
889 #define PIXEL_TYPE              uint16
890 #define GDI_GET_POINTER         gdi_GetPointer_16bpp
891 #define GDI_GET_PEN_COLOR       gdi_GetPenColor_16bpp
892
893 #define LINE_TO                 LineTo_BLACK_16bpp
894 #define SET_PIXEL_ROP2          SetPixel_BLACK_16bpp
895 #include "include/line.c"
896 #undef LINE_TO
897 #undef SET_PIXEL_ROP2
898
899 #define LINE_TO                 LineTo_NOTMERGEPEN_16bpp
900 #define SET_PIXEL_ROP2          SetPixel_NOTMERGEPEN_16bpp
901 #include "include/line.c"
902 #undef LINE_TO
903 #undef SET_PIXEL_ROP2
904
905 #define LINE_TO                 LineTo_MASKNOTPEN_16bpp
906 #define SET_PIXEL_ROP2          SetPixel_MASKNOTPEN_16bpp
907 #include "include/line.c"
908 #undef LINE_TO
909 #undef SET_PIXEL_ROP2
910
911 #define LINE_TO                 LineTo_NOTCOPYPEN_16bpp
912 #define SET_PIXEL_ROP2          SetPixel_NOTCOPYPEN_16bpp
913 #include "include/line.c"
914 #undef LINE_TO
915 #undef SET_PIXEL_ROP2
916
917 #define LINE_TO                 LineTo_MASKPENNOT_16bpp
918 #define SET_PIXEL_ROP2          SetPixel_MASKPENNOT_16bpp
919 #include "include/line.c"
920 #undef LINE_TO
921 #undef SET_PIXEL_ROP2
922
923 #define LINE_TO                 LineTo_NOT_16bpp
924 #define SET_PIXEL_ROP2          SetPixel_NOT_16bpp
925 #include "include/line.c"
926 #undef LINE_TO
927 #undef SET_PIXEL_ROP2
928
929 #define LINE_TO                 LineTo_XORPEN_16bpp
930 #define SET_PIXEL_ROP2          SetPixel_XORPEN_16bpp
931 #include "include/line.c"
932 #undef LINE_TO
933 #undef SET_PIXEL_ROP2
934
935 #define LINE_TO                 LineTo_NOTMASKPEN_16bpp
936 #define SET_PIXEL_ROP2          SetPixel_NOTMASKPEN_16bpp
937 #include "include/line.c"
938 #undef LINE_TO
939 #undef SET_PIXEL_ROP2
940
941 #define LINE_TO                 LineTo_MASKPEN_16bpp
942 #define SET_PIXEL_ROP2          SetPixel_MASKPEN_16bpp
943 #include "include/line.c"
944 #undef LINE_TO
945 #undef SET_PIXEL_ROP2
946
947 #define LINE_TO                 LineTo_NOTXORPEN_16bpp
948 #define SET_PIXEL_ROP2          SetPixel_NOTXORPEN_16bpp
949 #include "include/line.c"
950 #undef LINE_TO
951 #undef SET_PIXEL_ROP2
952
953 #define LINE_TO                 LineTo_NOP_16bpp
954 #define SET_PIXEL_ROP2          SetPixel_NOP_16bpp
955 #include "include/line.c"
956 #undef LINE_TO
957 #undef SET_PIXEL_ROP2
958
959 #define LINE_TO                 LineTo_MERGENOTPEN_16bpp
960 #define SET_PIXEL_ROP2          SetPixel_MERGENOTPEN_16bpp
961 #include "include/line.c"
962 #undef LINE_TO
963 #undef SET_PIXEL_ROP2
964
965 #define LINE_TO                 LineTo_COPYPEN_16bpp
966 #define SET_PIXEL_ROP2          SetPixel_COPYPEN_16bpp
967 #include "include/line.c"
968 #undef LINE_TO
969 #undef SET_PIXEL_ROP2
970
971 #define LINE_TO                 LineTo_MERGEPENNOT_16bpp
972 #define SET_PIXEL_ROP2          SetPixel_MERGEPENNOT_16bpp
973 #include "include/line.c"
974 #undef LINE_TO
975 #undef SET_PIXEL_ROP2
976
977 #define LINE_TO                 LineTo_MERGEPEN_16bpp
978 #define SET_PIXEL_ROP2          SetPixel_MERGEPEN_16bpp
979 #include "include/line.c"
980 #undef LINE_TO
981 #undef SET_PIXEL_ROP2
982
983 #define LINE_TO                 LineTo_WHITE_16bpp
984 #define SET_PIXEL_ROP2          SetPixel_WHITE_16bpp
985 #include "include/line.c"
986 #undef LINE_TO
987 #undef SET_PIXEL_ROP2
988
989 #undef PIXEL_TYPE
990 #undef GDI_GET_POINTER
991 #undef GDI_GET_PEN_COLOR
992
993 pLineTo_16bpp LineTo_ROP2_16bpp[32] =
994 {
995         LineTo_BLACK_16bpp,
996         LineTo_NOTMERGEPEN_16bpp,
997         LineTo_MASKNOTPEN_16bpp,
998         LineTo_NOTCOPYPEN_16bpp,
999         LineTo_MASKPENNOT_16bpp,
1000         LineTo_NOT_16bpp,
1001         LineTo_XORPEN_16bpp,
1002         LineTo_NOTMASKPEN_16bpp,
1003         LineTo_MASKPEN_16bpp,
1004         LineTo_NOTXORPEN_16bpp,
1005         LineTo_NOP_16bpp,
1006         LineTo_MERGENOTPEN_16bpp,
1007         LineTo_COPYPEN_16bpp,
1008         LineTo_MERGEPENNOT_16bpp,
1009         LineTo_MERGEPEN_16bpp,
1010         LineTo_WHITE_16bpp
1011 };
1012
1013 int LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd)
1014 {
1015         pLineTo_16bpp _LineTo;
1016         int rop2 = gdi_GetROP2(hdc) - 1;
1017
1018         _LineTo = LineTo_ROP2_16bpp[rop2];
1019
1020         if (_LineTo != NULL)
1021                 return _LineTo(hdc, nXEnd, nYEnd);
1022         else
1023                 return 0;
1024 }