Removed CALL_LARGE_STACK support.
[wine.git] / dlls / wineps / text.c
blob514b26b0da8a58c165518bfbd7efb2cb09a123cc
1 /*
2 * PostScript driver text functions
4 * Copyright 1998 Huw D M Davies
6 */
7 #include <string.h>
8 #include "psdrv.h"
9 #include "debugtools.h"
10 #include "winspool.h"
12 DEFAULT_DEBUG_CHANNEL(psdrv);
14 static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count,
15 BOOL bDrawBackground);
17 /***********************************************************************
18 * PSDRV_ExtTextOut
20 BOOL PSDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
21 const RECT *lprect, LPCWSTR str, UINT count,
22 const INT *lpDx )
24 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
25 BOOL bResult = TRUE;
26 BOOL bClipped = FALSE;
27 BOOL bOpaque = FALSE;
28 RECT rect;
30 TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d)\n", x, y,
31 flags, debugstr_wn(str, count), count);
33 /* write font if not already written */
34 PSDRV_SetFont(dc);
36 /* set clipping and/or draw background */
37 if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL))
39 rect.left = XLPTODP(dc, lprect->left);
40 rect.right = XLPTODP(dc, lprect->right);
41 rect.top = YLPTODP(dc, lprect->top);
42 rect.bottom = YLPTODP(dc, lprect->bottom);
44 PSDRV_WriteGSave(dc);
45 PSDRV_WriteRectangle(dc, rect.left, rect.top, rect.right - rect.left,
46 rect.bottom - rect.top);
48 if (flags & ETO_OPAQUE)
50 bOpaque = TRUE;
51 PSDRV_WriteGSave(dc);
52 PSDRV_WriteSetColor(dc, &physDev->bkColor);
53 PSDRV_WriteFill(dc);
54 PSDRV_WriteGRestore(dc);
57 if (flags & ETO_CLIPPED)
59 bClipped = TRUE;
60 PSDRV_WriteClip(dc);
63 bResult = PSDRV_Text(dc, x, y, str, count, !(bClipped && bOpaque));
64 PSDRV_WriteGRestore(dc);
66 else
68 bResult = PSDRV_Text(dc, x, y, str, count, TRUE);
71 return bResult;
74 /***********************************************************************
75 * PSDRV_Text
77 static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count,
78 BOOL bDrawBackground)
80 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
81 LPWSTR strbuf;
82 SIZE sz;
84 strbuf = HeapAlloc( PSDRV_Heap, 0, (count + 1) * sizeof(WCHAR));
85 if(!strbuf) {
86 WARN("HeapAlloc failed\n");
87 return FALSE;
90 if(dc->textAlign & TA_UPDATECP) {
91 x = dc->CursPosX;
92 y = dc->CursPosY;
95 x = XLPTODP(dc, x);
96 y = YLPTODP(dc, y);
98 GetTextExtentPoint32W(dc->hSelf, str, count, &sz);
99 sz.cx = XLSTODS(dc, sz.cx);
100 sz.cy = YLSTODS(dc, sz.cy);
102 switch(dc->textAlign & (TA_LEFT | TA_CENTER | TA_RIGHT) ) {
103 case TA_LEFT:
104 if(dc->textAlign & TA_UPDATECP)
105 dc->CursPosX = XDPTOLP(dc, x + sz.cx);
106 break;
108 case TA_CENTER:
109 x -= sz.cx/2;
110 break;
112 case TA_RIGHT:
113 x -= sz.cx;
114 if(dc->textAlign & TA_UPDATECP)
115 dc->CursPosX = XDPTOLP(dc, x);
116 break;
119 switch(dc->textAlign & (TA_TOP | TA_BASELINE | TA_BOTTOM) ) {
120 case TA_TOP:
121 y += physDev->font.tm.tmAscent;
122 break;
124 case TA_BASELINE:
125 break;
127 case TA_BOTTOM:
128 y -= physDev->font.tm.tmDescent;
129 break;
132 memcpy(strbuf, str, count * sizeof(WCHAR));
133 *(strbuf + count) = '\0';
135 if ((dc->backgroundMode != TRANSPARENT) && (bDrawBackground != FALSE))
137 PSDRV_WriteGSave(dc);
138 PSDRV_WriteNewPath(dc);
139 PSDRV_WriteRectangle(dc, x, y - physDev->font.tm.tmAscent, sz.cx,
140 physDev->font.tm.tmAscent +
141 physDev->font.tm.tmDescent);
142 PSDRV_WriteSetColor(dc, &physDev->bkColor);
143 PSDRV_WriteFill(dc);
144 PSDRV_WriteGRestore(dc);
147 PSDRV_WriteMoveTo(dc, x, y);
148 PSDRV_WriteShow(dc, strbuf, lstrlenW(strbuf));
151 * Underline and strikeout attributes.
153 if ((physDev->font.tm.tmUnderlined) || (physDev->font.tm.tmStruckOut)) {
155 /* Get the thickness and the position for the underline attribute */
156 /* We'll use the same thickness for the strikeout attribute */
158 float thick = physDev->font.afm->UnderlineThickness * physDev->font.scale;
159 float pos = -physDev->font.afm->UnderlinePosition * physDev->font.scale;
160 SIZE size;
161 INT escapement = physDev->font.escapement;
163 TRACE("Position = %f Thickness %f Escapement %d\n",
164 pos, thick, escapement);
166 /* Get the width of the text */
168 PSDRV_GetTextExtentPoint(dc, strbuf, lstrlenW(strbuf), &size);
169 size.cx = XLSTODS(dc, size.cx);
171 /* Do the underline */
173 if (physDev->font.tm.tmUnderlined) {
174 if (escapement != 0) /* rotated text */
176 PSDRV_WriteGSave(dc); /* save the graphics state */
177 PSDRV_WriteMoveTo(dc, x, y); /* move to the start */
179 /* temporarily rotate the coord system */
180 PSDRV_WriteRotate(dc, -escapement/10);
182 /* draw the underline relative to the starting point */
183 PSDRV_WriteRRectangle(dc, 0, (INT)pos, size.cx, (INT)thick);
185 else
186 PSDRV_WriteRectangle(dc, x, y + (INT)pos, size.cx, (INT)thick);
188 PSDRV_WriteFill(dc);
190 if (escapement != 0) /* rotated text */
191 PSDRV_WriteGRestore(dc); /* restore the graphics state */
194 /* Do the strikeout */
196 if (physDev->font.tm.tmStruckOut) {
197 pos = -physDev->font.tm.tmAscent / 2;
199 if (escapement != 0) /* rotated text */
201 PSDRV_WriteGSave(dc); /* save the graphics state */
202 PSDRV_WriteMoveTo(dc, x, y); /* move to the start */
204 /* temporarily rotate the coord system */
205 PSDRV_WriteRotate(dc, -escapement/10);
207 /* draw the underline relative to the starting point */
208 PSDRV_WriteRRectangle(dc, 0, (INT)pos, size.cx, (INT)thick);
210 else
211 PSDRV_WriteRectangle(dc, x, y + (INT)pos, size.cx, (INT)thick);
213 PSDRV_WriteFill(dc);
215 if (escapement != 0) /* rotated text */
216 PSDRV_WriteGRestore(dc); /* restore the graphics state */
220 HeapFree(PSDRV_Heap, 0, strbuf);
221 return TRUE;