[PATCH] gdi32: Fix glyph orientation for inverted axis in compatible mode.

Alexander Kochetkov al.kochet at gmail.com
Thu Feb 24 15:01:35 CST 2011


-------------- next part --------------
From 1121a58aa9a4aa60a0bd4668f79ae302d545001a Mon Sep 17 00:00:00 2001
From: Alexander Kochetkov <al.kochet at gmail.com>
Date: Thu, 24 Feb 2011 23:36:38 +0300
Subject: [PATCH] gdi32: Fix glyph orientation for inverted axis in compatible mode.

This is for the test application attached to the bug #22996
I'm not sure, should I remove FT_IS_SCALABLE? How can I test the patch with non 
scalable font? Could you please give me some advice?

Dmitry, could you please take a look at the patch?

---
 dlls/gdi32/freetype.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 512e08b..7b379bf 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -302,6 +302,7 @@ typedef struct {
     LOGFONTW lf;
     FMAT2 matrix;
     BOOL can_use_bitmap;
+    INT orientation;
 } FONT_DESC;
 
 typedef struct tagHFONTLIST {
@@ -3251,6 +3252,7 @@ static BOOL fontcmp(const GdiFont *font, FONT_DESC *fd)
     if(memcmp(&font->font_desc.matrix, &fd->matrix, sizeof(fd->matrix))) return TRUE;
     if(memcmp(&font->font_desc.lf, &fd->lf, offsetof(LOGFONTW, lfFaceName))) return TRUE;
     if(!font->font_desc.can_use_bitmap != !fd->can_use_bitmap) return TRUE;
+    if(!font->font_desc.orientation != !fd->orientation) return TRUE;
     return strcmpiW(font->font_desc.lf.lfFaceName, fd->lf.lfFaceName);
 }
 
@@ -3275,11 +3277,12 @@ static void calc_hash(FONT_DESC *pfd)
         if(!*pwc) break;
     }
     hash ^= !pfd->can_use_bitmap;
+    hash ^= pfd->orientation;
     pfd->hash = hash;
     return;
 }
 
-static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pmat, BOOL can_use_bitmap)
+static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pmat, BOOL can_use_bitmap, INT orientation)
 {
     GdiFont *ret;
     FONT_DESC fd;
@@ -3289,6 +3292,7 @@ static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pma
     fd.lf = *plf;
     fd.matrix = *pmat;
     fd.can_use_bitmap = can_use_bitmap;
+    fd.orientation = orientation;
     calc_hash(&fd);
 
     /* try the child list */
@@ -3481,11 +3485,13 @@ GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
     HFONTLIST *hflist;
     FMAT2 dcmat;
     FontSubst *psub = NULL;
+    INT orientation;
 
     if (!GetObjectW( hfont, sizeof(lf), &lf )) return NULL;
     lf.lfWidth = abs(lf.lfWidth);
 
     can_use_bitmap = GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_RA_ABLE;
+    orientation = lf.lfOrientation;
 
     TRACE("%s, h=%d, it=%d, weight=%d, PandF=%02x, charset=%d orient %d escapement %d\n",
 	  debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
@@ -3500,6 +3506,8 @@ GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
            font scaling abilities. */
         dcmat.eM11 = dcmat.eM22 = dc->vport2WorldValid ? fabs(dc->xformWorld2Vport.eM22) : 1.0;
         dcmat.eM21 = dcmat.eM12 = 0;
+        if (dc->vport2WorldValid && dc->xformWorld2Vport.eM11 * dc->xformWorld2Vport.eM22 < 0)
+            orientation = -orientation;
     }
 
     /* Try to avoid not necessary glyph transformations */
@@ -3517,7 +3525,7 @@ GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
     EnterCriticalSection( &freetype_cs );
 
     /* check the cache first */
-    if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
+    if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap, orientation)) != NULL) {
         TRACE("returning cached gdiFont(%p) for hFont %p\n", ret, hfont);
         LeaveCriticalSection( &freetype_cs );
         return ret;
@@ -3783,6 +3791,7 @@ found:
         GdiFont *cachedfont;
 
         /* FIXME: rotation of bitmap fonts is ignored */
+        orientation = 0;
         height = abs(GDI_ROUND( (double)height * ret->font_desc.matrix.eM22 ));
         if (ret->aveWidth)
             ret->aveWidth = (double)ret->aveWidth * ret->font_desc.matrix.eM11;
@@ -3790,7 +3799,7 @@ found:
         dcmat.eM11 = dcmat.eM22 = 1.0;
         /* As we changed the matrix, we need to search the cache for the font again,
          * otherwise we might explode the cache. */
-        if((cachedfont = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
+        if((cachedfont = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap, orientation)) != NULL) {
             TRACE("Found cached font after non-scalable matrix rescale!\n");
             free_font( ret );
             LeaveCriticalSection( &freetype_cs );
@@ -3838,7 +3847,7 @@ found:
         select_charmap(ret->ft_face, FT_ENCODING_APPLE_ROMAN);
     }
 
-    ret->orientation = FT_IS_SCALABLE(ret->ft_face) ? lf.lfOrientation : 0;
+    ret->orientation = orientation;
     ret->name = psub ? strdupW(psub->from.name) : strdupW(family->FamilyName);
     ret->underline = lf.lfUnderline ? 0xff : 0;
     ret->strikeout = lf.lfStrikeOut ? 0xff : 0;
-- 
1.7.0.4


More information about the wine-patches mailing list