bool DviImpl::GetSource(const DviPosition& pos, PathName& fileName, int* pLineNum) { CheckCondition(); BEGIN_CRITICAL_SECTION(dviMutex) { if (pos.pageIdx >= GetNumberOfPages()) { return false; } DviPageImpl* dviPage = reinterpret_cast<DviPageImpl*>(GetLoadedPage(pos.pageIdx)); if (dviPage == nullptr) { throw DviPageNotFoundException("", T_("The DVI page could not be found."), MiKTeXException::KVMAP(), MIKTEX_SOURCE_LOCATION()); } AutoUnlockPage autoUnlockPage(dviPage); SourceSpecial* pSourceSpecial1 = nullptr; SourceSpecial* pSourceSpecial2 = nullptr; int cursorOffset = OFFSET(pos.x, pos.y); int src1Offset = 0; int src2Offset = 0; SourceSpecial* pSourceSpecial; // find two adjacent src specials for (int j = -1; (pSourceSpecial = dviPage->GetNextSpecial<SourceSpecial>(j)) != nullptr; ) { int srcOffset = OFFSET(pSourceSpecial->GetX(), pSourceSpecial->GetY()); if (cursorOffset > srcOffset) { if (pSourceSpecial1 == nullptr || srcOffset > src1Offset) { pSourceSpecial1 = pSourceSpecial; src1Offset = srcOffset; } } else if (cursorOffset < srcOffset) { if (pSourceSpecial2 == nullptr || srcOffset < src2Offset) { pSourceSpecial2 = pSourceSpecial; src2Offset = srcOffset; } } } if (pSourceSpecial1 == nullptr && pSourceSpecial2 == nullptr) { return false; } int lineDelta = 0; if (pSourceSpecial1 == nullptr) { pSourceSpecial = pSourceSpecial2; } else if (pSourceSpecial2 == nullptr) { pSourceSpecial = pSourceSpecial1; } else if (MyPathNameCompare(pSourceSpecial1->GetFileName(), pSourceSpecial2->GetFileName()) != 0) { if (cursorOffset - src1Offset < src2Offset - cursorOffset) { pSourceSpecial = pSourceSpecial1; } else { pSourceSpecial = pSourceSpecial2; } } else { int d = src2Offset - src1Offset; if (d != 0) { int d1 = cursorOffset - src1Offset; int linesbetween = (pSourceSpecial2->GetLineNum() - pSourceSpecial1->GetLineNum() + 1); lineDelta = (d1 * linesbetween) / d; } pSourceSpecial = pSourceSpecial1; } fileName = pSourceSpecial->GetFileName(); if (pLineNum != nullptr) { *pLineNum = pSourceSpecial->GetLineNum() + lineDelta; } return true; } END_CRITICAL_SECTION(); }
bool DviImpl::GetSource (/*[in]*/ const DviPosition & pos, /*[out]*/ PathName & fileName, /*[out]*/ int * pLineNum) { CheckCondition (); MIKTEX_BEGIN_CRITICAL_SECTION (&criticalSectionMonitor) { if (pos.pageIdx >= GetNumberOfPages()) { return (false); } DviPageImpl * pPage = reinterpret_cast<DviPageImpl*>(GetLoadedPage(pos.pageIdx)); if (pPage == 0) { throw DviPageNotFoundException (0, T_("The DVI page could not be found."), 0, __FILE__, __LINE__); } AutoUnlockPage autoUnlockPage (pPage); SourceSpecial * pSourceSpecial1 = 0; SourceSpecial * pSourceSpecial2 = 0; int cursorOffset = OFFSET(pos.x, pos.y); int src1Offset = 0; int src2Offset = 0; SourceSpecial * pSourceSpecial; // find two adjacent src specials for (int j = -1; (pSourceSpecial = pPage->GetNextSpecial<SourceSpecial>(j)) != 0; ) { int srcOffset = OFFSET(pSourceSpecial->GetX(), pSourceSpecial->GetY()); if (cursorOffset > srcOffset) { if (pSourceSpecial1 == 0 || srcOffset > src1Offset) { pSourceSpecial1 = pSourceSpecial; src1Offset = srcOffset; } } else if (cursorOffset < srcOffset) { if (pSourceSpecial2 == 0 || srcOffset < src2Offset) { pSourceSpecial2 = pSourceSpecial; src2Offset = srcOffset; } } } if (pSourceSpecial1 == 0 && pSourceSpecial2 == 0) { return (false); } int lineDelta = 0; if (pSourceSpecial1 == 0) { pSourceSpecial = pSourceSpecial2; } else if (pSourceSpecial2 == 0) { pSourceSpecial = pSourceSpecial1; } else if (MyPathNameCompare(pSourceSpecial1->GetFileName(), pSourceSpecial2->GetFileName()) != 0) { if (cursorOffset - src1Offset < src2Offset - cursorOffset) { pSourceSpecial = pSourceSpecial1; } else { pSourceSpecial = pSourceSpecial2; } } else { int d = src2Offset - src1Offset; if (d != 0) { int d1 = cursorOffset - src1Offset; int linesbetween = (pSourceSpecial2->GetLineNum() - pSourceSpecial1->GetLineNum() + 1); lineDelta = (d1 * linesbetween) / d; } pSourceSpecial = pSourceSpecial1; } fileName = pSourceSpecial->GetFileName(); if (pLineNum != 0) { *pLineNum = pSourceSpecial->GetLineNum() + lineDelta; } return (true); } MIKTEX_END_CRITICAL_SECTION(); }