text.c 4.19 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1
/*
Alexandre Julliard's avatar
Alexandre Julliard committed
2
 *	PostScript driver text functions
Alexandre Julliard's avatar
Alexandre Julliard committed
3 4 5
 *
 *	Copyright 1998  Huw D M Davies
 *
6 7 8 9 10 11 12 13 14 15 16 17
 * 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
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */
#include <string.h>
21
#include <stdarg.h>
22
#include <stdlib.h>
23 24 25 26
#include <math.h>

#include "windef.h"
#include "wingdi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
27
#include "psdrv.h"
28
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
29

30
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
31

32 33
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
		       LPCWSTR str, UINT count,
34
		       BOOL bDrawBackground, const INT *lpDx);
35

Alexandre Julliard's avatar
Alexandre Julliard committed
36 37 38
/***********************************************************************
 *           PSDRV_ExtTextOut
 */
39
BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
40
		       const RECT *lprect, LPCWSTR str, UINT count,
41
		       const INT *lpDx )
Alexandre Julliard's avatar
Alexandre Julliard committed
42
{
43
    BOOL bResult = TRUE;
44 45
    BOOL bClipped = FALSE;
    BOOL bOpaque = FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
46

47 48
    TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y,
	  flags, debugstr_wn(str, count), count, lpDx);
Alexandre Julliard's avatar
Alexandre Julliard committed
49

50 51
    if(physDev->job.hJob == 0) return FALSE;

52
    /* write font if not already written */
53
    PSDRV_SetFont(physDev);
54

55 56
    PSDRV_SetClip(physDev);

57
    /* set clipping and/or draw background */
58
    if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL))
59
    {
60
	PSDRV_WriteGSave(physDev);
61 62
	PSDRV_WriteRectangle(physDev, lprect->left, lprect->top, lprect->right - lprect->left,
			     lprect->bottom - lprect->top);
63 64 65

	if (flags & ETO_OPAQUE)
	{
66
	    bOpaque = TRUE;
67 68 69 70
	    PSDRV_WriteGSave(physDev);
	    PSDRV_WriteSetColor(physDev, &physDev->bkColor);
	    PSDRV_WriteFill(physDev);
	    PSDRV_WriteGRestore(physDev);
71 72 73 74
	}

	if (flags & ETO_CLIPPED)
	{
75
	    bClipped = TRUE;
76
	    PSDRV_WriteClip(physDev);
77 78
	}

79
	bResult = PSDRV_Text(physDev, x, y, flags, str, count, !(bClipped && bOpaque), lpDx);
80
	PSDRV_WriteGRestore(physDev);
81 82 83
    }
    else
    {
84
	bResult = PSDRV_Text(physDev, x, y, flags, str, count, TRUE, lpDx);
85 86
    }

87
    PSDRV_ResetClip(physDev);
88 89 90 91 92 93
    return bResult;
}

/***********************************************************************
 *           PSDRV_Text
 */
94 95
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR str,
		       UINT count, BOOL bDrawBackground, const INT *lpDx)
96
{
97
    WORD *glyphs = NULL;
98 99
    double cosEsc, sinEsc;
    LOGFONTW lf;
100

101 102 103
    if (!count)
	return TRUE;

104 105 106 107 108 109 110 111
    GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
    if(lf.lfEscapement != 0) {
        cosEsc = cos(lf.lfEscapement * M_PI / 1800);
        sinEsc = sin(lf.lfEscapement * M_PI / 1800);
    } else {
        cosEsc = 1;
        sinEsc = 0;
    }
112 113

    if(physDev->font.fontloc == Download)
114
        glyphs = (LPWORD)str;
Alexandre Julliard's avatar
Alexandre Julliard committed
115

116
    PSDRV_WriteMoveTo(physDev, x, y);
117

118
    if(!lpDx) {
119 120 121 122 123
        if(physDev->font.fontloc == Download)
	    PSDRV_WriteDownloadGlyphShow(physDev, glyphs, count);
	else
	    PSDRV_WriteBuiltinGlyphShow(physDev, str, count);
    }
124
    else {
125
        UINT i;
126 127 128
	float dx = 0.0, dy = 0.0;
	float cos_theta = cos(physDev->font.escapement * M_PI / 1800.0);
	float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0);
129
        for(i = 0; i < count-1; i++) {
130
	    TRACE("lpDx[%d] = %d\n", i, lpDx[i]);
131 132 133 134
	    if(physDev->font.fontloc == Download)
	        PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
	    else
	        PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
135 136 137
	    dx += lpDx[i] * cos_theta;
	    dy -= lpDx[i] * sin_theta;
	    PSDRV_WriteMoveTo(physDev, x + dx, y + dy);
138
	}
139 140 141 142
	if(physDev->font.fontloc == Download)
	    PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
	else
	    PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
143 144
    }

Alexandre Julliard's avatar
Alexandre Julliard committed
145 146
    return TRUE;
}