Initial commit.
[pdfium.git] / fpdfsdk / src / fxedit / fxet_pageobjs.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 #define FX_EDIT_UNDERLINEHALFWIDTH                              0.5f\r
12 #define FX_EDIT_CROSSOUTHALFWIDTH                               0.5f\r
13 \r
14 extern CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord);\r
15 \r
16 CPDF_Rect GetUnderLineRect(const CPVT_Word& word)\r
17 {\r
18         return CPDF_Rect(word.ptWord.x, word.ptWord.y + word.fDescent * 0.5f,\r
19                                                 word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent * 0.25f);\r
20 }\r
21 \r
22 CPDF_Rect GetCrossoutRect(const CPVT_Word& word)\r
23 {\r
24         return CPDF_Rect(word.ptWord.x, word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f + word.fDescent * 0.25f,\r
25                                                         word.ptWord.x + word.fWidth, word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f);\r
26 }\r
27 \r
28 static void DrawTextString(CFX_RenderDevice* pDevice, const CPDF_Point& pt, CPDF_Font* pFont, FX_FLOAT fFontSize, CPDF_Matrix* pUser2Device,\r
29                                           const CFX_ByteString& str, FX_ARGB crTextFill, FX_ARGB crTextStroke, FX_INT32 nHorzScale)\r
30 {\r
31         FX_FLOAT x = pt.x, y = pt.y;\r
32         pUser2Device->Transform(x, y);\r
33 \r
34         if (pFont)\r
35         {\r
36                 if (nHorzScale != 100)\r
37                 {\r
38                         CPDF_Matrix mt(nHorzScale/100.0f,0,0,1,0,0);\r
39                         mt.Concat(*pUser2Device);\r
40 \r
41                         CPDF_RenderOptions ro;\r
42                         ro.m_Flags = RENDER_CLEARTYPE;\r
43                         ro.m_ColorMode = RENDER_COLOR_NORMAL;\r
44 \r
45                         if (crTextStroke != 0)\r
46                         {\r
47                                 CPDF_Point pt1(0,0), pt2(1,0);\r
48                                 pUser2Device->Transform(pt1.x, pt1.y);\r
49                                 pUser2Device->Transform(pt2.x, pt2.y);\r
50                                 CFX_GraphStateData gsd;\r
51                                 gsd.m_LineWidth = (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));\r
52 \r
53                                 CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, &mt, str, crTextFill, crTextStroke, &gsd, &ro);\r
54                         }\r
55                         else\r
56                                 CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, &mt, str, crTextFill, 0, NULL, &ro);\r
57                 }\r
58                 else\r
59                 {\r
60                         CPDF_RenderOptions ro;\r
61                         ro.m_Flags = RENDER_CLEARTYPE;\r
62                         ro.m_ColorMode = RENDER_COLOR_NORMAL;\r
63 \r
64                         if (crTextStroke != 0)\r
65                         {\r
66                                 CPDF_Point pt1(0,0), pt2(1,0);\r
67                                 pUser2Device->Transform(pt1.x, pt1.y);\r
68                                 pUser2Device->Transform(pt2.x, pt2.y);\r
69                                 CFX_GraphStateData gsd;\r
70                                 gsd.m_LineWidth = (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));\r
71 \r
72                                 CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, pUser2Device, str, crTextFill, crTextStroke, &gsd, &ro);\r
73                         }\r
74                         else\r
75                                 CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, pUser2Device, str, crTextFill, 0, NULL, &ro);\r
76                 }\r
77         }\r
78 }\r
79 \r
80 void IFX_Edit::DrawUnderline(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit, FX_COLORREF color,\r
81                                                                 const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange)\r
82 {\r
83         pDevice->SaveState();\r
84 \r
85         if (!rcClip.IsEmpty())\r
86         {\r
87                 CPDF_Rect rcTemp = rcClip;\r
88                 pUser2Device->TransformRect(rcTemp);\r
89                 FX_RECT rcDevClip;\r
90                 rcDevClip.left = (FX_INT32)rcTemp.left;\r
91                 rcDevClip.right = (FX_INT32)rcTemp.right;\r
92                 rcDevClip.top = (FX_INT32)rcTemp.top;\r
93                 rcDevClip.bottom = (FX_INT32)rcTemp.bottom;\r
94                 pDevice->SetClip_Rect(&rcDevClip);\r
95         }\r
96 \r
97         if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
98         {\r
99                 if (pEdit->GetFontMap())\r
100                 {\r
101                         if (pRange)\r
102                                 pIterator->SetAt(pRange->BeginPos);\r
103                         else\r
104                                 pIterator->SetAt(0);\r
105 \r
106                         while (pIterator->NextWord())\r
107                         {\r
108                                 CPVT_WordPlace place = pIterator->GetAt();\r
109                                 if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
110 \r
111                                 CPVT_Word word;                         \r
112                                 if (pIterator->GetWord(word))\r
113                                 {\r
114                                         CFX_PathData pathUnderline;\r
115                                         CPDF_Rect rcUnderline = GetUnderLineRect(word);\r
116                                         rcUnderline.left += ptOffset.x;\r
117                                         rcUnderline.right += ptOffset.x;\r
118                                         rcUnderline.top += ptOffset.y;\r
119                                         rcUnderline.bottom += ptOffset.y;\r
120                                         pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, rcUnderline.right, rcUnderline.top);\r
121 \r
122                                         pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, color, 0, FXFILL_WINDING);\r
123                                 }\r
124                         }                       \r
125                 }\r
126         }\r
127         \r
128         pDevice->RestoreState();\r
129 }\r
130 \r
131 void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit, FX_COLORREF crTextFill, FX_COLORREF crTextStroke, \r
132                                                 const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, IFX_SystemHandler* pSystemHandler, void* pFFLData)\r
133 {\r
134         \r
135         FX_BOOL bContinuous = pEdit->GetCharArray() == 0;\r
136         if (pEdit->GetCharSpace() > 0.0f)\r
137                 bContinuous = FALSE;\r
138 \r
139         FX_WORD SubWord = pEdit->GetPasswordChar();\r
140         FX_FLOAT fFontSize = pEdit->GetFontSize();\r
141         CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();\r
142         FX_INT32 nHorzScale = pEdit->GetHorzScale();\r
143 \r
144         FX_COLORREF crCurFill = crTextFill;\r
145         FX_COLORREF crOldFill = crCurFill;\r
146 \r
147         FX_BOOL bSelect = FALSE;\r
148         const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);\r
149         const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);\r
150 \r
151         CFX_ByteTextBuf sTextBuf;\r
152         FX_INT32 nFontIndex = -1;\r
153         CPDF_Point ptBT(0.0f,0.0f);\r
154 \r
155         pDevice->SaveState();\r
156 \r
157         if (!rcClip.IsEmpty())\r
158         {\r
159                 CPDF_Rect rcTemp = rcClip;\r
160                 pUser2Device->TransformRect(rcTemp);\r
161                 FX_RECT rcDevClip;\r
162                 rcDevClip.left = (FX_INT32)rcTemp.left;\r
163                 rcDevClip.right = (FX_INT32)rcTemp.right;\r
164                 rcDevClip.top = (FX_INT32)rcTemp.top;\r
165                 rcDevClip.bottom = (FX_INT32)rcTemp.bottom;\r
166                 pDevice->SetClip_Rect(&rcDevClip);\r
167         }\r
168 \r
169         if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
170         {\r
171                 if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())\r
172                 {\r
173                         if (pRange)\r
174                                 pIterator->SetAt(pRange->BeginPos);\r
175                         else\r
176                                 pIterator->SetAt(0);\r
177 \r
178                         CPVT_WordPlace oldplace;                        \r
179 \r
180                         while (pIterator->NextWord())\r
181                         {\r
182                                 CPVT_WordPlace place = pIterator->GetAt();\r
183                                 if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
184 \r
185                                 if (wrSelect.IsExist())\r
186                                 {\r
187                                         bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && place.WordCmp(wrSelect.EndPos) <= 0;\r
188                                         if (bSelect)\r
189                                         {                                               \r
190                                                 crCurFill = crWhite;                                            \r
191                                         }\r
192                                         else\r
193                                         {\r
194                                                 crCurFill = crTextFill;\r
195                                         }\r
196                                 }\r
197                                 if(pSystemHandler && pSystemHandler->IsSelectionImplemented())  \r
198                                 {\r
199                                         crCurFill = crTextFill;\r
200                                         crOldFill = crCurFill;\r
201                                 }\r
202                                 CPVT_Word word;                         \r
203                                 if (pIterator->GetWord(word))\r
204                                 {\r
205 \r
206                                         if (bSelect)\r
207                                         {\r
208                                                 \r
209                                                 CPVT_Line line;\r
210                                                 pIterator->GetLine(line);\r
211 \r
212                                                 if(pSystemHandler && pSystemHandler->IsSelectionImplemented())\r
213                                                 {\r
214                                                         CPDF_Rect rc(word.ptWord.x,line.ptLine.y + line.fLineDescent,\r
215                                                                 word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);\r
216                                                         rc.Intersect(rcClip);\r
217                                                         //CFX_Edit* pEt = (CFX_Edit*)pEdit;\r
218                                                         //CPDF_Rect rcEdit = pEt->VTToEdit(rc);\r
219                                                         pSystemHandler->OutputSelectedRect(pFFLData,rc);\r
220                                                 }\r
221                                                 else\r
222                                                 {       \r
223                                                         CFX_PathData pathSelBK;\r
224                                                         pathSelBK.AppendRect(word.ptWord.x,line.ptLine.y + line.fLineDescent,\r
225                                                                 word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);\r
226                                                         \r
227                                                         pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0, FXFILL_WINDING);  \r
228                                                 }\r
229                                         }\r
230 \r
231                                         if (bContinuous)\r
232                                         {\r
233                                                 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex || \r
234                                                         crOldFill != crCurFill)\r
235                                                 {\r
236                                                         if (sTextBuf.GetLength() > 0)\r
237                                                         {                                                               \r
238                                                                 DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(nFontIndex),\r
239                                                                         fFontSize, pUser2Device, sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);\r
240 \r
241                                                                 sTextBuf.Clear();\r
242                                                         }\r
243                                                         nFontIndex = word.nFontIndex;\r
244                                                         ptBT = word.ptWord;\r
245                                                         crOldFill = crCurFill;\r
246                                                 }\r
247 \r
248                                                 sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord);                                            \r
249                                         }\r
250                                         else\r
251                                         {\r
252                                                 DrawTextString(pDevice,CPDF_Point(word.ptWord.x+ptOffset.x, word.ptWord.y+ptOffset.y), pFontMap->GetPDFFont(word.nFontIndex),\r
253                                                         fFontSize, pUser2Device, GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord), crCurFill, crTextStroke, nHorzScale);\r
254 \r
255                                         }\r
256                                         oldplace = place;\r
257 \r
258 \r
259                                 }\r
260                         }\r
261 \r
262                         if (sTextBuf.GetLength() > 0)\r
263                         {                               \r
264                                 DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(nFontIndex),\r
265                                         fFontSize, pUser2Device, sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);\r
266                         }                       \r
267                 }\r
268         }\r
269         \r
270         pDevice->RestoreState();\r
271 }\r
272 \r
273 void IFX_Edit::DrawRichEdit(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit,  \r
274                                                 const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange)\r
275 {\r
276         //FX_FLOAT fFontSize = pEdit->GetFontSize();\r
277         CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();\r
278 \r
279         FX_COLORREF crCurText = ArgbEncode(255, 0,0,0);\r
280         FX_COLORREF crOld = crCurText;\r
281         FX_BOOL bSelect = FALSE;\r
282         const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);\r
283         const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);\r
284 \r
285         CFX_ByteTextBuf sTextBuf;\r
286         CPVT_WordProps wp;\r
287         CPDF_Point ptBT(0.0f,0.0f);\r
288 \r
289         pDevice->SaveState();\r
290 \r
291         if (!rcClip.IsEmpty())\r
292         {\r
293                 CPDF_Rect rcTemp = rcClip;\r
294                 pUser2Device->TransformRect(rcTemp);\r
295                 FX_RECT rcDevClip;\r
296                 rcDevClip.left = (FX_INT32)rcTemp.left;\r
297                 rcDevClip.right = (FX_INT32)rcTemp.right;\r
298                 rcDevClip.top = (FX_INT32)rcTemp.top;\r
299                 rcDevClip.bottom = (FX_INT32)rcTemp.bottom;\r
300                 pDevice->SetClip_Rect(&rcDevClip);\r
301         }\r
302 \r
303         if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
304         {\r
305                 if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())\r
306                 {\r
307                         if (pRange)\r
308                                 pIterator->SetAt(pRange->BeginPos);\r
309                         else\r
310                                 pIterator->SetAt(0);\r
311 \r
312                         CPVT_WordPlace oldplace;                        \r
313 \r
314                         while (pIterator->NextWord())\r
315                         {\r
316                                 CPVT_WordPlace place = pIterator->GetAt();\r
317                                 if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
318                                 \r
319                                 CPVT_Word word;                         \r
320                                 if (pIterator->GetWord(word))\r
321                                 {\r
322                                         word.WordProps.fFontSize = word.fFontSize;\r
323 \r
324                                         crCurText = ArgbEncode(255,word.WordProps.dwWordColor);\r
325 \r
326                                         if (wrSelect.IsExist())\r
327                                         {\r
328                                                 bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && place.WordCmp(wrSelect.EndPos) <= 0;\r
329                                                 if (bSelect)\r
330                                                 {                                               \r
331                                                         crCurText = crWhite;\r
332                                                 }\r
333                                         }\r
334 \r
335                                         if (bSelect)\r
336                                         {\r
337                                                 CPVT_Line line;\r
338                                                 pIterator->GetLine(line);\r
339 \r
340                                                 CFX_PathData pathSelBK;\r
341                                                 pathSelBK.AppendRect(word.ptWord.x              + ptOffset.x,\r
342                                                         line.ptLine.y + line.fLineDescent       + ptOffset.y,\r
343                                                         word.ptWord.x+word.fWidth                       + ptOffset.x,\r
344                                                         line.ptLine.y + line.fLineAscent        + ptOffset.y);\r
345 \r
346                                                 pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0, FXFILL_WINDING);                                                                                          \r
347                                         }\r
348 \r
349                                         if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || word.WordProps.nHorzScale != 100 || \r
350                                                 FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 || \r
351                                                 crOld != crCurText)\r
352                                         {\r
353                                                 if (sTextBuf.GetLength() > 0)\r
354                                                 {                                                               \r
355                                                         DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(wp.nFontIndex),\r
356                                                                 wp.fFontSize, pUser2Device, sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);\r
357 \r
358                                                         sTextBuf.Clear();\r
359                                                 }\r
360                                                 wp = word.WordProps;\r
361                                                 ptBT = word.ptWord;\r
362                                                 crOld = crCurText;\r
363                                         }\r
364 \r
365                                         sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, word.Word, 0);        \r
366                                         \r
367                                         if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE)\r
368                                         {\r
369                                                 CFX_PathData pathUnderline;\r
370                                                 CPDF_Rect rcUnderline = GetUnderLineRect(word);\r
371                                                 pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, rcUnderline.right, rcUnderline.top);\r
372 \r
373                                                 pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, crCurText, 0, FXFILL_WINDING);    \r
374                                         }\r
375 \r
376                                         if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT)\r
377                                         {\r
378                                                 CFX_PathData pathCrossout;\r
379                                                 CPDF_Rect rcCrossout = GetCrossoutRect(word);\r
380                                                 pathCrossout.AppendRect(rcCrossout.left, rcCrossout.bottom, rcCrossout.right, rcCrossout.top);\r
381 \r
382                                                 pDevice->DrawPath(&pathCrossout, pUser2Device, NULL, crCurText, 0, FXFILL_WINDING);\r
383                                         }\r
384 \r
385                                         oldplace = place;                                       \r
386                                 }\r
387                         }\r
388 \r
389                         if (sTextBuf.GetLength() > 0)\r
390                         {                               \r
391                                 DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(wp.nFontIndex),\r
392                                         wp.fFontSize, pUser2Device, sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);\r
393                         }\r
394                 }\r
395         }\r
396         \r
397         pDevice->RestoreState();\r
398 }\r
399 \r
400 static void AddLineToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crStroke, \r
401                                                                  const CPDF_Point& pt1, const CPDF_Point& pt2)\r
402 {\r
403         CPDF_PathObject* pPathObj = new CPDF_PathObject;\r
404         CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();\r
405 \r
406         pPathData->SetPointCount(2);\r
407         pPathData->SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);\r
408         pPathData->SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);\r
409 \r
410         FX_FLOAT rgb[3];\r
411         rgb[0] = FXARGB_R(crStroke) / 255.0f;\r
412         rgb[1] = FXARGB_G(crStroke) / 255.0f;\r
413         rgb[2] = FXARGB_B(crStroke) / 255.0f;\r
414         pPathObj->m_ColorState.SetStrokeColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);\r
415 \r
416         CFX_GraphStateData* pData = pPathObj->m_GraphState.GetModify();\r
417         pData->m_LineWidth = 1;\r
418 \r
419         pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pPathObj);\r
420 }\r
421 \r
422 static void AddRectToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crFill, const CPDF_Rect& rcFill)\r
423 {\r
424         CPDF_PathObject* pPathObj = new CPDF_PathObject;\r
425         CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();\r
426         pPathData->AppendRect(rcFill.left,rcFill.bottom,rcFill.right,rcFill.top);       \r
427         \r
428         FX_FLOAT rgb[3];\r
429         rgb[0] = FXARGB_R(crFill) / 255.0f ;\r
430         rgb[1] = FXARGB_G(crFill) / 255.0f;\r
431         rgb[2] = FXARGB_B(crFill) / 255.0f;\r
432         pPathObj->m_ColorState.SetFillColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);\r
433 \r
434         pPathObj->m_FillType = FXFILL_ALTERNATE;\r
435         pPathObj->m_bStroke = FALSE;\r
436 \r
437         pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pPathObj);\r
438 }\r
439 \r
440 static CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crText, \r
441                                                          CPDF_Font* pFont, FX_FLOAT fFontSize, FX_FLOAT fCharSpace, FX_INT32 nHorzScale, \r
442                                                          const CPDF_Point& point, const CFX_ByteString& text)\r
443 {\r
444         CPDF_TextObject* pTxtObj = new CPDF_TextObject;\r
445                         \r
446         CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();\r
447         pTextStateData->m_pFont = pFont;\r
448         pTextStateData->m_FontSize = fFontSize;\r
449         pTextStateData->m_CharSpace = fCharSpace;\r
450         pTextStateData->m_WordSpace = 0;\r
451         pTextStateData->m_TextMode  = 0;\r
452         pTextStateData->m_Matrix[0] = nHorzScale / 100.0f;\r
453         pTextStateData->m_Matrix[1] = 0;\r
454         pTextStateData->m_Matrix[2] = 0;\r
455         pTextStateData->m_Matrix[3] = 1;\r
456 \r
457         FX_FLOAT rgb[3];\r
458         rgb[0] = FXARGB_R(crText) / 255.0f ;\r
459         rgb[1] = FXARGB_G(crText) / 255.0f;\r
460         rgb[2] = FXARGB_B(crText) / 255.0f;\r
461         pTxtObj->m_ColorState.SetFillColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB),rgb, 3);\r
462         pTxtObj->m_ColorState.SetStrokeColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB),rgb, 3);\r
463 \r
464         pTxtObj->SetPosition(point.x,point.y);\r
465         pTxtObj->SetText(text); \r
466 \r
467         pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pTxtObj);\r
468 \r
469         return pTxtObj;\r
470 }\r
471 \r
472 /*\r
473 List of currently supported standard fonts:\r
474 Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique\r
475 Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique\r
476 Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic\r
477 Symbol, ZapfDingbats\r
478 */\r
479 \r
480 const char* g_sFXEDITStandardFontName[] = {"Courier", "Courier-Bold", "Courier-BoldOblique", "Courier-Oblique",\r
481         "Helvetica", "Helvetica-Bold", "Helvetica-BoldOblique", "Helvetica-Oblique",\r
482         "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",\r
483         "Symbol", "ZapfDingbats"};\r
484 \r
485 static FX_BOOL FX_EDIT_IsStandardFont(const CFX_ByteString& sFontName)\r
486 {\r
487         for (FX_INT32 i=0; i<14; i++)\r
488         {\r
489                 if (sFontName == g_sFXEDITStandardFontName[i])\r
490                         return TRUE;\r
491         }\r
492 \r
493         return FALSE;\r
494 }\r
495 \r
496 void IFX_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,\r
497                                                                    const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, FX_COLORREF crText, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)\r
498 {\r
499         FX_FLOAT fFontSize = pEdit->GetFontSize();\r
500 \r
501         FX_INT32 nOldFontIndex = -1;\r
502 \r
503         CFX_ByteTextBuf sTextBuf;\r
504         CPDF_Point ptBT(0.0f,0.0f);\r
505 \r
506         ObjArray.RemoveAll();\r
507 \r
508         if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
509         {\r
510                 if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())\r
511                 {\r
512                         if (pRange)\r
513                                 pIterator->SetAt(pRange->BeginPos);\r
514                         else\r
515                                 pIterator->SetAt(0);\r
516 \r
517                         CPVT_WordPlace oldplace;                        \r
518 \r
519                         while (pIterator->NextWord())\r
520                         {\r
521                                 CPVT_WordPlace place = pIterator->GetAt();\r
522                                 if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
523                                 \r
524                                 CPVT_Word word;                         \r
525                                 if (pIterator->GetWord(word))\r
526                                 {\r
527                                         if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex)\r
528                                         {\r
529                                                 if (sTextBuf.GetLength() > 0)\r
530                                                 {\r
531                                                         ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, 0.0f, 100,\r
532                                                                 CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));\r
533 \r
534                                                         sTextBuf.Clear();\r
535                                                 }\r
536 \r
537                                                 ptBT = word.ptWord;\r
538                                                 nOldFontIndex = word.nFontIndex;\r
539                                         }\r
540 \r
541                                         sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0);\r
542                                         oldplace = place;                                       \r
543                                 }\r
544                         }\r
545 \r
546                         if (sTextBuf.GetLength() > 0)\r
547                         {                               \r
548                                 ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, 0.0f, 100,\r
549                                         CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));\r
550                         }\r
551                 }\r
552         }\r
553 }\r
554 \r
555 void IFX_Edit::GenerateRichPageObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,\r
556                                                                    const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)\r
557 {\r
558 \r
559 \r
560         FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);\r
561         FX_COLORREF crOld = crCurText;\r
562 \r
563 \r
564         CFX_ByteTextBuf sTextBuf;\r
565         CPVT_WordProps wp;\r
566         CPDF_Point ptBT(0.0f,0.0f);\r
567 \r
568         ObjArray.RemoveAll();\r
569 \r
570         if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
571         {\r
572                 if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())\r
573                 {\r
574                         if (pRange)\r
575                                 pIterator->SetAt(pRange->BeginPos);\r
576                         else\r
577                                 pIterator->SetAt(0);\r
578 \r
579                         CPVT_WordPlace oldplace;                        \r
580 \r
581                         while (pIterator->NextWord())\r
582                         {\r
583                                 CPVT_WordPlace place = pIterator->GetAt();\r
584                                 if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
585                                 \r
586                                 CPVT_Word word;                         \r
587                                 if (pIterator->GetWord(word))\r
588                                 {\r
589                                         word.WordProps.fFontSize = word.fFontSize;\r
590 \r
591                                         crCurText = ArgbEncode(255,word.WordProps.dwWordColor);\r
592 \r
593                                         if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || word.WordProps.nHorzScale != 100 || \r
594                                                 FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 || \r
595                                                 crOld != crCurText)\r
596                                         {\r
597                                                 if (sTextBuf.GetLength() > 0)\r
598                                                 {\r
599                                                         ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, wp.fCharSpace, wp.nHorzScale,\r
600                                                                 CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));\r
601 \r
602                                                         sTextBuf.Clear();\r
603                                                 }\r
604 \r
605                                                 wp = word.WordProps;\r
606                                                 ptBT = word.ptWord;\r
607                                                 crOld = crCurText;\r
608         \r
609                                         }\r
610 \r
611                                         sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, word.Word, 0);        \r
612                                         \r
613                                         if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE)\r
614                                         {/*\r
615                                                 AddLineToPageObjects(pPageObjects, crCurText, \r
616                                                         CPDF_Point(word.ptWord.x, word.ptWord.y + word.fDescent * 0.4f),\r
617                                                         CPDF_Point(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent * 0.4f));                                                 \r
618 */\r
619                                                 CPDF_Rect rcUnderline = GetUnderLineRect(word);\r
620                                                 rcUnderline.left += ptOffset.x;\r
621                                                 rcUnderline.right += ptOffset.x;\r
622                                                 rcUnderline.top += ptOffset.y;\r
623                                                 rcUnderline.bottom += ptOffset.y;\r
624                                                 \r
625                                                 AddRectToPageObjects(pPageObjects, crCurText, rcUnderline);                                                     \r
626                                         }\r
627 \r
628                                         if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT)\r
629                                         {\r
630                                                 CPDF_Rect rcCrossout = GetCrossoutRect(word);\r
631                                                 rcCrossout.left += ptOffset.x;\r
632                                                 rcCrossout.right += ptOffset.x;\r
633                                                 rcCrossout.top += ptOffset.y;\r
634                                                 rcCrossout.bottom += ptOffset.y;\r
635 \r
636                                                 AddRectToPageObjects(pPageObjects, crCurText, rcCrossout);                                              \r
637                                         }\r
638 \r
639                                         oldplace = place;                                       \r
640                                 }\r
641                         }\r
642 \r
643                         if (sTextBuf.GetLength() > 0)\r
644                         {                               \r
645                                 ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, wp.fCharSpace, wp.nHorzScale,\r
646                                         CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));\r
647                         }\r
648                 }\r
649         }\r
650 }\r
651 \r
652 void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,\r
653                                                                    const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, FX_COLORREF color)\r
654 {\r
655 \r
656 \r
657         if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())\r
658         {\r
659                 if (pEdit->GetFontMap())\r
660                 {\r
661                         if (pRange)\r
662                                 pIterator->SetAt(pRange->BeginPos);\r
663                         else\r
664                                 pIterator->SetAt(0);\r
665 \r
666                         CPVT_WordPlace oldplace;                        \r
667 \r
668                         while (pIterator->NextWord())\r
669                         {\r
670                                 CPVT_WordPlace place = pIterator->GetAt();\r
671                                 if (pRange && place.WordCmp(pRange->EndPos) > 0) break;\r
672                                 \r
673                                 CPVT_Word word;                         \r
674                                 if (pIterator->GetWord(word))\r
675                                 {\r
676                                         CPDF_Rect rcUnderline = GetUnderLineRect(word);\r
677                                         rcUnderline.left += ptOffset.x;\r
678                                         rcUnderline.right += ptOffset.x;\r
679                                         rcUnderline.top += ptOffset.y;\r
680                                         rcUnderline.bottom += ptOffset.y;\r
681                                         AddRectToPageObjects(pPageObjects, color, rcUnderline);\r
682                                 }\r
683                         }\r
684                 }\r
685         }\r
686 }\r
687 \r