bool RichEditHost::RenderTo(Graphics& graphics, const MiniRect& rcRender) { if (!m_pTextServices || !m_pEdit) { return false; } MiniRect rcRootRender = rcRender; MiniRect rcRoot; m_pEdit->GetClientRect(rcRoot); rcRootRender += rcRoot.TopLeft(); Bitmap* pBitmap = graphics.GetBitmap(); byte* pBytes = (byte*)pBitmap->LockBits(rcRootRender); for (int i = 0; i < rcRender.Height(); ++i) { MiniARGB* pSrc = (MiniARGB*)(pBytes + i * pBitmap->GetBytesWidth()); MiniARGB* pDst = (MiniARGB*)(m_dib.GetData() + (i + rcRender.top) * m_dib.GetBytesWidth()) + rcRender.left; for (int j = 0; j < rcRender.Width(); ++j) { uint32 c = gTable[pSrc->alpha]; pDst->blue = (uint32)(c * (uint32)pSrc->blue + (1 << 23)) >> 24; pDst->green = (uint32)(c * (uint32)pSrc->green + (1 << 23)) >> 24; pDst->red = (uint32)(c * (uint32)pSrc->red + (1 << 23)) >> 24; pDst->alpha = 0xFF; pDst++; pSrc++; } } RECTL rc = {0, 0, m_size.cx, m_size.cy}; HRESULT hr = m_pTextServices->TxDraw(DVASPECT_CONTENT, 0, 0, 0, m_dib, 0, &rc, 0, 0, 0, 0, TXTVIEW_ACTIVE); if (SUCCEEDED(hr)) { if (m_bFocus && m_bShowCaret && m_bEnableCaret && m_bCaretState && !GetReadOnly()) { if (!m_hCaret) { ::PatBlt((HDC)m_dib, m_rcCaret.left, m_rcCaret.top, m_rcCaret.Width(), m_rcCaret.Height(), DSTINVERT); } else { HDC hdcMem = CreateCompatibleDC((HDC)m_dib); HGDIOBJ hOld = ::SelectObject(hdcMem, m_hCaret); ::BitBlt((HDC)m_dib, m_rcCaret.left, m_rcCaret.top, m_rcCaret.Width(), m_rcCaret.Height(), hdcMem, 0, 0, SRCINVERT); ::SelectObject(hdcMem, hOld); ::DeleteDC(hdcMem); } } for (int i = 0; i < rcRender.Height(); ++i) { MiniARGB* pSrc = (MiniARGB*)(m_dib.GetData() + (i + rcRender.top) * m_dib.GetBytesWidth()) + rcRender.left; MiniARGB* pDst = (MiniARGB*)(pBytes + i * pBitmap->GetBytesWidth()); for (int j = 0; j < rcRender.Width(); ++j) { uint32 alpha = (uint32)pDst->alpha + 1; pDst->blue = ((uint32)pSrc->blue * alpha) >> 8; pDst->green = ((uint32)pSrc->green * alpha) >> 8; pDst->red = ((uint32)pSrc->red * alpha) >> 8; pDst++; pSrc++; } } } return true; }