blob: 92e5bfc1dd7b4b86d2baedc3dcfa21872d11258d [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../../include/fxedit/fxet_stub.h"
#include "../../include/fxedit/fx_edit.h"
#include "../../include/fxedit/fxet_edit.h"
CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord)
{
ASSERT (pFontMap != NULL);
CFX_ByteString sWord;
if (CPDF_Font * pPDFFont = pFontMap->GetPDFFont(nFontIndex))
{
if (SubWord > 0)
{
Word = SubWord;
}
else
{
FX_DWORD dwCharCode = -1;
if (pPDFFont->IsUnicodeCompatible())
dwCharCode = pPDFFont->CharCodeFromUnicode(Word);
else
dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word);
if (dwCharCode > 0 )
{
pPDFFont->AppendChar(sWord, dwCharCode);
return sWord;
}
}
pPDFFont->AppendChar(sWord, Word);
}
return sWord;
}
static CFX_ByteString GetWordRenderString(const CFX_ByteString & strWords)
{
if (strWords.GetLength() > 0)
return PDF_EncodeString(strWords) + " Tj\n";
return "";
}
static CFX_ByteString GetFontSetString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_FLOAT fFontSize)
{
CFX_ByteTextBuf sRet;
if (pFontMap)
{
CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
if (sFontAlias.GetLength() > 0 && fFontSize > 0 )
sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
}
return sRet.GetByteString();
}
CFX_ByteString IFX_Edit::GetEditAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset,
const CPVT_WordRange * pRange /* = NULL*/, FX_BOOL bContinuous/* = TRUE*/, FX_WORD SubWord/* = 0*/)
{
CFX_ByteTextBuf sEditStream, sWords;
CPDF_Point ptOld(0.0f,0.0f),ptNew(0.0f,0.0f);
FX_INT32 nCurFontIndex = -1;
if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
{
if (pRange)
pIterator->SetAt(pRange->BeginPos);
else
pIterator->SetAt(0);
CPVT_WordPlace oldplace;
while (pIterator->NextWord())
{
CPVT_WordPlace place = pIterator->GetAt();
if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
if (bContinuous)
{
if (place.LineCmp(oldplace) != 0)
{
if (sWords.GetSize() > 0)
{
sEditStream << GetWordRenderString(sWords.GetByteString());
sWords.Clear();
}
CPVT_Word word;
if (pIterator->GetWord(word))
{
ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
}
else
{
CPVT_Line line;
pIterator->GetLine(line);
ptNew = CPDF_Point(line.ptLine.x + ptOffset.x, line.ptLine.y + ptOffset.y);
}
if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
{
sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
ptOld = ptNew;
}
}
CPVT_Word word;
if (pIterator->GetWord(word))
{
if (word.nFontIndex != nCurFontIndex)
{
if (sWords.GetSize() > 0)
{
sEditStream << GetWordRenderString(sWords.GetByteString());
sWords.Clear();
}
sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
nCurFontIndex = word.nFontIndex;
}
sWords << GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord);
}
oldplace = place;
}
else
{
CPVT_Word word;
if (pIterator->GetWord(word))
{
ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
{
sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
ptOld = ptNew;
}
if (word.nFontIndex != nCurFontIndex)
{
sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
nCurFontIndex = word.nFontIndex;
}
sEditStream << GetWordRenderString(GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord));
}
}
}
if (sWords.GetSize() > 0)
{
sEditStream << GetWordRenderString(sWords.GetByteString());
sWords.Clear();
}
}
CFX_ByteTextBuf sAppStream;
if (sEditStream.GetSize() > 0)
{
FX_INT32 nHorzScale = pEdit->GetHorzScale();
if (nHorzScale != 100)
{
sAppStream << nHorzScale << " Tz\n";
}
FX_FLOAT fCharSpace = pEdit->GetCharSpace();
if (!FX_EDIT_IsFloatZero(fCharSpace))
{
sAppStream << fCharSpace << " Tc\n";
}
sAppStream << sEditStream;
}
return sAppStream.GetByteString();
}
CFX_ByteString IFX_Edit::GetSelectAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset,
const CPVT_WordRange * pRange /*= NULL*/)
{
CFX_ByteTextBuf sRet;
if (pRange && pRange->IsExist())
{
if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
{
pIterator->SetAt(pRange->BeginPos);
while (pIterator->NextWord())
{
CPVT_WordPlace place = pIterator->GetAt();
if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
CPVT_Word word;
CPVT_Line line;
if (pIterator->GetWord(word) && pIterator->GetLine(line))
{
//CPDF_Rect rcWordSel = CPDF_Rect(word.ptWord.x,line.ptLine.y + line.fLineDescent,
// word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
sRet << word.ptWord.x + ptOffset.x << " " << line.ptLine.y + line.fLineDescent
<< " " << word.fWidth << " " << line.fLineAscent - line.fLineDescent << " re\nf\n";
}
}
}
}
return sRet.GetByteString();
}