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