/*! * Sanitizes the Rect so that both width() and * height() are non-negative. */ RectT& sanitize_size(void) { width(t_max(T(0), width())); height(t_max(T(0), height())); return *this; }
CMyRect MergeRect(const CMyRect& rc1, const CMyRect& rc2) { return CMyRect( t_min(rc1.left , rc2.left), t_min(rc1.top , rc2.top), t_max(rc1.right , rc2.right), t_max(rc1.bottom, rc2.bottom) ); }
void Ephemeris<Frame>::Prolong(Instant const& t) { IntegrationProblem<NewtonianMotionEquation> problem; problem.equation = massive_bodies_equation_; problem.append_state = std::bind(&Ephemeris::AppendMassiveBodiesState, this, _1); // Note that |t| may be before the last time that we integrated and still // after |t_max()|. In this case we want to make sure that the integrator // makes progress. problem.initial_state = &last_state_; if (t <= last_state_.time.value) { problem.t_final = last_state_.time.value + parameters_.step_; } else { problem.t_final = t; } // Perform the integration. Note that we may have to iterate until |t_max()| // actually reaches |t| because the last series may not be fully determined // after the first integration. while (t_max() < t) { parameters_.integrator_->Solve(problem, parameters_.step_); // Here |problem.initial_state| still points at |last_state_|, which is the // state at the end of the previous call to |Solve|. It is therefore the // right initial state for the next call to |Solve|, if any. problem.t_final += parameters_.step_; } }
void Ephemeris<Frame>::WriteToMessage( not_null<serialization::Ephemeris*> const message) const { LOG(INFO) << __FUNCTION__; // The bodies are serialized in the order in which they were given at // construction. for (auto const& unowned_body : unowned_bodies_) { unowned_body->WriteToMessage(message->add_body()); } // The trajectories are serialized in the order resulting from the separation // between oblate and spherical bodies. if (checkpoints_.empty()) { for (auto const& trajectory : trajectories_) { trajectory->WriteToMessage(message->add_trajectory()); } last_state_.WriteToMessage(message->mutable_last_state()); } else { auto const& checkpoints = checkpoints_.front().checkpoints; CHECK_EQ(trajectories_.size(), checkpoints.size()); for (int i = 0; i < trajectories_.size(); ++i) { trajectories_[i]->WriteToMessage(message->add_trajectory(), checkpoints[i]); } checkpoints_.front().system_state.WriteToMessage( message->mutable_last_state()); t_max().WriteToMessage(message->mutable_t_max()); } parameters_.WriteToMessage(message->mutable_fixed_step_parameters()); fitting_tolerance_.WriteToMessage(message->mutable_fitting_tolerance()); LOG(INFO) << NAMED(message->SpaceUsed()); LOG(INFO) << NAMED(message->ByteSize()); }
int CColor_Quote::Match_QuoteStr( const wchar_t* pszQuote, int nQuoteLen, int nPos, const CStringRef& cLineStr, bool bEscape ) { int nCharChars; int i; const int nCompLen = cLineStr.GetLength() - nQuoteLen + 1; const WCHAR quote1 = pszQuote[0]; const WCHAR* pLine = cLineStr.GetPtr(); for( i = nPos; i < nCompLen; i += nCharChars ){ if( quote1 == pLine[i] && wmemcmp( pszQuote + 1, pLine + i + 1, nQuoteLen - 1 ) == 0 ){ return i + nQuoteLen; } nCharChars = (Int)t_max(CLogicInt(1), CNativeW::GetSizeOfChar( pLine, cLineStr.GetLength(), i )); if( bEscape && pLine[i] == L'\\' ){ i += (Int)t_max(CLogicInt(1), CNativeW::GetSizeOfChar( pLine, cLineStr.GetLength(), i + nCharChars )); } } return cLineStr.GetLength(); }
void Ephemeris<Frame>::FlowWithFixedStep( std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories, std::vector<IntrinsicAcceleration> const& intrinsic_accelerations, Instant const& t, FixedStepParameters const& parameters) { VLOG(1) << __FUNCTION__ << " " << NAMED(parameters.step_) << " " << NAMED(t); if (empty() || t > t_max()) { Prolong(t); } std::vector<typename ContinuousTrajectory<Frame>::Hint> hints(bodies_.size()); NewtonianMotionEquation massless_body_equation; massless_body_equation.compute_acceleration = std::bind(&Ephemeris::ComputeMasslessBodiesTotalAccelerations, this, std::cref(intrinsic_accelerations), _1, _2, _3, &hints); typename NewtonianMotionEquation::SystemState initial_state; for (auto const& trajectory : trajectories) { auto const trajectory_last = trajectory->last(); auto const last_degrees_of_freedom = trajectory_last.degrees_of_freedom(); // TODO(phl): why do we keep rewriting this? Should we check consistency? initial_state.time = trajectory_last.time(); initial_state.positions.push_back(last_degrees_of_freedom.position()); initial_state.velocities.push_back(last_degrees_of_freedom.velocity()); } IntegrationProblem<NewtonianMotionEquation> problem; problem.equation = massless_body_equation; #if defined(WE_LOVE_228) typename NewtonianMotionEquation::SystemState last_state; problem.append_state = [&last_state]( typename NewtonianMotionEquation::SystemState const& state) { last_state = state; }; #else problem.append_state = std::bind(&Ephemeris::AppendMasslessBodiesState, _1, std::cref(trajectories)); #endif problem.t_final = t; problem.initial_state = &initial_state; parameters.integrator_->Solve(problem, parameters.step_); #if defined(WE_LOVE_228) // The |positions| are empty if and only if |append_state| was never called; // in that case there was not enough room to advance the |trajectories|. if (!last_state.positions.empty()) { AppendMasslessBodiesState(last_state, trajectories); } #endif }
uint cNtHeader::calculatePeLastVirtualAddress() const { uint last = 0; for (uint i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) { last = t_max((uint)(OptionalHeader.DataDirectory[i].Size + OptionalHeader.DataDirectory[i].VirtualAddress), last); } return last; }
bool cNtHeader::cNtPeFileMapping::memread(addressNumericValue address, void* buffer, uint length, cFragmentsDescriptor*) const { // TODO! // For now the fragmentation is ignore because it's irrelevant if (!m_parent->m_memoryImage.isEmpty()) { cForkStreamPtr stream = m_parent->m_memoryImage->fork(); stream->seek(address, basicInput::IO_SEEK_SET); stream->pipeRead((uint8*)buffer, length); return true; } // Reset buffer memset(buffer, IMAGE_RDATA_CELL_CODE , length); cList<cSectionPtr>::iterator i = m_parent->m_sections.begin(); for (; i != m_parent->m_sections.end(); ++i) { cNtSectionHeader& ntSection = *((cNtSectionHeader*)(*i).getPointer()); // For each section check if we have data within the range addressNumericValue SectionAddress = ntSection.VirtualAddress; addressNumericValue SectionLength = ntSection.SizeOfRawData; addressNumericValue SectionEnd = SectionAddress + SectionLength; if ((SectionEnd > address) && (SectionAddress < (address + length))) { // There is some overlapped addressNumericValue cBegin = t_max(SectionAddress, address); addressNumericValue cEnd = t_min(SectionEnd, (address + length)); cForkStreamPtr stream = ntSection.getSectionContentAccesser()->fork(); stream->seek(cBegin - SectionAddress, basicInput::IO_SEEK_SET); stream->pipeRead((uint8*)buffer + (cBegin - address), cEnd - cBegin); } } return true; }
int CColor_Quote::Match_Quote( wchar_t wcQuote, int nPos, const CStringRef& cLineStr, int escapeType, bool* pbEscapeEnd ) { int nCharChars; int i; for( i = nPos; i < cLineStr.GetLength(); ++i ){ // 2005-09-02 D.S.Koba GetSizeOfChar nCharChars = (Int)t_max(CLogicInt(1), CNativeW::GetSizeOfChar( cLineStr.GetPtr(), cLineStr.GetLength(), i )); if( escapeType == STRING_LITERAL_CPP ){ // エスケープ \" if( 1 == nCharChars && cLineStr.At(i) == L'\\' ){ ++i; if( i < cLineStr.GetLength() && WCODE::IsLineDelimiter(cLineStr.At(i), GetDllShareData().m_Common.m_sEdit.m_bEnableExtEol) ){ if( pbEscapeEnd ){ *pbEscapeEnd = true; } } }else if( 1 == nCharChars && cLineStr.At(i) == wcQuote ){ return i + 1; } }else if( escapeType == STRING_LITERAL_PLSQL ){ // エスケープ "" if( 1 == nCharChars && cLineStr.At(i) == wcQuote ){ if( i + 1 < cLineStr.GetLength() && cLineStr.At(i + 1) == wcQuote ){ ++i; }else{ return i + 1; } } }else{ // エスケープなし if( 1 == nCharChars && cLineStr.At(i) == wcQuote ){ return i + 1; } } if( 2 == nCharChars ){ ++i; } } return cLineStr.GetLength() + 1; // 終端なしはLength + 1 }
void Ephemeris<Frame>::AppendMassiveBodiesState( typename NewtonianMotionEquation::SystemState const& state) { last_state_ = state; int index = 0; for (auto& trajectory : trajectories_) { trajectory->Append( state.time.value, DegreesOfFreedom<Frame>(state.positions[index].value, state.velocities[index].value)); ++index; } // Record an intermediate state if we haven't done so for too long. CHECK(!trajectories_.empty()); Instant const t_last_intermediate_state = checkpoints_.empty() ? astronomy::InfinitePast : checkpoints_.back().system_state.time.value; if (t_max() - t_last_intermediate_state > max_time_between_checkpoints) { checkpoints_.push_back(GetCheckpoint()); } }
/*! 初期化 pcmemHokanWord == NULLのとき、補完候補がひとつだったら、補完ウィンドウを表示しないで終了します。 Search()呼び出し元で確定処理を進めてください。 @date 2002.2.17 YAZAKI CShareDataのインスタンスは、CProcessにひとつあるのみ。 */ int CHokanMgr::Search( POINT* ppoWin, int nWinHeight, int nColumnWidth, const wchar_t* pszCurWord, const TCHAR* pszHokanFile, bool bHokanLoHiCase, // 入力補完機能:英大文字小文字を同一視する 2001/06/19 asa-o bool bHokanByFile, // 編集中データから候補を探す 2003.06.23 Moca int nHokanType, bool bHokanByKeyword, CNativeW* pcmemHokanWord // 2001/06/19 asa-o ) { CEditView* pcEditView = reinterpret_cast<CEditView*>(m_lParam); /* 共有データ構造体のアドレスを返す */ m_pShareData = &GetDllShareData(); /* || 補完キーワードの検索 || || ・見つかった候補をすべて返す(改行で区切って返す) || ・指定された候補の最大数を超えると処理を中断する || ・見つかった数を返す || */ m_vKouho.clear(); CDicMgr::HokanSearch( pszCurWord, bHokanLoHiCase, // 引数からに変更 2001/06/19 asa-o m_vKouho, 0, //Max候補数 pszHokanFile ); // 2003.05.16 Moca 追加 編集中データ内から候補を探す if( bHokanByFile ){ pcEditView->HokanSearchByFile( pszCurWord, bHokanLoHiCase, m_vKouho, 1024 // 編集中データからなので数を制限しておく ); } // 2012.10.13 Moca 強調キーワードから候補を探す if( bHokanByKeyword ){ HokanSearchByKeyword( pszCurWord, bHokanLoHiCase, m_vKouho ); } { int nOption = ( (bHokanLoHiCase ? 0x01 : 0) | (bHokanByFile ? 0x02 : 0) ); CPlug::Array plugs; CPlug::Array plugType; CJackManager::getInstance()->GetUsablePlug( PP_COMPLEMENTGLOBAL, 0, &plugs ); if( nHokanType != 0 ){ CJackManager::getInstance()->GetUsablePlug( PP_COMPLEMENT, nHokanType, &plugType ); if( 0 < plugType.size() ){ plugs.push_back( plugType[0] ); } } for( auto it = plugs.begin(); it != plugs.end(); ++it ){ //インタフェースオブジェクト準備 CWSHIfObj::List params; std::wstring curWord = pszCurWord; CComplementIfObj* objComp = new CComplementIfObj( curWord , this, nOption ); objComp->AddRef(); params.push_back( objComp ); //プラグイン呼び出し (*it)->Invoke( pcEditView, params ); objComp->Release(); } } if( 0 == m_vKouho.size() ){ m_nCurKouhoIdx = -1; return 0; } // 2001/06/19 asa-o 候補が1つの場合補完ウィンドウは表示しない(逐次補完の場合は除く) if( 1 == m_vKouho.size() ){ if(pcmemHokanWord != NULL){ m_nCurKouhoIdx = -1; pcmemHokanWord->SetString( m_vKouho[0].c_str() ); return 1; } } // m_hFont = hFont; m_poWin.x = ppoWin->x; m_poWin.y = ppoWin->y; m_nWinHeight = nWinHeight; m_nColumnWidth = nColumnWidth; // m_cmemCurWord.SetData( pszCurWord, lstrlen( pszCurWord ) ); m_cmemCurWord.SetString( pszCurWord ); m_nCurKouhoIdx = 0; // SetCurKouhoStr(); // ::ShowWindow( GetHwnd(), SW_SHOWNA ); HWND hwndList; hwndList = GetItemHwnd( IDC_LIST_WORDS ); List_ResetContent( hwndList ); { size_t kouhoNum = m_vKouho.size(); for( size_t i = 0; i < kouhoNum; ++i ){ ::List_AddString( hwndList, m_vKouho[i].c_str() ); } } List_SetCurSel( hwndList, 0 ); //@@ ::EnableWindow( ::GetParent( ::GetParent( m_hwndParent ) ), FALSE ); int nX; int nY; int nCX; int nCY; RECT rcDesktop; // May 01, 2004 genta マルチモニタ対応 ::GetMonitorWorkRect( GetHwnd(), &rcDesktop ); nX = m_poWin.x - m_nColumnWidth; nY = m_poWin.y + m_nWinHeight + 4; nCX = m_nWidth; nCY = m_nHeight; /* 下に入るなら */ if( nY + nCY < rcDesktop.bottom ){ /* 何もしない */ }else /* 上に入るなら */ if( rcDesktop.top < m_poWin.y - m_nHeight - 4 ){ /* 上に出す */ nY = m_poWin.y - m_nHeight - 4; }else /* 上に出すか下に出すか(広いほうに出す) */ if( rcDesktop.bottom - nY > m_poWin.y ){ /* 下に出す */ // m_nHeight = rcDesktop.bottom - nY; nCY = rcDesktop.bottom - nY; }else{ /* 上に出す */ nY = rcDesktop.top; nCY = m_poWin.y - 4 - rcDesktop.top; } // 2001/06/19 Start by asa-o: 表示位置補正 // 右に入る if(nX + nCX < rcDesktop.right ){ // そのまま }else // 左に入る if(rcDesktop.left < nX - nCX + 8){ // 左に表示 nX -= nCX - 8; }else{ // サイズを調整して右に表示 nCX = t_max((int)(rcDesktop.right - nX) , 100); // 最低サイズを100くらいに } // 2001/06/19 End // 2001/06/18 Start by asa-o: 補正後の位置・サイズを保存 m_poWin.x = nX; m_poWin.y = nY; m_nHeight = nCY; m_nWidth = nCX; // 2001/06/18 End /* はみ出すなら小さくする */ // if( rcDesktop.bottom < nY + nCY ){ // /* 下にはみ出す */ // if( m_poWin.y - 4 - nCY < 0 ){ // /* 上にはみ出す */ // /* →高さだけ調節 */ // nCY = rcDesktop.bottom - nY - 4; // }else{ // // } // // } ::MoveWindow( GetHwnd(), nX, nY, nCX, nCY, TRUE ); ::ShowWindow( GetHwnd(), SW_SHOWNA ); // 2001/06/18 asa-o: ShowTip(); // 補完ウィンドウで選択中の単語にキーワードヘルプを表示 // 2003.06.25 Moca 他のメソッドで使っていないので、とりあえず削除しておく int kouhoNum = m_vKouho.size(); m_vKouho.clear(); return kouhoNum; }
void Ephemeris<Frame>::ComputeApsides(not_null<MassiveBody const*> const body1, not_null<MassiveBody const*> const body2, DiscreteTrajectory<Frame>& apoapsides1, DiscreteTrajectory<Frame>& periapsides1, DiscreteTrajectory<Frame>& apoapsides2, DiscreteTrajectory<Frame>& periapsides2) { not_null<ContinuousTrajectory<Frame> const*> const body1_trajectory = trajectory(body1); not_null<ContinuousTrajectory<Frame> const*> const body2_trajectory = trajectory(body2); typename ContinuousTrajectory<Frame>::Hint hint1; typename ContinuousTrajectory<Frame>::Hint hint2; // Computes the derivative of the squared distance between |body1| and |body2| // at time |t|. auto const evaluate_square_distance_derivative = [body1_trajectory, body2_trajectory, &hint1, &hint2]( Instant const& t) -> Variation<Square<Length>> { DegreesOfFreedom<Frame> const body1_degrees_of_freedom = body1_trajectory->EvaluateDegreesOfFreedom(t, &hint1); DegreesOfFreedom<Frame> const body2_degrees_of_freedom = body2_trajectory->EvaluateDegreesOfFreedom(t, &hint2); RelativeDegreesOfFreedom<Frame> const relative = body1_degrees_of_freedom - body2_degrees_of_freedom; return 2.0 * InnerProduct(relative.displacement(), relative.velocity()); }; std::experimental::optional<Instant> previous_time; std::experimental::optional<Variation<Square<Length>>> previous_squared_distance_derivative; for (Instant time = t_min(); time <= t_max(); time += parameters_.step()) { Variation<Square<Length>> const squared_distance_derivative = evaluate_square_distance_derivative(time); if (previous_squared_distance_derivative && Sign(squared_distance_derivative) != Sign(*previous_squared_distance_derivative)) { CHECK(previous_time); // The derivative of |squared_distance| changed sign. Find its zero by // bisection, this is the time of the apsis. Then compute the apsis and // append it to one of the output trajectories. Instant const apsis_time = Bisect(evaluate_square_distance_derivative, *previous_time, time); DegreesOfFreedom<Frame> const apsis1_degrees_of_freedom = body1_trajectory->EvaluateDegreesOfFreedom(apsis_time, &hint1); DegreesOfFreedom<Frame> const apsis2_degrees_of_freedom = body2_trajectory->EvaluateDegreesOfFreedom(apsis_time, &hint2); if (Sign(squared_distance_derivative).Negative()) { apoapsides1.Append(apsis_time, apsis1_degrees_of_freedom); apoapsides2.Append(apsis_time, apsis2_degrees_of_freedom); } else { periapsides1.Append(apsis_time, apsis1_degrees_of_freedom); periapsides2.Append(apsis_time, apsis2_degrees_of_freedom); } } previous_time = time; previous_squared_distance_derivative = squared_distance_derivative; } }
/* 文字列置換 */ void CLayoutMgr::ReplaceData_CLayoutMgr( LayoutReplaceArg* pArg ) { CLayoutInt nWork_nLines = m_nLines; //変更前の全行数の保存 @@@ 2002.04.19 MIK /* 置換先頭位置のレイアウト情報 */ EColorIndexType nCurrentLineType = COLORIDX_DEFAULT; CLayoutColorInfo* colorInfo = NULL; CLayoutInt nLineWork = pArg->sDelRange.GetFrom().GetY2(); CLayout* pLayoutWork = SearchLineByLayoutY( pArg->sDelRange.GetFrom().GetY2() ); if( pLayoutWork ){ while( 0 != pLayoutWork->GetLogicOffset() ){ pLayoutWork = pLayoutWork->GetPrevLayout(); nLineWork--; } nCurrentLineType = pLayoutWork->GetColorTypePrev(); colorInfo = pLayoutWork->GetLayoutExInfo()->DetachColorInfo(); }else if( GetLineCount() == pArg->sDelRange.GetFrom().GetY2() ){ // 2012.01.05 最終行のRedo/Undoでの色分けが正しくないのを修正 nCurrentLineType = m_nLineTypeBot; colorInfo = m_cLayoutExInfoBot.DetachColorInfo(); } /* || カーソル位置変換 || レイアウト位置(行頭からの表示桁位置、折り返しあり行位置) → || 物理位置(行頭からのバイト数、折り返し無し行位置) */ CLogicPoint ptFrom; CLogicPoint ptTo; LayoutToLogic( pArg->sDelRange.GetFrom(), &ptFrom ); LayoutToLogic( pArg->sDelRange.GetTo(), &ptTo ); /* 指定範囲のデータを置換(削除 & データを挿入) Fromを含む位置からToの直前を含むデータを削除する Fromの位置へテキストを挿入する */ DocLineReplaceArg DLRArg; DLRArg.sDelRange.SetFrom(ptFrom); //削除範囲from DLRArg.sDelRange.SetTo(ptTo); //削除範囲to DLRArg.pcmemDeleted = pArg->pcmemDeleted; // 削除されたデータを保存 DLRArg.pInsData = pArg->pInsData; // 挿入するデータ DLRArg.nDelSeq = pArg->nDelSeq; CSearchAgent(m_pcDocLineMgr).ReplaceData( &DLRArg ); pArg->nInsSeq = DLRArg.nInsSeq; /*--- 変更された行のレイアウト情報を再生成 ---*/ /* 論理行の指定範囲に該当するレイアウト情報を削除して */ /* 削除した範囲の直前のレイアウト情報のポインタを返す */ CLayoutInt nModifyLayoutLinesOld = CLayoutInt(0); CLayout* pLayoutPrev; CLogicInt nWork; nWork = t_max( DLRArg.nDeletedLineNum, DLRArg.nInsLineNum ); if( pLayoutWork ){ pLayoutPrev = DeleteLayoutAsLogical( pLayoutWork, nLineWork, ptFrom.GetY2(), ptFrom.GetY2() + nWork, ptFrom, &nModifyLayoutLinesOld ); /* 指定行より後の行のレイアウト情報について、論理行番号を指定行数だけシフトする */ /* 論理行が削除された場合は0より小さい行数 */ /* 論理行が挿入された場合は0より大きい行数 */ if( 0 != DLRArg.nInsLineNum - DLRArg.nDeletedLineNum ){ ShiftLogicalLineNum( pLayoutPrev, DLRArg.nInsLineNum - DLRArg.nDeletedLineNum ); } }else{ pLayoutPrev = m_pLayoutBot; } /* 指定レイアウト行に対応する論理行の次の論理行から指定論理行数だけ再レイアウトする */ CLogicInt nRowNum; if( NULL == pLayoutPrev ){ if( NULL == m_pLayoutTop ){ nRowNum = m_pcDocLineMgr->GetLineCount(); }else{ nRowNum = m_pLayoutTop->GetLogicLineNo(); } } else{ if( NULL == pLayoutPrev->GetNextLayout() ){ nRowNum = m_pcDocLineMgr->GetLineCount() - pLayoutPrev->GetLogicLineNo() - CLogicInt(1); }else{ nRowNum = pLayoutPrev->m_pNext->GetLogicLineNo() - pLayoutPrev->GetLogicLineNo() - CLogicInt(1); } } // 2009.08.28 nasukoji テキスト最大幅算出用の引数を設定 CalTextWidthArg ctwArg; ctwArg.ptLayout = pArg->sDelRange.GetFrom(); // 編集開始位置 ctwArg.nDelLines = pArg->sDelRange.GetTo().GetY2() - pArg->sDelRange.GetFrom().GetY2(); // 削除行数 - 1 ctwArg.nAllLinesOld = nWork_nLines; // 編集前のテキスト行数 ctwArg.bInsData = (pArg->pInsData && pArg->pInsData->size()) ? TRUE : FALSE; // 追加文字列の有無 /* 指定レイアウト行に対応する論理行の次の論理行から指定論理行数だけ再レイアウトする */ CLayoutInt nAddInsLineNum; pArg->nModLineTo = DoLayout_Range( pLayoutPrev, nRowNum, ptFrom, nCurrentLineType, colorInfo, &ctwArg, &nAddInsLineNum ); pArg->nAddLineNum = m_nLines - nWork_nLines; //変更後の全行数との差分 @@@ 2002.04.19 MIK if( 0 == pArg->nAddLineNum ) pArg->nAddLineNum = nModifyLayoutLinesOld - pArg->nModLineTo; /* 再描画ヒント レイアウト行の増減 */ pArg->nModLineFrom = pArg->sDelRange.GetFrom().GetY2(); /* 再描画ヒント 変更されたレイアウト行From */ pArg->nModLineTo += ( pArg->nModLineFrom - CLayoutInt(1) ) ; /* 再描画ヒント 変更されたレイアウト行To */ //2007.10.18 kobake LayoutReplaceArg::ptLayoutNewはここで算出するのが正しい LogicToLayout(DLRArg.ptNewPos, &pArg->ptLayoutNew); // 挿入された部分の次の位置 }
void CEditView::DrawBackImage(HDC hdc, RECT& rcPaint, HDC hdcBgImg) { #if 0 // テスト背景パターン static int testColorIndex = 0; testColorIndex = testColorIndex % 7; COLORREF cols[7] = {RGB(255,255,255), RGB(200,255,255),RGB(255,200,255),RGB(255,255,200), RGB(200,200,255),RGB(255,200,200),RGB(200,255,200), }; COLORREF colorOld = ::SetBkColor(hdc, cols[testColorIndex]); MyFillRect(hdc, rcPaint); ::SetBkColor(hdc, colorOld); testColorIndex++; #else CTypeSupport cTextType(this,COLORIDX_TEXT); COLORREF colorOld = ::SetBkColor(hdc, cTextType.GetBackColor()); const CTextArea& area = GetTextArea(); const CEditDoc& doc = *m_pcEditDoc; const STypeConfig& typeConfig = doc.m_cDocType.GetDocumentAttribute(); CMyRect rcImagePos; switch( typeConfig.m_backImgPos ){ case BGIMAGE_TOP_LEFT: case BGIMAGE_BOTTOM_LEFT: case BGIMAGE_CENTER_LEFT: rcImagePos.left = area.GetAreaLeft(); break; case BGIMAGE_TOP_RIGHT: case BGIMAGE_BOTTOM_RIGHT: case BGIMAGE_CENTER_RIGHT: rcImagePos.left = area.GetAreaRight() - doc.m_nBackImgWidth; break; case BGIMAGE_TOP_CENTER: case BGIMAGE_BOTTOM_CENTER: case BGIMAGE_CENTER: rcImagePos.left = area.GetAreaLeft() + area.GetAreaWidth()/2 - doc.m_nBackImgWidth/2; break; default: assert_warning(0 != typeConfig.m_backImgPos); break; } switch( typeConfig.m_backImgPos ){ case BGIMAGE_TOP_LEFT: case BGIMAGE_TOP_RIGHT: case BGIMAGE_TOP_CENTER: rcImagePos.top = area.GetAreaTop(); break; case BGIMAGE_BOTTOM_LEFT: case BGIMAGE_BOTTOM_RIGHT: case BGIMAGE_BOTTOM_CENTER: rcImagePos.top = area.GetAreaBottom() - doc.m_nBackImgHeight; break; case BGIMAGE_CENTER_LEFT: case BGIMAGE_CENTER_RIGHT: case BGIMAGE_CENTER: rcImagePos.top = area.GetAreaTop() + area.GetAreaHeight()/2 - doc.m_nBackImgHeight/2; break; default: assert_warning(0 != typeConfig.m_backImgPos); break; } rcImagePos.left += typeConfig.m_backImgPosOffset.x; rcImagePos.top += typeConfig.m_backImgPosOffset.y; // スクロール時の画面の端を作画するときの位置あたりへ移動 if( typeConfig.m_backImgScrollX ){ int tile = typeConfig.m_backImgRepeatX ? doc.m_nBackImgWidth : INT_MAX; Int posX = (area.GetViewLeftCol() % tile) * GetTextMetrics().GetCharPxWidth(); rcImagePos.left -= posX % tile; } if( typeConfig.m_backImgScrollY ){ int tile = typeConfig.m_backImgRepeatY ? doc.m_nBackImgHeight : INT_MAX; Int posY = (area.GetViewTopLine() % tile) * GetTextMetrics().GetHankakuDy(); rcImagePos.top -= posY % tile; } if( typeConfig.m_backImgRepeatX ){ if( 0 < rcImagePos.left ){ // rcImagePos.left = rcImagePos.left - (rcImagePos.left / doc.m_nBackImgWidth + 1) * doc.m_nBackImgWidth; rcImagePos.left = rcImagePos.left % doc.m_nBackImgWidth - doc.m_nBackImgWidth; } } if( typeConfig.m_backImgRepeatY ){ if( 0 < rcImagePos.top ){ // rcImagePos.top = rcImagePos.top - (rcImagePos.top / doc.m_nBackImgHeight + 1) * doc.m_nBackImgHeight; rcImagePos.top = rcImagePos.top % doc.m_nBackImgHeight - doc.m_nBackImgHeight; } } rcImagePos.SetSize(doc.m_nBackImgWidth, doc.m_nBackImgHeight); RECT rc = rcPaint; // rc.left = t_max((int)rc.left, area.GetAreaLeft()); rc.top = t_max((int)rc.top, area.GetRulerHeight()); // ルーラーを除外 const int nXEnd = area.GetAreaRight(); const int nYEnd = area.GetAreaBottom(); CMyRect rcBltAll; rcBltAll.SetLTRB(INT_MAX, INT_MAX, -INT_MAX, -INT_MAX); CMyRect rcImagePosOrg = rcImagePos; for(; rcImagePos.top <= nYEnd; ){ for(; rcImagePos.left <= nXEnd; ){ CMyRect rcBlt; if( ::IntersectRect(&rcBlt, &rc, &rcImagePos) ){ ::BitBlt( hdc, rcBlt.left, rcBlt.top, rcBlt.right - rcBlt.left, rcBlt.bottom - rcBlt.top, hdcBgImg, rcBlt.left - rcImagePos.left, rcBlt.top - rcImagePos.top, SRCCOPY ); rcBltAll.left = t_min(rcBltAll.left, rcBlt.left); rcBltAll.top = t_min(rcBltAll.top, rcBlt.top); rcBltAll.right = t_max(rcBltAll.right, rcBlt.right); rcBltAll.bottom = t_max(rcBltAll.bottom, rcBlt.bottom); } rcImagePos.left += doc.m_nBackImgWidth; rcImagePos.right += doc.m_nBackImgWidth; if( !typeConfig.m_backImgRepeatX ){ break; } } rcImagePos.left = rcImagePosOrg.left; rcImagePos.right = rcImagePosOrg.right; rcImagePos.top += doc.m_nBackImgHeight; rcImagePos.bottom += doc.m_nBackImgHeight; if( !typeConfig.m_backImgRepeatY ){ break; } } if( rcBltAll.left != INT_MAX ){ // 上下左右ななめの隙間を埋める CMyRect rcFill; LONG& x1 = rc.left; LONG& x2 = rcBltAll.left; LONG& x3 = rcBltAll.right; LONG& x4 = rc.right; LONG& y1 = rc.top; LONG& y2 = rcBltAll.top; LONG& y3 = rcBltAll.bottom; LONG& y4 = rc.bottom; if( y1 < y2 ){ rcFill.SetLTRB(x1,y1, x4,y2); MyFillRect(hdc, rcFill); } if( x1 < x2 ){ rcFill.SetLTRB(x1,y2, x2,y3); MyFillRect(hdc, rcFill); } if( x3 < x4 ){ rcFill.SetLTRB(x3,y2, x4,y3); MyFillRect(hdc, rcFill); } if( y3 < y4 ){ rcFill.SetLTRB(x1,y3, x4,y4); MyFillRect(hdc, rcFill); } }else{ MyFillRect(hdc, rc); } ::SetBkColor(hdc, colorOld); #endif }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::TriMeshLoader loader; auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto cube(loader.create_geometry_from_file( "cube", "data/objects/cube.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE | gua::TriMeshLoader::MAKE_PICKABLE) ); graph.add_node("/transform", cube); scm::math::vec3d cube_translation(0.0, 0.0, -3.0); cube->set_draw_bounding_box(true); auto ray_geometry(loader.create_geometry_from_file( "ray_geometry", "data/objects/cylinder.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE) ); graph.add_node("/", ray_geometry); ray_geometry->scale(0.02, 0.02, 0.1); auto light2 = graph.add_node<gua::node::LightNode>("/", "light2"); light2->data.set_type(gua::node::LightNode::Type::POINT); light2->data.brightness = 150.0f; light2->scale(12.f); light2->translate(-3.f, 5.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window auto resolution = gua::math::vec2ui(1920, 1080); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("Picking Example"); camera->config.set_enable_stereo(false); camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure( 1.0f); camera->get_pipeline_description()->add_pass( std::make_shared<gua::DebugViewPassDescription>()); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("Picking Example", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size( gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect( [&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect( std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); scm::math::vec3d camera_positon(0.0, 0.0, 2.0); scm::math::vec3d negative_z_viewing_direction(0.0, 0.0, -100.0); scm::math::vec3d::value_type t_max(200.0); //create ray that is located in the origin of the current screen and looks along the negative z-axis (pick ray is seen as circle) gua::Ray ray_from_camera_position(camera_positon, negative_z_viewing_direction, t_max); size_t frame_count = 0; ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(cube_translation[0], cube_translation[1], cube_translation[2]) * scm::math::make_translation(trackball.shiftx(), trackball.shifty(), trackball.distance()) * gua::math::mat4(trackball.rotation()); transform->set_transform(modelmatrix); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { //std::set<gua::PickResult> pick_results; //cube->ray_test_impl(ray_from_camera_position, gua::PickResult::Options::PICK_ONLY_FIRST_FACE, gua::Mask(), pick_results); auto pick_results = graph.ray_test(ray_from_camera_position, gua::PickResult::Options::PICK_ONLY_FIRST_FACE | gua::PickResult::Options::GET_WORLD_POSITIONS); if(0 == (++frame_count) % 100) { if(pick_results.size()) { //print first picked face world position result std::cout << "World space intersection position: " << pick_results.begin()->world_position << "\n"; } } renderer.queue_draw({&graph}); } }); loop.start(); return 0; }