//改行記号を描画した場合は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; }
/* テキスト反転 @param hdc @param nLineNum @param x @param y @param nX @note CCEditView::DrawLogicLine() での作画(WM_PAINT)時に、1レイアウト行をまとめて反転処理するための関数。 範囲選択の随時更新は、CEditView::DrawSelectArea() が選択・反転解除を行う。 */ void CEditView::DispTextSelected( HDC hdc, //!< 作画対象ビットマップを含むデバイス CLayoutInt nLineNum, //!< 反転処理対象レイアウト行番号(0開始) const CMyPoint& ptXY, //!< (相対レイアウト0桁目の左端座標, 対象行の上端座標) CLayoutInt nX_Layout //!< 対象行の終了桁位置。 [ABC\n]なら改行の後ろで4 ) { CLayoutInt nSelectFrom; CLayoutInt nSelectTo; RECT rcClip; int nLineHeight = GetTextMetrics().GetHankakuDy(); int nCharWidth = GetTextMetrics().GetCharPxWidth(); HRGN hrgnDraw; const CLayout* pcLayout = m_pcEditDoc->m_cLayoutMgr.SearchLineByLayoutY( nLineNum ); CLayoutRange& sSelect = GetSelectionInfo().m_sSelect; /* 選択範囲内の行かな */ // if( IsTextSelected() ){ if( nLineNum >= sSelect.GetFrom().y && nLineNum <= sSelect.GetTo().y ){ CLayoutRange selectArea = GetSelectionInfo().GetSelectAreaLine(nLineNum, pcLayout); nSelectFrom = selectArea.GetFrom().x; nSelectTo = selectArea.GetTo().x; if( nSelectFrom == INT_MAX ){ nSelectFrom = nX_Layout; } if( nSelectTo == INT_MAX ){ nSelectTo = nX_Layout; } // 2006.03.28 Moca 表示域外なら何もしない if( GetTextArea().GetRightCol() < nSelectFrom ){ return; } if( nSelectTo < GetTextArea().GetViewLeftCol() ){ // nSelectTo == GetTextArea().GetViewLeftCol()のケースは後で0文字マッチでないことを確認してから抜ける return; } if( nSelectFrom < GetTextArea().GetViewLeftCol() ){ nSelectFrom = GetTextArea().GetViewLeftCol(); } rcClip.left = ptXY.x + (Int)nSelectFrom * nCharWidth; rcClip.right = ptXY.x + (Int)nSelectTo * nCharWidth; rcClip.top = ptXY.y; rcClip.bottom = ptXY.y + nLineHeight; bool bOMatch = false; // 2005/04/02 かろと 0文字マッチだと反転幅が0となり反転されないので、1/3文字幅だけ反転させる // 2005/06/26 zenryaku 選択解除でキャレットの残骸が残る問題を修正 // 2005/09/29 ryoji スクロール時にキャレットのようなゴミが表示される問題を修正 if (GetSelectionInfo().IsTextSelected() && rcClip.right == rcClip.left && sSelect.IsLineOne() && sSelect.GetFrom().x >= GetTextArea().GetViewLeftCol()) { HWND hWnd = ::GetForegroundWindow(); if( hWnd && (hWnd == m_pcEditWnd->m_cDlgFind.GetHwnd() || hWnd == m_pcEditWnd->m_cDlgReplace.GetHwnd()) ){ rcClip.right = rcClip.left + 2; bOMatch = true; } } if( rcClip.right == rcClip.left ){ return; //0文字マッチによる反転幅拡張なし } // 2006.03.28 Moca ウィンドウ幅が大きいと正しく反転しない問題を修正 if( rcClip.right > GetTextArea().GetAreaRight() ){ rcClip.right = GetTextArea().GetAreaRight(); } // 選択色表示なら反転しない if( !bOMatch && CTypeSupport(this, COLORIDX_SELECT).IsDisp() ){ return; } HBRUSH hBrush = ::CreateSolidBrush( SELECTEDAREA_RGB ); int nROP_Old = ::SetROP2( hdc, SELECTEDAREA_ROP2 ); HBRUSH hBrushOld = (HBRUSH)::SelectObject( hdc, hBrush ); hrgnDraw = ::CreateRectRgn( rcClip.left, rcClip.top, rcClip.right, rcClip.bottom ); ::PaintRgn( hdc, hrgnDraw ); ::DeleteObject( hrgnDraw ); SetROP2( hdc, nROP_Old ); SelectObject( hdc, hBrushOld ); DeleteObject( hBrush ); } // } return; }