4 * Copyright 1993 Alexandre Julliard
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
19 static int tabstop = 8;
21 static int spacewidth;
22 static int prefix_offset;
25 static char *TEXT_NextLine(HDC hdc, char *str, int *count, char *dest,
26 int *len, int width, WORD format)
28 /* Return next line of text from a string.
31 * str - string to parse into lines.
32 * count - length of str.
33 * dest - destination in which to return line.
34 * len - length of resultant line in dest in chars.
35 * width - maximum width of line in pixels.
36 * format - format type passed to DrawText.
38 * Returns pointer to next char in str after end of the line
39 * or NULL if end of str reached.
47 int wb_i = 0, wb_j = 0, wb_count;
55 if (!(format & DT_SINGLELINE))
58 if (str[i] == CR || str[i] == LF)
64 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
66 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
73 if (!(format & DT_NOPREFIX))
75 prefix_offset = j + 1;
81 if (!(format & DT_NOCLIP))
83 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
91 if (format & DT_EXPANDTABS)
97 if (!GetTextExtentPoint(hdc, &dest[lasttab], j - lasttab,
101 numspaces = (tabwidth - size.cx) / spacewidth;
102 for (k = 0; k < numspaces; k++)
104 plen += tabwidth - size.cx;
105 lasttab = wb_j + numspaces;
109 dest[j++] = str[i++];
110 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
112 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
120 dest[j++] = str[i++];
121 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
126 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
133 dest[j++] = str[i++];
134 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
136 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
143 if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
147 if (format & DT_WORDBREAK)
167 /***********************************************************************
170 int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags )
174 static char line[1024];
175 int len, lh, prefix_x, prefix_len;
177 int x = rect->left, y = rect->top;
178 int width = rect->right - rect->left;
180 if (count == -1) count = strlen(str);
183 GetTextMetrics(hdc, &tm);
184 if (flags & DT_EXTERNALLEADING)
185 lh = tm.tmHeight + tm.tmExternalLeading;
189 if (flags & DT_TABSTOP)
190 tabstop = flags >> 8;
192 if (flags & DT_EXPANDTABS)
194 GetTextExtentPoint(hdc, " ", 1, &size);
195 spacewidth = size.cx;
196 GetTextExtentPoint(hdc, "o", 1, &size);
197 tabwidth = size.cx * tabstop;
203 strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags);
205 if (prefix_offset != -1)
207 GetTextExtentPoint(hdc, line, prefix_offset - 1, &size);
209 GetTextExtentPoint(hdc, line + prefix_offset, 1, &size);
210 prefix_len = size.cx;
213 if (!GetTextExtentPoint(hdc, line, len, &size)) return 0;
214 if (flags & DT_CENTER) x = (rect->left + rect->right -
216 else if (flags & DT_RIGHT) x = rect->right - size.cx;
218 if (flags & DT_SINGLELINE)
220 if (flags & DT_VCENTER) y = rect->top +
221 (rect->bottom - rect->top) / 2 - size.cy / 2;
222 else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
224 if (!(flags & DT_CALCRECT))
225 if (!TextOut(hdc, x, y, line, len)) return 0;
226 if (prefix_offset != -1)
228 MoveTo(hdc, x + prefix_x, y + size.cy);
229 LineTo(hdc, x + prefix_x + prefix_len, y + size.cy);
235 if (!(flags & DT_NOCLIP))
237 if (y > rect->bottom - lh)
243 if (flags & DT_CALCRECT) rect->bottom = y;
248 /***********************************************************************
251 BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count )
253 int dir, ascent, descent, i;
257 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
258 if (!dc) return FALSE;
259 if (!DC_SetupGCForText( dc )) return TRUE;
260 font = dc->u.x.font.fstruct;
262 if (dc->w.textAlign & TA_UPDATECP)
268 printf( "TextOut: %d,%d '%s', %d\n", x, y, str, count );
270 x = XLPTODP( dc, x );
271 y = YLPTODP( dc, y );
273 XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
274 info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
276 /* Compute starting position */
278 switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
281 if (dc->w.textAlign & TA_UPDATECP)
282 dc->w.CursPosX = XDPTOLP( dc, x + info.width );
286 if (dc->w.textAlign & TA_UPDATECP) dc->w.CursPosX = XDPTOLP( dc, x );
292 switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
306 if (!dc->w.charExtra && !dc->w.breakExtra)
308 if (dc->w.backgroundMode == TRANSPARENT)
309 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
310 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
312 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
313 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
319 for (i = 0; i < count; i++, p++)
321 XCharStruct * charStr;
322 unsigned char ch = *p;
325 if ((ch < font->min_char_or_byte2)||(ch > font->max_char_or_byte2))
326 ch = font->default_char;
327 if (!font->per_char) charStr = &font->min_bounds;
328 else charStr = font->per_char + ch - font->min_char_or_byte2;
330 extraWidth = dc->w.charExtra;
331 if (ch == dc->u.x.font.metrics.tmBreakChar)
332 extraWidth += dc->w.breakExtra;
334 if (dc->w.backgroundMode == TRANSPARENT)
335 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
336 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
339 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
340 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
341 XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
342 XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
343 dc->w.DCOrgX + xchar + charStr->width,
344 dc->w.DCOrgY + y - font->ascent,
345 extraWidth, font->ascent + font->descent );
346 XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
348 xchar += charStr->width + extraWidth;
352 /* Draw underline and strike-out if needed */
354 if (dc->u.x.font.metrics.tmUnderlined)
356 long linePos, lineWidth;
357 if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
358 linePos = font->descent-1;
359 if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
361 else if (lineWidth == 1) lineWidth = 0;
362 XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth,
363 LineSolid, CapRound, JoinBevel );
364 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
365 dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
366 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos );
368 if (dc->u.x.font.metrics.tmStruckOut)
370 long lineAscent, lineDescent;
371 if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
372 lineAscent = font->ascent / 3;
373 if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
374 lineDescent = -lineAscent;
375 XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent,
376 LineSolid, CapRound, JoinBevel );
377 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
378 dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
379 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );
385 /***********************************************************************
386 * GrayString (USER.185)
388 BOOL GrayString(HDC hdc, HBRUSH hbr, FARPROC gsprc, LPARAM lParam,
389 INT cch, INT x, INT y, INT cx, INT cy)
391 int s, current_color;
394 return CallGrayStringProc(gsprc, hdc, lParam,
395 cch ? cch : lstrlen((LPCSTR) lParam) );
397 current_color = GetTextColor(hdc);
398 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT) );
399 s = TextOut(hdc, x, y, (LPSTR) lParam,
400 cch ? cch : lstrlen((LPCSTR) lParam) );
401 SetTextColor(hdc, current_color);