You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.5 KiB
151 lines
4.5 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: text.c
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* This module contains the MessageBox API and related functions.
|
|
*
|
|
* History:
|
|
* 10-01-90 EricK Created.
|
|
* 11-20-90 DarrinM Merged in User text APIs.
|
|
* 02-07-91 DarrinM Removed TextOut, ExtTextOut, and GetTextExtentPoint stubs.
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
BOOL _TextOutW(
|
|
HDC hdc,
|
|
int x,
|
|
int y,
|
|
LPCWSTR lp,
|
|
UINT cc);
|
|
|
|
/***************************************************************************\
|
|
* xxxPSMTextOut
|
|
*
|
|
* Outputs the text and puts and _ below the character with an &
|
|
* before it. Note that this routine isn't used for menus since menus
|
|
* have their own special one so that it is specialized and faster...
|
|
*
|
|
* NOTE: A very similar routine (UserLpkPSMTextOut) exists on the client
|
|
* side in drawtext.c. Any non-kernel specific changes to this
|
|
* routine most likely need to be made in UserLpkPSMTextOut as well.
|
|
*
|
|
* History:
|
|
* 11-13-90 JimA Ported to NT.
|
|
* 30-Nov-1992 mikeke Client side version
|
|
* 8-Apr-1998 MCostea Added dwFlags
|
|
\***************************************************************************/
|
|
|
|
void xxxPSMTextOut(
|
|
HDC hdc,
|
|
int xLeft,
|
|
int yTop,
|
|
LPWSTR lpsz,
|
|
int cch,
|
|
DWORD dwFlags)
|
|
{
|
|
int cx;
|
|
LONG textsize, result;
|
|
/*
|
|
* In the kernel we have a limited amount of stack. So it should be a stack
|
|
* variable in user mode and static in kernel mode where it is thread safe
|
|
* since we are in the crit section.
|
|
*/
|
|
static WCHAR achWorkBuffer[255];
|
|
WCHAR *pchOut = achWorkBuffer;
|
|
TEXTMETRICW textMetric;
|
|
SIZE size;
|
|
RECT rc;
|
|
COLORREF color;
|
|
PTHREADINFO ptiCurrent = PtiCurrentShared();
|
|
|
|
if (CALL_LPK(ptiCurrent)) {
|
|
/*
|
|
* A user mode LPK is installed for layout and shaping.
|
|
* Perform callback and return.
|
|
*/
|
|
UNICODE_STRING ustrStr;
|
|
|
|
RtlInitUnicodeString(&ustrStr, lpsz);
|
|
xxxClientPSMTextOut(hdc, xLeft, yTop, &ustrStr, cch, dwFlags);
|
|
return;
|
|
}
|
|
|
|
if (cch > sizeof(achWorkBuffer)/sizeof(WCHAR)) {
|
|
pchOut = (WCHAR*)UserAllocPool((cch+1) * sizeof(WCHAR), TAG_RTL);
|
|
if (pchOut == NULL)
|
|
return;
|
|
}
|
|
|
|
result = GetPrefixCount(lpsz, cch, pchOut, cch);
|
|
|
|
if (!(dwFlags & DT_PREFIXONLY)) {
|
|
_TextOutW(hdc, xLeft, yTop, pchOut, cch - HIWORD(result));
|
|
}
|
|
|
|
/*
|
|
* Any true prefix characters to underline?
|
|
*/
|
|
if (LOWORD(result) == 0xFFFF || dwFlags & DT_HIDEPREFIX) {
|
|
if (pchOut != achWorkBuffer)
|
|
UserFreePool(pchOut);
|
|
return;
|
|
}
|
|
|
|
if (!_GetTextMetricsW(hdc, &textMetric)) {
|
|
textMetric.tmOverhang = 0;
|
|
textMetric.tmAscent = 0;
|
|
}
|
|
|
|
/*
|
|
* For proportional fonts, find starting point of underline.
|
|
*/
|
|
if (LOWORD(result) != 0) {
|
|
|
|
/*
|
|
* How far in does underline start (if not at 0th byte.).
|
|
*/
|
|
GreGetTextExtentW(hdc, (LPWSTR)pchOut, LOWORD(result), &size, GGTE_WIN3_EXTENT);
|
|
xLeft += size.cx;
|
|
|
|
/*
|
|
* Adjust starting point of underline if not at first char and there is
|
|
* an overhang. (Italics or bold fonts.)
|
|
*/
|
|
xLeft = xLeft - textMetric.tmOverhang;
|
|
}
|
|
|
|
/*
|
|
* Adjust for proportional font when setting the length of the underline and
|
|
* height of text.
|
|
*/
|
|
GreGetTextExtentW(hdc, (LPWSTR)(pchOut + LOWORD(result)), 1, &size, GGTE_WIN3_EXTENT);
|
|
textsize = size.cx;
|
|
|
|
/*
|
|
* Find the width of the underline character. Just subtract out the overhang
|
|
* divided by two so that we look better with italic fonts. This is not
|
|
* going to effect embolded fonts since their overhang is 1.
|
|
*/
|
|
cx = LOWORD(textsize) - textMetric.tmOverhang / 2;
|
|
|
|
/*
|
|
* Get height of text so that underline is at bottom.
|
|
*/
|
|
yTop += textMetric.tmAscent + 1;
|
|
|
|
/*
|
|
* Draw the underline using the foreground color.
|
|
*/
|
|
SetRect(&rc, xLeft, yTop, xLeft+cx, yTop+1);
|
|
color = GreSetBkColor(hdc, GreGetTextColor(hdc));
|
|
GreExtTextOutW(hdc, xLeft, yTop, ETO_OPAQUE, &rc, TEXT(""), 0, NULL);
|
|
GreSetBkColor(hdc, color);
|
|
|
|
if (pchOut != achWorkBuffer) {
|
|
UserFreePool(pchOut);
|
|
}
|
|
}
|
|
|