Commit ae4278ee authored by Huw D M Davies's avatar Huw D M Davies Committed by Alexandre Julliard

Added Type 1 and Type 42 font downloading.

Misc bug fixes.
parent 7a6ea919
...@@ -57,8 +57,10 @@ C_SRCS = \ ...@@ -57,8 +57,10 @@ C_SRCS = \
bitblt.c \ bitblt.c \
bitmap.c \ bitmap.c \
brush.c \ brush.c \
builtin.c \
clipping.c \ clipping.c \
color.c \ color.c \
download.c \
driver.c \ driver.c \
escape.c \ escape.c \
font.c \ font.c \
...@@ -71,7 +73,9 @@ C_SRCS = \ ...@@ -71,7 +73,9 @@ C_SRCS = \
ps.c \ ps.c \
text.c \ text.c \
truetype.c \ truetype.c \
type1.c \
type1afm.c \ type1afm.c \
type42.c \
$(DATA_C_SRCS) $(DATA_C_SRCS)
RC_SRCS= rsrc.rc RC_SRCS= rsrc.rc
......
...@@ -49,7 +49,7 @@ HBRUSH PSDRV_SelectBrush( PSDRV_PDEVICE *physDev, HBRUSH hbrush ) ...@@ -49,7 +49,7 @@ HBRUSH PSDRV_SelectBrush( PSDRV_PDEVICE *physDev, HBRUSH hbrush )
break; break;
case BS_PATTERN: case BS_PATTERN:
FIXME("Unsupported brush style %d\n", logbrush.lbStyle); case BS_DIBPATTERN:
break; break;
default: default:
...@@ -226,13 +226,28 @@ BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO) ...@@ -226,13 +226,28 @@ BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO)
} }
break; break;
case BS_DIBPATTERN:
{
BITMAPINFO *bmi = GlobalLock16(logbrush.lbHatch);
UINT usage = logbrush.lbColor;
TRACE("size %ldx%ldx%d\n", bmi->bmiHeader.biWidth,
bmi->bmiHeader.biHeight, bmi->bmiHeader.biBitCount);
if(physDev->pi->ppd->LanguageLevel > 1) {
PSDRV_WriteGSave(physDev);
ret = PSDRV_WriteDIBPatternDict(physDev, bmi, usage);
PSDRV_Fill(physDev, EO);
PSDRV_WriteGRestore(physDev);
} else {
FIXME("Trying to set a pattern brush on a level 1 printer\n");
ret = FALSE;
}
GlobalUnlock16(logbrush.lbHatch);
}
break;
default: default:
ret = FALSE; ret = FALSE;
break; break;
} }
return ret; return ret;
} }
/*
* PostScript driver downloadable font functions
*
* Copyright 2002 Huw D M Davies for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "winspool.h"
#include "gdi.h"
#include "psdrv.h"
#include "wine/debug.h"
#include "winerror.h"
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
/****************************************************************************
* get_download_name
*/
static void get_download_name(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA
potm, char **str)
{
int len;
char *p;
len = strlen((char*)potm + (ptrdiff_t)potm->otmpFullName) + 1;
*str = HeapAlloc(GetProcessHeap(),0,len);
strcpy(*str, (char*)potm + (ptrdiff_t)potm->otmpFullName);
p = *str;
while((p = strchr(p, ' ')))
*p = '_';
return;
}
/****************************************************************************
* is_font_downloaded
*/
static DOWNLOAD *is_font_downloaded(PSDRV_PDEVICE *physDev, char *ps_name)
{
DOWNLOAD *pdl;
for(pdl = physDev->downloaded_fonts; pdl; pdl = pdl->next)
if(!strcmp(pdl->ps_name, ps_name))
break;
return pdl;
}
/****************************************************************************
* PSDRV_SelectDownloadFont
*
* Set up physDev->font for a downloadable font
*
*/
BOOL PSDRV_SelectDownloadFont(PSDRV_PDEVICE *physDev)
{
char *ps_name;
LPOUTLINETEXTMETRICA potm;
DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
potm = HeapAlloc(GetProcessHeap(), 0, len);
GetOutlineTextMetricsA(physDev->hdc, len, potm);
get_download_name(physDev, potm, &ps_name);
physDev->font.fontloc = Download;
physDev->font.fontinfo.Download = is_font_downloaded(physDev, ps_name);
physDev->font.size = INTERNAL_YWSTODS(physDev->dc, /* ppem */
potm->otmTextMetrics.tmAscent +
potm->otmTextMetrics.tmDescent -
potm->otmTextMetrics.tmInternalLeading);
physDev->font.underlineThickness = potm->otmsUnderscoreSize;
physDev->font.underlinePosition = potm->otmsUnderscorePosition;
physDev->font.strikeoutThickness = potm->otmsStrikeoutSize;
physDev->font.strikeoutPosition = potm->otmsStrikeoutPosition;
HeapFree(GetProcessHeap(), 0, ps_name);
HeapFree(GetProcessHeap(), 0, potm);
return TRUE;
}
/****************************************************************************
* PSDRV_WriteSetDownloadFont
*
* Write setfont for download font.
*
*/
BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev)
{
char *ps_name;
LPOUTLINETEXTMETRICA potm;
DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
DOWNLOAD *pdl;
assert(physDev->font.fontloc == Download);
potm = HeapAlloc(GetProcessHeap(), 0, len);
GetOutlineTextMetricsA(physDev->hdc, len, potm);
get_download_name(physDev, potm, &ps_name);
if(physDev->font.fontinfo.Download == NULL) {
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;
if(physDev->pi->ppd->TTRasterizer == RO_Type42) {
pdl->typeinfo.Type42 = T42_download_header(physDev, potm,
ps_name);
pdl->type = Type42;
} else {
pdl->typeinfo.Type1 = T1_download_header(physDev, potm, ps_name);
pdl->type = Type1;
}
if(pdl) {
pdl->next = physDev->downloaded_fonts;
physDev->downloaded_fonts = pdl;
}
physDev->font.fontinfo.Download = pdl;
}
PSDRV_WriteSetFont(physDev, ps_name, physDev->font.size,
physDev->font.escapement);
HeapFree(GetProcessHeap(), 0, ps_name);
HeapFree(GetProcessHeap(), 0, potm);
return TRUE;
}
void get_glyph_name(HDC hdc, WORD index, char *name)
{
/* FIXME */
sprintf(name, "g%04x", index);
return;
}
/****************************************************************************
* PSDRV_WriteDownloadGlyphShow
*
* Download and write out a number of glyphs
*
*/
BOOL PSDRV_WriteDownloadGlyphShow(PSDRV_PDEVICE *physDev, WORD *glyphs,
UINT count)
{
UINT i;
char g_name[MAX_G_NAME + 1];
assert(physDev->font.fontloc == Download);
switch(physDev->font.fontinfo.Download->type) {
case Type42:
for(i = 0; i < count; i++) {
get_glyph_name(physDev->hdc, glyphs[i], g_name);
T42_download_glyph(physDev, physDev->font.fontinfo.Download,
glyphs[i], g_name);
PSDRV_WriteGlyphShow(physDev, g_name);
}
break;
case Type1:
for(i = 0; i < count; i++) {
get_glyph_name(physDev->hdc, glyphs[i], g_name);
T1_download_glyph(physDev, physDev->font.fontinfo.Download,
glyphs[i], g_name);
PSDRV_WriteGlyphShow(physDev, g_name);
}
break;
default:
ERR("Type = %d\n", physDev->font.fontinfo.Download->type);
assert(0);
}
return TRUE;
}
/****************************************************************************
* PSDRV_EmptyDownloadList
*
* Clear the list of downloaded fonts
*
*/
BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev)
{
DOWNLOAD *pdl, *old;
if(physDev->font.fontloc == Download) {
physDev->font.set = FALSE;
physDev->font.fontinfo.Download = NULL;
}
pdl = physDev->downloaded_fonts;
physDev->downloaded_fonts = NULL;
while(pdl) {
switch(pdl->type) {
case Type42:
T42_free(pdl->typeinfo.Type42);
break;
case Type1:
T1_free(pdl->typeinfo.Type1);
break;
default:
ERR("Type = %d\n", pdl->type);
assert(0);
}
HeapFree(GetProcessHeap(), 0, pdl->ps_name);
old = pdl;
pdl = pdl->next;
HeapFree(GetProcessHeap(), 0, old);
}
return TRUE;
}
...@@ -335,7 +335,10 @@ fwMode); ...@@ -335,7 +335,10 @@ fwMode);
FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n"); FIXME("Mode DM_UPDATE. Just do the same as DM_COPY\n");
if((fwMode & DM_COPY) || (fwMode & DM_UPDATE)) { if((fwMode & DM_COPY) || (fwMode & DM_UPDATE)) {
memcpy(lpdmOutput, pi->Devmode, sizeof(DEVMODEA)); if (lpdmOutput)
memcpy(lpdmOutput, pi->Devmode, sizeof(DEVMODEA));
else
FIXME("lpdmOutput is NULL what should we do??\n");
} }
return IDOK; return IDOK;
} }
......
...@@ -246,6 +246,7 @@ INT PSDRV_EndPage( PSDRV_PDEVICE *physDev ) ...@@ -246,6 +246,7 @@ INT PSDRV_EndPage( PSDRV_PDEVICE *physDev )
} }
if(!PSDRV_WriteEndPage( physDev )) if(!PSDRV_WriteEndPage( physDev ))
return 0; return 0;
PSDRV_EmptyDownloadList(physDev);
physDev->job.OutOfPage = TRUE; physDev->job.OutOfPage = TRUE;
return 1; return 1;
} }
......
...@@ -778,6 +778,22 @@ PPD *PSDRV_ParsePPD(char *fname) ...@@ -778,6 +778,22 @@ PPD *PSDRV_ParsePPD(char *fname)
tuple.value = NULL; tuple.value = NULL;
} }
else if(!strcmp("*TTRasterizer", tuple.key)) {
if(!strcasecmp("None", tuple.value))
ppd->TTRasterizer = RO_None;
else if(!strcasecmp("Accept68K", tuple.value))
ppd->TTRasterizer = RO_Accept68K;
else if(!strcasecmp("Type42", tuple.value))
ppd->TTRasterizer = RO_Type42;
else if(!strcasecmp("TrueImage", tuple.value))
ppd->TTRasterizer = RO_TrueImage;
else {
FIXME("Unknown option %s for *TTRasterizer\n",
tuple.value);
ppd->TTRasterizer = RO_None;
}
}
if(tuple.key) HeapFree(PSDRV_Heap, 0, tuple.key); if(tuple.key) HeapFree(PSDRV_Heap, 0, tuple.key);
if(tuple.option) HeapFree(PSDRV_Heap, 0, tuple.option); if(tuple.option) HeapFree(PSDRV_Heap, 0, tuple.option);
if(tuple.value) HeapFree(PSDRV_Heap, 0, tuple.value); if(tuple.value) HeapFree(PSDRV_Heap, 0, tuple.value);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "gdi.h"
#include "psdrv.h" #include "psdrv.h"
#include "winspool.h" #include "winspool.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -428,21 +429,20 @@ BOOL PSDRV_WriteArc(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h, double a ...@@ -428,21 +429,20 @@ BOOL PSDRV_WriteArc(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h, double a
return PSDRV_WriteSpool(physDev, buf, strlen(buf)); return PSDRV_WriteSpool(physDev, buf, strlen(buf));
} }
BOOL PSDRV_WriteSetFont(PSDRV_PDEVICE *physDev)
BOOL PSDRV_WriteSetFont(PSDRV_PDEVICE *physDev, const char *name, INT size, INT escapement)
{ {
char *buf; char *buf;
buf = (char *)HeapAlloc( PSDRV_Heap, 0, buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(pssetfont) +
sizeof(pssetfont) + strlen(physDev->font.afm->FontName) + 40); strlen(name) + 40);
if(!buf) { if(!buf) {
WARN("HeapAlloc failed\n"); WARN("HeapAlloc failed\n");
return FALSE; return FALSE;
} }
sprintf(buf, pssetfont, physDev->font.afm->FontName, sprintf(buf, pssetfont, name, size, -size, -escapement);
physDev->font.size, -physDev->font.size,
-physDev->font.escapement);
PSDRV_WriteSpool(physDev, buf, strlen(buf)); PSDRV_WriteSpool(physDev, buf, strlen(buf));
HeapFree(PSDRV_Heap, 0, buf); HeapFree(PSDRV_Heap, 0, buf);
...@@ -487,28 +487,19 @@ BOOL PSDRV_WriteSetPen(PSDRV_PDEVICE *physDev) ...@@ -487,28 +487,19 @@ BOOL PSDRV_WriteSetPen(PSDRV_PDEVICE *physDev)
return TRUE; return TRUE;
} }
BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCWSTR str, INT count) BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCSTR g_name)
{ {
char buf[128]; char buf[128];
int i; int l;
for (i = 0; i < count; ++i)
{
LPCSTR name;
int l;
name = PSDRV_UVMetrics(str[i], physDev->font.afm)->N->sz; l = snprintf(buf, sizeof(buf), psglyphshow, g_name);
l = snprintf(buf, sizeof(buf), psglyphshow, name);
if (l < sizeof(psglyphshow) - 2 || l > sizeof(buf) - 1) if (l < sizeof(psglyphshow) - 2 || l > sizeof(buf) - 1) {
{ WARN("Unusable glyph name '%s' - ignoring\n", g_name);
WARN("Unusable glyph name '%s' - ignoring\n", name); return FALSE;
continue;
}
PSDRV_WriteSpool(physDev, buf, l);
} }
PSDRV_WriteSpool(physDev, buf, l);
return TRUE; return TRUE;
} }
...@@ -815,3 +806,51 @@ BOOL PSDRV_WritePatternDict(PSDRV_PDEVICE *physDev, BITMAP *bm, BYTE *bits) ...@@ -815,3 +806,51 @@ BOOL PSDRV_WritePatternDict(PSDRV_PDEVICE *physDev, BITMAP *bm, BYTE *bits)
HeapFree(PSDRV_Heap, 0, buf); HeapFree(PSDRV_Heap, 0, buf);
return TRUE; return TRUE;
} }
BOOL PSDRV_WriteDIBPatternDict(PSDRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage)
{
char start[] = "<<\n /PaintType 1\n /PatternType 1\n /TilingType 1\n "
"/BBox [0 0 %d %d]\n /XStep %d\n /YStep %d\n /PaintProc {\n begin\n";
char end[] = " end\n }\n>>\n matrix makepattern setpattern\n";
char *buf, *ptr;
BYTE *bits;
INT w, h, x, y, colours;
COLORREF map[2];
if(bmi->bmiHeader.biBitCount != 1) {
FIXME("dib depth %d not supported\n", bmi->bmiHeader.biBitCount);
return FALSE;
}
bits = (char*)bmi + bmi->bmiHeader.biSize;
colours = bmi->bmiHeader.biClrUsed;
if(!colours && bmi->bmiHeader.biBitCount <= 8)
colours = 1 << bmi->bmiHeader.biBitCount;
bits += colours * ((usage == DIB_RGB_COLORS) ?
sizeof(RGBQUAD) : sizeof(WORD));
w = bmi->bmiHeader.biWidth & ~0x7;
h = bmi->bmiHeader.biHeight & ~0x7;
buf = HeapAlloc(PSDRV_Heap, 0, sizeof(start) + 100);
sprintf(buf, start, w, h, w, h);
PSDRV_WriteSpool(physDev, buf, strlen(buf));
PSDRV_WriteIndexColorSpaceBegin(physDev, 1);
map[0] = physDev->dc->textColor;
map[1] = physDev->dc->backgroundColor;
PSDRV_WriteRGB(physDev, map, 2);
PSDRV_WriteIndexColorSpaceEnd(physDev);
ptr = buf;
for(y = h-1; y >= 0; y--) {
for(x = 0; x < w/8; x++) {
sprintf(ptr, "%02x", *(bits + x/8 + y *
(bmi->bmiHeader.biWidth + 31) / 32 * 4));
ptr += 2;
}
}
PSDRV_WriteImageDict(physDev, 1, 0, 0, 8, 8, 8, 8, buf);
PSDRV_WriteSpool(physDev, end, sizeof(end) - 1);
HeapFree(PSDRV_Heap, 0, buf);
return TRUE;
}
...@@ -169,6 +169,9 @@ typedef struct _tagINPUTSLOT { ...@@ -169,6 +169,9 @@ typedef struct _tagINPUTSLOT {
struct _tagINPUTSLOT *next; struct _tagINPUTSLOT *next;
} INPUTSLOT; } INPUTSLOT;
typedef enum _RASTERIZEROPTION
{RO_None, RO_Accept68K, RO_Type42, RO_TrueImage} RASTERIZEROPTION;
typedef struct { typedef struct {
char *NickName; char *NickName;
int LanguageLevel; int LanguageLevel;
...@@ -184,6 +187,7 @@ typedef struct { ...@@ -184,6 +187,7 @@ typedef struct {
OPTION *InstalledOptions; OPTION *InstalledOptions;
CONSTRAINT *Constraints; CONSTRAINT *Constraints;
INPUTSLOT *InputSlots; INPUTSLOT *InputSlots;
RASTERIZEROPTION TTRasterizer;
} PPD; } PPD;
typedef struct { typedef struct {
...@@ -236,12 +240,50 @@ typedef struct { ...@@ -236,12 +240,50 @@ typedef struct {
typedef struct { typedef struct {
const AFM *afm; const AFM *afm;
TEXTMETRICW tm;
INT size;
float scale; float scale;
INT escapement; TEXTMETRICW tm;
} BUILTIN;
typedef struct tagTYPE42 TYPE42;
typedef struct tagTYPE1 TYPE1;
enum downloadtype {
Type1, Type42
};
typedef struct _tagDOWNLOAD {
enum downloadtype type;
union {
TYPE1 *Type1;
TYPE42 *Type42;
} typeinfo;
char *ps_name;
struct _tagDOWNLOAD *next;
} DOWNLOAD;
enum fontloc {
Builtin, Download
};
typedef struct {
enum fontloc fontloc;
union {
BUILTIN Builtin;
DOWNLOAD *Download;
} fontinfo;
int size;
PSCOLOR color; PSCOLOR color;
BOOL set; /* Have we done a setfont yet */ BOOL set; /* Have we done a setfont yet */
/* These are needed by PSDRV_ExtTextOut */
int escapement;
int underlineThickness;
int underlinePosition;
int strikeoutThickness;
int strikeoutPosition;
} PSFONT; } PSFONT;
typedef struct { typedef struct {
...@@ -269,6 +311,7 @@ typedef struct { ...@@ -269,6 +311,7 @@ typedef struct {
HDC hdc; HDC hdc;
struct tagDC *dc; struct tagDC *dc;
PSFONT font; /* Current PS font */ PSFONT font; /* Current PS font */
DOWNLOAD *downloaded_fonts;
PSPEN pen; PSPEN pen;
PSBRUSH brush; PSBRUSH brush;
PSCOLOR bkColor; PSCOLOR bkColor;
...@@ -355,8 +398,9 @@ extern BOOL PSDRV_WriteRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT width ...@@ -355,8 +398,9 @@ extern BOOL PSDRV_WriteRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT width
INT height); INT height);
extern BOOL PSDRV_WriteRRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT width, extern BOOL PSDRV_WriteRRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT width,
INT height); INT height);
extern BOOL PSDRV_WriteSetFont(PSDRV_PDEVICE *physDev); extern BOOL PSDRV_WriteSetFont(PSDRV_PDEVICE *physDev, const char *name, INT size,
extern BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCWSTR str, INT count); INT escapement);
extern BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCSTR g_name);
extern BOOL PSDRV_WriteSetPen(PSDRV_PDEVICE *physDev); extern BOOL PSDRV_WriteSetPen(PSDRV_PDEVICE *physDev);
extern BOOL PSDRV_WriteArc(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h, extern BOOL PSDRV_WriteArc(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h,
double ang1, double ang2); double ang1, double ang2);
...@@ -387,6 +431,7 @@ extern BOOL PSDRV_WriteDIBits24(PSDRV_PDEVICE *physDev, const BYTE *bits, int nu ...@@ -387,6 +431,7 @@ extern BOOL PSDRV_WriteDIBits24(PSDRV_PDEVICE *physDev, const BYTE *bits, int nu
extern BOOL PSDRV_WriteDIBits32(PSDRV_PDEVICE *physDev, const BYTE *bits, int number); extern BOOL PSDRV_WriteDIBits32(PSDRV_PDEVICE *physDev, const BYTE *bits, int number);
extern int PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPSTR lpData, WORD cch); extern int PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPSTR lpData, WORD cch);
extern BOOL PSDRV_WritePatternDict(PSDRV_PDEVICE *physDev, BITMAP *bm, BYTE *bits); extern BOOL PSDRV_WritePatternDict(PSDRV_PDEVICE *physDev, BITMAP *bm, BYTE *bits);
extern BOOL PSDRV_WriteDIBPatternDict(PSDRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage);
extern BOOL PSDRV_WriteArrayPut(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nIndex, LONG lCoord); extern BOOL PSDRV_WriteArrayPut(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nIndex, LONG lCoord);
extern BOOL PSDRV_WriteArrayDef(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nSize); extern BOOL PSDRV_WriteArrayDef(PSDRV_PDEVICE *physDev, CHAR *pszArrayName, INT nSize);
...@@ -453,6 +498,31 @@ BOOL PSDRV_GetType1Metrics(void); ...@@ -453,6 +498,31 @@ BOOL PSDRV_GetType1Metrics(void);
const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm); const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm);
SHORT PSDRV_CalcAvgCharWidth(const AFM *afm); SHORT PSDRV_CalcAvgCharWidth(const AFM *afm);
extern BOOL PSDRV_SelectBuiltinFont(PSDRV_PDEVICE *physDev, HFONT hfont,
LOGFONTW *plf, LPSTR FaceName);
extern BOOL PSDRV_WriteSetBuiltinFont(PSDRV_PDEVICE *physDev);
extern BOOL PSDRV_WriteBuiltinGlyphShow(PSDRV_PDEVICE *physDev, LPCWSTR str, INT count);
extern BOOL PSDRV_SelectDownloadFont(PSDRV_PDEVICE *physDev);
extern BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev);
extern BOOL PSDRV_WriteDownloadGlyphShow(PSDRV_PDEVICE *physDev, WORD *glpyhs,
UINT count);
extern BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev);
#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 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 BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl,
DWORD index, char *glyph_name);
extern void T42_free(TYPE42 *t42);
#endif #endif
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(psdrv); WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT count, static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
LPCWSTR str, UINT count,
BOOL bDrawBackground, const INT *lpDx); BOOL bDrawBackground, const INT *lpDx);
/*********************************************************************** /***********************************************************************
...@@ -70,12 +71,12 @@ BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, ...@@ -70,12 +71,12 @@ BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
PSDRV_WriteClip(physDev); PSDRV_WriteClip(physDev);
} }
bResult = PSDRV_Text(physDev, x, y, str, count, !(bClipped && bOpaque), lpDx); bResult = PSDRV_Text(physDev, x, y, flags, str, count, !(bClipped && bOpaque), lpDx);
PSDRV_WriteGRestore(physDev); PSDRV_WriteGRestore(physDev);
} }
else else
{ {
bResult = PSDRV_Text(physDev, x, y, str, count, TRUE, lpDx); bResult = PSDRV_Text(physDev, x, y, flags, str, count, TRUE, lpDx);
} }
return bResult; return bResult;
...@@ -84,21 +85,28 @@ BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, ...@@ -84,21 +85,28 @@ BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
/*********************************************************************** /***********************************************************************
* PSDRV_Text * PSDRV_Text
*/ */
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT count, static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR str,
BOOL bDrawBackground, const INT *lpDx) UINT count, BOOL bDrawBackground, const INT *lpDx)
{ {
LPWSTR strbuf;
SIZE sz; SIZE sz;
TEXTMETRICW tm;
POINT pt;
INT ascent, descent;
WORD *glyphs = NULL;
DC *dc = physDev->dc; DC *dc = physDev->dc;
UINT align = GetTextAlign( physDev->hdc ); UINT align = GetTextAlign( physDev->hdc );
if (!count) if (!count)
return TRUE; return TRUE;
strbuf = HeapAlloc( PSDRV_Heap, 0, (count + 1) * sizeof(WCHAR));
if(!strbuf) { if(physDev->font.fontloc == Download) {
WARN("HeapAlloc failed\n"); if(flags & ETO_GLYPH_INDEX)
return FALSE; glyphs = (LPWORD)str;
else {
glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD));
GetGlyphIndicesW(physDev->hdc, str, count, glyphs, 0);
}
} }
if(align & TA_UPDATECP) { if(align & TA_UPDATECP) {
...@@ -106,15 +114,25 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -106,15 +114,25 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
y = dc->CursPosY; y = dc->CursPosY;
} }
x = INTERNAL_XWPTODP(dc, x, y); pt.x = x;
y = INTERNAL_YWPTODP(dc, x, y); pt.y = y;
LPtoDP(physDev->hdc, &pt, 1);
x = pt.x;
y = pt.y;
if(physDev->font.fontloc == Download)
GetTextExtentPointI(physDev->hdc, glyphs, count, &sz);
else
GetTextExtentPoint32W(physDev->hdc, str, count, &sz);
GetTextExtentPoint32W(physDev->hdc, str, count, &sz);
if(lpDx) { if(lpDx) {
SIZE tmpsz; SIZE tmpsz;
INT i; INT i;
/* Get the width of the last char and add on all the offsets */ /* Get the width of the last char and add on all the offsets */
GetTextExtentPoint32W(physDev->hdc, str + count - 1, 1, &tmpsz); if(physDev->font.fontloc == Download)
GetTextExtentPointI(physDev->hdc, glyphs + count - 1, 1, &tmpsz);
else
GetTextExtentPoint32W(physDev->hdc, str + count - 1, 1, &tmpsz);
for(i = 0; i < count-1; i++) for(i = 0; i < count-1; i++)
tmpsz.cx += lpDx[i]; tmpsz.cx += lpDx[i];
sz.cx = tmpsz.cx; /* sz.cy remains untouched */ sz.cx = tmpsz.cx; /* sz.cy remains untouched */
...@@ -122,6 +140,11 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -122,6 +140,11 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
sz.cx = INTERNAL_XWSTODS(dc, sz.cx); sz.cx = INTERNAL_XWSTODS(dc, sz.cx);
sz.cy = INTERNAL_YWSTODS(dc, sz.cy); sz.cy = INTERNAL_YWSTODS(dc, sz.cy);
GetTextMetricsW(physDev->hdc, &tm);
ascent = INTERNAL_YWSTODS(dc, tm.tmAscent);
descent = INTERNAL_YWSTODS(dc, tm.tmDescent);
TRACE("textAlign = %x\n", align); TRACE("textAlign = %x\n", align);
switch(align & (TA_LEFT | TA_CENTER | TA_RIGHT) ) { switch(align & (TA_LEFT | TA_CENTER | TA_RIGHT) ) {
case TA_LEFT: case TA_LEFT:
...@@ -144,27 +167,23 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -144,27 +167,23 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
switch(align & (TA_TOP | TA_BASELINE | TA_BOTTOM) ) { switch(align & (TA_TOP | TA_BASELINE | TA_BOTTOM) ) {
case TA_TOP: case TA_TOP:
y += physDev->font.tm.tmAscent; y += ascent;
break; break;
case TA_BASELINE: case TA_BASELINE:
break; break;
case TA_BOTTOM: case TA_BOTTOM:
y -= physDev->font.tm.tmDescent; y -= descent;
break; break;
} }
memcpy(strbuf, str, count * sizeof(WCHAR));
*(strbuf + count) = '\0';
if ((GetBkMode( physDev->hdc ) != TRANSPARENT) && bDrawBackground) if ((GetBkMode( physDev->hdc ) != TRANSPARENT) && bDrawBackground)
{ {
PSDRV_WriteGSave(physDev); PSDRV_WriteGSave(physDev);
PSDRV_WriteNewPath(physDev); PSDRV_WriteNewPath(physDev);
PSDRV_WriteRectangle(physDev, x, y - physDev->font.tm.tmAscent, sz.cx, PSDRV_WriteRectangle(physDev, x, y - ascent, sz.cx,
physDev->font.tm.tmAscent + ascent + descent);
physDev->font.tm.tmDescent);
PSDRV_WriteSetColor(physDev, &physDev->bkColor); PSDRV_WriteSetColor(physDev, &physDev->bkColor);
PSDRV_WriteFill(physDev); PSDRV_WriteFill(physDev);
PSDRV_WriteGRestore(physDev); PSDRV_WriteGRestore(physDev);
...@@ -172,8 +191,12 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -172,8 +191,12 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
PSDRV_WriteMoveTo(physDev, x, y); PSDRV_WriteMoveTo(physDev, x, y);
if(!lpDx) if(!lpDx) {
PSDRV_WriteGlyphShow(physDev, strbuf, lstrlenW(strbuf)); if(physDev->font.fontloc == Download)
PSDRV_WriteDownloadGlyphShow(physDev, glyphs, count);
else
PSDRV_WriteBuiltinGlyphShow(physDev, str, count);
}
else { else {
INT i; INT i;
float dx = 0.0, dy = 0.0; float dx = 0.0, dy = 0.0;
...@@ -181,39 +204,34 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -181,39 +204,34 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0); float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0);
for(i = 0; i < count-1; i++) { for(i = 0; i < count-1; i++) {
TRACE("lpDx[%d] = %d\n", i, lpDx[i]); TRACE("lpDx[%d] = %d\n", i, lpDx[i]);
PSDRV_WriteGlyphShow(physDev, &strbuf[i], 1); if(physDev->font.fontloc == Download)
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
else
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
dx += lpDx[i] * cos_theta; dx += lpDx[i] * cos_theta;
dy -= lpDx[i] * sin_theta; dy -= lpDx[i] * sin_theta;
PSDRV_WriteMoveTo(physDev, x + INTERNAL_XWSTODS(dc, dx), PSDRV_WriteMoveTo(physDev, x + INTERNAL_XWSTODS(dc, dx),
y + INTERNAL_YWSTODS(dc, dy)); y + INTERNAL_YWSTODS(dc, dy));
} }
PSDRV_WriteGlyphShow(physDev, &strbuf[i], 1); if(physDev->font.fontloc == Download)
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
else
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
} }
/* /*
* Underline and strikeout attributes. * Underline and strikeout attributes.
*/ */
if ((physDev->font.tm.tmUnderlined) || (physDev->font.tm.tmStruckOut)) { if ((tm.tmUnderlined) || (tm.tmStruckOut)) {
/* Get the thickness and the position for the underline attribute */ /* Get the thickness and the position for the underline attribute */
/* We'll use the same thickness for the strikeout attribute */ /* We'll use the same thickness for the strikeout attribute */
float thick = physDev->font.afm->UnderlineThickness * physDev->font.scale;
float pos = -physDev->font.afm->UnderlinePosition * physDev->font.scale;
SIZE size;
INT escapement = physDev->font.escapement; INT escapement = physDev->font.escapement;
TRACE("Position = %f Thickness %f Escapement %d\n",
pos, thick, escapement);
/* Get the width of the text */
PSDRV_GetTextExtentPoint(physDev, strbuf, lstrlenW(strbuf), &size);
size.cx = INTERNAL_XWSTODS(dc, size.cx);
/* Do the underline */ /* Do the underline */
if (physDev->font.tm.tmUnderlined) { if (tm.tmUnderlined) {
PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */ PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */
if (escapement != 0) /* rotated text */ if (escapement != 0) /* rotated text */
{ {
...@@ -224,10 +242,12 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -224,10 +242,12 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
PSDRV_WriteRotate(physDev, -escapement/10); PSDRV_WriteRotate(physDev, -escapement/10);
/* draw the underline relative to the starting point */ /* draw the underline relative to the starting point */
PSDRV_WriteRRectangle(physDev, 0, (INT)pos, size.cx, (INT)thick); PSDRV_WriteRRectangle(physDev, 0, -physDev->font.underlinePosition,
sz.cx, physDev->font.underlineThickness);
} }
else else
PSDRV_WriteRectangle(physDev, x, y + (INT)pos, size.cx, (INT)thick); PSDRV_WriteRectangle(physDev, x, y - physDev->font.underlinePosition,
sz.cx, physDev->font.underlineThickness);
PSDRV_WriteFill(physDev); PSDRV_WriteFill(physDev);
...@@ -237,8 +257,7 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -237,8 +257,7 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
/* Do the strikeout */ /* Do the strikeout */
if (physDev->font.tm.tmStruckOut) { if (tm.tmStruckOut) {
pos = -physDev->font.tm.tmAscent / 2;
PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */ PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */
if (escapement != 0) /* rotated text */ if (escapement != 0) /* rotated text */
{ {
...@@ -248,11 +267,13 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -248,11 +267,13 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
/* temporarily rotate the coord system */ /* temporarily rotate the coord system */
PSDRV_WriteRotate(physDev, -escapement/10); PSDRV_WriteRotate(physDev, -escapement/10);
/* draw the underline relative to the starting point */ /* draw the line relative to the starting point */
PSDRV_WriteRRectangle(physDev, 0, (INT)pos, size.cx, (INT)thick); PSDRV_WriteRRectangle(physDev, 0, -physDev->font.strikeoutPosition,
sz.cx, physDev->font.strikeoutThickness);
} }
else else
PSDRV_WriteRectangle(physDev, x, y + (INT)pos, size.cx, (INT)thick); PSDRV_WriteRectangle(physDev, x, y - physDev->font.strikeoutPosition,
sz.cx, physDev->font.strikeoutThickness);
PSDRV_WriteFill(physDev); PSDRV_WriteFill(physDev);
...@@ -261,6 +282,6 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c ...@@ -261,6 +282,6 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, LPCWSTR str, UINT c
} }
} }
HeapFree(PSDRV_Heap, 0, strbuf); if(glyphs && glyphs != str) HeapFree(GetProcessHeap(), 0, glyphs);
return TRUE; return TRUE;
} }
/*
* PostScript driver Type1 font functions
*
* Copyright 2002 Huw D M Davies for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "winspool.h"
#include "psdrv.h"
#include "wine/debug.h"
#include "winerror.h"
#include "config.h"
#include "wine/port.h"
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
struct tagTYPE1 {
DWORD glyph_sent_size;
BOOL *glyph_sent;
DWORD emsize;
HFONT unscaled_font;
};
#define GLYPH_SENT_INC 128
/* Type 1 font commands */
enum t1_cmds {
rlineto = 5,
rrcurveto = 8,
closepath = 9,
hsbw = 13,
endchar = 14,
rmoveto = 21
};
TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm,
char *ps_name)
{
char *buf;
TYPE1 *t1;
LOGFONTW lf;
char dict[] = /* name, emsquare, fontbbox */
"25 dict begin\n"
" /FontName /%s def\n"
" /Encoding 256 array 0 1 255{1 index exch /.notdef put} for def\n"
" /PaintType 0 def\n"
" /FontMatrix [1 %d div 0 0 1 %d div 0 0] def\n"
" /FontBBox [%d %d %d %d] def\n"
" /FontType 1 def\n"
" /Private 7 dict begin\n"
" /RD {string currentfile exch readhexstring pop} def\n"
" /ND {def} def\n"
" /NP {put} def\n"
" /MinFeature {16 16} def\n"
" /BlueValues [] def\n"
" /password 5839 def\n"
" /lenIV -1 def\n"
" currentdict end def\n"
" currentdict dup /Private get begin\n"
" /CharStrings 256 dict begin\n"
" /.notdef 4 RD 8b8b0d0e ND\n"
" currentdict end put\n"
" end\n"
"currentdict end dup /FontName get exch definefont pop\n";
t1 = HeapAlloc(GetProcessHeap(), 0, sizeof(*t1));
t1->emsize = potm->otmEMSquare;
GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
lf.lfHeight = -t1->emsize;
t1->unscaled_font = CreateFontIndirectW(&lf);
t1->glyph_sent_size = GLYPH_SENT_INC;
t1->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
t1->glyph_sent_size *
sizeof(*(t1->glyph_sent)));
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(dict) + strlen(ps_name) +
100);
sprintf(buf, dict, ps_name, t1->emsize, t1->emsize,
potm->otmrcFontBox.left, potm->otmrcFontBox.bottom,
potm->otmrcFontBox.right, potm->otmrcFontBox.top);
PSDRV_WriteSpool(physDev, buf, strlen(buf));
HeapFree(GetProcessHeap(), 0, buf);
return t1;
}
typedef struct {
BYTE *str;
int len, max_len;
} STR;
static STR *str_init(int sz)
{
STR *str = HeapAlloc(GetProcessHeap(), 0, sizeof(*str));
str->max_len = sz;
str->str = HeapAlloc(GetProcessHeap(), 0, str->max_len);
str->len = 0;
return str;
}
static void str_free(STR *str)
{
HeapFree(GetProcessHeap(), 0, str->str);
HeapFree(GetProcessHeap(), 0, str);
}
static void str_add_byte(STR *str, BYTE b)
{
if(str->len == str->max_len) {
str->max_len *= 2;
str->str = HeapReAlloc(GetProcessHeap(), 0, str->str, str->max_len);
}
str->str[str->len++] = b;
}
static void str_add_num(STR *str, int num)
{
if(num <= 107 && num >= -107)
str_add_byte(str, num + 139);
else if(num >= 108 && num <= 1131) {
str_add_byte(str, ((num - 108) >> 8) + 247);
str_add_byte(str, (num - 108) & 0xff);
} else if(num <= -108 && num >= -1131) {
num = -num;
str_add_byte(str, ((num - 108) >> 8) + 251);
str_add_byte(str, (num - 108) & 0xff);
} else {
str_add_byte(str, 0xff);
str_add_byte(str, (num >> 24) & 0xff);
str_add_byte(str, (num >> 16) & 0xff);
str_add_byte(str, (num >> 8) & 0xff);
str_add_byte(str, (num & 0xff));
}
}
static void str_add_point(STR *str, POINTFX *pt, POINT *curpos)
{
POINT newpos;
newpos.x = pt->x.value + ((pt->x.fract >> 15) & 0x1);
newpos.y = pt->y.value + ((pt->y.fract >> 15) & 0x1);
str_add_num(str, newpos.x - curpos->x);
str_add_num(str, newpos.y - curpos->y);
*curpos = newpos;
}
static void str_add_cmd(STR *str, enum t1_cmds cmd)
{
str_add_byte(str, (BYTE)cmd);
}
static int str_get_bytes(STR *str, BYTE **b)
{
*b = str->str;
return str->len;
}
BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
char *glyph_name)
{
DWORD len, i;
char *buf;
TYPE1 *t1;
STR *charstring;
BYTE *bytes;
HFONT old_font;
GLYPHMETRICS gm;
char *glyph_buf;
POINT curpos;
TTPOLYGONHEADER *pph;
TTPOLYCURVE *ppc;
char glyph_def_begin[] =
"/%s findfont dup\n"
"/Private get begin\n"
"/CharStrings get begin\n"
"/%s %d RD\n";
char glyph_def_end[] =
"ND\n"
"end end\n";
TRACE("%ld %s\n", index, glyph_name);
assert(pdl->type == Type1);
t1 = pdl->typeinfo.Type1;
if(index < t1->glyph_sent_size) {
if(t1->glyph_sent[index])
return TRUE;
} else {
t1->glyph_sent_size = (index / GLYPH_SENT_INC + 1) * GLYPH_SENT_INC;
t1->glyph_sent = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
t1->glyph_sent,
t1->glyph_sent_size * sizeof(*(t1->glyph_sent)));
}
old_font = SelectObject(physDev->hdc, t1->unscaled_font);
len = GetGlyphOutlineW(physDev->hdc, index, GGO_GLYPH_INDEX | GGO_BEZIER,
&gm, 0, NULL, NULL);
if(len == GDI_ERROR) return FALSE;
glyph_buf = HeapAlloc(GetProcessHeap(), 0, len);
GetGlyphOutlineW(physDev->hdc, index, GGO_GLYPH_INDEX | GGO_BEZIER,
&gm, len, glyph_buf, NULL);
SelectObject(physDev->hdc, old_font);
charstring = str_init(100);
curpos.x = gm.gmptGlyphOrigin.x;
curpos.y = 0;
str_add_num(charstring, curpos.x);
str_add_num(charstring, gm.gmCellIncX);
str_add_cmd(charstring, hsbw);
pph = (TTPOLYGONHEADER*)glyph_buf;
while((char*)pph < glyph_buf + len) {
TRACE("contour len %ld\n", pph->cb);
ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph));
str_add_point(charstring, &pph->pfxStart, &curpos);
str_add_cmd(charstring, rmoveto);
while((char*)ppc < (char*)pph + pph->cb) {
TRACE("line type %d cpfx = %d\n", ppc->wType, ppc->cpfx);
switch(ppc->wType) {
case TT_PRIM_LINE:
for(i = 0; i < ppc->cpfx; i++) {
str_add_point(charstring, ppc->apfx + i, &curpos);
str_add_cmd(charstring, rlineto);
}
break;
case TT_PRIM_CSPLINE:
for(i = 0; i < ppc->cpfx/3; i++) {
str_add_point(charstring, ppc->apfx + 3 * i, &curpos);
str_add_point(charstring, ppc->apfx + 3 * i + 1, &curpos);
str_add_point(charstring, ppc->apfx + 3 * i + 2, &curpos);
str_add_cmd(charstring, rrcurveto);
}
break;
default:
ERR("curve type = %d\n", ppc->wType);
return FALSE;
}
ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) +
(ppc->cpfx - 1) * sizeof(POINTFX));
}
str_add_cmd(charstring, closepath);
pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb);
}
str_add_cmd(charstring, endchar);
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(glyph_def_begin) +
strlen(pdl->ps_name) + strlen(glyph_name) + 100);
sprintf(buf, "%%%%glyph %04lx\n", index);
PSDRV_WriteSpool(physDev, buf, strlen(buf));
len = str_get_bytes(charstring, &bytes);
sprintf(buf, glyph_def_begin, pdl->ps_name, glyph_name, len);
PSDRV_WriteSpool(physDev, buf, strlen(buf));
PSDRV_WriteBytes(physDev, bytes, len);
sprintf(buf, glyph_def_end);
PSDRV_WriteSpool(physDev, buf, strlen(buf));
str_free(charstring);
t1->glyph_sent[index] = TRUE;
HeapFree(GetProcessHeap(), 0, glyph_buf);
HeapFree(GetProcessHeap(), 0, buf);
return TRUE;
}
void T1_free(TYPE1 *t1)
{
HeapFree(GetProcessHeap(), 0, t1->glyph_sent);
DeleteObject(t1->unscaled_font);
HeapFree(GetProcessHeap(), 0, t1);
return;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment