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;
225 if (!(flags & DT_CALCRECT))
226 if (!TextOut(hdc, x, y, line, len)) return 0;
227 if (prefix_offset != -1)
229 MoveTo(hdc, x + prefix_x, y + size.cy);
230 LineTo(hdc, x + prefix_x + prefix_len, y + size.cy);
236 if (!(flags & DT_NOCLIP))
238 if (y > rect->bottom - lh)
244 if (flags & DT_CALCRECT) rect->bottom = y;
249 /***********************************************************************
252 BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count )
254 int dir, ascent, descent, i;
258 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
259 if (!dc) return FALSE;
260 if (!DC_SetupGCForText( dc )) return TRUE;
261 font = dc->u.x.font.fstruct;
263 if (dc->w.textAlign & TA_UPDATECP)
269 printf( "TextOut: %d,%d '%s'\n", x, y, str );
271 x = XLPTODP( dc, x );
272 y = YLPTODP( dc, y );
274 XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
275 info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
277 /* Compute starting position */
279 switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
282 if (dc->w.textAlign & TA_UPDATECP)
283 dc->w.CursPosX = XDPTOLP( dc, x + info.width );
287 if (dc->w.textAlign & TA_UPDATECP) dc->w.CursPosX = XDPTOLP( dc, x );
293 switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
307 if (!dc->w.charExtra && !dc->w.breakExtra)
309 if (dc->w.backgroundMode == TRANSPARENT)
310 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
311 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
313 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
314 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
320 for (i = 0; i < count; i++, p++)
322 XCharStruct * charStr;
323 unsigned char ch = *p;
326 if ((ch < font->min_char_or_byte2)||(ch > font->max_char_or_byte2))
327 ch = font->default_char;
328 if (!font->per_char) charStr = &font->min_bounds;
329 else charStr = font->per_char + ch - font->min_char_or_byte2;
331 extraWidth = dc->w.charExtra;
332 if (ch == dc->u.x.font.metrics.tmBreakChar)
333 extraWidth += dc->w.breakExtra;
335 if (dc->w.backgroundMode == TRANSPARENT)
336 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
337 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
340 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
341 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
342 XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
343 XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
344 dc->w.DCOrgX + xchar + charStr->width,
345 dc->w.DCOrgY + y - font->ascent,
346 extraWidth, font->ascent + font->descent );
347 XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
349 xchar += charStr->width + extraWidth;
353 /* Draw underline and strike-out if needed */
355 if (dc->u.x.font.metrics.tmUnderlined)
357 long linePos, lineWidth;
358 if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
359 linePos = font->descent-1;
360 if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
362 else if (lineWidth == 1) lineWidth = 0;
363 XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth,
364 LineSolid, CapRound, JoinBevel );
365 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
366 dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
367 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos );
369 if (dc->u.x.font.metrics.tmStruckOut)
371 long lineAscent, lineDescent;
372 if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
373 lineAscent = font->ascent / 3;
374 if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
375 lineDescent = -lineAscent;
376 XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent,
377 LineSolid, CapRound, JoinBevel );
378 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
379 dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
380 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );