void sFont2D::PrintBasic(sInt flags,const sRect *r,sInt x,sInt y,const sChar *text,sInt len) { UINT opt; if(len==-1) len=sGetStringLen(text); opt = 0; if(r) { opt |= ETO_CLIPPED; } if((flags & sF2P_OPAQUE) && r) { SetBkColor(sGDIDC,prv->BackColor); opt |= ETO_OPAQUE; SetBkMode(sGDIDC,OPAQUE); } else { SetBkMode(sGDIDC,TRANSPARENT); } SetTextColor(sGDIDC,prv->TextColor); SelectObject(sGDIDC,prv->Font); ExtTextOutW(sGDIDC,x,y,opt,(CONST RECT *)r,text,len,0); }
static LRESULT HostWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC fnOldProc; fnOldProc = (WNDPROC)GetPropW(hwnd, WNDPROP_SCCTRLW); if (!fnOldProc) return DefWindowProcW(hwnd, uMsg, wParam, lParam); switch (uMsg) { case WM_NCDESTROY: // detach RemovePropW(hwnd, WNDPROP_SCCTRLW); CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam); SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc); return 0; case WM_ERASEBKGND: if (wParam) { RECT rc; if (GetClientRect(hwnd, &rc)) { SetBkColor((HDC)wParam, ml_color(WADLG_WNDBG)); ExtTextOutW((HDC)wParam, 0, 0, ETO_OPAQUE, &rc, L"", 0, 0); } } return 1; case WM_SETFOCUS: if (htmlControl) { htmlControl->setFocus(TRUE); return 0; } break; } return CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam); }
void VDUIHotKeyExControlW32::OnPaint() { PAINTSTRUCT ps; HDC hdc = BeginPaint(mhwnd, &ps); if (!hdc) return; RECT r; if (GetClientRect(mhwnd, &r)) { VDVERIFY(DrawEdge(hdc, &r, EDGE_SUNKEN, BF_ADJUST | BF_RECT)); VDVERIFY(FillRect(hdc, &r, (HBRUSH)(COLOR_WINDOW + 1))); int cx = GetSystemMetrics(SM_CXEDGE); int cy = GetSystemMetrics(SM_CYEDGE); r.left += cx; r.top += cy; r.right -= cx; r.bottom -= cy; if (r.right > r.left && r.bottom > r.top) { SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); SetTextAlign(hdc, TA_TOP | TA_LEFT); HGDIOBJ holdFont = SelectObject(hdc, mhfont); if (holdFont) { ExtTextOutW(hdc, r.left, r.top, ETO_CLIPPED, &r, mBuffer.c_str(), mBuffer.size(), NULL); SelectObject(hdc, holdFont); } } } EndPaint(mhwnd, &ps); }
void CodePreview::FlushTextBuf(std::vector<wchar_t>& buf, unsigned char format, int x, int y) { int numChars = (int)buf.size(); if(numChars < 1) return; HFONT font = s_normalFont; unsigned int fgColor = MetalBar::s_codePreviewFg; unsigned int bgColor = MetalBar::s_codePreviewBg; switch(format) { case FormatType_Plain: break; case FormatType_Comment: fgColor = MetalBar::s_commentColor; break; case FormatType_Highlight: bgColor = MetalBar::s_codePreviewFg; fgColor = MetalBar::s_codePreviewBg; break; case FormatType_Keyword: font = s_boldFont; break; } SetBkColor(m_paintDC, RGB_TO_COLORREF(bgColor)); SetTextColor(m_paintDC, RGB_TO_COLORREF(fgColor)); SelectObject(m_paintDC, font); RECT r = { 1, 1, m_wndWidth - 1, m_wndHeight - 1 }; ExtTextOutW(m_paintDC, x, y, ETO_CLIPPED, &r, &buf[0], numChars, 0); buf.resize(0); }
static void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr) { RECT rect; SetBkColor(hDC, clr); SetRect(&rect, x, y, x + cx, y + cy); ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); }
/* Draws the Format button with an arrow */ void AP_Win32Dialog_Styles::_onDrawButton(LPDRAWITEMSTRUCT lpDrawItemStruct, HWND hWnd) { UINT uiState = lpDrawItemStruct->itemState; HPEN hPen; HPEN pOldPen; HDC hdc = lpDrawItemStruct->hDC; int nWidth; int nHeight; int x, xEnd, xStart; int y; POINT p; const char* pText; HWND hParent; LONG lData; UT_Win32LocaleString str; const XAP_StringSet * pSS = m_pApp->getStringSet(); pText= pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyFormat); nWidth = lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left; nHeight = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top; // set the pen color if (uiState&ODS_DISABLED) hPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_GRAYTEXT)); else hPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNTEXT)); pOldPen = (HPEN) SelectObject(hdc, hPen); // draw the border of the button if(uiState&ODS_SELECTED) DrawFrameControl(hdc, &lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH|DFCS_PUSHED); else DrawFrameControl(hdc, &lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH); // Draw arrow y = nHeight/2; xStart = (nWidth/6)*5; for (int i=0; i<4; i++) { x = xStart + i; xEnd = xStart + 7 - i; ::MoveToEx(hdc, x, y, &p); ::LineTo(hdc, xEnd, y); y++; } str.fromUTF8(pText); ExtTextOutW(hdc, (nWidth/6)*1, ((nHeight/4)), 0, NULL, str.c_str(), str.length(), NULL); // Clean Up SelectObject(hdc, pOldPen); DeleteObject(hPen); }
/* * @implemented */ BOOL WINAPI LpkExtTextOut( HDC hdc, int x, int y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT uCount, const INT *lpDx, INT unknown) { LPWORD glyphs = NULL; INT cGlyphs; UNREFERENCED_PARAMETER(unknown); if (!(fuOptions & ETO_IGNORELANGUAGE)) fuOptions |= ETO_IGNORELANGUAGE; /* Check text direction */ if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING)) { if (!(fuOptions & ETO_RTLREADING)) fuOptions |= ETO_RTLREADING; } /* Check if the string requires complex script processing and not a "glyph indices" array */ if (ScriptIsComplex(lpString, uCount, SIC_COMPLEX) == S_OK && !(fuOptions & ETO_GLYPH_INDEX)) { BIDI_Reorder(hdc, lpString, uCount, GCP_REORDER, (fuOptions & ETO_RTLREADING) ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR, NULL, uCount, NULL, &glyphs, &cGlyphs); fuOptions |= ETO_GLYPH_INDEX; if (uCount > cGlyphs) cGlyphs = uCount; return ExtTextOutW(hdc, x, y, fuOptions, lprc, (LPWSTR)glyphs, cGlyphs, lpDx); } return ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, uCount, lpDx); }
// // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; int wmId, wmEvent; PAINTSTRUCT ps; TCHAR szHello[MAX_LOADSTRING]; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_HELP_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDOK: SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); SendMessage (hWnd, WM_CLOSE, 0, 0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_CREATE: s_sai.cbSize = sizeof(SHACTIVATEINFO); hwndCB = CreateRpCommandBar(hWnd); break; case WM_PAINT: RECT rt; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rt); LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); DrawText(hdc, szHello, _tcslen(szHello), &rt, DT_SINGLELINE | DT_VCENTER | DT_CENTER); // Call bi-modal function. ExtTextOut(hdc, 10, 10, 0, NULL, _T("Call to ExtTextOut"), 18, NULL); // Call Unicode-only function. ExtTextOutW(hdc, 10, 30, 0, NULL, L"Call to ExtTextOutW", 19, NULL); EndPaint(hWnd, &ps); break; case WM_DESTROY: CommandBar_Destroy(hwndCB); PostQuitMessage(0); break; case WM_SETTINGCHANGE: SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
static void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr) { RECT rect; SetBkColor(hDC, clr); rect.left = x; rect.top = y; rect.right = x + cx; rect.bottom = y + cy; ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); }
static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChars, ME_Style *s, int *width, int nSelFrom, int nSelTo, int ymin, int cy) { HDC hDC = c->hDC; HGDIOBJ hOldFont; COLORREF rgbOld, rgbBack; int yOffset = 0, yTwipsOffset = 0; hOldFont = ME_SelectStyleFont(c->editor, hDC, s); rgbBack = ME_GetBackColor(c->editor); if ((s->fmt.dwMask & CFM_COLOR) && (s->fmt.dwEffects & CFE_AUTOCOLOR)) rgbOld = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); else rgbOld = SetTextColor(hDC, s->fmt.crTextColor); if ((s->fmt.dwMask & s->fmt.dwEffects) & CFM_OFFSET) { yTwipsOffset = s->fmt.yOffset; } if ((s->fmt.dwMask & s->fmt.dwEffects) & (CFM_SUPERSCRIPT | CFM_SUBSCRIPT)) { if (s->fmt.dwEffects & CFE_SUPERSCRIPT) yTwipsOffset = s->fmt.yHeight/3; if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12; } if (yTwipsOffset) { int numerator = 1; int denominator = 1; if (c->editor->nZoomNumerator) { numerator = c->editor->nZoomNumerator; denominator = c->editor->nZoomDenominator; } yOffset = yTwipsOffset * GetDeviceCaps(hDC, LOGPIXELSY) * numerator / denominator / 1440; } ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL); if (width) { SIZE sz; GetTextExtentPoint32W(hDC, szText, nChars, &sz); *width = sz.cx; } if (nSelFrom < nChars && nSelTo >= 0 && nSelFrom<nSelTo) { SIZE sz; if (nSelFrom < 0) nSelFrom = 0; if (nSelTo > nChars) nSelTo = nChars; GetTextExtentPoint32W(hDC, szText, nSelFrom, &sz); x += sz.cx; GetTextExtentPoint32W(hDC, szText+nSelFrom, nSelTo-nSelFrom, &sz); /* Invert selection if not hidden by EM_HIDESELECTION */ if (c->editor->bHideSelection == FALSE) PatBlt(hDC, x, ymin, sz.cx, cy, DSTINVERT); } SetTextColor(hDC, rgbOld); ME_UnselectStyleFont(c->editor, hDC, s, hOldFont); }
void CExtentVisualWindow::OnPaint(HWND hwnd, HDC hdc) { HFONT hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); HFONT hfontOld = (HFONT)SelectObject(hdc, hfont); RECT rc; GetClientRect(hwnd, &rc); SetBkColor(hdc, _cr); // ExtTextOutW(hdc, 2, 2, ETO_OPAQUE, &rc, _sz, lstrlenW(_sz), NULL); ExtTextOutW(hdc, 2, 2, ETO_OPAQUE, &rc, _sz, 0, NULL); SelectObject(hdc, hfontOld); }
void TextRenderGdi::Draw(const WCHAR *s, size_t sLen, RectF& bb, bool isRtl) { #if 0 DrawTransparent(s, sLen, bb, isRtl); #else CrashIf(!hdcGfxLocked); // hasn't been Lock()ed int x = (int) bb.X; int y = (int) bb.Y; UINT opts = ETO_OPAQUE; if (isRtl) opts = opts | ETO_RTLREADING; ExtTextOutW(hdcGfxLocked, x, y, opts, NULL, s, (int)sLen, NULL); #endif }
/************************************************************************* * FileMenu_DrawItem [SHELL32.105] */ LRESULT WINAPI FileMenu_DrawItem( HWND hWnd, LPDRAWITEMSTRUCT lpdis) { LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData); COLORREF clrPrevText, clrPrevBkgnd; int xi,yi,xt,yt; HIMAGELIST hImageList; RECT TextRect; LPFMINFO menuinfo; TRACE("%p %p %s\n", hWnd, lpdis, debugstr_w(pMyItem->szItemText)); if (lpdis->itemState & ODS_SELECTED) { clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT)); clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT)); } else { clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT)); clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU)); } CopyRect(&TextRect, &(lpdis->rcItem)); /* add the menubitmap */ menuinfo = FM_GetMenuInfo(pMyItem->hMenu); if (menuinfo->nBorderWidth) TextRect.left += menuinfo->nBorderWidth; TextRect.left += FM_LEFTBORDER; xi = TextRect.left + FM_SPACE1; yi = TextRect.top + FM_Y_SPACE/2; TextRect.bottom -= FM_Y_SPACE/2; xt = xi + FM_ICON_SIZE + FM_SPACE2; yt = yi; ExtTextOutW (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL); Shell_GetImageList(0, &hImageList); ImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL); TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom); SetTextColor(lpdis->hDC, clrPrevText); SetBkColor(lpdis->hDC, clrPrevBkgnd); return TRUE; }
// based on http://theartofdev.wordpress.com/2013/10/24/transparent-text-rendering-with-gdi/, // TODO: look into using http://theartofdev.wordpress.com/2014/01/12/gdi-text-rendering-to-image/ // TODO: doesn't actually look good (i.e. similar to DrawText when using transparent SetBkMode()) // which kind of makes sense, because I'm using transparent mode to draw to in-memory bitmap as well // TODO: doesn't actually do alpha bf.SourceConstantAlpha > 4 looks the same, values 1-4 produce // different, but not expected, results // TODO: the bitmap should be cached so that we don't call CreateDIBSection every time // TODO: I would like to figure out a way to draw text without the need to Lock()/Unlock() // maybe draw to in-memory bitmap, convert to Graphics bitmap and blit that bitmap to // Graphics object void TextRenderGdi::DrawTransparent(const WCHAR *s, size_t sLen, RectF& bb, bool isRtl) { CrashIf(!hdcGfxLocked); // hasn't been Lock()ed //SetBkMode(hdcGfxLocked, 1); HDC memHdc = CreateCompatibleDC(hdcGfxLocked); SetBkMode(memHdc, TRANSPARENT); int x = (int) bb.X; int y = (int) bb.Y; int dx = (int) bb.Width; int dy = (int) bb.Height; BITMAPINFO bmi = { }; bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = dx; bmi.bmiHeader.biHeight = dy; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = dx * dy * 4; // doesn't seem necessary? unsigned char *bmpData = NULL; HBITMAP dib = CreateDIBSection(memHdc, &bmi, DIB_RGB_COLORS, (void **)&bmpData, NULL, 0); if (!dib) return; memset(bmpData, 0, bmi.bmiHeader.biSizeImage); SelectObject(memHdc, dib); //BitBlt(memHdc, 0, 0, dx, dy, hdcGfxLocked, x, y, SRCCOPY); SelectObject(memHdc, currFont); ::SetTextColor(memHdc, textColor.ToCOLORREF()); #if 0 TextOut(memHdc, 0, 0, s, sLen); #else UINT opts = 0; //ETO_OPAQUE; if (isRtl) opts = opts | ETO_RTLREADING; ExtTextOutW(memHdc, 0, 0, opts, NULL, s, (int)sLen, NULL); #endif BLENDFUNCTION bf = {}; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.AlphaFormat = 0; // 0 - ignore source alpha, AC_SRC_ALPHA (1) - use source alpha bf.SourceConstantAlpha = 0x3; //textColor.GetA(); AlphaBlend(hdcGfxLocked, x, y, dx, dy, memHdc, 0, 0, dx, dy, bf); DeleteObject(dib); DeleteDC(memHdc); }
static int notepad_print_header(HDC hdc, RECT *rc, BOOL dopage, BOOL header, int page, LPWSTR text) { SIZE szMetric; if (*text) { /* Write the header or footer */ GetTextExtentPoint32W(hdc, text, lstrlenW(text), &szMetric); if (dopage) ExtTextOutW(hdc, (rc->left + rc->right - szMetric.cx) / 2, header ? rc->top : rc->bottom - szMetric.cy, ETO_CLIPPED, rc, text, lstrlenW(text), NULL); return 1; } return 0; }
NTSTATUS WINAPI User32CallLPKFromKernel(PVOID Arguments, ULONG ArgumentLength) { BOOL bResult; PLPK_CALLBACK_ARGUMENTS Argument; Argument = (PLPK_CALLBACK_ARGUMENTS)Arguments; Argument->lpString = (LPWSTR)((ULONG_PTR)Argument->lpString + (ULONG_PTR)Argument); bResult = ExtTextOutW(Argument->hdc, Argument->x, Argument->y, Argument->flags, (Argument->bRect) ? &Argument->rect : NULL, Argument->lpString, Argument->count, NULL); return ZwCallbackReturn(&bResult, sizeof(BOOL), STATUS_SUCCESS); }
void Tooltip::onPaint(PAINTSTRUCT& ps) { int len = (int) wcslen(text); RECT rc, textrc = {0}; GetClientRect( hwnd, &rc ); Draw3DBorder( ps.hdc, &rc, GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_3DDKSHADOW), 1); SetBkMode( ps.hdc, TRANSPARENT ); SetTextColor(ps.hdc, GetSysColor(COLOR_INFOTEXT) ); HGDIOBJ old_font = SelectObject( ps.hdc, GetStockObject(DEFAULT_GUI_FONT)); SIZE size; GetTextExtentPoint32W( ps.hdc, text, len, &size ); rc.top += (rc.bottom - size.cy)/2; rc.left += (rc.right - size.cx)/2; ExtTextOutW( ps.hdc, rc.left, rc.top, 0, &textrc, text, len, NULL ); SelectObject( ps.hdc, old_font ); }
BOOL WINAPI ShadowExtTextOutW(HDC textdc, int x, int y, UINT fuoptions, CONST RECT *lprc, LPCWSTR lptext, UINT cb, CONST INT *lpdx) { char szText[MAXTEXTOUT] = NULLSTR; int iLenText = 0; BOOL bRet = FALSE; BOOL bUsed = FALSE; // write to text buffer if it isnt a glyph if ((fuoptions & ETO_GLYPH_INDEX) != ETO_GLYPH_INDEX) { iLenText = WideCharToMultiByte(CP_THREAD_ACP, WC_NO_BEST_FIT_CHARS, lptext, cb, szText, MAXTEXTOUT, "*", &bUsed); WriteToTextBuffer((LPCSTR)szText, (UINT)iLenText); } // pass on call to real function UnhookFunction((PHOOKREC)&_hrExtTextOutW); bRet = ExtTextOutW(textdc, x, y, fuoptions, lprc, lptext, cb, lpdx); HookFunction((PHOOKREC)&_hrExtTextOutW); return bRet; }
//=========================================================================== int DrawTextUTF8(HDC hDC, const char *s, int nCount, RECT *p, unsigned format) { WCHAR wstr[1000]; SIZE size; int x, y, n, r; n = MultiByteToWideChar(CP_UTF8, 0, s, nCount, wstr, array_count(wstr)); if (n) --n; if (usingNT) return DrawTextW(hDC, wstr, n, p, format); GetTextExtentPoint32W(hDC, wstr, n, &size); if (format & DT_CALCRECT) { p->right = p->left + size.cx; p->bottom = p->top + size.cy; return 1; } if (format & DT_RIGHT) x = imax(p->left, p->right - size.cx); else if (format & DT_CENTER) x = imax(p->left, (p->left + p->right - size.cx) / 2); else x = p->left; if (format & DT_BOTTOM) y = imax(p->top, p->bottom - size.cy); else if (format & DT_VCENTER) y = imax(p->top, (p->top + p->bottom - size.cy) / 2); else y = p->top; //SetTextAlign(hDC, TA_LEFT | TA_TOP); r = ExtTextOutW(hDC, x, y, ETO_CLIPPED, p, wstr, n, NULL); return r; }
/*********************************************************************** * FD31_WMDrawItem [internal] */ LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, int savedlg, LPDRAWITEMSTRUCT lpdis) { WCHAR *str; HICON hIcon; COLORREF oldText = 0, oldBk = 0; if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) { if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE; SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)str); if ((lpdis->itemState & ODS_SELECTED) && !savedlg) { oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } if (savedlg) SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) ); ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1, lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, &(lpdis->rcItem), str, lstrlenW(str), NULL); if (lpdis->itemState & ODS_SELECTED) DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) ); if ((lpdis->itemState & ODS_SELECTED) && !savedlg) { SetBkColor( lpdis->hDC, oldBk ); SetTextColor( lpdis->hDC, oldText ); } HeapFree(GetProcessHeap(), 0, str); return TRUE; } if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) { if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE; SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)str); if (lpdis->itemState & ODS_SELECTED) { oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth, lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, &(lpdis->rcItem), str, lstrlenW(str), NULL); if (lpdis->itemState & ODS_SELECTED) DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) ); if (lpdis->itemState & ODS_SELECTED) { SetBkColor( lpdis->hDC, oldBk ); SetTextColor( lpdis->hDC, oldText ); } DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder); HeapFree(GetProcessHeap(), 0, str); return TRUE; } if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) { char root[] = "a:"; if (!(str = HeapAlloc(GetProcessHeap(), 0, BUFFILEALLOC))) return FALSE; SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, (LPARAM)str); root[0] += str[2] - 'a'; switch(GetDriveTypeA(root)) { case DRIVE_REMOVABLE: hIcon = hFloppy; break; case DRIVE_CDROM: hIcon = hCDRom; break; case DRIVE_REMOTE: hIcon = hNet; break; case DRIVE_FIXED: default: hIcon = hHDisk; break; } if (lpdis->itemState & ODS_SELECTED) { oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth, lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, &(lpdis->rcItem), str, lstrlenW(str), NULL); if (lpdis->itemState & ODS_SELECTED) { SetBkColor( lpdis->hDC, oldBk ); SetTextColor( lpdis->hDC, oldText ); } DrawIcon(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon); HeapFree(GetProcessHeap(), 0, str); return TRUE; } return FALSE; }
/* WINE synced 22-May-2006 */ static LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCWSTR lpstr, INT count, INT cTabStops, const INT *lpTabPos, INT nTabOrg, BOOL fDisplayText ) { INT defWidth; SIZE extent; int i, j; int start = x; if (!lpTabPos) cTabStops=0; if (cTabStops == 1) { defWidth = *lpTabPos; cTabStops = 0; } else { TEXTMETRICA tm; GetTextMetricsA( hdc, &tm ); defWidth = 8 * tm.tmAveCharWidth; } while (count > 0) { RECT r; INT x0; x0 = x; r.left = x0; /* chop the string into substrings of 0 or more <tabs> * possibly followed by 1 or more normal characters */ for (i = 0; i < count; i++) if (lpstr[i] != '\t') break; for (j = i; j < count; j++) if (lpstr[j] == '\t') break; /* get the extent of the normal character part */ GetTextExtentPointW( hdc, lpstr + i, j - i , &extent ); /* and if there is a <tab>, calculate its position */ if( i) { /* get x coordinate for the drawing of this string */ for (; cTabStops > i; lpTabPos++, cTabStops--) { if( nTabOrg + abs( *lpTabPos) > x) { if( lpTabPos[ i - 1] >= 0) { /* a left aligned tab */ x = nTabOrg + lpTabPos[ i-1] + extent.cx; break; } else { /* if tab pos is negative then text is right-aligned * to tab stop meaning that the string extends to the * left, so we must subtract the width of the string */ if (nTabOrg - lpTabPos[ i - 1] - extent.cx > x) { x = nTabOrg - lpTabPos[ i - 1]; x0 = x - extent.cx; break; } } } } /* if we have run out of tab stops and we have a valid default tab * stop width then round x up to that width */ if ((cTabStops <= i) && (defWidth > 0)) { x0 = nTabOrg + ((x - nTabOrg) / defWidth + i) * defWidth; x = x0 + extent.cx; } else if ((cTabStops <= i) && (defWidth < 0)) { x = nTabOrg + ((x - nTabOrg + extent.cx) / -defWidth + i) * -defWidth; x0 = x - extent.cx; } } else x += extent.cx; if (fDisplayText) { r.top = y; r.right = x; r.bottom = y + extent.cy; ExtTextOutW( hdc, x0, y, GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0, &r, lpstr + i, j - i, NULL ); } count -= j; lpstr += j; } return MAKELONG(x - start, extent.cy); }
/* * @implemented * * Synced with wine 1.1.32 */ INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count, LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp ) { SIZE size; const WCHAR *strPtr; WCHAR *retstr, *p_retstr; size_t size_retstr; WCHAR line[MAX_BUFFER]; int len, lh, count=i_count; TEXTMETRICW tm; int lmargin = 0, rmargin = 0; int x = rect->left, y = rect->top; int width = rect->right - rect->left; int max_width = 0; int last_line; int tabwidth /* to keep gcc happy */ = 0; int prefix_offset; ellipsis_data ellip; int invert_y=0; TRACE("%s, %d, [%s] %08x\n", debugstr_wn (str, count), count, wine_dbgstr_rect(rect), flags); if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n", dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin); if (!str) return 0; strPtr = str; if (flags & DT_SINGLELINE) flags &= ~DT_WORDBREAK; GetTextMetricsW(hdc, &tm); if (flags & DT_EXTERNALLEADING) lh = tm.tmHeight + tm.tmExternalLeading; else lh = tm.tmHeight; if (str[0] && count == 0) return lh; if (dtp && dtp->cbSize != sizeof(DRAWTEXTPARAMS)) return 0; if (count == -1) { count = strlenW(str); if (count == 0) { if( flags & DT_CALCRECT) { rect->right = rect->left; if( flags & DT_SINGLELINE) rect->bottom = rect->top + lh; else rect->bottom = rect->top; } return lh; } } if (GetGraphicsMode(hdc) == GM_COMPATIBLE) { SIZE window_ext, viewport_ext; GetWindowExtEx(hdc, &window_ext); GetViewportExtEx(hdc, &viewport_ext); if ((window_ext.cy > 0) != (viewport_ext.cy > 0)) invert_y = 1; } if (dtp) { lmargin = dtp->iLeftMargin; rmargin = dtp->iRightMargin; if (!(flags & (DT_CENTER | DT_RIGHT))) x += lmargin; dtp->uiLengthDrawn = 0; /* This param RECEIVES number of chars processed */ } if (flags & DT_EXPANDTABS) { int tabstop = ((flags & DT_TABSTOP) && dtp) ? dtp->iTabLength : 8; tabwidth = tm.tmAveCharWidth * tabstop; } if (flags & DT_CALCRECT) flags |= DT_NOCLIP; if (flags & DT_MODIFYSTRING) { size_retstr = (count + 4) * sizeof (WCHAR); retstr = HeapAlloc(GetProcessHeap(), 0, size_retstr); if (!retstr) return 0; memcpy (retstr, str, size_retstr); } else { size_retstr = 0; retstr = NULL; } p_retstr = retstr; do { len = sizeof(line)/sizeof(line[0]); if (invert_y) last_line = !(flags & DT_NOCLIP) && y - ((flags & DT_EDITCONTROL) ? 2*lh-1 : lh) < rect->bottom; else last_line = !(flags & DT_NOCLIP) && y + ((flags & DT_EDITCONTROL) ? 2*lh-1 : lh) > rect->bottom; strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags, &size, last_line, &p_retstr, tabwidth, &prefix_offset, &ellip); if (flags & DT_CENTER) x = (rect->left + rect->right - size.cx) / 2; else if (flags & DT_RIGHT) x = rect->right - size.cx; if (flags & DT_SINGLELINE) { if (flags & DT_VCENTER) y = rect->top + (rect->bottom - rect->top) / 2 - size.cy / 2; else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } if (!(flags & DT_CALCRECT)) { const WCHAR *str = line; int xseg = x; while (len) { int len_seg; SIZE size; if ((flags & DT_EXPANDTABS)) { const WCHAR *p; p = str; while (p < str+len && *p != TAB) p++; len_seg = p - str; if (len_seg != len && !GetTextExtentPointW(hdc, str, len_seg, &size)) return 0; } else len_seg = len; if (!ExtTextOutW( hdc, xseg, y, ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) | ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0), rect, str, len_seg, NULL )) return 0; if (prefix_offset != -1 && prefix_offset < len_seg) { TEXT_DrawUnderscore (hdc, xseg, y + tm.tmAscent + 1, str, prefix_offset, (flags & DT_NOCLIP) ? NULL : rect); } len -= len_seg; str += len_seg; if (len) { assert ((flags & DT_EXPANDTABS) && *str == TAB); len--; str++; xseg += ((size.cx/tabwidth)+1)*tabwidth; if (prefix_offset != -1) { if (prefix_offset < len_seg) { /* We have just drawn an underscore; we ought to * figure out where the next one is. I am going * to leave it for now until I have a better model * for the line, which will make reprefixing easier. * This is where ellip would be used. */ prefix_offset = -1; } else prefix_offset -= len_seg; } } } } else if (size.cx > max_width) max_width = size.cx; if (invert_y) y -= lh; else y += lh; if (dtp) dtp->uiLengthDrawn += len; } while (strPtr && !last_line); if (flags & DT_CALCRECT) { rect->right = rect->left + max_width; rect->bottom = y; if (dtp) rect->right += lmargin + rmargin; } if (retstr) { memcpy (str, retstr, size_retstr); HeapFree (GetProcessHeap(), 0, retstr); } return y - rect->top; }
JNIEXPORT jlong JNICALL Java_sun_font_FileFontStrike__1getGlyphImageFromWindows (JNIEnv *env, jobject unused, jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) { GLYPHMETRICS glyphMetrics; LOGFONTW lf; BITMAPINFO bmi; TEXTMETRIC textMetric; RECT rect; int bytesWidth, dibBytesWidth, extra, imageSize, dibImageSize; unsigned char* dibImage = NULL, *rowPtr, *pixelPtr, *dibPixPtr, *dibRowPtr; unsigned char r,g,b; unsigned char* igTable; GlyphInfo* glyphInfo = NULL; int nameLen; LPWSTR name; HFONT oldFont, hFont; MAT2 mat2; unsigned short width; unsigned short height; short advanceX; short advanceY; int topLeftX; int topLeftY; int err; int bmWidth, bmHeight; int x, y; HBITMAP hBitmap = NULL, hOrigBM; int gamma, orient; HWND hWnd = NULL; HDC hDesktopDC = NULL; HDC hMemoryDC = NULL; hWnd = GetDesktopWindow(); hDesktopDC = GetWindowDC(hWnd); if (hDesktopDC == NULL) { return (jlong)0; } if (GetDeviceCaps(hDesktopDC, BITSPIXEL) < 15) { FREE_AND_RETURN; } hMemoryDC = CreateCompatibleDC(hDesktopDC); if (hMemoryDC == NULL || fontFamily == NULL) { FREE_AND_RETURN; } err = SetMapMode(hMemoryDC, MM_TEXT); if (err == 0) { FREE_AND_RETURN; } memset(&lf, 0, sizeof(LOGFONTW)); lf.lfHeight = -size; lf.lfWeight = (style & 1) ? FW_BOLD : FW_NORMAL; lf.lfItalic = (style & 2) ? 0xff : 0; lf.lfCharSet = DEFAULT_CHARSET; lf.lfQuality = CLEARTYPE_QUALITY; lf.lfOutPrecision = OUT_TT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfPitchAndFamily = DEFAULT_PITCH; nameLen = (*env)->GetStringLength(env, fontFamily); name = (LPWSTR)alloca((nameLen+1)*2); if (name == NULL) { FREE_AND_RETURN; } (*env)->GetStringRegion(env, fontFamily, 0, nameLen, name); name[nameLen] = '\0'; if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) { wcscpy(lf.lfFaceName, name); } else { FREE_AND_RETURN; } hFont = CreateFontIndirectW(&lf); if (hFont == NULL) { FREE_AND_RETURN; } oldFont = SelectObject(hMemoryDC, hFont); memset(&textMetric, 0, sizeof(TEXTMETRIC)); err = GetTextMetrics(hMemoryDC, &textMetric); if (err == 0) { FREE_AND_RETURN; } memset(&glyphMetrics, 0, sizeof(GLYPHMETRICS)); memset(&mat2, 0, sizeof(MAT2)); mat2.eM11.value = 1; mat2.eM22.value = 1; err = GetGlyphOutline(hMemoryDC, glyphCode, GGO_METRICS|GGO_GLYPH_INDEX, &glyphMetrics, 0, NULL, &mat2); if (err == GDI_ERROR) { /* Probably no such glyph - ie the font wasn't the one we expected. */ FREE_AND_RETURN; } width = (unsigned short)glyphMetrics.gmBlackBoxX; height = (unsigned short)glyphMetrics.gmBlackBoxY; /* Don't handle "invisible" glyphs in this code */ if (width <= 0 || height == 0) { FREE_AND_RETURN; } advanceX = glyphMetrics.gmCellIncX; advanceY = glyphMetrics.gmCellIncY; topLeftX = glyphMetrics.gmptGlyphOrigin.x; topLeftY = glyphMetrics.gmptGlyphOrigin.y; /* GetGlyphOutline pre-dates cleartype and I'm not sure that it will * account for all pixels touched by the rendering. Need to widen, * and also adjust by one the x position at which it is rendered. * The extra pixels of width are used as follows : * One extra pixel at the left and the right will be needed to absorb * the pixels that will be touched by filtering by GDI to compensate * for colour fringing. * However there seem to be some cases where GDI renders two extra * pixels to the right, so we add one additional pixel to the right, * and in the code that copies this to the image cache we test for * the (rare) cases when this is touched, and if its not reduce the * stated image width for the blitting loops. * For fractional metrics : * One extra pixel at each end to account for sub-pixel positioning used * when fractional metrics is on in LCD mode. * The pixel at the left is needed so the blitting loop can index into * that a byte at a time to more accurately position the glyph. * The pixel at the right is needed so that when such indexing happens, * the blitting still can use the same width. * Consequently the width that is specified for the glyph is one less * than that of the actual image. * Note that in the FM case as a consequence we need to adjust the * position at which GDI renders, and the declared width of the glyph * See the if (fm) {} cases in the code. * For the non-FM case, we not only save 3 bytes per row, but this * prevents apparent glyph overlapping which affects the rendering * performance of accelerated pipelines since it adds additional * read-back requirements. */ width+=3; if (fm) { width+=1; } /* DIB scanline must end on a DWORD boundary. We specify 3 bytes per pixel, * so must round up as needed to a multiple of 4 bytes. */ dibBytesWidth = bytesWidth = width*3; extra = dibBytesWidth % 4; if (extra != 0) { dibBytesWidth += (4-extra); } /* The glyph cache image must be a multiple of 3 bytes wide. */ extra = bytesWidth % 3; if (extra != 0) { bytesWidth += (3-extra); } bmWidth = width; bmHeight = height; /* Must use desktop DC to create a bitmap of that depth */ hBitmap = CreateCompatibleBitmap(hDesktopDC, bmWidth, bmHeight); if (hBitmap == NULL) { FREE_AND_RETURN; } hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap); /* Fill in black */ rect.left = 0; rect.top = 0; rect.right = bmWidth; rect.bottom = bmHeight; FillRect(hMemoryDC, (LPRECT)&rect, GetStockObject(BLACK_BRUSH)); /* Set text color to white, background to black. */ SetBkColor(hMemoryDC, RGB(0,0,0)); SetTextColor(hMemoryDC, RGB(255,255,255)); /* adjust rendering position */ x = -topLeftX+1; if (fm) { x += 1; } y = topLeftY - textMetric.tmAscent; err = ExtTextOutW(hMemoryDC, x, y, ETO_GLYPH_INDEX|ETO_OPAQUE, (LPRECT)&rect, (LPCWSTR)&glyphCode, 1, NULL); if (err == 0) { FREE_AND_RETURN; } /* Now get the image into a DIB. * MS docs for GetDIBits says the compatible bitmap must not be * selected into a DC, so restore the original first. */ SelectObject(hMemoryDC, hOrigBM); SelectObject(hMemoryDC, oldFont); DeleteObject(hFont); memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; dibImage = SAFE_SIZE_ARRAY_ALLOC(malloc, dibBytesWidth, height); if (dibImage == NULL) { FREE_AND_RETURN; } dibImageSize = dibBytesWidth*height; memset(dibImage, 0, dibImageSize); err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage, &bmi, DIB_RGB_COLORS); if (err == 0) { /* GetDIBits failed. */ FREE_AND_RETURN; } err = SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &orient, 0); if (err == 0) { FREE_AND_RETURN; } err = SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &gamma, 0); if (err == 0) { FREE_AND_RETURN; } igTable = getIGTable(gamma/10); if (igTable == NULL) { FREE_AND_RETURN; } /* Now copy glyph image into a GlyphInfo structure and return it. * NB the xadvance calculated here may be overwritten by the caller. * 1 is subtracted from the bitmap width to get the glyph width, since * that extra "1" was added as padding, so the sub-pixel positioning of * fractional metrics could index into it. */ glyphInfo = (GlyphInfo*)SAFE_SIZE_STRUCT_ALLOC(malloc, sizeof(GlyphInfo), bytesWidth, height); if (glyphInfo == NULL) { FREE_AND_RETURN; } imageSize = bytesWidth*height; glyphInfo->cellInfo = NULL; glyphInfo->rowBytes = bytesWidth; glyphInfo->width = width; if (fm) { glyphInfo->width -= 1; // must subtract 1 } glyphInfo->height = height; glyphInfo->advanceX = advanceX; glyphInfo->advanceY = advanceY; glyphInfo->topLeftX = (float)(topLeftX-1); if (fm) { glyphInfo->topLeftX -= 1; } glyphInfo->topLeftY = (float)-topLeftY; glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo); memset(glyphInfo->image, 0, imageSize); /* DIB 24bpp data is always stored in BGR order, but we usually * need this in RGB, so we can't just memcpy and need to swap B and R. * Also need to apply inverse gamma adjustment here. * We re-use the variable "extra" to see if the last pixel is touched * at all. If its not we can reduce the glyph image width. This comes * into play in some cases where GDI touches more pixels than accounted * for by increasing width by two pixels over the B&W image. Whilst * the bytes are in the cache, it doesn't affect rendering performance * of the hardware pipelines. */ extra = 0; if (fm) { extra = 1; // always need it. } dibRowPtr = dibImage; rowPtr = glyphInfo->image; for (y=0;y<height;y++) { pixelPtr = rowPtr; dibPixPtr = dibRowPtr; for (x=0;x<width;x++) { if (orient == FE_FONTSMOOTHINGORIENTATIONRGB) { b = *dibPixPtr++; g = *dibPixPtr++; r = *dibPixPtr++; } else { r = *dibPixPtr++; g = *dibPixPtr++; b = *dibPixPtr++; } *pixelPtr++ = igTable[r]; *pixelPtr++ = igTable[g]; *pixelPtr++ = igTable[b]; if (!fm && (x==(width-1)) && (r|g|b)) { extra = 1; } } dibRowPtr += dibBytesWidth; rowPtr += bytesWidth; } if (!extra) { glyphInfo->width -= 1; } free(dibImage); ReleaseDC(hWnd, hDesktopDC); DeleteObject(hMemoryDC); DeleteObject(hBitmap); return ptr_to_jlong(glyphInfo); }
//Hook TextOutW 的过程 DLLEXPORT BOOL WINAPI NHExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbCount, CONST INT *lpDx) { POINT pt; HWND hWDC; HWND hWPT; DWORD dwThreadIdWithPoint = 0; DWORD dwThreadIdCurr = 0; // restore RestoreWin32Api(&g_ExtTextOutWHook, HOOK_NEED_CHECK); /* { char cBuffer[0x100]; wsprintf(cBuffer, "-> NHExtTextOutW : %s\n", "start"); OutputDebugString(cBuffer); } */ //DbgFilePrintf("-> NHExtTextOutW : lpString(%s), cbCount(%d)\n", lpString, cbCount); pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y; hWDC = WindowFromDC(hdc); hWPT = WindowFromPoint(pt); // 01/17/2000 // Fix Bug3: get word error when IE window overlaps. // Fix Bug3 begin dwThreadIdWithPoint = GetWindowThreadProcessId(hWPT, NULL); dwThreadIdCurr = GetCurrentThreadId(); if(dwThreadIdWithPoint == dwThreadIdCurr) { // Fix Bug3 end if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpString, cbCount)) && (cbCount > 0)) { /* { //char cBuffer[0x100]; //wsprintf(cBuffer, ">>>----> NHExtTextOutW : (%s) %d\n", lpTemp, cbCount); //OutputDebugString(cBuffer); } */ g_nTextAlign = GetTextAlign(hdc); g_nExtra = GetTextCharacterExtra(hdc); GetCurrentPositionEx(hdc, &g_CurPos); GetTextMetrics(hdc, &g_tm); g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; bRecAllRect = FALSE; GetStringRectW(hdc, lpString, cbCount, X, Y, &g_rcTotalRect, lpDx); bRecAllRect = TRUE; //{DbgFilePrintf("--> NHExtTextOutW: lpTemp(%s)len(%d)\n", lpTemp, strlen(lpTemp));} //{DbgFilePrintf("--> NHExtTextOutW: X(%d)Y(%d), g_rcTotalRect(%d,%d,%d,%d)\n", X, Y, g_rcTotalRect.left, g_rcTotalRect.top, g_rcTotalRect.right, g_rcTotalRect.bottom);} if ((WindowFromDC != NULL)&&(WindowFromDC(hdc) == NULL)) { g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; // 01/19/2000 // Fix Bug5: get word position error sometimes // Fix Bug5 begin AddToTextOutBufferW(hdc, lpString, cbCount, X, Y, lpDx); // Fix Bug5 end } else { GetDCOrgEx(hdc, &g_dwDCOrg); // 01/19/2000 // Fix Bug5: get word position error sometimes // Fix Bug5 begin GetCurMousePosWordW(hdc, lpString, cbCount, X, Y, lpDx); // Fix Bug5 end } } } } // call ExtTextOutW ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); //调用封装好的HooK过程 HookWin32Api(&g_ExtTextOutWHook, HOOK_NEED_CHECK); return TRUE; }
void curses_drawwindow(WINDOW *win) { int i,j,w,drawx,drawy; unsigned tmp; RECT update = {win->x * fontwidth, -1, (win->x + win->width) * fontwidth, -1}; for (j=0; j<win->height; j++){ if (win->line[j].touched) { update.bottom = (win->y+j+1)*fontheight; if (update.top == -1) { update.top = update.bottom - fontheight; } win->line[j].touched=false; for (i=0,w=0; w<win->width; i++,w++){ drawx=((win->x+w)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){ const char* utf8str = win->line[j].chars+i; int len = ANY_LENGTH; tmp = UTF8_getch(&utf8str, &len); int FG = win->line[j].FG[w]; int BG = win->line[j].BG[w]; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if (tmp != UNKNOWN_UNICODE) { int color = RGB(windowsPalette[FG].rgbRed,windowsPalette[FG].rgbGreen,windowsPalette[FG].rgbBlue); SetTextColor(backbuffer,color); int cw = mk_wcwidth(tmp); len = ANY_LENGTH-len; if (cw > 1) { FillRectDIB(drawx+fontwidth*(cw-1), drawy, fontwidth, fontheight, BG); w += cw - 1; } if (len > 1) { i += len - 1; } if (tmp) ExtTextOutW (backbuffer, drawx, drawy, 0, NULL, (WCHAR*)&tmp, 1, NULL); } else { switch ((unsigned char)win->line[j].chars[i]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; } };//switch (tmp) }//(tmp < 0) };//for (i=0;i<_windows[w].width;i++) } };// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if (update.top != -1) { RedrawWindow(WindowHandle, &update, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } }
static BOOL notepad_print_page(HDC hdc, RECT *rc, BOOL dopage, int page, LPTEXTINFO tInfo) { int b, y; TEXTMETRICW tm; SIZE szMetrics; WCHAR *footer_text = NULL; footer_text = expand_header_vars(Globals.szFooter, page); if (footer_text == NULL) return FALSE; if (dopage) { if (StartPage(hdc) <= 0) { static const WCHAR failedW[] = { 'S','t','a','r','t','P','a','g','e',' ','f','a','i','l','e','d',0 }; static const WCHAR errorW[] = { 'P','r','i','n','t',' ','E','r','r','o','r',0 }; MessageBoxW(Globals.hMainWnd, failedW, errorW, MB_ICONEXCLAMATION); HeapFree(GetProcessHeap(), 0, footer_text); return FALSE; } } GetTextMetricsW(hdc, &tm); y = rc->top + notepad_print_header(hdc, rc, dopage, TRUE, page, Globals.szFileName) * tm.tmHeight; b = rc->bottom - 2 * notepad_print_header(hdc, rc, FALSE, FALSE, page, footer_text) * tm.tmHeight; do { INT m, n; if (!tInfo->len) { /* find the end of the line */ while (tInfo->mptr < tInfo->mend && *tInfo->mptr != '\n' && *tInfo->mptr != '\r') { if (*tInfo->mptr == '\t') { /* replace tabs with spaces */ for (m = 0; m < SPACES_IN_TAB; m++) { if (tInfo->len < PRINT_LEN_MAX) tInfo->lptr[tInfo->len++] = ' '; else if (Globals.bWrapLongLines) break; } } else if (tInfo->len < PRINT_LEN_MAX) tInfo->lptr[tInfo->len++] = *tInfo->mptr; if (tInfo->len >= PRINT_LEN_MAX && Globals.bWrapLongLines) break; tInfo->mptr++; } } /* Find out how much we should print if line wrapping is enabled */ if (Globals.bWrapLongLines) { GetTextExtentExPointW(hdc, tInfo->lptr, tInfo->len, rc->right - rc->left, &n, NULL, &szMetrics); if (n < tInfo->len && tInfo->lptr[n] != ' ') { m = n; /* Don't wrap words unless it's a single word over the entire line */ while (m && tInfo->lptr[m] != ' ') m--; if (m > 0) n = m + 1; } } else n = tInfo->len; if (dopage) ExtTextOutW(hdc, rc->left, y, ETO_CLIPPED, rc, tInfo->lptr, n, NULL); tInfo->len -= n; if (tInfo->len) { memcpy(tInfo->lptr, tInfo->lptr + n, tInfo->len * sizeof(WCHAR)); y += tm.tmHeight + tm.tmExternalLeading; } else { /* find the next line */ while (tInfo->mptr < tInfo->mend && y < b && (*tInfo->mptr == '\n' || *tInfo->mptr == '\r')) { if (*tInfo->mptr == '\n') y += tm.tmHeight + tm.tmExternalLeading; tInfo->mptr++; } } } while (tInfo->mptr < tInfo->mend && y < b); notepad_print_header(hdc, rc, dopage, FALSE, page, footer_text); if (dopage) { EndPage(hdc); } HeapFree(GetProcessHeap(), 0, footer_text); return TRUE; }
/* * Print one screeful to the GDI printer. */ static int gdi_screenful(struct ea *ea, unsigned short rows, unsigned short cols, const char **fail) { HDC dc = pstate.dlg.hDC; LPDEVMODE devmode; int row, col, baddr; int rc = 0; int status; int fa_addr = find_field_attribute_ea(0, ea); unsigned char fa = ea[fa_addr].fa; bool fa_high, high; bool fa_underline, underline; bool fa_reverse, reverse; unsigned long uc; bool is_dbcs; char c; int usable_rows; HFONT got_font = NULL, want_font; #if defined(GDI_DEBUG) /*[*/ const char *want_font_name; #endif /*]*/ enum { COLOR_NONE, COLOR_NORMAL, COLOR_REVERSE } got_color = COLOR_NONE, want_color; devmode = (LPDEVMODE)GlobalLock(pstate.dlg.hDevMode); /* Compute the usable rows, including the caption. */ usable_rows = pstate.usable_rows; if (pstate.caption) { usable_rows -= 2; } /* * Does this screen fit? * (Note that the first test, "pstate.out_row", is there so that if the * font is so big the image won't fit at all, we still print as much * of it as we can.) */ if (pstate.out_row && pstate.out_row + ROWS > usable_rows) { if (EndPage(dc) <= 0) { *fail = "EndPage failed"; rc = -1; goto done; } pstate.out_row = 0; pstate.screens = 0; } /* If there is a caption, put it on the last line. */ if (pstate.out_row == 0 && pstate.caption != NULL) { SelectObject(dc, pstate.caption_font); status = ExtTextOut(dc, pstate.hmargin_pixels - pchar.poffX, pstate.vmargin_pixels + ((pstate.usable_rows - 1) * pstate.space_size.cy) - pchar.poffY, 0, NULL, pstate.caption, (UINT)strlen(pstate.caption), NULL); if (status <= 0) { *fail = "ExtTextOut failed"; rc = -1; goto done; } } /* Draw a line separating the screens. */ if (pstate.out_row) { HPEN pen; pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0)); SelectObject(dc, pen); status = MoveToEx(dc, pstate.hmargin_pixels - pchar.poffX, pstate.vmargin_pixels + (pstate.out_row * pstate.space_size.cy) + (pstate.space_size.cy / 2) - pchar.poffY, NULL); if (status == 0) { *fail = "MoveToEx failed"; rc = -1; goto done; } status = LineTo(dc, pstate.hmargin_pixels - pchar.poffX + pstate.usable_xpixels, pstate.vmargin_pixels + (pstate.out_row * pstate.space_size.cy) + (pstate.space_size.cy / 2) - pchar.poffY); if (status == 0) { *fail = "LineTo failed"; rc = -1; goto done; } DeleteObject(pen); } /* Now dump out a screen's worth. */ if (ea[fa_addr].gr & GR_INTENSIFY) { fa_high = true; } else { fa_high = FA_IS_HIGH(fa); } fa_reverse = ((ea[fa_addr].gr & GR_REVERSE) != 0); fa_underline = ((ea[fa_addr].gr & GR_UNDERLINE) != 0); for (baddr = 0, row = 0; row < ROWS; row++) { if (pstate.out_row + row >= usable_rows) { break; } for (col = 0; col < COLS; col++, baddr++) { if (ea[baddr].fa) { fa = ea[baddr].fa; if (ea[baddr].gr & GR_INTENSIFY) { fa_high = true; } else { fa_high = FA_IS_HIGH(fa); } fa_reverse = ((ea[fa_addr].gr & GR_REVERSE) != 0); fa_underline = ((ea[fa_addr].gr & GR_UNDERLINE) != 0); /* Just skip it. */ continue; } if (col >= pstate.usable_cols) { continue; } is_dbcs = FALSE; if (FA_IS_ZERO(fa)) { if (ctlr_dbcs_state_ea(baddr, ea) == DBCS_LEFT) { uc = 0x3000; } else { uc = ' '; } } else { /* Convert EBCDIC to Unicode. */ switch (ctlr_dbcs_state(baddr)) { case DBCS_NONE: case DBCS_SB: uc = ebcdic_to_unicode(ea[baddr].cc, ea[baddr].cs, EUO_NONE); if (uc == 0) { uc = ' '; } break; case DBCS_LEFT: is_dbcs = TRUE; uc = ebcdic_to_unicode((ea[baddr].cc << 8) | ea[baddr + 1].cc, CS_BASE, EUO_NONE); if (uc == 0) { uc = 0x3000; } break; case DBCS_RIGHT: /* skip altogether, we took care of it above */ continue; default: uc = ' '; break; } } /* Figure out the attributes of the current buffer position. */ high = ((ea[baddr].gr & GR_INTENSIFY) != 0); if (!high) { high = fa_high; } reverse = ((ea[fa_addr].gr & GR_REVERSE) != 0); if (!reverse) { reverse = fa_reverse; } underline = ((ea[fa_addr].gr & GR_UNDERLINE) != 0); if (!underline) { underline = fa_underline; } /* Set the bg/fg color and font. */ if (reverse) { want_color = COLOR_REVERSE; } else { want_color = COLOR_NORMAL; } if (want_color != got_color) { switch (want_color) { case COLOR_REVERSE: SetTextColor(dc, 0xffffff); SetBkColor(dc, 0); SetBkMode(dc, OPAQUE); break; case COLOR_NORMAL: SetTextColor(dc, 0); SetBkColor(dc, 0xffffff); SetBkMode(dc, TRANSPARENT); break; default: break; } got_color = want_color; } if (!high && !underline) { want_font = pstate.font; #if defined(GDI_DEBUG) /*[*/ want_font_name = "Roman"; #endif /*]*/ } else if (high && !underline) { want_font = pstate.bold_font; #if defined(GDI_DEBUG) /*[*/ want_font_name = "Bold"; #endif /*]*/ } else if (!high && underline) { want_font = pstate.underscore_font; #if defined(GDI_DEBUG) /*[*/ want_font_name = "Underscore"; #endif /*]*/ } else { want_font = pstate.bold_underscore_font; #if defined(GDI_DEBUG) /*[*/ want_font_name = "Underscore"; #endif /*]*/ } if (want_font != got_font) { SelectObject(dc, want_font); got_font = want_font; #if defined(GDI_DEBUG) /*[*/ vtrace("[gdi] selecting %s\n", want_font_name); #endif /*]*/ } /* * Handle spaces and DBCS spaces (U+3000). * If not reverse or underline, just skip over them. * Otherwise, print a space or two spaces, using the * right font and modes. */ if (uc == ' ' || uc == 0x3000) { if (reverse || underline) { status = ExtTextOut(dc, pstate.hmargin_pixels + (col * pstate.space_size.cx) - pchar.poffX, pstate.vmargin_pixels + ((pstate.out_row + row + 1) * pstate.space_size.cy) - pchar.poffY, 0, NULL, " ", (uc == 0x3000)? 2: 1, pstate.dx); if (status <= 0) { *fail = "ExtTextOut failed"; rc = -1; goto done; } } continue; } /* * Emit one character at a time. This should be optimized to print * strings of characters with the same attributes. */ if (is_dbcs) { wchar_t w; INT wdx; w = (wchar_t)uc; wdx = pstate.space_size.cx; status = ExtTextOutW(dc, pstate.hmargin_pixels + (col * pstate.space_size.cx) - pchar.poffX, pstate.vmargin_pixels + ((pstate.out_row + row + 1) * pstate.space_size.cy) - pchar.poffY, 0, NULL, &w, 1, &wdx); if (status <= 0) { *fail = "ExtTextOutW failed"; rc = -1; goto done; } continue; } c = (char)uc; status = ExtTextOut(dc, pstate.hmargin_pixels + (col * pstate.space_size.cx) - pchar.poffX, pstate.vmargin_pixels + ((pstate.out_row + row + 1) * pstate.space_size.cy) - pchar.poffY, 0, NULL, &c, 1, pstate.dx); #if defined(GDI_DEBUG) /*[*/ if (c != ' ') { vtrace("[gdi] row %d col %d x=%ld y=%ld '%c'\n", row, col, pstate.hmargin_pixels + (col * pstate.space_size.cx) - pchar.poffX, pstate.vmargin_pixels + ((pstate.out_row + row + 1) * pstate.space_size.cy) - pchar.poffY, c); } #endif /*]*/ if (status <= 0) { *fail = "ExtTextOut failed"; rc = -1; goto done; } } } /* Tally the current screen and see if we need to go to a new page. */ pstate.out_row += (row + 1); /* current screen plus a gap */ pstate.screens++; if (pstate.out_row >= usable_rows || pstate.screens >= uparm.spp) { if (EndPage(dc) <= 0) { *fail = "EndPage failed"; rc = -1; goto done; } pstate.out_row = 0; pstate.screens = 0; } done: GlobalUnlock(devmode); return rc; }
cairo_int_status_t _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst, const cairo_pattern_t *source, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, cairo_bool_t glyph_indexing) { #if CAIRO_HAS_WIN32_FONT WORD glyph_buf_stack[STACK_GLYPH_SIZE]; WORD *glyph_buf = glyph_buf_stack; int dxy_buf_stack[2 * STACK_GLYPH_SIZE]; int *dxy_buf = dxy_buf_stack; BOOL win_result = 0; int i, j; cairo_solid_pattern_t *solid_pattern; COLORREF color; cairo_matrix_t device_to_logical; int start_x, start_y; double user_x, user_y; int logical_x, logical_y; unsigned int glyph_index_option; /* We can only handle win32 fonts */ assert (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32); /* We can only handle opaque solid color sources and destinations */ assert (_cairo_pattern_is_opaque_solid(source)); assert (dst->format == CAIRO_FORMAT_RGB24); solid_pattern = (cairo_solid_pattern_t *)source; color = RGB(((int)solid_pattern->color.red_short) >> 8, ((int)solid_pattern->color.green_short) >> 8, ((int)solid_pattern->color.blue_short) >> 8); cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical); SaveDC(dst->dc); cairo_win32_scaled_font_select_font(scaled_font, dst->dc); SetTextColor(dst->dc, color); SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT); SetBkMode(dst->dc, TRANSPARENT); if (num_glyphs > STACK_GLYPH_SIZE) { glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD)); dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2); } /* It is vital that dx values for dxy_buf are calculated from the delta of * _logical_ x coordinates (not user x coordinates) or else the sum of all * previous dx values may start to diverge from the current glyph's x * coordinate due to accumulated rounding error. As a result strings could * be painted shorter or longer than expected. */ user_x = glyphs[0].x; user_y = glyphs[0].y; cairo_matrix_transform_point(&device_to_logical, &user_x, &user_y); logical_x = _cairo_lround (user_x); logical_y = _cairo_lround (user_y); start_x = logical_x; start_y = logical_y; for (i = 0, j = 0; i < num_glyphs; ++i, j = 2 * i) { glyph_buf[i] = (WORD) glyphs[i].index; if (i == num_glyphs - 1) { dxy_buf[j] = 0; dxy_buf[j+1] = 0; } else { double next_user_x = glyphs[i+1].x; double next_user_y = glyphs[i+1].y; int next_logical_x, next_logical_y; cairo_matrix_transform_point(&device_to_logical, &next_user_x, &next_user_y); next_logical_x = _cairo_lround (next_user_x); next_logical_y = _cairo_lround (next_user_y); dxy_buf[j] = _cairo_lround (next_logical_x - logical_x); dxy_buf[j+1] = _cairo_lround (next_logical_y - logical_y); logical_x = next_logical_x; logical_y = next_logical_y; } } if (glyph_indexing) glyph_index_option = ETO_GLYPH_INDEX; else glyph_index_option = 0; win_result = ExtTextOutW(dst->dc, start_x, start_y, glyph_index_option | ETO_PDY, NULL, glyph_buf, num_glyphs, dxy_buf); if (!win_result) { _cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)"); } RestoreDC(dst->dc, -1); if (glyph_buf != glyph_buf_stack) { free(glyph_buf); free(dxy_buf); } return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED; #else return CAIRO_INT_STATUS_UNSUPPORTED; #endif }
void curses_drawwindow(WINDOW *win) { int i,j,drawx,drawy; unsigned tmp; RECT update = {win->x * fontwidth, -1, (win->x + win->width) * fontwidth, -1}; for (j=0; j<win->height; j++){ if (win->line[j].touched) { update.bottom = (win->y+j+1)*fontheight; if (update.top == -1) { update.top = update.bottom - fontheight; } win->line[j].touched=false; for (i=0; i<win->width; i++){ const cursecell &cell = win->line[j].chars[i]; if( cell.ch.empty() ) { continue; // second cell of a multi-cell character } drawx=((win->x+i)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if( drawx + fontwidth > WindowWidth || drawy + fontheight > WindowHeight ) { // Outside of the display area, would not render anyway continue; } const char* utf8str = cell.ch.c_str(); int len = cell.ch.length(); tmp = UTF8_getch(&utf8str, &len); int FG = cell.FG; int BG = cell.BG; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if (tmp != UNKNOWN_UNICODE) { int color = RGB(windowsPalette[FG].rgbRed,windowsPalette[FG].rgbGreen,windowsPalette[FG].rgbBlue); SetTextColor(backbuffer,color); int cw = mk_wcwidth(tmp); if (cw > 1) { FillRectDIB(drawx+fontwidth*(cw-1), drawy, fontwidth, fontheight, BG); i += cw - 1; } if (tmp) { const std::wstring utf16 = widen(cell.ch); ExtTextOutW( backbuffer, drawx, drawy, 0, NULL, utf16.c_str(), utf16.length(), NULL ); } } else { switch ((unsigned char)win->line[j].chars[i].ch[0]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; };//switch (tmp) }//(tmp < 0) };//for (i=0;i<_windows[w].width;i++) } };// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if (update.top != -1) { RedrawWindow(WindowHandle, &update, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } }
void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr) { SetBkColor(hDC, clr); ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); }