int CXTPSyntaxEditDrawTextProcessor::DrawRowPart(CDC* pDC, int nRow, LPCTSTR pcszText, int nchCount)
{
	if (m_nDrawingRow != nRow)
	{
		if (nRow >= 0) // the new row started
			ResetRowInfo(nRow);

		m_nDrawingRow = nRow;
		m_nNextRowPosX = 0;
	}

	if (nRow == -1)
		return 0;


	//--------------------------------------------------------
	int nTextLen = 0;

	if (nchCount < 0)
	{
		nchCount = (int) _tcsclen(pcszText);
		nTextLen = (int) _tcslen(pcszText);
	}
	else
	{
#ifdef XTP_FIXED
// "nchCount" meen byte length.
// so, need not translate form TextLength to ByteLength.
		nTextLen = nchCount;
#else
		nTextLen = (int) _tcsnbcnt(pcszText, nchCount);
#endif
	}
//  ASSERT(nchCount <= (int) _tcsclen(pcszText));

	//--------------------------------------------------------
	int nY = m_rcTextRect.top + nRow * m_nRowHeight;
	int nX = m_rcTextRect.left - m_nScrollXOffset + m_nNextRowPosX;

	CRect rcText = m_rcTextRect;
	rcText.left = max(rcText.left, nX); // ENSURE THE TEXT IS CLIPPED APPROPRIATELY
	pDC->ExtTextOut(nX, nY, ETO_CLIPPED, &rcText, pcszText, nTextLen, NULL);

	//--------------------------------------------------------
	if (m_arBuf_aDx.GetSize() < nTextLen)
		m_arBuf_aDx.SetSize(nTextLen + 100);

	int nMaxExtent = m_rcTextRect.Width() + m_nScrollXOffset - m_nNextRowPosX + 30; // 30 is a gap to be sure
	nMaxExtent = max(nMaxExtent, 30);

	int nFit = 0;
	LPINT alpDx = (int*)m_arBuf_aDx.GetData();
	CSize szText(0, 0);

	BOOL bResExt = GetTextExtentExPoint(pDC->m_hAttribDC, pcszText, nTextLen,
										0,      // nMaxExtent,
										NULL,   // &nFit,
										alpDx,  // array of partial string widths
										&szText // string dimensions
									);
	nFit = nTextLen;

	VERIFY(bResExt);

	CXTPRowInfo* pRI = GetRowInfo(nRow);
	if (pRI)
	{
		if (nFit >= 0 && nFit <= nTextLen)
		{
			int i;

			LPCTSTR p = pcszText;
			LPCTSTR p_prev = pcszText;
			for (i = 0; i < nFit; i++)
			{
				pRI->arCharsEnds.AddData(m_nNextRowPosX + alpDx[i]);

				p_prev = p;
				p = _tcsinc(p);
				int nCharLen = int(p - p_prev);
#ifdef XTP_FIXED
				if (nCharLen > 1)
					pRI->arCharsEnds.AddData(m_nNextRowPosX + alpDx[i]);
				// ASSERT( nCharLen > 2 );
#endif
				i += nCharLen - 1; // skip second byte for MBCS chars.
			}
		}
		else
		{
			ASSERT(FALSE);
		}

		pRI->nMaxWidth += szText.cx;
	}

	m_nNextRowPosX += szText.cx;

	return m_nNextRowPosX;
}
int CXTPSyntaxEditDrawTextProcessor::PrintRowPart(CDC* pDC, int nRow, int nPosY, UINT nFlags,
												  LPCTSTR pcszText, int nchCount, int *pnPrintedTextLen)
{
	if (pnPrintedTextLen)
		*pnPrintedTextLen = 0;

	if (m_nPrintingRow != nRow)
	{
		m_nPrintingRow = nRow;
		m_ptNextPrintPos = CPoint(0, 0);
	}

	if (nRow == -1)
		return 0;

	//--------------------------------------------------------
	int nTextLen = 0;

	if (nchCount < 0)
	{
		nchCount = (int)_tcsclen(pcszText);
		nTextLen = (int)_tcslen(pcszText);
	}
	else
	{
		nTextLen = (int)_tcsnbcnt(pcszText, nchCount);
	}
	ASSERT(nchCount <= (int)_tcsclen(pcszText));

	//--------------------------------------------------------
	if (m_arBuf_aDx.GetSize() < nTextLen)
		m_arBuf_aDx.SetSize(nTextLen + 100);

	LPINT alpDx = (int*)m_arBuf_aDx.GetData();

	//--------------------------------------------------------
	CRect rcText = m_rcTextRect;
	int nTextLen_rest = nTextLen;
	LPCTSTR pTxt = NULL;

	for (pTxt = pcszText; nTextLen_rest;)
	{
		int nY = m_rcTextRect.top + nPosY + m_ptNextPrintPos.y;
		int nX = m_rcTextRect.left + m_ptNextPrintPos.x;

		if (nY + GetRowHeight() > m_rcTextRect.bottom)
			break;

		//--------------------------------------------------------
		int nMaxExtent = max(0, rcText.right - nX - 20);
		int nFit = 0;

		CSize szText(0, 0);

		BOOL bResExt = GetTextExtentExPoint(
						m_bUseOutputDC ? pDC->m_hDC : pDC->m_hAttribDC,  // HDC hdc, // handle to DC
						pTxt,               // LPCTSTR lpString,         // character string
						nTextLen_rest,      // int nCount,               // number of characters
						nMaxExtent,         // maximum extent for string
						&nFit,              // LPINT lpnFit,    // maximum number of characters
						alpDx,     // array of partial string widths
						&szText //LPSIZE lpSize    // string dimensions
					);
		VERIFY(bResExt);

		//nFit = min(nFit, nTextLen_rest);

		LPCTSTR pTextToDtaw = pTxt;
		BOOL bAllTextDrawn = (nFit == nTextLen_rest);

		if (nFit > 0 && nFit <= nTextLen_rest)
		{
			CString strSeps = _T(" .,!?)-+=;\\"); //_T(" .,!?)-+=*&^%$#@~`:;\\|/");
			int nFit_wb = 0;
			int nTextLen_wb = nTextLen_rest;
			LPCTSTR pTxt_wb = pTxt;

			LPCTSTR p_prev = NULL;
			int i = 0;
			for (i = 0; i < nFit; i++)
			{
				p_prev = pTxt;
				pTxt = _tcsinc(pTxt);
				int nCharLen = int(pTxt - p_prev);
				i += nCharLen - 1; // skip second byte for MBCS chars.

				nTextLen_rest--;

				if ((nFlags & DT_WORDBREAK) && strSeps.Find(*p_prev, 0) >= 0)
				{
					nFit_wb = i+1;
					nTextLen_wb = nTextLen_rest;
					pTxt_wb = pTxt;
				}
			}

			if (!bAllTextDrawn && (nFlags & DT_WORDBREAK))
			{
				if (nFit_wb >= 0)
				{
					nFit = nFit_wb;
					nTextLen_rest = nTextLen_wb;
					pTxt = pTxt_wb;
				}
			}

			if (nFit)
			{
				m_ptNextPrintPos.x += alpDx[nFit - 1] + 1;
			}
		}

		// Draw text (if need)
		if (nFit && (nFlags & DT_CALCRECT) == 0)
		{
			rcText.left = max(rcText.left, nX); // ENSURE THE TEXT IS CLIPPED APPROPRIATELY
			pDC->ExtTextOut(nX, nY, ETO_CLIPPED, &rcText, pTextToDtaw, nFit, NULL);
		}

		CXTPRowInfo* pRI = GetRowInfo(nRow);
		if (pRI)
			pRI->nMaxWidth = m_ptNextPrintPos.x;

		// Move point to the next line (if need)
		if (!bAllTextDrawn && (nFlags & DT_SINGLELINE) == 0)
		{
			int nIconX = m_rcTextRect.left + m_ptNextPrintPos.x + 3;
			int nIconY = m_rcTextRect.top + nPosY + m_ptNextPrintPos.y;

			int nDelta = GetRowHeight() - GetRowHeight()/4;

			CPen pen1(PS_SOLID, 1, RGB(0,0,0));
			CPen pen2(PS_SOLID, 2, RGB(0,0,0));

			CPen* pPen_old = pDC->SelectObject(&pen1);

			pDC->MoveTo(nIconX, nIconY + nDelta/2);
			pDC->LineTo(nIconX, nIconY + nDelta);
			pDC->LineTo(nIconX + nDelta/2 - 1, nIconY + nDelta);

			pDC->SelectObject(&pen2);
			pDC->MoveTo(nIconX + 1, nIconY + nDelta - 1);
			pDC->LineTo(nIconX + nDelta/2, nIconY + nDelta/2);

			pDC->SelectObject(pPen_old);

			int nSublineOffsetX = m_tmText.tmAveCharWidth * 3;
			m_ptNextPrintPos.y += GetRowHeight();
			m_ptNextPrintPos.x = nSublineOffsetX;

			if (pRI)
				pRI->nMaxWidth = m_ptNextPrintPos.x;
		}
		else
		{
			break;
		}
	}

	if (pnPrintedTextLen)
	{
		int nLen0 = int(pTxt - pcszText);
		*pnPrintedTextLen = (int)_tcsnccnt(pcszText, nLen0);
	}

	return m_ptNextPrintPos.y + GetRowHeight();
}
Пример #3
0
void CDxDatePickerMonth::DrawDaysOfWeek(CDCHandle dc)
{
    if (m_rcDaysOfWeek.IsRectEmpty())
        return;

    // fill background
    dc.FillSolidRect(m_rcDaysOfWeek, m_clrDaysOfWeekBack);

    // draw days of week text
    dc.SetBkColor(m_clrDaysOfWeekBack);
    dc.SetTextColor(m_clrDaysOfWeekText);

    HFONT hFontOld = (HFONT)dc.SelectFont(CDxFontManager::GetSingleton().GetFont(DUIF_DEFAULTFONT));

    int nMaxX = 0;
    SIZE szText;

    dc.GetTextExtent(_T("XX"), 2, &szText);

    int nTwoLetterWidth = szText.cx;
    int nWholeLetterWidth = 0;

    for (int i = 0; i < XTP_WEEK_DAYS; i++)
    {
        CString strText(m_pControl->GetDayOfWeekName(i));

        dc.GetTextExtent(strText, strText.GetLength(), &szText);
        nWholeLetterWidth = max(nWholeLetterWidth, szText.cx);
    }

    for (int nDayDelta = 0; nDayDelta < XTP_WEEK_DAYS; nDayDelta++)
    {
        // calc item rect
        CDxDatePickerDay* pDay = GetDay(nDayDelta);
        CRect rcItem(pDay->GetRect());
        rcItem.top = m_rcDaysOfWeek.top;
        rcItem.bottom = m_rcDaysOfWeek.bottom - 2;
        nMaxX = rcItem.right;

        // get item text
        CString strText(m_pControl->GetDayOfWeekName(pDay->GetDate().GetDayOfWeek()));

        // Check if we can draw whole text
        if (nWholeLetterWidth + 4 <= rcItem.Width())
        {
            dc.DrawText(strText, strText.GetLength(), &rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
        }
        else if (nTwoLetterWidth + 4 <= rcItem.Width()) // Draw 2 letters
        {
            int nChrLen = (int)_tcsnbcnt(strText, 2);
            dc.DrawText(strText, nChrLen, &rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
        }
        else // Draw only first letter
        {
            int nChrLen = (int)_tcsnbcnt(strText, 1);
            dc.DrawText(strText, nChrLen, &rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
        }
    }

    // draw bottom line on days of the week
    CRect rcBottomLine(m_rcDaysOfWeek);
    rcBottomLine.bottom--;
    rcBottomLine.top = rcBottomLine.bottom - 1;
    rcBottomLine.left = m_rcWeekNumbers.right - 1;
    rcBottomLine.right = nMaxX;
    dc.FillSolidRect(rcBottomLine, m_clrMonthBorder);

    dc.SelectFont(hFontOld);
}