// 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(); | |
} | |