fonts: scale otm bbox correctly

Huw D M Davies h.davies1 at physics.ox.ac.uk
Wed Nov 12 06:45:09 CST 2003


        Huw Davies <huw at codeweavers.com>
	Scale the OUTLINETEXTMETRIC's bounding box with the font size.
	Fix wineps's font downloaders to cope with this behaviour.
-- 
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/freetype.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/freetype.c,v
retrieving revision 1.43
diff -u -r1.43 freetype.c
--- dlls/gdi/freetype.c	11 Nov 2003 20:39:34 -0000	1.43
+++ dlls/gdi/freetype.c	12 Nov 2003 12:43:11 -0000
@@ -2267,10 +2267,10 @@
     font->potm->otmLineGap = (pFT_MulFix(pOS2->sTypoLineGap, y_scale) + 32) >> 6;
     font->potm->otmsCapEmHeight = (pFT_MulFix(pOS2->sCapHeight, y_scale) + 32) >> 6;
     font->potm->otmsXHeight = (pFT_MulFix(pOS2->sxHeight, y_scale) + 32) >> 6;
-    font->potm->otmrcFontBox.left = ft_face->bbox.xMin;
-    font->potm->otmrcFontBox.right = ft_face->bbox.xMax;
-    font->potm->otmrcFontBox.top = ft_face->bbox.yMin;
-    font->potm->otmrcFontBox.bottom = ft_face->bbox.yMax;
+    font->potm->otmrcFontBox.left = (pFT_MulFix(ft_face->bbox.xMin, x_scale) + 32) >> 6;
+    font->potm->otmrcFontBox.right = (pFT_MulFix(ft_face->bbox.xMax, x_scale) + 32) >> 6;
+    font->potm->otmrcFontBox.top = (pFT_MulFix(ft_face->bbox.yMax, y_scale) + 32) >> 6;
+    font->potm->otmrcFontBox.bottom = (pFT_MulFix(ft_face->bbox.yMin, y_scale) + 32) >> 6;
     font->potm->otmMacAscent = 0; /* where do these come from ? */
     font->potm->otmMacDescent = 0;
     font->potm->otmMacLineGap = 0;
Index: dlls/wineps/download.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/download.c,v
retrieving revision 1.6
diff -u -r1.6 download.c
--- dlls/wineps/download.c	5 Sep 2003 23:08:28 -0000	1.6
+++ dlls/wineps/download.c	12 Nov 2003 12:43:11 -0000
@@ -35,6 +35,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
 
+#define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+          ( ( (DWORD)_x4 << 24 ) |     \
+            ( (DWORD)_x3 << 16 ) |     \
+            ( (DWORD)_x2 <<  8 ) |     \
+              (DWORD)_x1         )
+
+#define GET_BE_WORD(ptr)  MAKEWORD( ((BYTE *)(ptr))[1], ((BYTE *)(ptr))[0] )
+#define GET_BE_DWORD(ptr) ((DWORD)MAKELONG( GET_BE_WORD(&((WORD *)(ptr))[1]), \
+                                            GET_BE_WORD(&((WORD *)(ptr))[0]) ))
 
 /****************************************************************************
  *  get_download_name
@@ -87,6 +96,31 @@
 }
 
 /****************************************************************************
+ *  get_bbox
+ *
+ * This retrieves the bounding box of the font in font units as well as
+ * the size of the emsquare.  To avoid having to worry about mapping mode and
+ * the font size we'll get the data directly from the TrueType HEAD table rather
+ * than using GetOutlineTextMetrics.
+ */
+static BOOL get_bbox(PSDRV_PDEVICE *physDev, RECT *rc, UINT *emsize)
+{
+    BYTE head[54]; /* the head table is 54 bytes long */
+
+    if(GetFontData(physDev->hdc, MS_MAKE_TAG('h','e','a','d'), 0, head,
+                   sizeof(head)) == GDI_ERROR) {
+        ERR("Can't retrieve head table\n");
+        return FALSE;
+    }
+    *emsize = GET_BE_WORD(head + 18); /* unitsPerEm */
+    rc->left = (signed short)GET_BE_WORD(head + 36); /* xMin */
+    rc->bottom = (signed short)GET_BE_WORD(head + 38); /* yMin */
+    rc->right = (signed short)GET_BE_WORD(head + 40); /* xMax */
+    rc->top = (signed short)GET_BE_WORD(head + 42); /* yMax */
+    return TRUE;
+}
+
+/****************************************************************************
  *  PSDRV_SelectDownloadFont
  *
  *  Set up physDev->font for a downloadable font
@@ -140,21 +174,24 @@
     get_download_name(physDev, potm, &ps_name);
 
     if(physDev->font.fontinfo.Download == NULL) {
+        RECT bbox;
+        UINT emsize;
+
         pdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pdl));
 	pdl->ps_name = HeapAlloc(GetProcessHeap(), 0, strlen(ps_name)+1);
 	strcpy(pdl->ps_name, ps_name);
 	pdl->next = NULL;
 
+        get_bbox(physDev, &bbox, &emsize);
         if(!is_room_for_font(physDev))
             PSDRV_EmptyDownloadList(physDev, TRUE);
 
         if(physDev->pi->ppd->TTRasterizer == RO_Type42) {
-	    pdl->typeinfo.Type42 = T42_download_header(physDev, potm,
-						       ps_name);
+	    pdl->typeinfo.Type42 = T42_download_header(physDev, ps_name, &bbox, emsize);
 	    pdl->type = Type42;
 	}
 	if(pdl->typeinfo.Type42 == NULL) {
-	    pdl->typeinfo.Type1 = T1_download_header(physDev, potm, ps_name);
+	    pdl->typeinfo.Type1 = T1_download_header(physDev, ps_name, &bbox, emsize);
 	    pdl->type = Type1;
 	}
 	pdl->next = physDev->downloaded_fonts;
Index: dlls/wineps/psdrv.h
===================================================================
RCS file: /home/wine/wine/dlls/wineps/psdrv.h,v
retrieving revision 1.44
diff -u -r1.44 psdrv.h
--- dlls/wineps/psdrv.h	11 Nov 2003 20:41:14 -0000	1.44
+++ dlls/wineps/psdrv.h	12 Nov 2003 12:43:11 -0000
@@ -532,16 +532,14 @@
 #define MAX_G_NAME 31 /* max length of PS glyph name */
 extern void get_glyph_name(HDC hdc, WORD index, char *name);
 
-extern TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev,
-				 LPOUTLINETEXTMETRICA potm,
-				 char *ps_name);
+extern TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, char *ps_name,
+                                 RECT *bbox, UINT emsize);
 extern BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl,
 			      DWORD index, char *glyph_name);
 extern void T1_free(TYPE1 *t1);
 
-extern TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev,
-				   LPOUTLINETEXTMETRICA ptom,
-				   char *ps_name);
+extern TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, char *ps_name,
+                                   RECT *bbox, UINT emsize);
 extern BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl,
 			       DWORD index, char *glyph_name);
 extern void T42_free(TYPE42 *t42);
Index: dlls/wineps/type1.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/type1.c,v
retrieving revision 1.6
diff -u -r1.6 type1.c
--- dlls/wineps/type1.c	5 Sep 2003 23:08:28 -0000	1.6
+++ dlls/wineps/type1.c	12 Nov 2003 12:43:11 -0000
@@ -55,8 +55,7 @@
 };
 
 
-TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm,
-			  char *ps_name)
+TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, char *ps_name, RECT *bbox, UINT emsize)
 {
     char *buf;
     TYPE1 *t1;
@@ -86,7 +85,7 @@
       "currentdict end dup /FontName get exch definefont pop\n";
 
     t1 = HeapAlloc(GetProcessHeap(), 0, sizeof(*t1));
-    t1->emsize = potm->otmEMSquare;
+    t1->emsize = emsize;
 
     t1->glyph_sent_size = GLYPH_SENT_INC;
     t1->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
@@ -97,8 +96,7 @@
 		    100);
 
     sprintf(buf, dict, ps_name, t1->emsize, t1->emsize,
-	    potm->otmrcFontBox.left, potm->otmrcFontBox.bottom,
-	    potm->otmrcFontBox.right, potm->otmrcFontBox.top);
+	    bbox->left, bbox->bottom, bbox->right, bbox->top);
 
     PSDRV_WriteSpool(physDev, buf, strlen(buf));
 
Index: dlls/wineps/type42.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/type42.c,v
retrieving revision 1.7
diff -u -r1.7 type42.c
--- dlls/wineps/type42.c	11 Nov 2003 20:40:27 -0000	1.7
+++ dlls/wineps/type42.c	12 Nov 2003 12:43:11 -0000
@@ -133,8 +133,8 @@
     return TRUE;
 }
 
-TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm,
-			    char *ps_name)
+TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, char *ps_name,
+                            RECT *bbox, UINT emsize)
 {
     DWORD i, j, tablepos, nb_blocks, glyf_off = 0, loca_off = 0, cur_off;
     WORD num_of_tables = sizeof(tables_templ) / sizeof(tables_templ[0]) - 1;
@@ -158,14 +158,14 @@
     const char storage[] ="]\nhavetype42gdir{pop}{{string} forall}ifelse\n";
     const char end[] = "] def\n"
       "havetype42gdir{/GlyphDirectory 256 dict def\n"
-      " sfnts 0 get dup %ld (x) putinterval %ld (x) putinterval}if\n"
+      " sfnts 0 get dup %ld (locx) putinterval %ld (glfx) putinterval}if\n"
       "currentdict end dup /FontName get exch definefont pop\n";
 
 
     t42 = HeapAlloc(GetProcessHeap(), 0, sizeof(*t42));
     memcpy(t42->tables, tables_templ, sizeof(tables_templ));
     t42->loca_tab = t42->glyf_tab = t42->head_tab = t42->hmtx_tab = -1;
-    t42->emsize = potm->otmEMSquare;
+    t42->emsize = emsize;
     t42->num_of_written_tables = 0;
 
     for(i = 0; i < num_of_tables; i++) {
@@ -198,10 +198,8 @@
 		    100);
 
     sprintf(buf, start, ps_name,
-	    (float)potm->otmrcFontBox.left / potm->otmEMSquare,
-	    (float)potm->otmrcFontBox.bottom / potm->otmEMSquare,
-	    (float)potm->otmrcFontBox.right / potm->otmEMSquare,
-	    (float)potm->otmrcFontBox.top / potm->otmEMSquare);
+	    (float)bbox->left / emsize, (float)bbox->bottom / emsize,
+	    (float)bbox->right / emsize, (float)bbox->top / emsize);
 
     PSDRV_WriteSpool(physDev, buf, strlen(buf));
 



More information about the wine-patches mailing list