示例#1
0
//! 全角スペース描画
void CFigure_ZenSpace::DispSpace(CGraphics& gr, DispPos* pDispPos, CEditView* pcView, bool bTrans) const
{
	// 2010.09.21 PP用実装追加
	// プロポーショナルでは、全角SPと□の幅が違うことがある。違う場合は独自に描画
	CTypeSupport cZenSpace(pcView, COLORIDX_ZENSPACE);

	int dx[1];
	dx[0] = pcView->GetTextMetrics().CalcTextWidth3(L" ", 1);

	RECT rc;
	//クリッピング矩形を計算。画面外なら描画しない
	if(pcView->GetTextArea().GenerateClipRect(&rc, *pDispPos, CHabaXInt(dx[0])))
	{
		int u25a1Dx = pcView->GetTextMetrics().CalcTextWidth3(L"□", 1);
		bool bDrawMySelf = dx[0] != u25a1Dx;
		const wchar_t* pZenSp = (bDrawMySelf ? L" " : L"□");
		int fontNo = WCODE::GetFontNo(*pZenSp);
		if( fontNo ){
			SFONT sFont;
			sFont.m_sFontAttr = gr.GetCurrentMyFontAttr();
			sFont.m_hFont = pcView->GetFontset().ChooseFontHandle(fontNo, sFont.m_sFontAttr);
			gr.PushMyFont(sFont);
		}
		int nHeightMargin = pcView->GetTextMetrics().GetCharHeightMarginByFontNo(fontNo);
		//描画
		ExtTextOutW_AnyBuild(
			gr,
			pDispPos->GetDrawPos().x,
			pDispPos->GetDrawPos().y + nHeightMargin,
			ExtTextOutOption() & ~(bTrans? ETO_OPAQUE: 0),
			&rc,
			pZenSp,
			1,
			dx
		);
		if( fontNo ){
			gr.PopMyFont();
		}
		if( bDrawMySelf ){
			gr.PushClipping(rc); // FIXME: 正確にはCombineRgn RGN_AND が必要
			
			// 全角SPの大きさ指定
			CMyRect rcZenSp;
			// 注:ベースライン無視
			rcZenSp.SetPos(pDispPos->GetDrawPos().x, pDispPos->GetDrawPos().y);
			rcZenSp.SetSize(dx[0]- pcView->m_pcEditDoc->m_cDocType.GetDocumentAttribute().m_nColumnSpace,
				pcView->GetTextMetrics().GetHankakuHeight());

			// 描画
			// 文字色や太字かどうかを現在の DC から調べる	// 2009.05.29 ryoji 
			// (検索マッチ等の状況に柔軟に対応するため、ここは記号の色指定には決め打ちしない)
			Draw_ZenSpace(gr, rcZenSp);

			// リージョン破棄
			gr.PopClipping();
			
			// To Here 2003.08.17 ryoji 改行文字が欠けないように
		}
		
	}

	//位置進める
	pDispPos->ForwardDrawCol(CLayoutXInt(dx[0]));
}
//改行記号を描画した場合はtrueを返す?
bool CEditView::DrawLayoutLine(SColorStrategyInfo* pInfo)
{
	bool bDispEOF = false;
	CTypeSupport cTextType(this,COLORIDX_TEXT);

	const CLayout* pcLayout = pInfo->m_pDispPos->GetLayoutRef(); //m_pcEditDoc->m_cLayoutMgr.SearchLineByLayoutY( pInfo->pDispPos->GetLayoutLineRef() );

	// レイアウト情報
	if( pcLayout ){
		pInfo->m_pLineOfLogic = pcLayout->GetDocLineRef()->GetPtr();
	}
	else{
		pInfo->m_pLineOfLogic = NULL;
	}

	//文字列参照
	const CDocLine* pcDocLine = pInfo->GetDocLine();
	CStringRef cLineStr = pcDocLine->GetStringRefWithEOL();

	// 描画範囲外の場合は色切替だけで抜ける
	if(pInfo->m_pDispPos->GetDrawPos().y < GetTextArea().GetAreaTop()){
		if(pcLayout){
			bool bChange = false;
			int nPosTo = pcLayout->GetLogicOffset() + pcLayout->GetLengthWithEOL();
			CColor3Setting cColor;
			while(pInfo->m_nPosInLogic < nPosTo){
				//色切替
				bChange |= pInfo->CheckChangeColor(cLineStr);

				//1文字進む
				pInfo->m_nPosInLogic += CNativeW::GetSizeOfChar(
											cLineStr.GetPtr(),
											cLineStr.GetLength(),
											pInfo->m_nPosInLogic
										);
			}
			if( bChange ){
				pInfo->DoChangeColor(&cColor);
				SetCurrentColor(pInfo->m_gr, cColor.eColorIndex, cColor.eColorIndex2, cColor.eColorIndexBg);
			}
		}
		return false;
	}

	// コンフィグ
	int nLineHeight = GetTextMetrics().GetHankakuDy();  //行の縦幅?
	CTypeSupport	cCaretLineBg(this, COLORIDX_CARETLINEBG);
	CTypeSupport	cEvenLineBg(this, COLORIDX_EVENLINEBG);
	CTypeSupport	cPageViewBg(this, COLORIDX_PAGEVIEW);
	CEditView& cActiveView = m_pcEditWnd->GetActiveView();
	CTypeSupport&	cBackType = (cCaretLineBg.IsDisp() &&
		GetCaret().GetCaretLayoutPos().GetY() == pInfo->m_pDispPos->GetLayoutLineRef() && !m_bMiniMap
			? cCaretLineBg
			: cEvenLineBg.IsDisp() && pInfo->m_pDispPos->GetLayoutLineRef() % 2 == 1 && !m_bMiniMap
				? cEvenLineBg
				: (cPageViewBg.IsDisp() && m_bMiniMap
					&& cActiveView.GetTextArea().GetViewTopLine() <= pInfo->m_pDispPos->GetLayoutLineRef()
					&& pInfo->m_pDispPos->GetLayoutLineRef() < cActiveView.GetTextArea().GetBottomLine())
						? cPageViewBg
						: cTextType);
	bool bTransText = IsBkBitmap();
	if( bTransText ){
		bTransText = cBackType.GetBackColor() == cTextType.GetBackColor();
	}

	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	//                        行番号描画                           //
	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	GetTextDrawer().DispLineNumber(
		pInfo->m_gr,
		pInfo->m_pDispPos->GetLayoutLineRef(),
		pInfo->m_pDispPos->GetDrawPos().y
	);


	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	//                       本文描画開始                          //
	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	pInfo->m_pDispPos->ResetDrawCol();


	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	//                 行頭(インデント)背景描画                    //
	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	if(pcLayout && pcLayout->GetIndent()!=0)
	{
		RECT rcClip;
		if(!bTransText && GetTextArea().GenerateClipRect(&rcClip, *pInfo->m_pDispPos, pcLayout->GetIndent())){
			cBackType.FillBack(pInfo->m_gr,rcClip);
		}
		//描画位置進める
		pInfo->m_pDispPos->ForwardDrawCol(pcLayout->GetIndent());
	}


	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	//                         本文描画                            //
	// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
	bool bSkipRight = false; // 続きを描画しなくていい場合はスキップする
	if(pcLayout){
		const CLayout* pcLayoutNext = pcLayout->GetNextLayout();
		if( NULL == pcLayoutNext ){
			bSkipRight = true;
		}else if( pcLayoutNext->GetLogicOffset() == 0 ){
			bSkipRight = true; // 次の行は別のロジック行なのでスキップ可能
		}
		if( !bSkipRight ){
			bSkipRight = CColorStrategyPool::getInstance()->IsSkipBeforeLayout();
		}
	}
	//行終端または折り返しに達するまでループ
	if(pcLayout){
		int nPosTo = pcLayout->GetLogicOffset() + pcLayout->GetLengthWithEOL();
		CFigureManager* pcFigureManager = CFigureManager::getInstance();
		while(pInfo->m_nPosInLogic < nPosTo){
			//色切替
			if( pInfo->CheckChangeColor(cLineStr) ){
				CColor3Setting cColor;
				pInfo->DoChangeColor(&cColor);
				SetCurrentColor(pInfo->m_gr, cColor.eColorIndex, cColor.eColorIndex2, cColor.eColorIndexBg);
			}

			//1文字情報取得 $$高速化可能
			CFigure& cFigure = pcFigureManager->GetFigure(&cLineStr.GetPtr()[pInfo->GetPosInLogic()],
				cLineStr.GetLength() - pInfo->GetPosInLogic());

			//1文字描画
			cFigure.DrawImp(pInfo);
			if( bSkipRight && GetTextArea().GetAreaRight() < pInfo->m_pDispPos->GetDrawPos().x ){
				pInfo->m_nPosInLogic = nPosTo;
				break;
			}
		}
	}

	// 必要ならEOF描画
	void _DispEOF( CGraphics& gr, DispPos* pDispPos, const CEditView* pcView);
	if(pcLayout && pcLayout->GetNextLayout()==NULL && pcLayout->GetLayoutEol().GetLen()==0){
		// 有文字行のEOF
		_DispEOF(pInfo->m_gr,pInfo->m_pDispPos,this);
		bDispEOF = true;
	}
	else if(!pcLayout && pInfo->m_pDispPos->GetLayoutLineRef()==m_pcEditDoc->m_cLayoutMgr.GetLineCount()){
		// 空行のEOF
		const CLayout* pBottom = m_pcEditDoc->m_cLayoutMgr.GetBottomLayout();
		if(pBottom==NULL || (pBottom && pBottom->GetLayoutEol().GetLen())){
			_DispEOF(pInfo->m_gr,pInfo->m_pDispPos,this);
			bDispEOF = true;
		}
	}

	// 必要なら折り返し記号描画
	if(pcLayout && pcLayout->GetLayoutEol().GetLen()==0 && pcLayout->GetNextLayout()!=NULL){
		_DispWrap(pInfo->m_gr,pInfo->m_pDispPos,this,pInfo->m_pDispPos->GetLayoutLineRef());
	}

	// 行末背景描画
	RECT rcClip;
	bool rcClipRet = GetTextArea().GenerateClipRectRight(&rcClip,*pInfo->m_pDispPos);
	if(rcClipRet){
		if( !bTransText ){
			cBackType.FillBack(pInfo->m_gr,rcClip);
		}
		CTypeSupport cSelectType(this, COLORIDX_SELECT);
		if( GetSelectionInfo().IsTextSelected() && cSelectType.IsDisp() ){
			// 選択範囲の指定色:必要ならテキストのない部分の矩形選択を作画
			CLayoutRange selectArea = GetSelectionInfo().GetSelectAreaLine(pInfo->m_pDispPos->GetLayoutLineRef(), pcLayout);
			// 2010.10.04 スクロール分の足し忘れ
			CPixelXInt nSelectFromPx =  GetTextMetrics().GetCharPxWidth(selectArea.GetFrom().x - GetTextArea().GetViewLeftCol());
			CPixelXInt nSelectToPx   = GetTextMetrics().GetCharPxWidth(selectArea.GetTo().x - GetTextArea().GetViewLeftCol());
			if( nSelectFromPx < nSelectToPx && selectArea.GetTo().x != INT_MAX ){
				RECT rcSelect; // Pixel
				rcSelect.top    = pInfo->m_pDispPos->GetDrawPos().y;
				rcSelect.bottom = pInfo->m_pDispPos->GetDrawPos().y + GetTextMetrics().GetHankakuDy();
				rcSelect.left   = GetTextArea().GetAreaLeft() + nSelectFromPx;
				rcSelect.right  = GetTextArea().GetAreaLeft() + nSelectToPx;
				RECT rcDraw;
				if( ::IntersectRect(&rcDraw, &rcClip, &rcSelect) ){
					COLORREF color = GetBackColorByColorInfo2(cSelectType.GetColorInfo(), cBackType.GetColorInfo());
					if( color != cBackType.GetBackColor() ){
						pInfo->m_gr.FillSolidMyRect(rcDraw, color);
					}
				}
			}
		}
	}

	// ノート線描画
	if( !m_bMiniMap ){
		GetTextDrawer().DispNoteLine(
			pInfo->m_gr,
			pInfo->m_pDispPos->GetDrawPos().y,
			pInfo->m_pDispPos->GetDrawPos().y + nLineHeight,
			GetTextArea().GetAreaLeft(),
			GetTextArea().GetAreaRight()
		);
	}

	// 指定桁縦線描画
	GetTextDrawer().DispVerticalLines(
		pInfo->m_gr,
		pInfo->m_pDispPos->GetDrawPos().y,
		pInfo->m_pDispPos->GetDrawPos().y + nLineHeight,
		CLayoutInt(0),
		CLayoutInt(-1)
	);

	// 折り返し桁縦線描画
	if( !m_bMiniMap ){
		GetTextDrawer().DispWrapLine(
			pInfo->m_gr,
			pInfo->m_pDispPos->GetDrawPos().y,
			pInfo->m_pDispPos->GetDrawPos().y + nLineHeight
		);
	}

	// 反転描画
	if( pcLayout && GetSelectionInfo().IsTextSelected() ){
		DispTextSelected(
			pInfo->m_gr,
			pInfo->m_pDispPos->GetLayoutLineRef(),
			CMyPoint(pInfo->m_sDispPosBegin.GetDrawPos().x, pInfo->m_pDispPos->GetDrawPos().y),
			pcLayout->CalcLayoutWidth(m_pcEditDoc->m_cLayoutMgr)
				+ CLayoutInt(pcLayout->GetLayoutEol().GetLen()
					? (CTypeSupport(this, COLORIDX_EOL).IsDisp()
						? (GetTextMetrics().GetLayoutXDefault()+CLayoutXInt(4)) // HACK:EOLの描画幅分だけ確保する。4pxはCRLFのはみ出している分
						: CLayoutXInt(2)) // 非表示 = 2px
					: CLayoutInt(0))
		);
	}

	return bDispEOF;
}