Huw Davies : gdi32/tests: Add tests for text rendering.

Alexandre Julliard julliard at winehq.org
Mon Nov 14 13:34:00 CST 2011


Module: wine
Branch: master
Commit: d43d17e24857fafcb7964c91d8a7a05520964df3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d43d17e24857fafcb7964c91d8a7a05520964df3

Author: Huw Davies <huw at codeweavers.com>
Date:   Mon Nov 14 12:49:08 2011 +0000

gdi32/tests: Add tests for text rendering.

---

 dlls/gdi32/tests/dib.c |  195 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 195 insertions(+), 0 deletions(-)

diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index c358196..bd33df7 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -2021,6 +2021,187 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sh
     DeleteObject(solid_pen);
 }
 
+static const BYTE ramp[17] =
+{
+    0,    0x4d, 0x68, 0x7c,
+    0x8c, 0x9a, 0xa7, 0xb2,
+    0xbd, 0xc7, 0xd0, 0xd9,
+    0xe1, 0xe9, 0xf0, 0xf8,
+    0xff
+};
+
+static inline void get_range(BYTE alpha, DWORD text_comp, BYTE *min_comp, BYTE *max_comp)
+{
+    *min_comp = (ramp[alpha] * text_comp) / 0xff;
+    *max_comp = ramp[16 - alpha] + ((0xff - ramp[16 - alpha]) * text_comp) / 0xff;
+}
+
+static inline BYTE aa_comp(BYTE dst, BYTE text, BYTE alpha)
+{
+    BYTE min_comp, max_comp;
+
+    if (alpha == 16)  return text;
+    if (alpha <= 1)   return dst;
+    if (text == dst)  return dst;
+
+    get_range( alpha, text, &min_comp, &max_comp );
+
+    if (dst > text)
+    {
+        DWORD diff = dst - text;
+        DWORD range = max_comp - text;
+        dst = text + (diff * range ) / (0xff - text);
+        return dst;
+    }
+    else
+    {
+        DWORD diff = text - dst;
+        DWORD range = text - min_comp ;
+        dst = text - (diff * range) / text;
+        return dst;
+    }
+}
+
+static inline COLORREF aa_colorref( COLORREF dst, COLORREF text, BYTE glyph )
+{
+    COLORREF ret;
+
+    ret = RGB( aa_comp( GetRValue(dst), GetRValue(text), glyph ),
+               aa_comp( GetGValue(dst), GetGValue(text), glyph ),
+               aa_comp( GetBValue(dst), GetBValue(text), glyph ) );
+    return ret;
+}
+
+static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+
+static void draw_text_2( HDC hdc, BITMAPINFO *bmi, BYTE *bits, BOOL aa )
+{
+    DWORD dib_size = get_dib_size(bmi), ret;
+    LOGFONT lf;
+    HFONT font;
+    GLYPHMETRICS gm;
+    BYTE g_buf[10000];
+    int i, stride, x, y;
+    static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
+    char *eto_hash = NULL, *diy_hash = NULL;
+    static const char *str = "Hello Wine";
+    POINT origin, g_org;
+    static const BYTE vals[4] = { 0x00, 0x00, 0x00, 0x00 };
+    TEXTMETRIC tm;
+    COLORREF text_color;
+
+    for(i = 0; i < dib_size; i++)
+        bits[i] = vals[i % 4];
+
+    memset( &lf, 0, sizeof(lf) );
+    strcpy( lf.lfFaceName, "Tahoma" );
+    lf.lfHeight = 24;
+    lf.lfQuality = aa ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY;
+
+    font = CreateFontIndirect( &lf );
+    font = SelectObject( hdc, font );
+
+    GetTextMetrics( hdc, &tm );
+    if (!(tm.tmPitchAndFamily & TMPF_VECTOR))
+    {
+        skip( "skipping as a bitmap font has been selected for Tahoma.\n" );
+        DeleteObject( SelectObject( hdc, font ) );
+        return;
+    }
+
+    SetTextColor( hdc, RGB(0xff, 0x00, 0x00) );
+    SetTextAlign( hdc, TA_BASELINE );
+    SetBkMode( hdc, TRANSPARENT );
+    origin.x = 10;
+    origin.y = 100;
+
+    ExtTextOut( hdc, origin.x, origin.y, 0, NULL, str, strlen(str), NULL );
+    eto_hash = hash_dib( bmi, bits );
+
+    for(i = 0; i < dib_size; i++)
+        bits[i] = vals[i % 4];
+
+    if (bmi->bmiHeader.biBitCount <= 8) aa = FALSE;
+
+    text_color = GetTextColor( hdc );
+    for (i = 0; i < strlen(str); i++)
+    {
+        DWORD ggo_flags = aa ? GGO_GRAY4_BITMAP : GGO_BITMAP;
+
+        ret = GetGlyphOutline( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
+
+        if (ret == GDI_ERROR) continue;
+
+        if (ret) GetGlyphOutline( hdc, str[i], ggo_flags, &gm, sizeof(g_buf), g_buf, &identity );
+
+        g_org.x = origin.x + gm.gmptGlyphOrigin.x;
+        g_org.y = origin.y - gm.gmptGlyphOrigin.y;
+
+        origin.x += gm.gmCellIncX;
+        origin.y += gm.gmCellIncY;
+
+        if (!ret) continue;
+
+        if (aa)
+        {
+            stride = (gm.gmBlackBoxX + 3) & ~3;
+
+            for (y = 0; y < gm.gmBlackBoxY; y++)
+            {
+                BYTE *g_ptr = g_buf + y * stride;
+                COLORREF val;
+
+                for (x = 0; x < gm.gmBlackBoxX; x++)
+                {
+                    if (g_ptr[x] <= 1) continue;
+                    if (g_ptr[x] >= 16) val = text_color;
+                    else
+                    {
+                        val = GetPixel( hdc, g_org.x + x, g_org.y + y );
+                        val = aa_colorref( val, text_color, g_ptr[x] );
+                    }
+                    SetPixel( hdc, g_org.x + x, g_org.y + y, val );
+                }
+            }
+        }
+        else
+        {
+            stride = ((gm.gmBlackBoxX + 31) >> 3) & ~3;
+
+            for (y = 0; y < gm.gmBlackBoxY; y++)
+            {
+                BYTE *g_ptr = g_buf + y * stride;
+                for (x = 0; x < gm.gmBlackBoxX; x++)
+                {
+                    if (g_ptr[x / 8] & masks[x % 8])
+                        SetPixel( hdc, g_org.x + x, g_org.y + y, text_color );
+                }
+            }
+        }
+    }
+
+    diy_hash = hash_dib( bmi, bits );
+    ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - aa %d\n", aa );
+
+    HeapFree( GetProcessHeap(), 0, diy_hash );
+    HeapFree( GetProcessHeap(), 0, eto_hash );
+
+    font = SelectObject( hdc, font );
+    DeleteObject( font );
+}
+
+static void draw_text( HDC hdc, BITMAPINFO *bmi, BYTE *bits )
+{
+    draw_text_2( hdc, bmi, bits, FALSE );
+
+    /* Rounding errors make these cases hard to test */
+    if ((bmi->bmiHeader.biCompression == BI_BITFIELDS && ((DWORD*)bmi->bmiColors)[0] == 0x3f000) ||
+        (bmi->bmiHeader.biBitCount == 16))
+        return;
+
+    draw_text_2( hdc, bmi, bits, TRUE );
+}
+
 static void test_simple_graphics(void)
 {
     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
@@ -2061,6 +2242,7 @@ static void test_simple_graphics(void)
     dst_format = "8888";
     sha1 = sha1_graphics_a8r8g8b8;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2086,6 +2268,7 @@ static void test_simple_graphics(void)
     dst_format = "8888 - bitfields";
     sha1 = sha1_graphics_a8r8g8b8;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2111,6 +2294,7 @@ static void test_simple_graphics(void)
     dst_format = "a8b8g8r8";
     sha1 = sha1_graphics_a8b8g8r8;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2136,6 +2320,7 @@ static void test_simple_graphics(void)
     dst_format = "r10g10b10";
     sha1 = sha1_graphics_r10g10b10;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2161,6 +2346,7 @@ static void test_simple_graphics(void)
     dst_format = "r6g6b6";
     sha1 = sha1_graphics_r6g6b6;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2177,6 +2363,7 @@ static void test_simple_graphics(void)
     dst_format = "24";
     sha1 = sha1_graphics_24;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2199,6 +2386,7 @@ static void test_simple_graphics(void)
     dst_format = "r5g5b5";
     sha1 = sha1_graphics_r5g5b5;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2223,6 +2411,7 @@ static void test_simple_graphics(void)
     dst_format = "r4g4b4";
     sha1 = sha1_graphics_r4g4b4;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2246,6 +2435,7 @@ static void test_simple_graphics(void)
     dst_format = "8 color";
     sha1 = sha1_graphics_8_color;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2265,6 +2455,7 @@ static void test_simple_graphics(void)
     dst_format = "8 grayscale";
     sha1 = sha1_graphics_8_grayscale;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2298,6 +2489,7 @@ static void test_simple_graphics(void)
     dst_format = "8";
     sha1 = sha1_graphics_8;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2314,6 +2506,7 @@ static void test_simple_graphics(void)
     dst_format = "4";
     sha1 = sha1_graphics_4;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2331,6 +2524,7 @@ static void test_simple_graphics(void)
     dst_format = "4 grayscale";
     sha1 = sha1_graphics_4_grayscale;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
@@ -2355,6 +2549,7 @@ static void test_simple_graphics(void)
     dst_format = "1";
     sha1 = sha1_graphics_1;
     draw_graphics(mem_dc, bmi, bits, &sha1);
+    draw_text(mem_dc, bmi, bits);
 
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);




More information about the wine-cvs mailing list