• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetPDFWordString(IFX_Edit_FontMap * pFontMap,FX_INT32 nFontIndex,FX_WORD Word,FX_WORD SubWord)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 
GetWordRenderString(const CFX_ByteString & strWords)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 
GetFontSetString(IFX_Edit_FontMap * pFontMap,FX_INT32 nFontIndex,FX_FLOAT fFontSize)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 
GetEditAppearanceStream(IFX_Edit * pEdit,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange,FX_BOOL bContinuous,FX_WORD SubWord)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 
GetSelectAppearanceStream(IFX_Edit * pEdit,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange)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