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