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))
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_end;
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, &size);
219 GetTextExtentPoint(hdc, line, prefix_offset + 1, &size);
220 prefix_end = size.cx - 1;
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 HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
239 HPEN oldPen = SelectObject( hdc, hpen );
240 MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
241 LineTo(hdc, x + prefix_end, y + tm.tmAscent + 1 );
242 SelectObject( hdc, oldPen );
243 DeleteObject( hpen );
249 if (!(flags & DT_NOCLIP))
251 if (y > rect->bottom - lh)
257 if (flags & DT_CALCRECT) rect->bottom = y;
262 /***********************************************************************
265 BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count )
267 int dir, ascent, descent, i;
271 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
274 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
275 if (!dc) return FALSE;
276 MF_TextOut(dc, x, y, str, count);
280 if (!DC_SetupGCForText( dc )) return TRUE;
281 font = dc->u.x.font.fstruct;
283 if (dc->w.textAlign & TA_UPDATECP)
289 printf( "TextOut: %d,%d '%s', %d\n", x, y, str, count );
291 x = XLPTODP( dc, x );
292 y = YLPTODP( dc, y );
294 XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
295 info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
297 /* Compute starting position */
299 switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
302 if (dc->w.textAlign & TA_UPDATECP)
303 dc->w.CursPosX = XDPTOLP( dc, x + info.width );
307 if (dc->w.textAlign & TA_UPDATECP) dc->w.CursPosX = XDPTOLP( dc, x );
313 switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
327 if (!dc->w.charExtra && !dc->w.breakExtra)
329 if (dc->w.backgroundMode == TRANSPARENT)
330 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
331 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
333 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
334 dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
340 for (i = 0; i < count; i++, p++)
342 XCharStruct * charStr;
343 unsigned char ch = *p;
346 if ((ch < font->min_char_or_byte2)||(ch > font->max_char_or_byte2))
347 ch = font->default_char;
348 if (!font->per_char) charStr = &font->min_bounds;
349 else charStr = font->per_char + ch - font->min_char_or_byte2;
351 extraWidth = dc->w.charExtra;
352 if (ch == dc->u.x.font.metrics.tmBreakChar)
353 extraWidth += dc->w.breakExtra;
355 if (dc->w.backgroundMode == TRANSPARENT)
356 XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
357 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
360 XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
361 dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
362 XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
363 XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
364 dc->w.DCOrgX + xchar + charStr->width,
365 dc->w.DCOrgY + y - font->ascent,
366 extraWidth, font->ascent + font->descent );
367 XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
369 xchar += charStr->width + extraWidth;
373 /* Draw underline and strike-out if needed */
375 if (dc->u.x.font.metrics.tmUnderlined)
377 long linePos, lineWidth;
378 if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
379 linePos = font->descent-1;
380 if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
382 else if (lineWidth == 1) lineWidth = 0;
383 XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth,
384 LineSolid, CapRound, JoinBevel );
385 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
386 dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
387 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos );
389 if (dc->u.x.font.metrics.tmStruckOut)
391 long lineAscent, lineDescent;
392 if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
393 lineAscent = font->ascent / 3;
394 if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
395 lineDescent = -lineAscent;
396 XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent,
397 LineSolid, CapRound, JoinBevel );
398 XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
399 dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
400 dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );
406 /***********************************************************************
407 * GrayString (USER.185)
409 BOOL GrayString(HDC hdc, HBRUSH hbr, FARPROC gsprc, LPARAM lParam,
410 INT cch, INT x, INT y, INT cx, INT cy)
412 int s, current_color;
415 return CallGrayStringProc(gsprc, hdc, lParam,
416 cch ? cch : lstrlen((LPCSTR) lParam) );
418 current_color = GetTextColor(hdc);
419 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT) );
420 s = TextOut(hdc, x, y, (LPSTR) lParam,
421 cch ? cch : lstrlen((LPCSTR) lParam) );
422 SetTextColor(hdc, current_color);
428 /***********************************************************************
429 * TabbedTextOut [USER.196]
431 LONG TabbedTextOut(HDC hDC, short x, short y, LPSTR lpStr, short nCount,
432 short nTabCount, LPINT lpTabPos, short nTabOrg)
435 printf("EMPTY STUB !!! TabbedTextOut(); ! call TextOut() for now !\n");
436 height = HIWORD(GetTextExtent(hDC, lpStr, nCount));
437 width = LOWORD(GetTextExtent(hDC, lpStr, nCount));
438 TextOut(hDC, x, y, lpStr, nCount);
439 return MAKELONG(width, height);
443 /***********************************************************************
444 * ExtTextOut [GDI.351]
446 BOOL ExtTextOut(HDC hDC, short x, short y, WORD wOptions, LPRECT lprect,
447 LPSTR str, WORD count, LPINT lpDx)
449 printf("EMPTY STUB !!! ExtTextOut(); ! call TextOut() for now !\n");
450 TextOut(hDC, x, y, str, count);