Home | History | Annotate | Download | only in fxedit
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../include/fxedit/fxet_stub.h"
      8 #include "../../include/fxedit/fx_edit.h"
      9 #include "../../include/fxedit/fxet_edit.h"
     10 
     11 CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord)
     12 {
     13 	ASSERT (pFontMap != NULL);
     14 
     15 	CFX_ByteString sWord;
     16 
     17 	if (CPDF_Font * pPDFFont = pFontMap->GetPDFFont(nFontIndex))
     18 	{
     19 		if (SubWord > 0)
     20 		{
     21 			Word = SubWord;
     22 		}
     23 		else
     24 		{
     25 			FX_DWORD dwCharCode = -1;
     26 
     27 			if (pPDFFont->IsUnicodeCompatible())
     28 				dwCharCode = pPDFFont->CharCodeFromUnicode(Word);
     29 			else
     30 				dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word);
     31 
     32 			if (dwCharCode > 0 )
     33 			{
     34 				pPDFFont->AppendChar(sWord, dwCharCode);
     35 				return sWord;
     36 			}
     37 		}
     38 
     39 		pPDFFont->AppendChar(sWord, Word);
     40 	}
     41 
     42 	return sWord;
     43 }
     44 
     45 static CFX_ByteString GetWordRenderString(const CFX_ByteString & strWords)
     46 {
     47 	if (strWords.GetLength() > 0)
     48 		return PDF_EncodeString(strWords) + " Tj\n";
     49 
     50 	return "";
     51 }
     52 
     53 static CFX_ByteString GetFontSetString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_FLOAT fFontSize)
     54 {
     55 	CFX_ByteTextBuf sRet;
     56 
     57 	if (pFontMap)
     58 	{
     59 		CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
     60 
     61 		if (sFontAlias.GetLength() > 0 && fFontSize > 0 )
     62 			sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
     63 	}
     64 
     65 	return sRet.GetByteString();
     66 }
     67 
     68 CFX_ByteString IFX_Edit::GetEditAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset,
     69 												 const CPVT_WordRange * pRange /* = NULL*/, FX_BOOL bContinuous/* = TRUE*/, FX_WORD SubWord/* = 0*/)
     70 {
     71 	CFX_ByteTextBuf sEditStream, sWords;
     72 
     73 	CPDF_Point ptOld(0.0f,0.0f),ptNew(0.0f,0.0f);
     74 	FX_INT32 nCurFontIndex = -1;
     75 
     76 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
     77 	{
     78 		if (pRange)
     79 			pIterator->SetAt(pRange->BeginPos);
     80 		else
     81 			pIterator->SetAt(0);
     82 
     83 		CPVT_WordPlace oldplace;
     84 
     85 		while (pIterator->NextWord())
     86 		{
     87 			CPVT_WordPlace place = pIterator->GetAt();
     88 
     89 			if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
     90 
     91 			if (bContinuous)
     92 			{
     93 				if (place.LineCmp(oldplace) != 0)
     94 				{
     95 					if (sWords.GetSize() > 0)
     96 					{
     97 						sEditStream << GetWordRenderString(sWords.GetByteString());
     98 						sWords.Clear();
     99 					}
    100 
    101 					CPVT_Word word;
    102 					if (pIterator->GetWord(word))
    103 					{
    104 						ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
    105 					}
    106 					else
    107 					{
    108 						CPVT_Line line;
    109 						pIterator->GetLine(line);
    110 						ptNew = CPDF_Point(line.ptLine.x + ptOffset.x, line.ptLine.y + ptOffset.y);
    111 					}
    112 
    113 					if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
    114 					{
    115 						sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
    116 
    117 						ptOld = ptNew;
    118 					}
    119 				}
    120 
    121 				CPVT_Word word;
    122 				if (pIterator->GetWord(word))
    123 				{
    124 					if (word.nFontIndex != nCurFontIndex)
    125 					{
    126 						if (sWords.GetSize() > 0)
    127 						{
    128 							sEditStream << GetWordRenderString(sWords.GetByteString());
    129 							sWords.Clear();
    130 						}
    131 						sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
    132 						nCurFontIndex = word.nFontIndex;
    133 					}
    134 
    135 					sWords << GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord);
    136 				}
    137 
    138 				oldplace = place;
    139 			}
    140 			else
    141 			{
    142 				CPVT_Word word;
    143 				if (pIterator->GetWord(word))
    144 				{
    145 					ptNew = CPDF_Point(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
    146 
    147 					if (ptNew.x != ptOld.x || ptNew.y != ptOld.y)
    148 					{
    149 						sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n";
    150 						ptOld = ptNew;
    151 					}
    152 
    153 					if (word.nFontIndex != nCurFontIndex)
    154 					{
    155 						sEditStream << GetFontSetString(pEdit->GetFontMap(),word.nFontIndex,word.fFontSize);
    156 						nCurFontIndex = word.nFontIndex;
    157 					}
    158 
    159 					sEditStream << GetWordRenderString(GetPDFWordString(pEdit->GetFontMap(),nCurFontIndex,word.Word,SubWord));
    160 				}
    161 			}
    162 		}
    163 
    164 		if (sWords.GetSize() > 0)
    165 		{
    166 			sEditStream << GetWordRenderString(sWords.GetByteString());
    167 			sWords.Clear();
    168 		}
    169 	}
    170 
    171 	CFX_ByteTextBuf sAppStream;
    172 	if (sEditStream.GetSize() > 0)
    173 	{
    174 		FX_INT32 nHorzScale = pEdit->GetHorzScale();
    175 		if (nHorzScale != 100)
    176 		{
    177 			sAppStream << nHorzScale << " Tz\n";
    178 		}
    179 
    180 		FX_FLOAT fCharSpace = pEdit->GetCharSpace();
    181 		if (!FX_EDIT_IsFloatZero(fCharSpace))
    182 		{
    183 			sAppStream << fCharSpace << " Tc\n";
    184 		}
    185 
    186 		sAppStream << sEditStream;
    187 	}
    188 
    189 	return sAppStream.GetByteString();
    190 }
    191 
    192 CFX_ByteString IFX_Edit::GetSelectAppearanceStream(IFX_Edit* pEdit, const CPDF_Point & ptOffset,
    193 							const CPVT_WordRange * pRange /*= NULL*/)
    194 {
    195 	CFX_ByteTextBuf sRet;
    196 
    197 	if (pRange && pRange->IsExist())
    198 	{
    199 		if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
    200 		{
    201 			pIterator->SetAt(pRange->BeginPos);
    202 
    203 			while (pIterator->NextWord())
    204 			{
    205 				CPVT_WordPlace place = pIterator->GetAt();
    206 
    207 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
    208 
    209 				CPVT_Word word;
    210 				CPVT_Line line;
    211 				if (pIterator->GetWord(word) && pIterator->GetLine(line))
    212 				{
    213 					//CPDF_Rect rcWordSel = CPDF_Rect(word.ptWord.x,line.ptLine.y + line.fLineDescent,
    214 					//		word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
    215 
    216 					sRet << word.ptWord.x + ptOffset.x << " " << line.ptLine.y + line.fLineDescent
    217 						<< " " << word.fWidth << " " << line.fLineAscent - line.fLineDescent << " re\nf\n";
    218 				}
    219 			}
    220 		}
    221 	}
    222 
    223 	return sRet.GetByteString();
    224 }
    225 
    226