FX Bool considered harmful, part 3
[pdfium.git] / fpdfsdk / src / fxedit / fxet_ap.cpp
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, int32_t 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, int32_t 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*/, 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         int32_t 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                 int32_t 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