📄 text.c
字号:
PDC pdc;
int n, nLines = 0, width = 0;
BOOL bOutput = TRUE;
int x, y;
RECT rcDraw, rcOutput;
int nTabWidth;
int line_height;
pdc = dc_HDC2PDC(hdc);
if (nCount == -1)
nCount = strlen (pText);
line_height = pdc->pLogFont->size + pdc->alExtra + pdc->blExtra;
if (nFormat & DT_TABSTOP)
nTabWidth = HIWORD (nFormat) *
(*pdc->pLogFont->sbc_devfont->font_ops->get_ave_width)
(pdc->pLogFont, pdc->pLogFont->sbc_devfont);
else
nTabWidth = pdc->tabstop *
(*pdc->pLogFont->sbc_devfont->font_ops->get_ave_width)
(pdc->pLogFont, pdc->pLogFont->sbc_devfont);
// Transfer logical to device to screen here.
rcDraw = *pRect;
coor_LP2SP(pdc, &rcDraw.left, &rcDraw.top);
coor_LP2SP(pdc, &rcDraw.right, &rcDraw.bottom);
NormalizeRect (&rcDraw);
if (dc_IsGeneralHDC(hdc)) {
pthread_mutex_lock (&pdc->pGCRInfo->lock);
if (!dc_GenerateECRgn (pdc, FALSE))
bOutput = FALSE;
}
pthread_mutex_lock (&__mg_gdilock);
// set graphics context.
GAL_SetGC (pdc->gc);
// Draw text here.
if (nFormat & DT_CALCRECT)
bOutput = FALSE;
y = rcDraw.top;
if (nFormat & DT_SINGLELINE) {
if (nFormat & DT_BOTTOM)
y = rcDraw.bottom - pdc->pLogFont->size;
else if (nFormat & DT_VCENTER)
y = rcDraw.top + ((RECTH (rcDraw) - pdc->pLogFont->size) >> 1);
}
memset (&rcOutput, 0, sizeof(RECT));
while (nCount != 0) {
int nOutput;
int line_x, maxwidth;
if (nLines == 0) {
line_x = indent;
maxwidth = rcDraw.right - rcDraw.left - indent;
if (maxwidth <= 0) {
/* new line */
y += line_height;
nLines ++;
continue;
}
}
else {
line_x = 0;
maxwidth = rcDraw.right - rcDraw.left;
}
gdi_start_new_line (pdc->pLogFont);
width = txtGetOneLine (pdc, pText, nCount, nTabWidth, maxwidth, nFormat, &n);
nOutput = n;
if ( (pText[n-1] == '\n' || pText[n-1] == '\r') && (nFormat & DT_SINGLELINE) ) {
int tmpx = 0, tmpy = 0;
nOutput = n - 1;
width += gdi_width_one_char (pdc->pLogFont, pdc->pLogFont->sbc_devfont,
pText + n - 1, 1, &tmpx, &tmpy);
}
if (nFormat & DT_RIGHT)
x = rcDraw.right - width;
else if (nFormat & DT_CENTER)
x = rcDraw.left + ((RECTW (rcDraw) - width) >> 1);
else
x = rcDraw.left;
x += line_x;
if (firstline) {
firstline->nr_chars = nOutput;
firstline->startx = x;
firstline->starty = y;
firstline->width = width;
firstline->height = line_height;
break;
}
rcOutput.left = x;
rcOutput.top = y;
rcOutput.right = rcOutput.left + width;
rcOutput.bottom = rcOutput.top + line_height;
NormalizeRect(&rcOutput);
if (nFormat & DT_CALCRECT) {
if (nLines == 0)
*pRect = rcOutput;
else
GetBoundRect (pRect, pRect, &rcOutput);
}
// draw one line
if (bOutput && width > 0) {
if (!dc_IsMemHDC(hdc)) ShowCursorForGDI(FALSE, &rcOutput);
if (nFormat & DT_NOCLIP)
txtDrawOneLine (pdc, pText, nOutput, x, y,
&rcOutput, nFormat, nTabWidth);
else {
RECT rcClip;
IntersectRect (&rcClip, &rcOutput, &rcDraw);
txtDrawOneLine (pdc, pText, nOutput, x, y,
&rcClip, nFormat, nTabWidth);
}
if (!dc_IsMemHDC(hdc)) ShowCursorForGDI (TRUE, &rcOutput);
}
pText += n;
// new line
y += line_height;
nLines ++;
// left characters
nCount = nCount - n;
}
pthread_mutex_unlock (&__mg_gdilock);
if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock);
if (firstline) {
coor_SP2LP (pdc, &firstline->startx, &firstline->starty);
return 0;
}
if (nFormat & DT_CALCRECT) {
coor_SP2LP (pdc, &pRect->left, &pRect->top);
coor_SP2LP (pdc, &pRect->right, &pRect->bottom);
}
if (!(nFormat & DT_CALCRECT)) {
// update text out position
x += width;
y -= line_height;
coor_SP2LP (pdc, &x, &y);
pdc->CurTextPos.x = x;
pdc->CurTextPos.y = y;
}
return line_height * nLines;
}
/************************* Text parse support ********************************/
int GUIAPI GetTextMCharInfo (PLOGFONT log_font, const char* mstr, int len,
int* pos_chars)
{
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
int count = 0;
int left_bytes = len;
int len_cur_char;
while (left_bytes > 0) {
if (pos_chars)
pos_chars [count] = len - left_bytes;
if (mbc_devfont) {
len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (mstr, left_bytes);
if (len_cur_char != 0) {
count ++;
left_bytes -= len_cur_char;
mstr += len_cur_char;
continue;
}
}
len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (mstr, left_bytes);
if (len_cur_char != 0) {
count ++;
left_bytes -= len_cur_char;
mstr += len_cur_char;
}
}
return count;
}
int GUIAPI GetTextWordInfo (PLOGFONT log_font, const char* mstr, int len,
int* pos_words, WORDINFO* info_words)
{
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
WORDINFO word_info;
int count = 0;
int left_bytes = len;
int mbc_sub_len, sbc_sub_len, word_len;
while (left_bytes > 0) {
sbc_sub_len = left_bytes;
if (mbc_devfont) {
int mbc_pos;
mbc_pos = (*mbc_devfont->charset_ops->pos_first_char) (mstr, left_bytes);
if (mbc_pos == 0) {
mbc_sub_len = (*mbc_devfont->charset_ops->len_first_substr) (mstr, left_bytes);
while (mbc_sub_len) {
(*mbc_devfont->charset_ops->get_next_word) (mstr, mbc_sub_len, &word_info);
if (pos_words)
pos_words [count] = len - left_bytes;
if (info_words)
memcpy (info_words + count, &word_info, sizeof (WORDINFO));
count ++;
word_len = word_info.len + word_info.nr_delimiters;
mbc_sub_len -= word_len;
left_bytes -= word_len;
mstr += word_len;
}
continue;
}
else if (mbc_pos > 0)
sbc_sub_len = mbc_pos;
}
while (sbc_sub_len) {
(*sbc_devfont->charset_ops->get_next_word) (mstr, sbc_sub_len, &word_info);
if (pos_words)
pos_words [count] = len - left_bytes;
if (info_words)
memcpy (info_words + count, &word_info, sizeof (WORDINFO));
count ++;
word_len = word_info.len + word_info.nr_delimiters;
sbc_sub_len -= word_len;
left_bytes -= word_len;
mstr += word_len;
}
}
return count;
}
int GUIAPI GetFirstMCharLen (PLOGFONT log_font, const char* mstr, int len)
{
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
int len_cur_char = 0;
if (mbc_devfont) {
len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (mstr, len);
if (len_cur_char != 0)
return len_cur_char;
}
len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (mstr, len);
if (len_cur_char != 0)
return len_cur_char;
return len_cur_char;
}
int GUIAPI GetLastMCharLen (PLOGFONT log_font, const char* mstr, int len)
{
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
int left_bytes = len;
int len_cur_char;
int lastlen = 0;
while (left_bytes > 0) {
if (mbc_devfont) {
len_cur_char = (*mbc_devfont->charset_ops->len_first_char) (mstr, left_bytes);
if (len_cur_char != 0) {
left_bytes -= len_cur_char;
mstr += len_cur_char;
lastlen = len_cur_char;
continue;
}
}
len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (mstr, left_bytes);
if (len_cur_char != 0) {
left_bytes -= len_cur_char;
mstr += len_cur_char;
lastlen = len_cur_char;
}
}
return lastlen;
}
int GUIAPI GetFirstWord (PLOGFONT log_font, const char* mstr, int len,
WORDINFO* word_info)
{
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
if (mbc_devfont) {
int mbc_pos;
mbc_pos = (*mbc_devfont->charset_ops->pos_first_char) (mstr, len);
if (mbc_pos == 0) {
len = (*mbc_devfont->charset_ops->len_first_substr) (mstr, len);
(*mbc_devfont->charset_ops->get_next_word) (mstr, len, word_info);
return word_info->len + word_info->nr_delimiters;
}
else if (mbc_pos > 0)
len = mbc_pos;
}
(*sbc_devfont->charset_ops->get_next_word) (mstr, len, word_info);
return word_info->len + word_info->nr_delimiters;
}
int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len, int max_extent,
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
{
PDC pdc = dc_HDC2PDC (hdc);
LOGFONT* log_font = pdc->pLogFont;
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
int len_cur_char, width_cur_char;
int left_bytes = len;
int char_count = 0;
int x = 0, y = 0;
gdi_start_new_line (log_font);
size->cy = log_font->size + pdc->alExtra + pdc->blExtra;
size->cx = 0;
while (left_bytes > 0) {
if (pos_chars)
pos_chars [char_count] = len - left_bytes;
if (dx_chars)
dx_chars [char_count] = size->cx;
if (mbc_devfont &&
(len_cur_char = (*mbc_devfont->charset_ops->len_first_char)
(text, left_bytes))) {
width_cur_char = gdi_width_one_char (log_font, mbc_devfont,
text, len_cur_char, &x, &y);
}
else {
if ((len_cur_char = (*sbc_devfont->charset_ops->len_first_char)
(text, left_bytes)))
width_cur_char = gdi_width_one_char (log_font, sbc_devfont,
text, len_cur_char, &x, &y);
else
break;
}
width_cur_char += pdc->cExtra;
if (max_extent > 0 && (size->cx + width_cur_char) > max_extent) {
goto ret;
}
char_count ++;
size->cx += width_cur_char;
left_bytes -= len_cur_char;
text += len_cur_char;
}
ret:
if (fit_chars) *fit_chars = char_count;
return len - left_bytes;
}
int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text, int len, int max_extent,
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
{
PDC pdc = dc_HDC2PDC (hdc);
LOGFONT* log_font = pdc->pLogFont;
DEVFONT* sbc_devfont = log_font->sbc_devfont;
DEVFONT* mbc_devfont = log_font->mbc_devfont;
int left_bytes = len;
int len_cur_char;
int tab_width, line_height;
int last_line_width = 0;
int char_count = 0;
int x = 0, y = 0;
gdi_start_new_line (log_font);
size->cx = 0;
size->cy = 0;
tab_width = (*sbc_devfont->font_ops->get_ave_width) (log_font, sbc_devfont)
* pdc->tabstop;
line_height = log_font->size + pdc->alExtra + pdc->blExtra;
while (left_bytes > 0) {
if (pos_chars)
pos_chars [char_count] = len - left_bytes;
if (dx_chars)
dx_chars [char_count] = last_line_width;
if (mbc_devfont &&
(len_cur_char = (*mbc_devfont->charset_ops->len_first_char)
(text, left_bytes))) {
last_line_width += gdi_width_one_char (log_font, mbc_devfont,
text, len_cur_char, &x, &y);
last_line_width += pdc->cExtra;
}
else {
len_cur_char = (*sbc_devfont->charset_ops->len_first_char) (text, left_bytes);
if (len_cur_char == 0)
break;
switch (*text) {
case '\n':
size->cy += line_height;
case '\r':
if (last_line_width > size->cx)
size->cx = last_line_width;
last_line_width = 0;
gdi_start_new_line (log_font);
break;
case '\t':
last_line_width += tab_width;
gdi_start_new_line (log_font);
break;
default:
last_line_width += gdi_width_one_char (log_font, sbc_devfont,
text, len_cur_char, &x, &y);
last_line_width += pdc->cExtra;
}
}
if (max_extent > 0 && last_line_width > max_extent) {
goto ret;
}
if (last_line_width > size->cx)
size->cx = last_line_width;
char_count ++;
left_bytes -= len_cur_char;
text += len_cur_char;
}
ret:
if (fit_chars) *fit_chars = char_count;
return len - left_bytes;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -