| OLD | NEW |
| (Empty) |
| 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 "core/include/fpdfapi/fpdf_parser_decode.h" | |
| 8 #include "core/include/fpdfapi/fpdf_resource.h" | |
| 9 #include "fpdfsdk/include/fxedit/fx_edit.h" | |
| 10 #include "fpdfsdk/include/fxedit/fxet_edit.h" | |
| 11 | |
| 12 CFX_ByteString GetPDFWordString(IFX_Edit_FontMap* pFontMap, | |
| 13 int32_t nFontIndex, | |
| 14 FX_WORD Word, | |
| 15 FX_WORD SubWord) { | |
| 16 CFX_ByteString sWord; | |
| 17 if (CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex)) { | |
| 18 if (SubWord > 0) { | |
| 19 Word = SubWord; | |
| 20 } else { | |
| 21 FX_DWORD dwCharCode = -1; | |
| 22 | |
| 23 if (pPDFFont->IsUnicodeCompatible()) | |
| 24 dwCharCode = pPDFFont->CharCodeFromUnicode(Word); | |
| 25 else | |
| 26 dwCharCode = pFontMap->CharCodeFromUnicode(nFontIndex, Word); | |
| 27 | |
| 28 if (dwCharCode > 0) { | |
| 29 pPDFFont->AppendChar(sWord, dwCharCode); | |
| 30 return sWord; | |
| 31 } | |
| 32 } | |
| 33 | |
| 34 pPDFFont->AppendChar(sWord, Word); | |
| 35 } | |
| 36 | |
| 37 return sWord; | |
| 38 } | |
| 39 | |
| 40 static CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) { | |
| 41 if (strWords.GetLength() > 0) | |
| 42 return PDF_EncodeString(strWords) + " Tj\n"; | |
| 43 | |
| 44 return ""; | |
| 45 } | |
| 46 | |
| 47 static CFX_ByteString GetFontSetString(IFX_Edit_FontMap* pFontMap, | |
| 48 int32_t nFontIndex, | |
| 49 FX_FLOAT fFontSize) { | |
| 50 CFX_ByteTextBuf sRet; | |
| 51 | |
| 52 if (pFontMap) { | |
| 53 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex); | |
| 54 | |
| 55 if (sFontAlias.GetLength() > 0 && fFontSize > 0) | |
| 56 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n"; | |
| 57 } | |
| 58 | |
| 59 return sRet.GetByteString(); | |
| 60 } | |
| 61 | |
| 62 CFX_ByteString IFX_Edit::GetEditAppearanceStream( | |
| 63 IFX_Edit* pEdit, | |
| 64 const CFX_FloatPoint& ptOffset, | |
| 65 const CPVT_WordRange* pRange /* = NULL*/, | |
| 66 FX_BOOL bContinuous /* = TRUE*/, | |
| 67 FX_WORD SubWord /* = 0*/) { | |
| 68 CFX_ByteTextBuf sEditStream, sWords; | |
| 69 | |
| 70 CFX_FloatPoint ptOld(0.0f, 0.0f), ptNew(0.0f, 0.0f); | |
| 71 int32_t nCurFontIndex = -1; | |
| 72 | |
| 73 if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) { | |
| 74 if (pRange) | |
| 75 pIterator->SetAt(pRange->BeginPos); | |
| 76 else | |
| 77 pIterator->SetAt(0); | |
| 78 | |
| 79 CPVT_WordPlace oldplace; | |
| 80 | |
| 81 while (pIterator->NextWord()) { | |
| 82 CPVT_WordPlace place = pIterator->GetAt(); | |
| 83 | |
| 84 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
| 85 break; | |
| 86 | |
| 87 if (bContinuous) { | |
| 88 if (place.LineCmp(oldplace) != 0) { | |
| 89 if (sWords.GetSize() > 0) { | |
| 90 sEditStream << GetWordRenderString(sWords.GetByteString()); | |
| 91 sWords.Clear(); | |
| 92 } | |
| 93 | |
| 94 CPVT_Word word; | |
| 95 if (pIterator->GetWord(word)) { | |
| 96 ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x, | |
| 97 word.ptWord.y + ptOffset.y); | |
| 98 } else { | |
| 99 CPVT_Line line; | |
| 100 pIterator->GetLine(line); | |
| 101 ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x, | |
| 102 line.ptLine.y + ptOffset.y); | |
| 103 } | |
| 104 | |
| 105 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) { | |
| 106 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y | |
| 107 << " Td\n"; | |
| 108 | |
| 109 ptOld = ptNew; | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 CPVT_Word word; | |
| 114 if (pIterator->GetWord(word)) { | |
| 115 if (word.nFontIndex != nCurFontIndex) { | |
| 116 if (sWords.GetSize() > 0) { | |
| 117 sEditStream << GetWordRenderString(sWords.GetByteString()); | |
| 118 sWords.Clear(); | |
| 119 } | |
| 120 sEditStream << GetFontSetString(pEdit->GetFontMap(), | |
| 121 word.nFontIndex, word.fFontSize); | |
| 122 nCurFontIndex = word.nFontIndex; | |
| 123 } | |
| 124 | |
| 125 sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex, | |
| 126 word.Word, SubWord); | |
| 127 } | |
| 128 | |
| 129 oldplace = place; | |
| 130 } else { | |
| 131 CPVT_Word word; | |
| 132 if (pIterator->GetWord(word)) { | |
| 133 ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x, | |
| 134 word.ptWord.y + ptOffset.y); | |
| 135 | |
| 136 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) { | |
| 137 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y | |
| 138 << " Td\n"; | |
| 139 ptOld = ptNew; | |
| 140 } | |
| 141 | |
| 142 if (word.nFontIndex != nCurFontIndex) { | |
| 143 sEditStream << GetFontSetString(pEdit->GetFontMap(), | |
| 144 word.nFontIndex, word.fFontSize); | |
| 145 nCurFontIndex = word.nFontIndex; | |
| 146 } | |
| 147 | |
| 148 sEditStream << GetWordRenderString(GetPDFWordString( | |
| 149 pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord)); | |
| 150 } | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 if (sWords.GetSize() > 0) { | |
| 155 sEditStream << GetWordRenderString(sWords.GetByteString()); | |
| 156 sWords.Clear(); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 CFX_ByteTextBuf sAppStream; | |
| 161 if (sEditStream.GetSize() > 0) { | |
| 162 int32_t nHorzScale = pEdit->GetHorzScale(); | |
| 163 if (nHorzScale != 100) { | |
| 164 sAppStream << nHorzScale << " Tz\n"; | |
| 165 } | |
| 166 | |
| 167 FX_FLOAT fCharSpace = pEdit->GetCharSpace(); | |
| 168 if (!FX_EDIT_IsFloatZero(fCharSpace)) { | |
| 169 sAppStream << fCharSpace << " Tc\n"; | |
| 170 } | |
| 171 | |
| 172 sAppStream << sEditStream; | |
| 173 } | |
| 174 | |
| 175 return sAppStream.GetByteString(); | |
| 176 } | |
| 177 | |
| 178 CFX_ByteString IFX_Edit::GetSelectAppearanceStream( | |
| 179 IFX_Edit* pEdit, | |
| 180 const CFX_FloatPoint& ptOffset, | |
| 181 const CPVT_WordRange* pRange) { | |
| 182 CFX_ByteTextBuf sRet; | |
| 183 | |
| 184 if (pRange && pRange->IsExist()) { | |
| 185 if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) { | |
| 186 pIterator->SetAt(pRange->BeginPos); | |
| 187 | |
| 188 while (pIterator->NextWord()) { | |
| 189 CPVT_WordPlace place = pIterator->GetAt(); | |
| 190 | |
| 191 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
| 192 break; | |
| 193 | |
| 194 CPVT_Word word; | |
| 195 CPVT_Line line; | |
| 196 if (pIterator->GetWord(word) && pIterator->GetLine(line)) { | |
| 197 sRet << word.ptWord.x + ptOffset.x << " " | |
| 198 << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " " | |
| 199 << line.fLineAscent - line.fLineDescent << " re\nf\n"; | |
| 200 } | |
| 201 } | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 return sRet.GetByteString(); | |
| 206 } | |
| OLD | NEW |