From ef2ac7acc34c63b5a7631787903316b56198a3fe Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Wed, 12 Nov 2003 22:42:55 +0000 Subject: [PATCH] Scale the OUTLINETEXTMETRIC's bounding box with the font size. Fix wineps's font downloaders to cope with this behaviour. --- dlls/gdi/freetype.c | 8 ++++---- dlls/wineps/download.c | 43 ++++++++++++++++++++++++++++++++++++++++--- dlls/wineps/psdrv.h | 10 ++++------ dlls/wineps/type1.c | 8 +++----- dlls/wineps/type42.c | 14 ++++++-------- 5 files changed, 57 insertions(+), 26 deletions(-) diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 14c7d2e3954..ad7de4b7c29 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -2267,10 +2267,10 @@ UINT WineEngGetOutlineTextMetrics(GdiFont font, UINT cbSize, 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; diff --git a/dlls/wineps/download.c b/dlls/wineps/download.c index c4ce963d2bb..9c48b550c8d 100644 --- a/dlls/wineps/download.c +++ b/dlls/wineps/download.c @@ -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 @@ static BOOL is_room_for_font(PSDRV_PDEVICE *physDev) } /**************************************************************************** + * 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 @@ BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev) 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; diff --git a/dlls/wineps/psdrv.h b/dlls/wineps/psdrv.h index 18ed54aa01f..f8dc543d9de 100644 --- a/dlls/wineps/psdrv.h +++ b/dlls/wineps/psdrv.h @@ -532,16 +532,14 @@ extern BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev, BOOL write_undef); #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); diff --git a/dlls/wineps/type1.c b/dlls/wineps/type1.c index 0a4eef8748a..b16dc7f6774 100644 --- a/dlls/wineps/type1.c +++ b/dlls/wineps/type1.c @@ -55,8 +55,7 @@ enum t1_cmds { }; -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 @@ TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm, "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 @@ TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm, 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)); diff --git a/dlls/wineps/type42.c b/dlls/wineps/type42.c index e15cec46d31..bd0a93012e8 100644 --- a/dlls/wineps/type42.c +++ b/dlls/wineps/type42.c @@ -133,8 +133,8 @@ static BOOL get_glyf_pos(TYPE42 *t42, DWORD index, DWORD *start, DWORD *end) 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 @@ TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm, 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 @@ TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm, 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)); -- 2.11.4.GIT