int check_b(const string &s) //表达式括号配对检测 { Stack<char> a(100); char c; for(int i=0; s[i]; i++) { if(!IsBracket(s[i])) continue; else if(IsBracket(s[i])==1) { if(!a.PushStack(s[i])) return 0; } else if(s[i]==')') { if(s[i-1]=='(') return 0; if(a.PopStack(c)&&c=='(') continue; return 0; } else if(s[i]==']') { if(s[i-1]=='(') return 0; if(a.PopStack(c)&&c=='[') continue; return 0; } else if(s[i]=='}') { if(s[i-1]=='(') return 0; if(a.PopStack(c)&&c=='{') continue; return 0; } } if(a.State()>=0) return 0; return 1; }
inline string GetBracketData(const string &s,int &i) //获取一对括号中的内容 { string s1="\0"; int j,k=1; i++; while(s[i]) { j=IsBracket(s[i]); if(j==1) k++; else if(j==2) k--; if(k==0) { i++; break; } s1+=s[i++]; } return s1; }
/*! 対括弧の強調表示 @date 2002/09/18 ai @date 2003/02/18 ai 再描画対応の為大改造 */ void CEditView::DrawBracketPair( bool bDraw ) { // 03/03/06 ai すべて置換、すべて置換後のUndo&Redoがかなり遅い問題に対応 if( m_bDoing_UndoRedo || !GetDrawSwitch() ){ return; } if( !m_pTypeData->m_ColorInfoArr[COLORIDX_BRACKET_PAIR].m_bDisp ){ return; } // 括弧の強調表示位置が未登録の場合は終了 if( m_ptBracketPairPos_PHY.HasNegative() || m_ptBracketCaretPos_PHY.HasNegative() ){ return; } // 描画指定(bDraw=true) かつ // ( テキストが選択されている 又は // 選択範囲を描画している 又は // フォーカスを持っていない 又は // アクティブなペインではない ) 場合は終了 if( bDraw &&( GetSelectionInfo().IsTextSelected() || GetSelectionInfo().m_bDrawSelectArea || !m_bDrawBracketPairFlag || ( m_pcEditWnd->GetActivePane() != m_nMyIndex ) ) ){ return; } CGraphics gr; gr.Init(::GetDC(GetHwnd())); bool bCaretChange = false; gr.SetTextBackTransparent(true); for( int i = 0; i < 2; i++ ) { // i=0:対括弧,i=1:カーソル位置の括弧 // 2011.11.23 ryoji 対括弧 -> カーソル位置の括弧 の順に処理順序を変更 // # { と } が異なる行にある場合に { を BS で消すと } の強調表示が解除されない問題(Wiki BugReport/89)の対策 // # この順序変更によりカーソル位置が括弧でなくなっていても対括弧があれば対括弧側の強調表示は解除される CLayoutPoint ptColLine; if( i == 0 ){ m_pcEditDoc->m_cLayoutMgr.LogicToLayout( m_ptBracketPairPos_PHY, &ptColLine ); }else{ m_pcEditDoc->m_cLayoutMgr.LogicToLayout( m_ptBracketCaretPos_PHY, &ptColLine ); } if ( ( ptColLine.x >= GetTextArea().GetViewLeftCol() ) && ( ptColLine.x <= GetTextArea().GetRightCol() ) && ( ptColLine.y >= GetTextArea().GetViewTopLine() ) && ( ptColLine.y <= GetTextArea().GetBottomLine() ) ) { // 表示領域内の場合 if( !bDraw && GetSelectionInfo().m_bDrawSelectArea && ( 0 == IsCurrentPositionSelected( ptColLine ) ) ) { // 選択範囲描画済みで消去対象の括弧が選択範囲内の場合 continue; } const CLayout* pcLayout; CLogicInt nLineLen; const wchar_t* pLine = m_pcEditDoc->m_cLayoutMgr.GetLineStr( ptColLine.GetY2(), &nLineLen, &pcLayout ); if( pLine ) { EColorIndexType nColorIndex; CLogicInt OutputX = LineColumnToIndex( pcLayout, ptColLine.GetX2() ); if( bDraw ) { nColorIndex = COLORIDX_BRACKET_PAIR; } else{ if( IsBracket( pLine, OutputX, CLogicInt(1) ) ){ DispPos _sPos(0,0); // 注意:この値はダミー。CheckChangeColorでの参照位置は不正確 SColorStrategyInfo _sInfo; SColorStrategyInfo* pInfo = &_sInfo; pInfo->m_pDispPos = &_sPos; pInfo->m_pcView = this; // 03/10/24 ai 折り返し行のColorIndexが正しく取得できない問題に対応 // 2009.02.07 ryoji GetColorIndex に渡すインデックスの仕様変更(元はこっちの仕様だった模様) CColor3Setting cColor = GetColorIndex( pcLayout, ptColLine.GetY2(), OutputX, pInfo ); nColorIndex = cColor.eColorIndex2; } else{ SetBracketPairPos( false ); break; } } CTypeSupport cCuretLineBg(this,COLORIDX_CARETLINEBG); EColorIndexType nColorIndexBg = (cCuretLineBg.IsDisp() && ptColLine.GetY2() == GetCaret().GetCaretLayoutPos().GetY2() ? COLORIDX_CARETLINEBG : CTypeSupport(this,COLORIDX_EVENLINEBG).IsDisp() && ptColLine.GetY2() % 2 == 1 ? COLORIDX_EVENLINEBG : COLORIDX_TEXT); // 03/03/03 ai カーソルの左に括弧があり括弧が強調表示されている状態でShift+←で選択開始すると // 選択範囲内に反転表示されない部分がある問題の修正 CLayoutInt caretX = GetCaret().GetCaretLayoutPos().GetX2(); bool bCaretHide = (!bCaretChange && (ptColLine.x == caretX || ptColLine.x + 1 == caretX) && GetCaret().GetCaretShowFlag()); if( bCaretHide ){ bCaretChange = true; GetCaret().HideCaret_( GetHwnd() ); // キャレットが一瞬消えるのを防止 } { int nWidth = GetTextMetrics().GetHankakuDx(); int nHeight = GetTextMetrics().GetHankakuDy(); int nLeft = (GetTextArea().GetDocumentLeftClientPointX()) + GetTextMetrics().GetCharPxWidth(ptColLine.x); int nTop = (Int)( ptColLine.GetY2() - GetTextArea().GetViewTopLine() ) * nHeight + GetTextArea().GetAreaTop(); CLayoutXInt charsWidth = m_pcEditDoc->m_cLayoutMgr.GetLayoutXOfChar(pLine, nLineLen, OutputX); //色設定 CTypeSupport cTextType(this,COLORIDX_TEXT); cTextType.SetGraphicsState_WhileThisObj(gr); // 2013.05.24 背景色がテキストの背景色と同じならカーソル行の背景色を適用 CTypeSupport cColorIndexType(this,nColorIndex); CTypeSupport cColorIndexBgType(this,nColorIndexBg); CTypeSupport* pcColorBack = &cColorIndexType; if( cColorIndexType.GetBackColor() == cTextType.GetBackColor() && nColorIndexBg != COLORIDX_TEXT ){ pcColorBack = &cColorIndexBgType; } SetCurrentColor( gr, nColorIndex, nColorIndex, nColorIndexBg ); bool bTrans = false; // DEBUG_TRACE( _T("DrawBracket %d %d ") , ptColLine.y, ptColLine.x ); if( IsBkBitmap() && cTextType.GetBackColor() == pcColorBack->GetBackColor() ){ bTrans = true; RECT rcChar; rcChar.left = nLeft; rcChar.top = nTop; rcChar.right = nLeft + GetTextMetrics().GetCharPxWidth(charsWidth); rcChar.bottom = nTop + nHeight; HDC hdcBgImg = ::CreateCompatibleDC(gr); HBITMAP hBmpOld = (HBITMAP)::SelectObject(hdcBgImg, m_pcEditDoc->m_hBackImg); DrawBackImage(gr, rcChar, hdcBgImg); ::SelectObject(hdcBgImg, hBmpOld); ::DeleteDC(hdcBgImg); } DispPos sPos(nWidth, nHeight); sPos.InitDrawPos(CMyPoint(nLeft, nTop)); GetTextDrawer().DispText(gr, &sPos, 0, &pLine[OutputX], 1, bTrans); GetTextDrawer().DispNoteLine(gr, nTop, nTop + nHeight, nLeft, nLeft + (Int)charsWidth * nWidth); // 2006.04.30 Moca 対括弧の縦線対応 GetTextDrawer().DispVerticalLines(gr, nTop, nTop + nHeight, ptColLine.x, ptColLine.x + charsWidth); //※括弧が全角幅である場合を考慮 cTextType.RewindGraphicsState(gr); } if( ( m_pcEditWnd->GetActivePane() == m_nMyIndex ) && ( ( ptColLine.y == GetCaret().GetCaretLayoutPos().GetY() ) || ( ptColLine.y - 1 == GetCaret().GetCaretLayoutPos().GetY() ) ) ){ // 03/02/27 ai 行の間隔が"0"の時にアンダーラインが欠ける事がある為修正 GetCaret().m_cUnderLine.CaretUnderLineON( true, false ); } } } } if( bCaretChange ){ GetCaret().ShowCaret_( GetHwnd() ); // キャレットが一瞬消えるのを防止 } ::ReleaseDC( GetHwnd(), gr ); }
int compute1(long double &a,string s,int angle=0)//算术综合运算 { if(!check_b(s)) return 0; Stack<long double> ss(20); Stack<char> sf(20); int i=0,j; string s1,s2; char c; long double b; while(IsUselessChar(s[i])) i++; if(s[i]=='-') { ss.PushStack(-1); sf.PushStack('*'); i++; } else if(s[i]=='+') i++; while(s[i]) { s2="\0"; if(IsUselessChar(s[i])) i++; else if(IsBracket(s[i])==1) { if(i>0&&!IsOperator1(s[i-1])) if(!sf.PushStack('*')) return 0; s2=GetBracketData(s,i); if(!compute1(a,s2,angle)||!ss.PushStack(a)) return 0; } else if(IsOperator1(s[i])) { if(s[i]=='!') { if(!ss.PopStack(b)||!factorial(a,(int)b)||!ss.PushStack(a)) return 0; i++; continue; } while(sf.GetTopData(c)) { if(PRI(s[i])>PRI(c)) break; if(!ss.PopStack(b)||!ss.PopStack(a)||!sf.PopStack(c)||!Account1(a,b,c)||!ss.PushStack(a)) return 0; } if(!sf.PushStack(s[i++])) return 0; } else if(IsData(s[i])==1) { while(IsData(s[i])==1) s2+=s[i++]; if(!ss.PushStack(string_double(s2))) return 0; } else if(s[i]=='S') { if(i>0&&!IsOperator1(s[i-1])) if(!sf.PushStack('*')) return 0; s2="\0"; for(j=0; j<4&&s[i]; j++,i++) s2+=s[i]; if(s2!="Sqrt"||IsBracket(s[i])!=1) return 0; s2=GetBracketData(s,i); s1="\0"; for(j=0; s2[j]; j++) { if(IsBracket(s2[j])==1) s1+="("+GetBracketData(s2,j)+")"; if(s2[j]==',') { j++; break; } else s1+=s2[j]; } if(!compute1(a,s1,angle)) return 0; s1="\0"; for(; s2[j]; j++) s1+=s2[j]; if(!compute1(b,s1,angle)||!Sqrt(a,b)||!ss.PushStack(a)) return 0; } else if(s[i]>='a'&&s[i]<='z'||s[i]=='L') { s1="\0"; if(i>0&&!IsOperator1(s[i-1])) if(!sf.PushStack('*')) return 0; while(s[i]>='a'&&s[i]<='z'||s[i]=='L'||s[i]=='^') { s1+=s[i++]; if(s[i-1]=='e'&&s[i]!='^') s1+='^'; } if(s[i-1]=='e') s2="1"; else if(IsBracket(s[i])==1) s2=GetBracketData(s,i); else if(IsData(s[i])==1) { while(s[i]) { if(IsData(s[i])==1) s2+=s[i++]; else break; } } else if(s[i]=='P'||s[i+1]=='i') s2="Pi"; else if(s[i]=='S') { for(j=0; j<4&&s[i]; j++,i++) s2+=s[i]; if(s2!="Sqrt"||IsBracket(s[i])!=1) return 0; s2+="("+GetBracketData(s,i)+")"; } else return 0; if(!compute1(a,s2,angle)||!compute3(b,s1,a,angle)||!ss.PushStack(b)) return 0; } else if(s[i]=='P') { if(i>0&&!IsOperator1(s[i-1])&&!sf.PushStack('*')||!ss.PushStack(P)) return 0; i+=2; } else return 0; } while(sf.PopStack(c)) if(!ss.PopStack(b)||!ss.PopStack(a)||!Account1(a,b,c)||!ss.PushStack(a)) return 0; if(!ss.PopStack(a)||ss.State()>=0) return 0; return 1; }