?? text-lite.c
字號:
/*** $Id: text-lite.c,v 1.14 2003/09/04 03:09:52 weiym Exp $**** text-lite.c: The Text Support of GDI for MiniGUI-Lite.**** Copyright (C) 2000 ~ 2002 Wei Yongming.** Copyright (C) 2003 Feynman Software.**** Current maintainer: Wei Yongming.**** Create date: 2000/4/19*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*** TODO:*/ #include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "cliprect.h"#include "gal.h"#include "internals.h"#include "ctrlclass.h"#include "dc.h"#include "drawtext.h"#include "cursor.h"extern BOOL dc_GenerateECRgn (PDC pdc, BOOL fForce);int GUIAPI GetFontHeight (HDC hdc){ PDC pdc = dc_HDC2PDC(hdc); return pdc->pLogFont->size;}int GUIAPI GetMaxFontWidth (HDC hdc){ PDC pdc = dc_HDC2PDC(hdc); DEVFONT* sbc_devfont = pdc->pLogFont->sbc_devfont; DEVFONT* mbc_devfont = pdc->pLogFont->mbc_devfont; int sbc_max_width = (*sbc_devfont->font_ops->get_max_width) (pdc->pLogFont, sbc_devfont); int mbc_max_width = 0; if (mbc_devfont) mbc_max_width = (*mbc_devfont->font_ops->get_max_width) (pdc->pLogFont, mbc_devfont); return (sbc_max_width > mbc_max_width) ? sbc_max_width : mbc_max_width;}void GUIAPI GetTextExtent (HDC hdc, const char* spText, int len, SIZE* pSize){ PDC pdc; pdc = dc_HDC2PDC(hdc); if (len < 0) len = strlen (spText); gdi_get_TextOut_extent (pdc, pdc->pLogFont, spText, len, pSize);}void GUIAPI GetTabbedTextExtent (HDC hdc, const char* spText, int len, SIZE* pSize){ PDC pdc; pdc = dc_HDC2PDC(hdc); if (len < 0) len = strlen (spText); gdi_get_TabbedTextOut_extent (pdc, pdc->pLogFont, pdc->tabstop, spText, len, pSize, NULL);}void GUIAPI GetLastTextOutPos (HDC hdc, POINT* pt){ PDC pdc; pdc = dc_HDC2PDC(hdc); *pt = pdc->CurTextPos;}int GUIAPI TextOutLen (HDC hdc, int x, int y, const char* spText, int len){ PCLIPRECT pClipRect; PDC pdc; RECT rcOutput; SIZE size; if (len == 0) return 0; if (len < 0) len = strlen (spText); pdc = dc_HDC2PDC(hdc); gdi_get_TextOut_extent (pdc, pdc->pLogFont, spText, len, &size); { // update text out position int width = size.cx; extent_x_SP2LP (pdc, &width); pdc->CurTextPos.x = x + width; pdc->CurTextPos.y = y; } if (dc_IsGeneralHDC(hdc)) { if (!dc_GenerateECRgn (pdc, FALSE)) { return size.cx; } } // Transfer logical to device to screen here. coor_LP2SP(pdc, &x, &y); rcOutput.left = x; rcOutput.top = y; rcOutput.right = x + size.cx + 1; rcOutput.bottom = y + size.cy + 1; NormalizeRect(&rcOutput); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC(pdc->gc); // set text out mode. pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); gdi_strnwrite (pdc, x, y, spText, len); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); return size.cx;}int GUIAPI TabbedTextOutLen (HDC hdc, int x, int y, const char* spText, int len) { PCLIPRECT pClipRect; PDC pdc; SIZE size; RECT rcOutput; if (len == 0) return 0; if (len < 0) len = strlen (spText); pdc = dc_HDC2PDC(hdc); coor_LP2SP (pdc, &pdc->CurTextPos.x, &pdc->CurTextPos.y); gdi_get_TabbedTextOut_extent (pdc, pdc->pLogFont, pdc->tabstop, spText, len, &size, &pdc->CurTextPos); coor_SP2LP (pdc, &pdc->CurTextPos.x, &pdc->CurTextPos.y); if (dc_IsGeneralHDC(hdc)) { if (!dc_GenerateECRgn (pdc, FALSE)) { return size.cx; } } // Transfer logical to device to screen here. coor_LP2SP(pdc, &x, &y); rcOutput.left = x; rcOutput.top = y; rcOutput.right = x + size.cx + 1; rcOutput.bottom = y + size.cy + 1; NormalizeRect(&rcOutput); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC(pdc->gc); pClipRect = pdc->ecrgn.head; while(pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); gdi_tabbedtextout (pdc, x, y, spText, len); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); return size.cx;}char* strnchr (const char* s, size_t n, int c){ size_t i; for (i=0; i<n; i++) { if ( *s == c) return (char *)s; s ++; } return NULL;}int substrlen (const char* text, int len, char delimiter, int* nr_delim){ char* substr; *nr_delim = 0; if ( (substr = strnchr (text, len, delimiter)) == NULL) return len; len = substr - text; while (*substr == delimiter) { (*nr_delim) ++; substr ++; } return len;}int GUIAPI TabbedTextOutEx (HDC hdc, int x, int y, const char* spText, int nCount, int nTabs, int *pTabPos, int nTabOrig){ PDC pdc; int line_len, sub_len; int nr_tab = 0, tab_pos, def_tab; int x_orig = x, max_x = x; int line_height; int nr_delim_newline, nr_delim_tab; if (nCount == 0) return 0; if (nCount < 0) nCount = strlen (spText); pdc = dc_HDC2PDC(hdc); line_height = pdc->pLogFont->size + pdc->alExtra + pdc->blExtra; y += pdc->alExtra; if (nTabs == 0 || pTabPos == NULL) { int ave_width = (*pdc->pLogFont->sbc_devfont->font_ops->get_ave_width) (pdc->pLogFont, pdc->pLogFont->sbc_devfont); def_tab = ave_width * pdc->tabstop; } else def_tab = pTabPos [nTabs - 1]; while (nCount) { line_len = substrlen (spText, nCount, '\n', &nr_delim_newline); nCount -= line_len + nr_delim_newline; nr_tab = 0; x = x_orig; tab_pos = nTabOrig; while (line_len) { int i, width; sub_len = substrlen (spText, line_len, '\t', &nr_delim_tab); width = TextOutLen (hdc, x, y, spText, sub_len); x += width; if (x >= tab_pos) { while (x >= tab_pos) tab_pos += (nr_tab >= nTabs) ? def_tab : pTabPos [nr_tab++]; for (i = 0; i < nr_delim_tab - 1; i ++) tab_pos += (nr_tab >= nTabs) ? def_tab : pTabPos [nr_tab++]; } else { for (i = 0; i < nr_delim_tab; i ++) tab_pos += (nr_tab >= nTabs) ? def_tab : pTabPos [nr_tab++]; } x = tab_pos; line_len -= sub_len + nr_delim_tab; spText += sub_len + nr_delim_tab; } if (max_x < x) max_x = x; spText += nr_delim_newline; y += line_height * nr_delim_newline; } return max_x - x_orig;}static void txtDrawOneLine (PDC pdc, const char* pText, int nLen, int x, int y, const RECT* prcOutput, UINT nFormat, int nTabWidth){ RECT rcInter; PCLIPRECT pClipRect; pClipRect = pdc->ecrgn.head; while(pClipRect) { if (IntersectRect (&rcInter, prcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, rcInter.left, rcInter.top, rcInter.right - 1, rcInter.bottom - 1); if (nFormat & DT_EXPANDTABS) { const char* sub = pText; const char* left; int nSubLen = nLen; int nOutputLen; while ((left = strnchr (sub, nSubLen, '\t'))) { nOutputLen = left - sub; x += gdi_strnwrite (pdc, x, y, sub, nOutputLen); nSubLen -= (nOutputLen + 1); sub = left + 1; x += nTabWidth; } if (nSubLen != 0) gdi_strnwrite (pdc, x, y, sub, nSubLen); } else gdi_strnwrite (pdc, x, y, pText, nLen); } pClipRect = pClipRect->next; }}static int txtGetWidthOfNextWord (PDC pdc, const char* pText, int nCount, int* nChars){ int width; DEVFONT* sbc_devfont = pdc->pLogFont->sbc_devfont; DEVFONT* mbc_devfont = pdc->pLogFont->mbc_devfont; WORDINFO word_info; *nChars = 0; if (nCount == 0) return 0; if (mbc_devfont) { int mbc_pos, sub_len; mbc_pos = (*mbc_devfont->charset_ops->pos_first_char) (pText, nCount); if (mbc_pos == 0) { sub_len = (*mbc_devfont->charset_ops->len_first_substr) (pText, nCount); (*mbc_devfont->charset_ops->get_next_word) (pText, sub_len, &word_info); width = (*mbc_devfont->font_ops->get_str_width) (pdc->pLogFont, mbc_devfont, pText, word_info.len, pdc->cExtra); *nChars = word_info.len; return width; } else if (mbc_pos > 0) nCount = mbc_pos; } (*sbc_devfont->charset_ops->get_next_word) (pText, nCount, &word_info); width = (*sbc_devfont->font_ops->get_str_width) (pdc->pLogFont, sbc_devfont, pText, word_info.len, pdc->cExtra); *nChars = word_info.len;#if 0 fprintf (stderr, "text: %s, width: %d, word len: %d\n", pText, width, word_info.len);#endif return width;}// This function return the normal characters' number (refrence)// and tab's number per line (return value).static int txtGetOneLine (PDC pdc, const char* pText, int nCount, int nTabWidth, int maxwidth, UINT uFormat, int* nChar){ int tabs = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -