예제 #1
0
파일: src.cpp 프로젝트: MiKTeX/miktex
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();
}
예제 #2
0
파일: src.cpp 프로젝트: bngabonziza/miktex
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();
}