Example #1
0
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;
}