예제 #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 프로젝트: MiKTeX/miktex
bool DviImpl::FindSource(const char* fileName, int line, DviPosition& position)
{
  CheckCondition();

  BEGIN_CRITICAL_SECTION(dviMutex)
  {
    trace_search->WriteFormattedLine("libdvi", T_("searching src special %d %s"), line, fileName);

    SourceSpecial* pSourceSpecial1Best = nullptr;
    SourceSpecial* pSourceSpecial2Best = nullptr;

    int pageIdx1 = -1;
    int pageIdx2 = -1;

    // get fully qualified path to the directory location of the
    // document
    PathName documentLocation(fqDviFileName);
    documentLocation.RemoveFileSpec();

    // file name relative to the location of the DVI document
    const char* lpszRelFileName;

    // absolute file name
    PathName fqFileName;

    if (Utils::IsAbsolutePath(fileName))
    {
      lpszRelFileName = Utils::GetRelativizedPath(fileName, documentLocation.GetData());
      fqFileName = fileName;
      fqFileName.MakeAbsolute();
    }
    else
    {
      lpszRelFileName = fileName;
      fqFileName = documentLocation;
      fqFileName /= fileName;
      fqFileName.MakeAbsolute();
    }

    //
    // scan the document
    //

    for (int pageIdx = 0; pageIdx < GetNumberOfPages(); ++pageIdx)
    {
      DviPageImpl* dviPage;

      try
      {
        dviPage = reinterpret_cast<DviPageImpl*>(GetLoadedPage(pageIdx));
      }
      catch (const OperationCancelledException&)
      {
        return false;
      }

      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;

      SourceSpecial* pSourceSpecial;

      for (int j = -1; (pSourceSpecial = dviPage->GetNextSpecial<SourceSpecial>(j)) != nullptr; )
      {
        const char* name = pSourceSpecial->GetFileName();

        // try exact match
        bool nameMatch = (MyPathNameCompare(name, fileName) == 0);

        // try fully qualified file names
        if (!nameMatch)
        {
          PathName fqName;
          if (Utils::IsAbsolutePath(name))
          {
            fqName = name;
            fqName.MakeAbsolute();
          }
          else
          {
            fqName = documentLocation;
            fqName /= name;
            fqName.MakeAbsolute();
          }
          nameMatch = (MyPathNameCompare(fqName, fqFileName) == 0);
        }

        // try relative file names
        if (!nameMatch && lpszRelFileName != nullptr)
        {
          const char* lpszRelName;
          if (!Utils::IsAbsolutePath(name))
          {
            lpszRelName = name;
          }
          else
          {
            lpszRelName = Utils::GetRelativizedPath(name, documentLocation.GetData());
          }
          nameMatch = lpszRelName != nullptr && MyPathNameCompare(lpszRelName, lpszRelFileName) == 0;
        }

        if (!nameMatch)
        {
          continue;
        }

        if (line >= pSourceSpecial->GetLineNum())
        {
          if (pSourceSpecial1 == nullptr || (pSourceSpecial->GetLineNum() > pSourceSpecial1->GetLineNum()))
          {
            pSourceSpecial1 = pSourceSpecial;
          }
        }

        if (line <= pSourceSpecial->GetLineNum())
        {
          if (pSourceSpecial2 == nullptr || (pSourceSpecial->GetLineNum() < pSourceSpecial2->GetLineNum()))
          {
            pSourceSpecial2 = pSourceSpecial;
          }
        }
      }

      if (pSourceSpecial1 != nullptr && pSourceSpecial2 != nullptr)
      {
        pSourceSpecial1Best = pSourceSpecial1;
        pageIdx1 = pageIdx;
        pSourceSpecial2Best = pSourceSpecial2;
        pageIdx2 = pageIdx;
        break;
      }
      else if (pSourceSpecial1 != nullptr
        && (pSourceSpecial1Best == nullptr || (abs(pSourceSpecial1Best->GetLineNum() - line) > abs(pSourceSpecial1->GetLineNum() - line))))
      {
        pSourceSpecial1Best = pSourceSpecial1;
        pageIdx1 = pageIdx;
        pSourceSpecial2Best = nullptr;
        pageIdx2 = -1;
      }
      else if (pSourceSpecial2 != nullptr && (pSourceSpecial2Best == nullptr || (abs(pSourceSpecial2Best->GetLineNum() - line) > abs(pSourceSpecial2->GetLineNum() - line))))
      {
        pSourceSpecial2Best = pSourceSpecial2;
        pageIdx2 = pageIdx;
        pSourceSpecial1Best = nullptr;
        pageIdx1 = -1;
      }
    }

    //
    // evaluate the results
    //

    if (pSourceSpecial1Best == nullptr && pSourceSpecial2Best == nullptr)
    {
      trace_search->WriteLine("libdvi", T_("search failed"));
      return false;
    }

    if (pSourceSpecial1Best == nullptr)
    {
      trace_search->WriteFormattedLine("libdvi", T_("found src2 on page #%d"), pageIdx2);
      trace_search->WriteFormattedLine("libdvi", "   src2 = [%d (%d,%d)]", pSourceSpecial2Best->GetLineNum(), pSourceSpecial2Best->GetX(), pSourceSpecial2Best->GetY());
      position.pageIdx = pageIdx2;
      position.x = pSourceSpecial2Best->GetX();
      position.y = pSourceSpecial2Best->GetY();
    }
    else if (pSourceSpecial2Best == nullptr)
    {
      trace_search->WriteFormattedLine("libdvi", T_("found src1 on page #%d"), pageIdx1);
      trace_search->WriteFormattedLine("libdvi", "   src1 = [%d (%d,%d)]", pSourceSpecial1Best->GetLineNum(), pSourceSpecial1Best->GetX(), pSourceSpecial1Best->GetY());
      position.pageIdx = pageIdx1;
      position.x = pSourceSpecial1Best->GetX();
      position.y = pSourceSpecial1Best->GetY();
    }
    else
    {
      position.pageIdx = pageIdx1;
      trace_search->WriteFormattedLine("libdvi", T_("found src region on page #%d"), position.pageIdx);
      trace_search->WriteFormattedLine("libdvi", "   src1 = [%d (%d,%d)]", pSourceSpecial1Best->GetLineNum(), pSourceSpecial1Best->GetX(), pSourceSpecial1Best->GetY());
      trace_search->WriteFormattedLine("libdvi", "   src2 = [%d (%d,%d)]", pSourceSpecial2Best->GetLineNum(), pSourceSpecial2Best->GetX(), pSourceSpecial2Best->GetY());
      position.x = pSourceSpecial1Best->GetX();
      if (pSourceSpecial2Best->GetLineNum() == pSourceSpecial1Best->GetLineNum())
      {
        position.y = pSourceSpecial1Best->GetY();
      }
      else
      {
        position.y = (pSourceSpecial1Best->GetY()
          + ((line - pSourceSpecial1Best->GetLineNum())
            * (pSourceSpecial2Best->GetY()
              - pSourceSpecial1Best->GetY())
            / (pSourceSpecial2Best->GetLineNum()
              - pSourceSpecial1Best->GetLineNum())));
      }
      trace_search->WriteFormattedLine("libdvi", "   interpolated (x,y) = (%d,%d)", position.x, position.y);
    }

    return true;
  }
  END_CRITICAL_SECTION();
}
예제 #3
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();
}