[PATCH 05/12] gdi32: Add a helper function to get the GGO glyph from the FreeType glyph."

Byeongsik Jeon bsjeon at hanmail.net
Tue Jan 29 03:12:29 CST 2019


Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
 dlls/gdi32/freetype.c | 697 +++++++++++++++++++++---------------------
 1 file changed, 350 insertions(+), 347 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index c42f4287dd..292a39909e 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -7001,7 +7001,7 @@ static FT_BBox compute_gm_abc_metrics( GdiFont *incoming_font, GdiFont *font,
     return bbox;
 }
 
-static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf)
+static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int buflen, BYTE *buf)
 {
     TTPOLYGONHEADER *pph;
     TTPOLYCURVE *ppc;
@@ -7074,7 +7074,7 @@ static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int b
     return needed;
 }
 
-static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf)
+static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int buflen, BYTE *buf)
 {
     /* Convert the quadratic Beziers to cubic Beziers.
        The parametric eqn for a cubic Bezier is, from PLRM:
@@ -7198,6 +7198,344 @@ static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int b
     return needed;
 }
 
+static DWORD get_ggo_glyph_from_outline( FT_GlyphSlot glyph, UINT format, FT_BBox bbox, GLYPHMETRICS *gm,
+                                         BOOL needsTransform, FT_Matrix *transMatTategaki,
+                                         DWORD buflen, BYTE *buf )
+{
+    DWORD width  = (bbox.xMax - bbox.xMin) >> 6;
+    DWORD height = (bbox.yMax - bbox.yMin) >> 6;
+    FT_Outline *outline = &glyph->outline;
+    FT_Bitmap ft_bitmap;
+    DWORD max_level, pitch, needed = 0;
+
+    switch (format)
+    {
+        case GGO_BITMAP:
+            pitch = ((width + 31) >> 5) << 2;
+            needed = pitch * height;
+
+            if (!buf || !buflen) break;
+            if (!needed) return GDI_ERROR;  /* empty glyph */
+            if (needed > buflen) return GDI_ERROR;
+
+            ft_bitmap.width = width;
+            ft_bitmap.rows = height;
+            ft_bitmap.pitch = pitch;
+            ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
+            ft_bitmap.buffer = buf;
+
+            if (needsTransform)
+                pFT_Outline_Transform( outline, transMatTategaki );
+            pFT_Outline_Translate( outline, -bbox.xMin, -bbox.yMin );
+
+            /* Note: FreeType will only set 'black' bits for us. */
+            memset( buf, 0, needed );
+            pFT_Outline_Get_Bitmap( library, outline, &ft_bitmap );
+            break;
+
+        case GGO_GRAY2_BITMAP:
+        case GGO_GRAY4_BITMAP:
+        case GGO_GRAY8_BITMAP:
+        case WINE_GGO_GRAY16_BITMAP:
+            pitch = (width + 3) / 4 * 4;
+            needed = pitch * height;
+
+            if (!buf || !buflen) break;
+            if (!needed) return GDI_ERROR;  /* empty glyph */
+            if (needed > buflen) return GDI_ERROR;
+
+            ft_bitmap.width = width;
+            ft_bitmap.rows = height;
+            ft_bitmap.pitch = pitch;
+            ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
+            ft_bitmap.buffer = buf;
+
+            if (needsTransform)
+                pFT_Outline_Transform( outline, transMatTategaki );
+            pFT_Outline_Translate( outline, -bbox.xMin, -bbox.yMin );
+
+            memset( ft_bitmap.buffer, 0, buflen );
+            pFT_Outline_Get_Bitmap( library, outline, &ft_bitmap );
+
+            max_level = get_max_level( format );
+            if (max_level != 255)
+            {
+                BYTE *start, *ptr;
+                UINT row, col;
+
+                for (row = 0, start = buf; row < height; row++)
+                {
+                    for (col = 0, ptr = start; col < width; col++, ptr++)
+                        *ptr = (((int)*ptr) * (max_level + 1)) / 256;
+                    start += pitch;
+                }
+            }
+            break;
+
+        case WINE_GGO_HRGB_BITMAP:
+        case WINE_GGO_HBGR_BITMAP:
+        case WINE_GGO_VRGB_BITMAP:
+        case WINE_GGO_VBGR_BITMAP:
+        {
+            BYTE *src;
+            unsigned int *dst;
+            INT x, rgb_interval, hmul, vmul;
+            INT src_pitch, src_width, src_height, x_shift, y_shift;
+            const INT *sub_order;
+            const INT rgb_order[3] = { 0, 1, 2 };
+            const INT bgr_order[3] = { 2, 1, 0 };
+            FT_Render_Mode render_mode =
+                (format == WINE_GGO_HRGB_BITMAP ||
+                 format == WINE_GGO_HBGR_BITMAP) ? FT_RENDER_MODE_LCD: FT_RENDER_MODE_LCD_V;
+
+            if (!width || !height) /* empty glyph */
+            {
+                if (!buf || !buflen) break;
+                return GDI_ERROR;
+            }
+
+            if (render_mode == FT_RENDER_MODE_LCD)
+            {
+                gm->gmBlackBoxX += 2;
+                gm->gmptGlyphOrigin.x -= 1;
+                bbox.xMin -= (1 << 6);
+            }
+            else
+            {
+                gm->gmBlackBoxY += 2;
+                gm->gmptGlyphOrigin.y += 1;
+                bbox.yMax += (1 << 6);
+            }
+
+            width  = gm->gmBlackBoxX;
+            height = gm->gmBlackBoxY;
+            pitch  = width * 4;
+            needed = pitch * height;
+
+            if (!buf || !buflen) break;
+            if (needed > buflen) return GDI_ERROR;
+
+            memset( buf, 0, buflen );
+            dst = (unsigned int *)buf;
+
+            if (needsTransform)
+                pFT_Outline_Transform( outline, transMatTategaki );
+
+#ifdef FT_LCD_FILTER_H
+            if (pFT_Library_SetLcdFilter)
+                pFT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT );
+#endif
+            pFT_Render_Glyph( glyph, render_mode );
+
+            src = glyph->bitmap.buffer;
+            src_pitch = glyph->bitmap.pitch;
+            src_width = glyph->bitmap.width;
+            src_height = glyph->bitmap.rows;
+
+            rgb_interval = render_mode == FT_RENDER_MODE_LCD ? 1 : src_pitch;
+            hmul         = render_mode == FT_RENDER_MODE_LCD ? 3 : 1;
+            vmul         = render_mode == FT_RENDER_MODE_LCD ? 1 : 3;
+
+            x_shift = glyph->bitmap_left - (bbox.xMin >> 6);
+            if (x_shift < 0)
+            {
+                src += hmul * -x_shift;
+                src_width -= hmul * -x_shift;
+            }
+            else if (x_shift > 0)
+            {
+                dst += x_shift;
+                width -= x_shift;
+            }
+
+            y_shift = (bbox.yMax >> 6) - glyph->bitmap_top;
+            if (y_shift < 0)
+            {
+                src += src_pitch * vmul * -y_shift;
+                src_height -= vmul * -y_shift;
+            }
+            else if (y_shift > 0)
+            {
+                dst += y_shift * (pitch / sizeof(*dst));
+                height -= y_shift;
+            }
+
+            width = min( width, src_width / hmul );
+            height = min( height, src_height / vmul );
+
+            sub_order = (format == WINE_GGO_HRGB_BITMAP ||
+                         format == WINE_GGO_VRGB_BITMAP) ? rgb_order : bgr_order;
+
+            while (height--)
+            {
+                for (x = 0; x < width; x++)
+                {
+                    dst[x] = ((unsigned int)src[hmul * x + rgb_interval * sub_order[0]] << 16) |
+                             ((unsigned int)src[hmul * x + rgb_interval * sub_order[1]] << 8) |
+                             ((unsigned int)src[hmul * x + rgb_interval * sub_order[2]]);
+                }
+                src += src_pitch * vmul;
+                dst += pitch / sizeof(*dst);
+            }
+            break;
+        }
+        case GGO_NATIVE:
+            if (buflen == 0) buf = NULL;
+
+            if (needsTransform && buf)
+                pFT_Outline_Transform( outline, transMatTategaki );
+
+            needed = get_native_glyph_outline( outline, buflen, NULL );
+
+            if (!buf || !buflen) break;
+            if (needed > buflen) return GDI_ERROR;
+
+            get_native_glyph_outline( outline, buflen, buf );
+            break;
+
+        case GGO_BEZIER:
+            if (buflen == 0) buf = NULL;
+
+            if (needsTransform && buf)
+                pFT_Outline_Transform( outline, transMatTategaki );
+
+            needed = get_bezier_glyph_outline( outline, buflen, NULL );
+
+            if (!buf || !buflen) break;
+            if (needed > buflen) return GDI_ERROR;
+
+            get_bezier_glyph_outline( outline, buflen, buf );
+            break;
+
+        default:
+            FIXME("Unsupported format %d\n", format);
+            return GDI_ERROR;
+    }
+
+    return needed;
+}
+
+static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+
+static DWORD get_ggo_glyph_from_bitmap( FT_GlyphSlot glyph, UINT format, FT_BBox bbox,
+                                        GdiFont *font,
+                                        DWORD buflen, BYTE *buf )
+{
+    BYTE *src, *dst;
+    DWORD width  = (bbox.xMax - bbox.xMin) >> 6;
+    DWORD height = (bbox.yMax - bbox.yMin) >> 6;
+    DWORD max_level, pitch, needed = 0;
+    INT x, w, h;
+
+    switch (format)
+    {
+        case GGO_BITMAP:
+            pitch = ((width + 31) >> 5) << 2;
+            needed = pitch * height;
+
+            if (!buf || !buflen) break;
+            if (!needed) return GDI_ERROR;  /* empty glyph */
+            if (needed > buflen) return GDI_ERROR;
+
+            src = glyph->bitmap.buffer;
+            dst = buf;
+            w = min( pitch, (glyph->bitmap.width + 7) >> 3 );
+            h = min( height, glyph->bitmap.rows );
+            while (h--)
+            {
+                if (!font->fake_bold)
+                    memcpy( dst, src, w );
+                else
+                {
+                    dst[0] = 0;
+                    for (x = 0; x < w; x++)
+                    {
+                        dst[x] = (dst[x] & 0x80) | (src[x] >> 1) | src[x];
+                        if (x + 1 < pitch)
+                            dst[x + 1] = (src[x] & 0x01) << 7;
+                    }
+                }
+                src += glyph->bitmap.pitch;
+                dst += pitch;
+            }
+            break;
+
+        case GGO_GRAY2_BITMAP:
+        case GGO_GRAY4_BITMAP:
+        case GGO_GRAY8_BITMAP:
+        case WINE_GGO_GRAY16_BITMAP:
+            pitch = (width + 3) / 4 * 4;
+            needed = pitch * height;
+
+            if(!buf || !buflen) break;
+            if (!needed) return GDI_ERROR;  /* empty glyph */
+            if (needed > buflen) return GDI_ERROR;
+
+            src = glyph->bitmap.buffer;
+            dst = buf;
+            memset( buf, 0, buflen );
+            max_level = get_max_level( format );
+            h = min( height, glyph->bitmap.rows );
+            while (h--)
+            {
+                for (x = 0; x < pitch && x < glyph->bitmap.width; x++)
+                {
+                    if (src[x / 8] & masks[x % 8])
+                    {
+                        dst[x] = max_level;
+                        if (font->fake_bold && x + 1 < pitch)
+                            dst[x+1] = max_level;
+                    }
+                }
+                src += glyph->bitmap.pitch;
+                dst += pitch;
+            }
+            break;
+
+        case WINE_GGO_HRGB_BITMAP:
+        case WINE_GGO_HBGR_BITMAP:
+        case WINE_GGO_VRGB_BITMAP:
+        case WINE_GGO_VBGR_BITMAP:
+            pitch  = width * 4;
+            needed = pitch * height;
+
+            if (!buf || !buflen) break;
+            if (!needed) return GDI_ERROR;  /* empty glyph */
+            if (needed > buflen) return GDI_ERROR;
+
+            src = glyph->bitmap.buffer;
+            dst = buf;
+            memset(buf, 0, buflen);
+            h = min( height, glyph->bitmap.rows );
+            while (h--)
+            {
+                for (x = 0; x < width && x < glyph->bitmap.width; x++)
+                {
+                    if (src[x / 8] & masks[x % 8])
+                    {
+                        ((unsigned int *)dst)[x] = ~0u;
+                        if (font->fake_bold && x + 1 < width)
+                            ((unsigned int *)dst)[x + 1] = ~0u;
+                    }
+                }
+                src += glyph->bitmap.pitch;
+                dst += pitch;
+            }
+            break;
+
+        case GGO_NATIVE:
+        case GGO_BEZIER:
+            TRACE("loaded a bitmap\n");
+            return GDI_ERROR;
+
+        default:
+            FIXME("Unsupported format %d\n", format);
+            return GDI_ERROR;
+    }
+
+    return needed;
+}
+
 static FT_Int get_load_flags( UINT format, GdiFont *font )
 {
     BOOL natural_width;
@@ -7226,8 +7564,6 @@ static FT_Int get_load_flags( UINT format, GdiFont *font )
     return load_flags;
 }
 
-static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-
 static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
                                LPGLYPHMETRICS lpgm, ABC *abc, DWORD buflen, LPVOID buf,
                                const MAT2* lpmat)
@@ -7238,8 +7574,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
     GdiFont *font = incoming_font;
     FT_Glyph_Metrics metrics;
     FT_UInt glyph_index;
-    DWORD width, height, pitch, needed = 0;
-    FT_Bitmap ft_bitmap;
+    DWORD needed = 0;
     FT_Error err;
     FT_BBox bbox;
     FT_Int load_flags = get_load_flags(format, incoming_font);
@@ -7328,9 +7663,6 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
                                    &transMat, &transMatTategaki, &transMatUnrotated,
                                    &gm, abc );
 
-    width  = (bbox.xMax - bbox.xMin) >> 6;
-    height = (bbox.yMax - bbox.yMin) >> 6;
-
     if ((format == GGO_METRICS || format == GGO_BITMAP || format ==  WINE_GGO_GRAY16_BITMAP) &&
         is_identity_MAT2(lpmat)) /* don't cache custom transforms */
         cache_gm_abc_metrics( font, glyph_index, &gm, abc );
@@ -7341,352 +7673,23 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
         return 1; /* FIXME */
     }
 
-    if(ft_face->glyph->format != ft_glyph_format_outline &&
-       (format == GGO_NATIVE || format == GGO_BEZIER))
+    switch (ft_face->glyph->format)
     {
-        TRACE("loaded a bitmap\n");
-	return GDI_ERROR;
-    }
-
-    switch(format) {
-    case GGO_BITMAP:
-	pitch = ((width + 31) >> 5) << 2;
-        needed = pitch * height;
-
-	if(!buf || !buflen) break;
-        if (!needed) return GDI_ERROR;  /* empty glyph */
-        if (needed > buflen)
-            return GDI_ERROR;
-
-	switch(ft_face->glyph->format) {
-	case ft_glyph_format_bitmap:
-	  {
-	    BYTE *src = ft_face->glyph->bitmap.buffer, *dst = buf;
-	    INT w = min( pitch, (ft_face->glyph->bitmap.width + 7) >> 3 );
-	    INT h = min( height, ft_face->glyph->bitmap.rows );
-	    while(h--) {
-		if (!font->fake_bold)
-		    memcpy(dst, src, w);
-		else {
-		    INT x;
-		    dst[0] = 0;
-		    for (x = 0; x < w; x++) {
-			dst[x  ] = (dst[x] & 0x80) | (src[x] >> 1) | src[x];
-			if (x+1 < pitch)
-			    dst[x+1] = (src[x] & 0x01) << 7;
-		    }
-		}
-		src += ft_face->glyph->bitmap.pitch;
-		dst += pitch;
-	    }
-	    break;
-	  }
-
-	case ft_glyph_format_outline:
-	    ft_bitmap.width = width;
-	    ft_bitmap.rows = height;
-	    ft_bitmap.pitch = pitch;
-	    ft_bitmap.pixel_mode = ft_pixel_mode_mono;
-	    ft_bitmap.buffer = buf;
-
-	    if(needsTransform)
-		pFT_Outline_Transform(&ft_face->glyph->outline, &transMatTategaki);
-
-	    pFT_Outline_Translate(&ft_face->glyph->outline, -bbox.xMin, -bbox.yMin );
-
-	    /* Note: FreeType will only set 'black' bits for us. */
-	    memset(buf, 0, needed);
-	    pFT_Outline_Get_Bitmap(library, &ft_face->glyph->outline, &ft_bitmap);
-	    break;
-
-	default:
-	    FIXME("loaded glyph format %x\n", ft_face->glyph->format);
-	    return GDI_ERROR;
-	}
-	break;
-
-    case GGO_GRAY2_BITMAP:
-    case GGO_GRAY4_BITMAP:
-    case GGO_GRAY8_BITMAP:
-    case WINE_GGO_GRAY16_BITMAP:
-      {
-	unsigned int max_level, row, col;
-	BYTE *start, *ptr;
-
-	pitch = (width + 3) / 4 * 4;
-	needed = pitch * height;
-
-	if(!buf || !buflen) break;
-        if (!needed) return GDI_ERROR;  /* empty glyph */
-        if (needed > buflen)
-            return GDI_ERROR;
-
-        max_level = get_max_level( format );
-
-	switch(ft_face->glyph->format) {
-	case ft_glyph_format_bitmap:
-	  {
-            BYTE *src = ft_face->glyph->bitmap.buffer, *dst = buf;
-            INT h = min( height, ft_face->glyph->bitmap.rows );
-            INT x;
-            memset( buf, 0, needed );
-            while(h--) {
-                for(x = 0; x < pitch && x < ft_face->glyph->bitmap.width; x++) {
-                    if (src[x / 8] & masks[x % 8]) {
-                        dst[x] = max_level;
-                        if (font->fake_bold && x+1 < pitch) dst[x+1] = max_level;
-                    }
-                }
-                src += ft_face->glyph->bitmap.pitch;
-                dst += pitch;
-            }
-            break;
-	  }
-        case ft_glyph_format_outline:
-          {
-            ft_bitmap.width = width;
-            ft_bitmap.rows = height;
-            ft_bitmap.pitch = pitch;
-            ft_bitmap.pixel_mode = ft_pixel_mode_grays;
-            ft_bitmap.buffer = buf;
-
-            if(needsTransform)
-                pFT_Outline_Transform(&ft_face->glyph->outline, &transMatTategaki);
-
-            pFT_Outline_Translate(&ft_face->glyph->outline, -bbox.xMin, -bbox.yMin );
-
-            memset(ft_bitmap.buffer, 0, buflen);
-
-            pFT_Outline_Get_Bitmap(library, &ft_face->glyph->outline, &ft_bitmap);
-
-            if (max_level != 255)
-            {
-                for (row = 0, start = buf; row < height; row++)
-                {
-                    for (col = 0, ptr = start; col < width; col++, ptr++)
-                        *ptr = (((int)*ptr) * (max_level + 1)) / 256;
-                    start += pitch;
-                }
-            }
-            break;
-          }
-
-        default:
-            FIXME("loaded glyph format %x\n", ft_face->glyph->format);
-            return GDI_ERROR;
-        }
-	break;
-      }
-
-    case WINE_GGO_HRGB_BITMAP:
-    case WINE_GGO_HBGR_BITMAP:
-    case WINE_GGO_VRGB_BITMAP:
-    case WINE_GGO_VBGR_BITMAP:
-      {
-        switch (ft_face->glyph->format)
-        {
         case FT_GLYPH_FORMAT_BITMAP:
-          {
-            BYTE *src, *dst;
-            INT src_pitch, x;
-
-            pitch  = width * 4;
-            needed = pitch * height;
-
-            if (!buf || !buflen) break;
-            if (!needed) return GDI_ERROR;  /* empty glyph */
-            if (needed > buflen)
-                return GDI_ERROR;
-
-            memset(buf, 0, buflen);
-            dst = buf;
-            src = ft_face->glyph->bitmap.buffer;
-            src_pitch = ft_face->glyph->bitmap.pitch;
-
-            height = min( height, ft_face->glyph->bitmap.rows );
-            while ( height-- )
-            {
-                for (x = 0; x < width && x < ft_face->glyph->bitmap.width; x++)
-                {
-                    if ( src[x / 8] & masks[x % 8] )
-                    {
-                        ((unsigned int *)dst)[x] = ~0u;
-                        if (font->fake_bold && x+1 < width) ((unsigned int *)dst)[x+1] = ~0u;
-                    }
-                }
-                src += src_pitch;
-                dst += pitch;
-            }
-
+            needed = get_ggo_glyph_from_bitmap( ft_face->glyph, format, bbox, font,
+                                                buflen, buf );
             break;
-          }
-
         case FT_GLYPH_FORMAT_OUTLINE:
-          {
-            unsigned int *dst;
-            BYTE *src;
-            INT x, src_pitch, src_width, src_height, rgb_interval, hmul, vmul;
-            INT x_shift, y_shift;
-            const INT *sub_order;
-            const INT rgb_order[3] = { 0, 1, 2 };
-            const INT bgr_order[3] = { 2, 1, 0 };
-            FT_Render_Mode render_mode =
-                (format == WINE_GGO_HRGB_BITMAP || format == WINE_GGO_HBGR_BITMAP)?
-                    FT_RENDER_MODE_LCD: FT_RENDER_MODE_LCD_V;
-
-            if (!width || !height)
-            {
-                if (!buf || !buflen) break;
-                return GDI_ERROR;
-            }
-
-            if ( render_mode == FT_RENDER_MODE_LCD)
-            {
-                gm.gmBlackBoxX += 2;
-                gm.gmptGlyphOrigin.x -= 1;
-                bbox.xMin -= (1 << 6);
-            }
-            else
-            {
-                gm.gmBlackBoxY += 2;
-                gm.gmptGlyphOrigin.y += 1;
-                bbox.yMax += (1 << 6);
-            }
-
-            width  = gm.gmBlackBoxX;
-            height = gm.gmBlackBoxY;
-            pitch  = width * 4;
-            needed = pitch * height;
-
-            if (!buf || !buflen) break;
-            if (needed > buflen)
-                return GDI_ERROR;
-
-            memset(buf, 0, buflen);
-            dst = buf;
-
-            if ( needsTransform )
-                pFT_Outline_Transform (&ft_face->glyph->outline, &transMatTategaki);
-
-#ifdef FT_LCD_FILTER_H
-            if ( pFT_Library_SetLcdFilter )
-                pFT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT );
-#endif
-            pFT_Render_Glyph (ft_face->glyph, render_mode);
-
-            src = ft_face->glyph->bitmap.buffer;
-            src_pitch = ft_face->glyph->bitmap.pitch;
-            src_width = ft_face->glyph->bitmap.width;
-            src_height = ft_face->glyph->bitmap.rows;
-
-            if ( render_mode == FT_RENDER_MODE_LCD)
-            {
-                rgb_interval = 1;
-                hmul = 3;
-                vmul = 1;
-            }
-            else
-            {
-                rgb_interval = src_pitch;
-                hmul = 1;
-                vmul = 3;
-            }
-
-            x_shift = ft_face->glyph->bitmap_left - (bbox.xMin >> 6);
-            if ( x_shift < 0 )
-            {
-                src += hmul * -x_shift;
-                src_width -= hmul * -x_shift;
-            }
-            else if ( x_shift > 0 )
-            {
-                dst += x_shift;
-                width -= x_shift;
-            }
-
-            y_shift = (bbox.yMax >> 6) - ft_face->glyph->bitmap_top;
-            if ( y_shift < 0 )
-            {
-                src += src_pitch * vmul * -y_shift;
-                src_height -= vmul * -y_shift;
-            }
-            else if ( y_shift > 0 )
-            {
-                dst += y_shift * ( pitch / sizeof(*dst) );
-                height -= y_shift;
-            }
-
-            width = min( width, src_width / hmul );
-            height = min( height, src_height / vmul );
-
-            sub_order = (format == WINE_GGO_HRGB_BITMAP || format == WINE_GGO_VRGB_BITMAP)?
-                        rgb_order : bgr_order;
-
-            while ( height-- )
-            {
-                for ( x = 0; x < width; x++ )
-                {
-                    dst[x] = ((unsigned int)src[hmul * x + rgb_interval * sub_order[0]] << 16) |
-                             ((unsigned int)src[hmul * x + rgb_interval * sub_order[1]] << 8) |
-                             ((unsigned int)src[hmul * x + rgb_interval * sub_order[2]]);
-                }
-                src += src_pitch * vmul;
-                dst += pitch / sizeof(*dst);
-            }
-
+            needed = get_ggo_glyph_from_outline( ft_face->glyph, format, bbox, &gm,
+                                                 needsTransform, &transMatTategaki,
+                                                 buflen, buf );
             break;
-          }
-
         default:
-            FIXME ("loaded glyph format %x\n", ft_face->glyph->format);
-            return GDI_ERROR;
-        }
-
-        break;
-      }
-
-    case GGO_NATIVE:
-      {
-        FT_Outline *outline = &ft_face->glyph->outline;
-
-        if(buflen == 0) buf = NULL;
-
-        if (needsTransform && buf)
-            pFT_Outline_Transform(outline, &transMatTategaki);
-
-        needed = get_native_glyph_outline(outline, buflen, NULL);
-
-        if (!buf || !buflen)
-            break;
-        if (needed > buflen)
-            return GDI_ERROR;
-
-        get_native_glyph_outline(outline, buflen, buf);
-        break;
-      }
-    case GGO_BEZIER:
-      {
-        FT_Outline *outline = &ft_face->glyph->outline;
-        if(buflen == 0) buf = NULL;
-
-        if (needsTransform && buf)
-            pFT_Outline_Transform(outline, &transMatTategaki);
-
-        needed = get_bezier_glyph_outline(outline, buflen, NULL);
-
-        if (!buf || !buflen)
-            break;
-        if (needed > buflen)
+            FIXME("loaded glyph format %x\n", ft_face->glyph->format);
             return GDI_ERROR;
-
-        get_bezier_glyph_outline(outline, buflen, buf);
-        break;
-      }
-
-    default:
-        FIXME("Unsupported format %d\n", format);
-	return GDI_ERROR;
     }
+    if (needed == GDI_ERROR) return GDI_ERROR;
+
     *lpgm = gm;
     return needed;
 }
-- 
2.20.1




More information about the wine-devel mailing list