4 * Copyright 1993 Alexandre Julliard
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
20 static int tabstop = 8;
22 static int spacewidth;
23 static int prefix_offset;
26 static char *TEXT_NextLine(HDC hdc, char *str, int *count, char *dest,
27 int *len, int width, WORD format)
29 /* Return next line of text from a string.
32 * str - string to parse into lines.
33 * count - length of str.
34 * dest - destination in which to return line.
35 * len - length of resultant line in dest in chars.
36 * width - maximum width of line in pixels.
37 * format - format type passed to DrawText.
39 * Returns pointer to next char in str after end of the line
40 * or NULL if end of str reached.
48 int wb_i = 0, wb_j = 0, wb_count;
56 if (!(format & DT_SINGLELINE))
59 if (str[i] == CR || str[i] == LF)
65 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
66 (format & DT_WORDBREAK))
68 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
75 if (!(format & DT_NOPREFIX))
77 prefix_offset = j + 1;
83 if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
85 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
93 if (format & DT_EXPANDTABS)
99 if (!GetTextExtentPoint(hdc, &dest[lasttab], j - lasttab,
103 numspaces = (tabwidth - size.cx) / spacewidth;
104 for (k = 0; k < numspaces; k++)
106 plen += tabwidth - size.cx;
107 lasttab = wb_j + numspaces;
111 dest[j++] = str[i++];
112 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
113 (format & DT_WORDBREAK))
115 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
123 dest[j++] = str[i++];
124 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
125 (format & DT_WORDBREAK))
130 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
137 dest[j++] = str[i++];
138 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
139 (format & DT_WORDBREAK))
141 if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
148 if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
152 if (format & DT_WORDBREAK)
155 *count = wb_count - 1;
172 /***********************************************************************
175 int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags )
179 static char line[1024];
180 int len, lh, prefix_x, prefix_len;
182 int x = rect->left, y = rect->top;
183 int width = rect->right - rect->left;
186 printf( "DrawText: '%s', %d , [(%d,%d),(%d,%d)]\n", str, count,
187 rect->left, rect->top, rect->right, rect->bottom);
190 if (count == -1) count = strlen(str);
193 GetTextMetrics(hdc, &tm);
194 if (flags & DT_EXTERNALLEADING)
195 lh = tm.tmHeight + tm.tmExternalLeading;
199 if (flags & DT_TABSTOP)
200 tabstop = flags >> 8;
202 if (flags & DT_EXPANDTABS)
204 GetTextExtentPoint(hdc, " ", 1, &size);
205 spacewidth = size.cx;
206 GetTextExtentPoint(hdc, "o", 1, &size);
207 tabwidth = size.cx * tabstop;
213 strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags);
215 if (prefix_offset != -1)
217 GetTextExtentPoint(hdc, line, prefix_offset - 1, &size);
219 GetTextExtentPoint(hdc, line + prefix_offset, 1, &size);
220 prefix_len = size.cx;
223 if (!GetTextExtentPoint(hdc, line, len, &size)) return 0;
224 if (flags & DT_CENTER) x = (rect->left + rect->right -
226 else if (flags & DT_RIGHT) x = rect->right - size.cx;
228 if (flags & DT_SINGLELINE)
230 if (flags & DT_VCENTER) y = rect->top +
231 (rect->bottom - rect->top) / 2 - size.cy / 2;
232 else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
234 if (!(flags & DT_CALCRECT))
235 if (!TextOut(hdc, x, y, line, len)) return 0;
236 if (prefix_offset != -1)
238 MoveTo(hdc, x + prefix_x, y + size.cy);
239 LineTo(hdc, x + prefix_x + prefix_len, y + size.cy);
245 if (!(flags & DT_NOCLIP))
247 if (y > rect->bottom - lh)
253 if (flags & DT_CALCRECT) rect->bottom = y;
258 /***********************************************************************
261 BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count )
263 int dir, ascent, descent, i;
267 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
270 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
271 if (!dc) return FALSE;
272 MF_TextOut(dc, x, y, str, count);
276 if (!DC_SetupGCForText( dc )) return TRUE;
277 font = dc->u.x.font.fstruct;
279 if (dc->w.textAlign & TA_UPDATECP)
285 printf( "TextOut: %d,%d '%s', %d\n", x, y, str, count );
287 x = XLPTODP( dc, x );
288 y = YLPTODP( dc, y );
290 XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
291 info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
293 /* Compute starting position */
295 switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
298 if (dc->w.textAlign & TA_UPDATECP)
299 dc->w.CursPosX = XDPTOLP( dc, x + info.width );
303 if (dc->w.textAlign & TA_UPDATECP) dc->w.CursPosX = XDPTOLP( dc, x );
309 switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
323 if (!dc->w.charExtra && !dc->w.breakExtra)
325 if (dc->w.backgroundMode == TRANSPARENT)
326 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
327 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
329 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
330 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
336 for (i = 0; i < count; i++, p++)
338 XCharStruct * charStr;
339 unsigned char ch = *p;
342 if ((ch < font->min_char_or_byte2)||(ch > font->max_char_or_byte2))
343 ch = font->default_char;
344 if (!font->per_char) charStr = &font->min_bounds;
345 else charStr = font->per_char + ch - font->min_char_or_byte2;
347 extraWidth = dc->w.charExtra;
348 if (ch == dc->u.x.font.metrics.tmBreakChar)
349 extraWidth += dc->w.breakExtra;
351 if (dc->w.backgroundMode == TRANSPARENT)
352 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
353 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
356 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
357 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
358 XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
359 XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
360 dc->w.DCOrgX + xchar + charStr->width,
361 dc->w.DCOrgY + y - font->ascent,
362 extraWidth, font->ascent + font->descent );
363 XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
365 xchar += charStr->width + extraWidth;
369 /* Draw underline and strike-out if needed */
371 if (dc->u.x.font.metrics.tmUnderlined)
373 long linePos, lineWidth;
374 if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
375 linePos = font->descent-1;
376 if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
378 else if (lineWidth == 1) lineWidth = 0;
379 XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth,
380 LineSolid, CapRound, JoinBevel );
381 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
382 dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
383 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos );
385 if (dc->u.x.font.metrics.tmStruckOut)
387 long lineAscent, lineDescent;
388 if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
389 lineAscent = font->ascent / 3;
390 if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
391 lineDescent = -lineAscent;
392 XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent,
393 LineSolid, CapRound, JoinBevel );
394 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
395 dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
396 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );
402 /***********************************************************************
403 * GrayString (USER.185)
405 BOOL GrayString(HDC hdc, HBRUSH hbr, FARPROC gsprc, LPARAM lParam,
406 INT cch, INT x, INT y, INT cx, INT cy)
408 int s, current_color;
411 return CallGrayStringProc(gsprc, hdc, lParam,
412 cch ? cch : lstrlen((LPCSTR) lParam) );
414 current_color = GetTextColor(hdc);
415 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT) );
416 s = TextOut(hdc, x, y, (LPSTR) lParam,
417 cch ? cch : lstrlen((LPCSTR) lParam) );
418 SetTextColor(hdc, current_color);
424 /***********************************************************************
425 * ExtTextOut [GDI.351]
427 BOOL ExtTextOut(HDC hDC, short x, short y, WORD wOptions, LPRECT lprect,
428 LPSTR str, WORD count, LPINT lpDx)
430 printf("EMPTY STUB !!! ExtTextOut(); ! call TextOut() for now !\n");
431 TextOut(hDC, x, y, str, count);