2 * FreeRDP: A Remote Desktop Protocol Client
3 * GDI 8bpp Internal Buffer Routines
5 * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <freerdp/api.h>
24 #include <freerdp/freerdp.h>
25 #include <freerdp/gdi/gdi.h>
26 #include <freerdp/codec/color.h>
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>
34 #include <freerdp/gdi/8bpp.h>
36 int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
38 /* TODO: Implement 8bpp FillRect() */
42 static int BitBlt_BLACKNESS_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
47 for (y = 0; y < nHeight; y++)
49 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
52 memset(dstp, 0, nWidth * hdcDest->bytesPerPixel);
58 static int BitBlt_WHITENESS_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
63 for (y = 0; y < nHeight; y++)
65 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
68 memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel);
74 static int BitBlt_SRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
80 if ((hdcDest->selectedObject != hdcSrc->selectedObject) ||
81 gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0)
83 for (y = 0; y < nHeight; y++)
85 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
86 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
88 if (srcp != 0 && dstp != 0)
89 memcpy(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
97 /* copy down (bottom to top) */
98 for (y = nHeight - 1; y >= 0; y--)
100 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
101 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
103 if (srcp != 0 && dstp != 0)
104 memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
107 else if (nYSrc > nYDest || nXSrc > nXDest)
109 /* copy up or left (top top bottom) */
110 for (y = 0; y < nHeight; y++)
112 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
113 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
115 if (srcp != 0 && dstp != 0)
116 memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
121 /* copy straight right */
122 for (y = 0; y < nHeight; y++)
124 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
125 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
127 if (srcp != 0 && dstp != 0)
128 memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
135 static int BitBlt_NOTSRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
141 for (y = 0; y < nHeight; y++)
143 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
144 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
148 for (x = 0; x < nWidth; x++)
160 static int BitBlt_DSTINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
165 for (y = 0; y < nHeight; y++)
167 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
171 for (x = 0; x < nWidth; x++)
182 static int BitBlt_SRCERASE_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
188 for (y = 0; y < nHeight; y++)
190 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
191 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
195 for (x = 0; x < nWidth; x++)
197 *dstp = *srcp & ~(*dstp);
207 static int BitBlt_NOTSRCERASE_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
213 for (y = 0; y < nHeight; y++)
215 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
216 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
220 for (x = 0; x < nWidth; x++)
222 *dstp = ~(*srcp) & ~(*dstp);
232 static int BitBlt_SRCINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
238 for (y = 0; y < nHeight; y++)
240 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
241 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
245 for (x = 0; x < nWidth; x++)
257 static int BitBlt_SRCAND_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
263 for (y = 0; y < nHeight; y++)
265 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
266 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
270 for (x = 0; x < nWidth; x++)
282 static int BitBlt_SRCPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
288 for (y = 0; y < nHeight; y++)
290 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
291 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
295 for (x = 0; x < nWidth; x++)
307 static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
309 /* TODO: Implement 8bpp DSPDxax BitBlt */
313 static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
320 for (y = 0; y < nHeight; y++)
322 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
323 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
327 for (x = 0; x < nWidth; x++)
329 patp = gdi_get_brush_pointer(hdcDest, x, y);
331 *dstp = *srcp & ~(*patp);
342 static int BitBlt_PDxn_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
348 for (y = 0; y < nHeight; y++)
350 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
354 for (x = 0; x < nWidth; x++)
356 patp = gdi_get_brush_pointer(hdcDest, x, y);
358 *dstp = *dstp ^ ~(*patp);
368 static int BitBlt_DSna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
374 for (y = 0; y < nHeight; y++)
376 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
377 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
381 for (x = 0; x < nWidth; x++)
383 *dstp = ~(*srcp) & (*dstp);
393 static int BitBlt_MERGECOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
400 for (y = 0; y < nHeight; y++)
402 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
403 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
407 for (x = 0; x < nWidth; x++)
409 patp = gdi_get_brush_pointer(hdcDest, x, y);
411 *dstp = *srcp & *patp;
422 static int BitBlt_MERGEPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
428 for (y = 0; y < nHeight; y++)
430 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
431 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
435 for (x = 0; x < nWidth; x++)
437 *dstp = ~(*srcp) | *dstp;
447 static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
454 if(hdcDest->brush->style == GDI_BS_SOLID)
456 palIndex = ((hdcDest->brush->color >> 16) & 0xFF);
457 for (y = 0; y < nHeight; y++)
459 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
462 for (x = 0; x < nWidth; x++)
472 for (y = 0; y < nHeight; y++)
474 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
478 for (x = 0; x < nWidth; x++)
480 patp = gdi_get_brush_pointer(hdcDest, x, y);
493 static int BitBlt_PATINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
500 if(hdcDest->brush->style == GDI_BS_SOLID)
502 palIndex = ((hdcDest->brush->color >> 16) & 0xFF);
503 for (y = 0; y < nHeight; y++)
505 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
508 for (x = 0; x < nWidth; x++)
518 for (y = 0; y < nHeight; y++)
520 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
524 for (x = 0; x < nWidth; x++)
526 patp = gdi_get_brush_pointer(hdcDest, x, y);
528 *dstp = *patp ^ *dstp;
539 static int BitBlt_PATPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
546 for (y = 0; y < nHeight; y++)
548 srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
549 dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
553 for (x = 0; x < nWidth; x++)
555 patp = gdi_get_brush_pointer(hdcDest, x, y);
557 *dstp = *dstp | (*patp | ~(*srcp));
568 int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop)
572 if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0)
577 if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0)
581 gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
586 return BitBlt_BLACKNESS_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
590 return BitBlt_WHITENESS_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
594 return BitBlt_SRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
598 return BitBlt_SPna_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
602 return BitBlt_DSna_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
606 return BitBlt_DSPDxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
610 return BitBlt_NOTSRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
614 return BitBlt_DSTINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
618 return BitBlt_SRCERASE_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
621 case GDI_NOTSRCERASE:
622 return BitBlt_NOTSRCERASE_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
626 return BitBlt_SRCINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
630 return BitBlt_SRCAND_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
634 return BitBlt_SRCPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
638 return BitBlt_MERGECOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
642 return BitBlt_MERGEPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
646 return BitBlt_PATCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
650 return BitBlt_PATINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight);
654 return BitBlt_PATPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
658 printf("BitBlt: unknown rop: 0x%08X\n", rop);
662 int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop)
664 if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0)
667 gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight);
672 return BitBlt_PATCOPY_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
676 return BitBlt_PATINVERT_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
680 return BitBlt_DSTINVERT_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
684 return BitBlt_BLACKNESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
688 return BitBlt_WHITENESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
692 return BitBlt_PDxn_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
699 printf("PatBlt: unknown rop: 0x%08X\n", rop);
703 INLINE void SetPixel_BLACK_8bpp(uint8* pixel, uint8* pen)
709 INLINE void SetPixel_NOTMERGEPEN_8bpp(uint8* pixel, uint8* pen)
712 *pixel = ~(*pixel | *pen);
715 INLINE void SetPixel_MASKNOTPEN_8bpp(uint8* pixel, uint8* pen)
721 INLINE void SetPixel_NOTCOPYPEN_8bpp(uint8* pixel, uint8* pen)
727 INLINE void SetPixel_MASKPENNOT_8bpp(uint8* pixel, uint8* pen)
730 *pixel = *pen & ~*pixel;
733 INLINE void SetPixel_NOT_8bpp(uint8* pixel, uint8* pen)
739 INLINE void SetPixel_XORPEN_8bpp(uint8* pixel, uint8* pen)
742 *pixel = *pixel ^ *pen;
745 INLINE void SetPixel_NOTMASKPEN_8bpp(uint8* pixel, uint8* pen)
748 *pixel = ~(*pixel & *pen);
751 INLINE void SetPixel_MASKPEN_8bpp(uint8* pixel, uint8* pen)
757 INLINE void SetPixel_NOTXORPEN_8bpp(uint8* pixel, uint8* pen)
760 *pixel = ~(*pixel ^ *pen);
763 INLINE void SetPixel_NOP_8bpp(uint8* pixel, uint8* pen)
768 INLINE void SetPixel_MERGENOTPEN_8bpp(uint8* pixel, uint8* pen)
774 INLINE void SetPixel_COPYPEN_8bpp(uint8* pixel, uint8* pen)
780 INLINE void SetPixel_MERGEPENNOT_8bpp(uint8* pixel, uint8* pen)
783 *pixel = *pen | ~(*pixel);
786 INLINE void SetPixel_MERGEPEN_8bpp(uint8* pixel, uint8* pen)
792 INLINE void SetPixel_WHITE_8bpp(uint8* pixel, uint8* pen)
798 #define PIXEL_TYPE uint8
799 #define GDI_GET_POINTER gdi_GetPointer_8bpp
800 #define GDI_GET_PEN_COLOR gdi_GetPenColor_8bpp
802 #define LINE_TO LineTo_BLACK_8bpp
803 #define SET_PIXEL_ROP2 SetPixel_BLACK_8bpp
804 #include "include/line.c"
806 #undef SET_PIXEL_ROP2
808 #define LINE_TO LineTo_NOTMERGEPEN_8bpp
809 #define SET_PIXEL_ROP2 SetPixel_NOTMERGEPEN_8bpp
810 #include "include/line.c"
812 #undef SET_PIXEL_ROP2
814 #define LINE_TO LineTo_MASKNOTPEN_8bpp
815 #define SET_PIXEL_ROP2 SetPixel_MASKNOTPEN_8bpp
816 #include "include/line.c"
818 #undef SET_PIXEL_ROP2
820 #define LINE_TO LineTo_NOTCOPYPEN_8bpp
821 #define SET_PIXEL_ROP2 SetPixel_NOTCOPYPEN_8bpp
822 #include "include/line.c"
824 #undef SET_PIXEL_ROP2
826 #define LINE_TO LineTo_MASKPENNOT_8bpp
827 #define SET_PIXEL_ROP2 SetPixel_MASKPENNOT_8bpp
828 #include "include/line.c"
830 #undef SET_PIXEL_ROP2
832 #define LINE_TO LineTo_NOT_8bpp
833 #define SET_PIXEL_ROP2 SetPixel_NOT_8bpp
834 #include "include/line.c"
836 #undef SET_PIXEL_ROP2
838 #define LINE_TO LineTo_XORPEN_8bpp
839 #define SET_PIXEL_ROP2 SetPixel_XORPEN_8bpp
840 #include "include/line.c"
842 #undef SET_PIXEL_ROP2
844 #define LINE_TO LineTo_NOTMASKPEN_8bpp
845 #define SET_PIXEL_ROP2 SetPixel_NOTMASKPEN_8bpp
846 #include "include/line.c"
848 #undef SET_PIXEL_ROP2
850 #define LINE_TO LineTo_MASKPEN_8bpp
851 #define SET_PIXEL_ROP2 SetPixel_MASKPEN_8bpp
852 #include "include/line.c"
854 #undef SET_PIXEL_ROP2
856 #define LINE_TO LineTo_NOTXORPEN_8bpp
857 #define SET_PIXEL_ROP2 SetPixel_NOTXORPEN_8bpp
858 #include "include/line.c"
860 #undef SET_PIXEL_ROP2
862 #define LINE_TO LineTo_NOP_8bpp
863 #define SET_PIXEL_ROP2 SetPixel_NOP_8bpp
864 #include "include/line.c"
866 #undef SET_PIXEL_ROP2
868 #define LINE_TO LineTo_MERGENOTPEN_8bpp
869 #define SET_PIXEL_ROP2 SetPixel_MERGENOTPEN_8bpp
870 #include "include/line.c"
872 #undef SET_PIXEL_ROP2
874 #define LINE_TO LineTo_COPYPEN_8bpp
875 #define SET_PIXEL_ROP2 SetPixel_COPYPEN_8bpp
876 #include "include/line.c"
878 #undef SET_PIXEL_ROP2
880 #define LINE_TO LineTo_MERGEPENNOT_8bpp
881 #define SET_PIXEL_ROP2 SetPixel_MERGEPENNOT_8bpp
882 #include "include/line.c"
884 #undef SET_PIXEL_ROP2
886 #define LINE_TO LineTo_MERGEPEN_8bpp
887 #define SET_PIXEL_ROP2 SetPixel_MERGEPEN_8bpp
888 #include "include/line.c"
890 #undef SET_PIXEL_ROP2
892 #define LINE_TO LineTo_WHITE_8bpp
893 #define SET_PIXEL_ROP2 SetPixel_WHITE_8bpp
894 #include "include/line.c"
896 #undef SET_PIXEL_ROP2
899 #undef GDI_GET_POINTER
900 #undef GDI_GET_PEN_COLOR
902 pLineTo_8bpp LineTo_ROP2_8bpp[32] =
905 LineTo_NOTMERGEPEN_8bpp,
906 LineTo_MASKNOTPEN_8bpp,
907 LineTo_NOTCOPYPEN_8bpp,
908 LineTo_MASKPENNOT_8bpp,
911 LineTo_NOTMASKPEN_8bpp,
913 LineTo_NOTXORPEN_8bpp,
915 LineTo_MERGENOTPEN_8bpp,
917 LineTo_MERGEPENNOT_8bpp,
918 LineTo_MERGEPEN_8bpp,
922 int LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd)
924 pLineTo_8bpp _LineTo;
925 int rop2 = gdi_GetROP2(hdc) - 1;
927 _LineTo = LineTo_ROP2_8bpp[rop2];
930 return _LineTo(hdc, nXEnd, nYEnd);