Fixed font drawing.
authorArmin Novak <armin.novak@thincast.com>
Fri, 5 Aug 2016 12:10:53 +0000 (14:10 +0200)
committerArmin Novak <armin.novak@thincast.com>
Thu, 6 Oct 2016 11:43:08 +0000 (13:43 +0200)
include/freerdp/gdi/gdi.h
libfreerdp/gdi/brush.c
libfreerdp/gdi/graphics.c

index 6d77a86..295314f 100644 (file)
 #define GDI_MERGEPAINT                 0x00BB0226 /* D = ~S | D */
 #define GDI_PATCOPY                    0x00F00021 /* D = P */
 #define GDI_PATPAINT                   0x00FB0A09 /* D = D | (P | ~S) */
+#define GDI_PSo                                0x00FC008A
+#define GDI_PSDnoo                     0x00FD0A0A
+#define GDI_DPSoo                      0x00FE02A9
+#define GDI_DSPDoax                    0x00620786
 #define GDI_PATINVERT                  0x005A0049 /* D = P ^ D */
 #define GDI_DSTINVERT                  0x00550009 /* D = ~D */
 #define GDI_BLACKNESS                  0x00000042 /* D = 0 */
 #define GDI_SDno                       0x00DD0228 /* D = S | ~D */
 #define GDI_PDno                       0x00F50225 /* D = P | ~D */
 #define GDI_DPo                                0x00FA0089 /* D = D | P */
+#define GDI_todo                       0xFFFFFFFF /* TODO: Find out which ROP this implements */
 
 /* Brush Styles */
 #define GDI_BS_SOLID                   0x00
index 686570d..b9c370f 100644 (file)
@@ -461,28 +461,382 @@ static BOOL BitBlt_PATPAINT(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
                             UINT32 nXSrc, UINT32 nYSrc)
 {
        UINT32 x, y;
+       UINT32 color;
 
        /* DPSnoo */
        if (!hdcDest || !hdcSrc)
                return FALSE;
 
-       for (y = 0; y < nHeight; y++)
+       switch (gdi_GetBrushStyle(hdcDest))
        {
-               for (x = 0; x < nWidth; x++)
-               {
-                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
-                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
-                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+               case GDI_BS_SOLID:
+                       color = hdcDest->brush->color;
 
-                       if (srcp && patp && dstp)
+                       for (y = 0; y < nHeight; y++)
                        {
-                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
-                               UINT32 colorB = ReadColor(patp, hdcDest->format);
-                               UINT32 colorC = ReadColor(srcp, hdcDest->format);
-                               UINT32 color = ~colorA | colorB | colorC;
-                               WriteColor(dstp, hdcDest->format, color);
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = ~colorA | color | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
                        }
-               }
+
+                       break;
+
+               default:
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && patp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorB = ReadColor(patp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = ~colorA | colorB | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+       }
+
+       return TRUE;
+}
+
+static BOOL BitBlt_PSo(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
+                       UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
+                       UINT32 nXSrc, UINT32 nYSrc)
+{
+       UINT32 x, y;
+       UINT32 color;
+
+       /* DPSnoo */
+       if (!hdcDest || !hdcSrc)
+               return FALSE;
+
+       switch (gdi_GetBrushStyle(hdcDest))
+       {
+               case GDI_BS_SOLID:
+                       color = hdcDest->brush->color;
+
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && dstp)
+                                       {
+                                               UINT32 colorC = ReadColor(srcp, hdcDest->format);
+                                               UINT32 dstColor = color | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+
+               default:
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && patp && dstp)
+                                       {
+                                               UINT32 colorB = ReadColor(patp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = colorB | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+       }
+
+       return TRUE;
+}
+
+static BOOL BitBlt_DSPnoo(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
+                          UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
+                          UINT32 nXSrc, UINT32 nYSrc)
+{
+       UINT32 x, y;
+       UINT32 color;
+
+       /* DPSnoo */
+       if (!hdcDest || !hdcSrc)
+               return FALSE;
+
+       switch (gdi_GetBrushStyle(hdcDest))
+       {
+               case GDI_BS_SOLID:
+                       color = hdcDest->brush->color;
+
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = ~colorA | colorC | color;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+
+               default:
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && patp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorB = ReadColor(patp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = ~colorA | colorB | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+       }
+
+       return TRUE;
+}
+
+static BOOL BitBlt_DSPDoax(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
+                           UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
+                           UINT32 nXSrc, UINT32 nYSrc)
+{
+       UINT32 x, y;
+       UINT32 color;
+
+       /* DPSnoo */
+       if (!hdcDest || !hdcSrc)
+               return FALSE;
+
+       switch (gdi_GetBrushStyle(hdcDest))
+       {
+               case GDI_BS_SOLID:
+                       color = hdcDest->brush->color;
+
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = colorA | colorC & color ^ colorA;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+
+               default:
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && patp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorB = ReadColor(patp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = dstColor = colorA | colorC & colorB ^ colorA;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+       }
+
+       return TRUE;
+}
+
+static BOOL BitBlt_todo(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
+                        UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
+                        UINT32 nXSrc, UINT32 nYSrc)
+{
+       UINT32 x, y;
+       UINT32 color;
+
+       /* DPSnoo */
+       if (!hdcDest || !hdcSrc)
+               return FALSE;
+
+       switch (gdi_GetBrushStyle(hdcDest))
+       {
+               case GDI_BS_SOLID:
+                       color = hdcDest->brush->color;
+
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = (color & colorC) | (colorA & ~colorC);
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+
+               default:
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && patp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorB = ReadColor(patp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = (colorB & colorC) | (colorA & ~colorC);
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+       }
+
+       return TRUE;
+}
+
+static BOOL BitBlt_DPSoo(HGDI_DC hdcDest, UINT32 nXDest, UINT32 nYDest,
+                         UINT32 nWidth, UINT32 nHeight, HGDI_DC hdcSrc,
+                         UINT32 nXSrc, UINT32 nYSrc)
+{
+       UINT32 x, y;
+       UINT32 color;
+
+       /* DPSnoo */
+       if (!hdcDest || !hdcSrc)
+               return FALSE;
+
+       switch (gdi_GetBrushStyle(hdcDest))
+       {
+               case GDI_BS_SOLID:
+                       color = hdcDest->brush->color;
+
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = color | colorA | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
+
+               default:
+                       for (y = 0; y < nHeight; y++)
+                       {
+                               for (x = 0; x < nWidth; x++)
+                               {
+                                       const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
+                                       const BYTE* patp = gdi_get_brush_pointer(hdcDest, nXDest + x, nYDest + y);
+                                       BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, nXDest + x, nYDest + y);
+
+                                       if (srcp && patp && dstp)
+                                       {
+                                               UINT32 colorA = ReadColor(dstp, hdcDest->format);
+                                               UINT32 colorB = ReadColor(patp, hdcDest->format);
+                                               UINT32 colorC = ReadColor(srcp, hdcSrc->format);
+                                               UINT32 dstColor;
+                                               colorC = ConvertColor(colorC, hdcSrc->format, hdcDest->format, NULL);
+                                               dstColor = colorB | colorA | colorC;
+                                               WriteColor(dstp, hdcDest->format, dstColor);
+                                       }
+                               }
+                       }
+
+                       break;
        }
 
        return TRUE;
@@ -628,6 +982,26 @@ BOOL gdi_PatBlt(HGDI_DC hdc, UINT32 nXLeft, UINT32 nYLeft,
                        return BitBlt_PATPAINT(hdc, nXLeft, nYLeft, nWidth, nHeight,
                                               hdcSrc, nXSrc, nYSrc);
 
+               case GDI_PSo:
+                       return BitBlt_PSo(hdc, nXLeft, nYLeft, nWidth, nHeight,
+                                         hdcSrc, nXSrc, nYSrc);
+
+               case GDI_PSDnoo:
+                       return BitBlt_DSPnoo(hdc, nXLeft, nYLeft, nWidth, nHeight,
+                                            hdcSrc, nXSrc, nYSrc);
+
+               case GDI_DPSoo:
+                       return BitBlt_DPSoo(hdc, nXLeft, nYLeft, nWidth, nHeight,
+                                           hdcSrc, nXSrc, nYSrc);
+
+               case GDI_DSPDoax:
+                       return BitBlt_DSPDoax(hdc, nXLeft, nYLeft, nWidth, nHeight,
+                                             hdcSrc, nXSrc, nYSrc);
+
+               case GDI_todo:
+                       return BitBlt_todo(hdc, nXLeft, nYLeft, nWidth, nHeight,
+                                          hdcSrc, nXSrc, nYSrc);
+
                case GDI_PATCOPY:
                        return BitBlt_PATCOPY(hdc, nXLeft, nYLeft, nWidth, nHeight);
 
index df67447..ec3d477 100644 (file)
@@ -267,7 +267,7 @@ static BOOL gdi_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, UINT32 x,
        gdi_glyph = (gdiGlyph*) glyph;
        return gdi_BitBlt(gdi->drawing->hdc, x, y, gdi_glyph->bitmap->width,
                          gdi_glyph->bitmap->height, gdi_glyph->hdc, 0, 0,
-                         GDI_DSPDxox, &context->gdi->palette);
+                         GDI_todo, &context->gdi->palette);
 }
 
 static BOOL gdi_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y,
@@ -290,13 +290,13 @@ static BOOL gdi_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y,
        if (!gdi_decode_color(gdi, fgcolor, &fgcolor, NULL))
                return FALSE;
 
-       gdi->drawing->hdc->brush = gdi_CreateSolidBrush(fgcolor);
+       gdi->drawing->hdc->brush = gdi_CreateSolidBrush(bgcolor);
 
        if (!gdi->drawing->hdc->brush)
                return FALSE;
 
-       gdi_SetTextColor(gdi->drawing->hdc, fgcolor);
-       gdi_SetBkColor(gdi->drawing->hdc, bgcolor);
+       gdi_SetTextColor(gdi->drawing->hdc, bgcolor);
+       gdi_SetBkColor(gdi->drawing->hdc, fgcolor);
        return gdi_SetClipRgn(gdi->drawing->hdc, x, y, width, height);
 }