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/reflow/reflowengine.h"
8 #include "reflowedpage.h"
CPDF_ProgressiveReflowPageParser()9 CPDF_ProgressiveReflowPageParser::CPDF_ProgressiveReflowPageParser()
10 {
11 m_nObjProcessed = 0;
12 m_pReflowEngine = NULL;
13 m_pProvider = NULL;
14 }
~CPDF_ProgressiveReflowPageParser()15 CPDF_ProgressiveReflowPageParser::~CPDF_ProgressiveReflowPageParser()
16 {
17 if(m_pProvider) {
18 delete m_pProvider;
19 }
20 m_pProvider = NULL;
21 if(m_pReflowEngine) {
22 delete m_pReflowEngine;
23 }
24 m_pReflowEngine = NULL;
25 }
Init()26 void CPDF_ProgressiveReflowPageParser::Init()
27 {
28 m_Status = Ready;
29 }
CPDF_ReflowedPage(CFX_GrowOnlyPool * pMemoryPool)30 CPDF_ReflowedPage::CPDF_ReflowedPage(CFX_GrowOnlyPool* pMemoryPool)
31 {
32 m_PageWidth = 0;
33 m_PageHeight = 0;
34 m_bWaiting = TRUE;
35 if(pMemoryPool) {
36 m_pMemoryPool = pMemoryPool;
37 m_bCreateMemoryPool = FALSE;
38 } else {
39 m_pMemoryPool = new CFX_GrowOnlyPool;
40 m_bCreateMemoryPool = TRUE;
41 }
42 m_pCharState = new CRF_CharStateArray(10);
43 m_pReflowed = new CRF_DataPtrArray(500);
44 m_pPageInfos = NULL;
45 }
~CPDF_ReflowedPage()46 CPDF_ReflowedPage::~CPDF_ReflowedPage()
47 {
48 if (m_pReflowed) {
49 for(int i = 0; i < m_pReflowed->GetSize(); i++) {
50 CRF_Data* pData = (*m_pReflowed)[i];
51 if(pData->m_Type == CRF_Data::Image) {
52 delete ((CRF_ImageData*)pData)->m_pBitmap;
53 }
54 }
55 m_pReflowed->RemoveAll();
56 delete m_pReflowed;
57 }
58 m_pReflowed = NULL;
59 if (m_pCharState) {
60 m_pCharState->RemoveAll();
61 delete m_pCharState;
62 }
63 m_pCharState = NULL;
64 if(m_bCreateMemoryPool && m_pMemoryPool) {
65 m_pMemoryPool->FreeAll();
66 }
67 if (m_pMemoryPool) {
68 delete m_pMemoryPool;
69 }
70 m_pMemoryPool = NULL;
71 m_pPDFPage = NULL;
72 if (m_pPageInfos) {
73 ReleasePageObjsMemberShip();
74 }
75 }
RetainPageObjsMemberShip()76 FX_BOOL CPDF_ReflowedPage::RetainPageObjsMemberShip()
77 {
78 if (NULL == m_pPDFPage) {
79 return FALSE;
80 }
81 if (NULL == m_pPageInfos) {
82 m_pPageInfos = new CFX_MapPtrToPtr();
83 } else {
84 return TRUE;
85 }
86 FX_POSITION pos = m_pPDFPage->GetFirstObjectPosition();
87 if (!pos) {
88 return FALSE;
89 }
90 CPDF_PageObject* pPageObj = NULL;
91 while (pos) {
92 pPageObj = m_pPDFPage->GetNextObject(pos);
93 MarkPageObjMemberShip(pPageObj, NULL);
94 pPageObj = NULL;
95 }
96 return TRUE;
97 }
MarkPageObjMemberShip(CPDF_PageObject * pObj,CRF_PageInfo * pParent)98 void CPDF_ReflowedPage::MarkPageObjMemberShip(CPDF_PageObject* pObj, CRF_PageInfo* pParent)
99 {
100 if (NULL == m_pPageInfos) {
101 return;
102 }
103 CRF_PageInfo* pPageInfo = new CRF_PageInfo(pObj, pParent);
104 m_pPageInfos->SetAt(pObj, pPageInfo);
105 if (PDFPAGE_FORM != pObj->m_Type) {
106 return;
107 }
108 CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj;
109 FX_POSITION pos;
110 pos = pFormObj->m_pForm->GetFirstObjectPosition();
111 if (!pos) {
112 return;
113 }
114 CPDF_PageObject* pPageObj = NULL;
115 while (pos) {
116 pPageObj = pFormObj->m_pForm->GetNextObject(pos);
117 MarkPageObjMemberShip(pPageObj, pPageInfo);
118 pPageObj = NULL;
119 }
120 }
ReleasePageObjsMemberShip()121 void CPDF_ReflowedPage::ReleasePageObjsMemberShip()
122 {
123 if (NULL == m_pPageInfos) {
124 return;
125 }
126 CPDF_PageObject* pPageObj = NULL;
127 CRF_PageInfo* pPageInfo = NULL;
128 FX_POSITION pos = m_pPageInfos->GetStartPosition();
129 while (pos) {
130 m_pPageInfos->GetNextAssoc(pos, (void*&)pPageObj, (void*&)pPageInfo);
131 delete pPageInfo;
132 }
133 m_pPageInfos->RemoveAll();
134 delete m_pPageInfos;
135 m_pPageInfos = NULL;
136 }
GetFormResDict(CPDF_PageObject * pObj)137 CPDF_Dictionary* CPDF_ReflowedPage::GetFormResDict(CPDF_PageObject* pObj)
138 {
139 if (NULL == m_pPageInfos) {
140 return NULL;
141 }
142 if (FALSE == RetainPageObjsMemberShip()) {
143 return NULL;
144 }
145 CRF_PageInfo* pPageInfo = (CRF_PageInfo*)m_pPageInfos->GetValueAt(pObj);
146 if (NULL == pPageInfo) {
147 return NULL;
148 }
149 return pPageInfo->GetFormDict();
150 }
GetDisplayMatrix(CFX_AffineMatrix & matrix,FX_INT32 xPos,FX_INT32 yPos,FX_INT32 xSize,FX_INT32 ySize,FX_INT32 iRotate,const CFX_AffineMatrix * pPageMatrix)151 void CPDF_ReflowedPage::GetDisplayMatrix(CFX_AffineMatrix& matrix, FX_INT32 xPos, FX_INT32 yPos, FX_INT32 xSize, FX_INT32 ySize, FX_INT32 iRotate, const CFX_AffineMatrix* pPageMatrix)
152 {
153 CFX_AffineMatrix display_matrix;
154 if(m_PageHeight == 0) {
155 matrix.Set(1, 0, 0, -1, 0, 0);
156 return;
157 }
158 FX_INT32 x0, y0, x1, y1, x2, y2;
159 iRotate %= 4;
160 switch (iRotate) {
161 case 0:
162 x0 = xPos;
163 y0 = yPos;
164 x1 = xPos;
165 y1 = yPos + ySize;
166 x2 = xPos + xSize;
167 y2 = yPos;
168 break;
169 case 3:
170 x0 = xPos;
171 y0 = ySize + yPos;
172 x1 = xPos + xSize;
173 y1 = yPos + ySize;
174 x2 = xPos;
175 y2 = yPos;
176 break;
177 case 2:
178 x0 = xSize + xPos;
179 y0 = ySize + yPos;
180 x1 = xSize + xPos ;
181 y1 = yPos;
182 x2 = xPos;
183 y2 = ySize + yPos;
184 break;
185 case 1:
186 x0 = xPos + xSize;
187 y0 = yPos;
188 x1 = xPos;
189 y1 = yPos;
190 x2 = xPos + xSize;
191 y2 = yPos + ySize;
192 break;
193 }
194 display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth),
195 FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth),
196 FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight),
197 FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight),
198 (FX_FLOAT)(x0), (FX_FLOAT)(y0));
199 matrix.Set(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
200 matrix.Concat(display_matrix);
201 return;
202 }
GetPageHeight()203 FX_FLOAT CPDF_ReflowedPage::GetPageHeight()
204 {
205 return m_PageHeight;
206 }
FocusGetData(const CFX_AffineMatrix matrix,FX_INT32 x,FX_INT32 y,CFX_ByteString & str)207 void CPDF_ReflowedPage::FocusGetData(const CFX_AffineMatrix matrix, FX_INT32 x, FX_INT32 y, CFX_ByteString& str)
208 {
209 if (NULL == m_pReflowed) {
210 return;
211 }
212 CFX_AffineMatrix revMatrix;
213 revMatrix.SetReverse(matrix);
214 FX_FLOAT x1, y1;
215 revMatrix.Transform((float)x, (float)y, x1, y1);
216 int count = m_pReflowed->GetSize();
217 FX_FLOAT dx = 1000, dy = 1000;
218 FX_INT32 pos = 0;
219 FX_INT32 i;
220 for(i = 0; i < count; i++) {
221 CRF_Data* pData = (*m_pReflowed)[i];
222 FX_FLOAT tempdy = FXSYS_fabs(pData->m_PosY - y1);
223 if(FXSYS_fabs(tempdy - dy) < 1) {
224 continue;
225 }
226 CFX_FloatRect rect (0, pData->m_PosY + pData->m_Height, this->m_PageWidth, pData->m_PosY);
227 if(rect.Contains(x1, y1)) {
228 pos = i;
229 dx = 0;
230 dy = 0;
231 break;
232 } else if(tempdy < dy) {
233 dy = tempdy;
234 dx = FXSYS_fabs(pData->m_PosX - x1);
235 pos = i;
236 } else if (tempdy == dy) {
237 FX_FLOAT tempdx = FXSYS_fabs(pData->m_PosX - x1);
238 if(tempdx < dx) {
239 dx = tempdx;
240 pos = i;
241 }
242 } else if (tempdy > dy) {
243 break;
244 }
245 }
246 if(dx != 0 || dy != 0) {
247 count = count < (pos + 10) ? count : (pos + 10);
248 for(i = 0 > (pos - 10) ? 0 : (pos - 10); i < count; i++) {
249 CRF_Data* pData = (*m_pReflowed)[i];
250 FX_FLOAT tempdy = FXSYS_fabs(pData->m_PosY - y1);
251 if(tempdy < dy) {
252 dy = tempdy;
253 dx = FXSYS_fabs(pData->m_PosX - x1);
254 pos = i;
255 } else if (tempdy == dy) {
256 FX_FLOAT tempdx = FXSYS_fabs(pData->m_PosX - x1);
257 if(tempdx < dx) {
258 dx = tempdx;
259 pos = i;
260 }
261 }
262 }
263 }
264 str.Format("%d", pos);
265 }
FocusGetPosition(const CFX_AffineMatrix matrix,CFX_ByteString str,FX_INT32 & x,FX_INT32 & y)266 FX_BOOL CPDF_ReflowedPage::FocusGetPosition(const CFX_AffineMatrix matrix, CFX_ByteString str, FX_INT32& x, FX_INT32& y)
267 {
268 if (NULL == m_pReflowed) {
269 return FALSE;
270 }
271 FX_INT32 pos = FXSYS_atoi(str);
272 if(pos < 0 || pos >= m_pReflowed->GetSize()) {
273 return FALSE;
274 }
275 CRF_Data* pData = (*m_pReflowed)[pos];
276 FX_FLOAT x1, y1;
277 matrix.Transform(pData->m_PosX, pData->m_PosY + pData->m_Height, x1, y1);
278 x = (int)x1;
279 y = (int)y1;
280 return TRUE;
281 }
GetPosition()282 int CPDF_ProgressiveReflowPageParser::GetPosition()
283 {
284 if(!m_pProvider) {
285 return 0;
286 }
287 if(!m_pReflowEngine) {
288 return m_pProvider->GetPosition() / 2;
289 }
290 return m_pProvider->GetPosition() / 2 + m_pReflowEngine->GetPosition() / 2;
291 }
Continue(IFX_Pause * pPause)292 void CPDF_ProgressiveReflowPageParser::Continue(IFX_Pause* pPause)
293 {
294 if (NULL == m_pReflowPage) {
295 return;
296 }
297 if(m_Status != ToBeContinued) {
298 return;
299 }
300 m_pPause = pPause;
301 if(m_pReflowEngine) {
302 if(m_pReflowEngine->Continue() != LayoutToBeContinued) {
303 m_Status = Done;
304 }
305 } else {
306 if(m_pProvider->Continue() == LayoutFinished) {
307 m_pReflowEngine = IPDF_LayoutProcessor::Create_LayoutProcessor_Reflow(m_TopIndent, m_ReflowedWidth, m_fScreenHeight, m_pReflowPage, m_flags, m_ParseStyle.m_LineSpace);
308 CFX_AffineMatrix matrix;
309 m_pPDFPage->GetDisplayMatrix(matrix, 0, 0, (int)(m_pPDFPage->GetPageWidth()), (int)(m_pPDFPage->GetPageHeight()), 0);
310 if(m_pReflowEngine->StartProcess(m_pProvider->GetRoot(), m_pPause, &matrix) != LayoutToBeContinued) {
311 m_Status = Done;
312 }
313 }
314 }
315 if(m_TopIndent && m_Status == Done) {
316 m_pReflowPage->m_PageHeight -= m_TopIndent;
317 }
318 }
Clear()319 void CPDF_ProgressiveReflowPageParser::Clear()
320 {
321 this->Init();
322 return;
323 }
IsTaggedPage(CPDF_PageObjects * pPage)324 FX_BOOL IPDF_ProgressiveReflowPageParser::IsTaggedPage(CPDF_PageObjects*pPage)
325 {
326 if(!pPage) {
327 return FALSE;
328 }
329 CPDF_StructTree* pPageTree = CPDF_StructTree::LoadPage(pPage->m_pDocument, pPage->m_pFormDict);
330 if(pPageTree) {
331 int count = pPageTree->CountTopElements();
332 if(count) {
333 for(int i = 0; i < count; i++) {
334 CPDF_StructElement* pElm = pPageTree->GetTopElement(i);
335 if(pElm) {
336 delete pPageTree;
337 pPageTree = NULL;
338 return TRUE;
339 }
340 }
341 }
342 delete pPageTree;
343 pPageTree = NULL;
344 return FALSE;
345 }
346 return FALSE;
347 }
Start(IPDF_ReflowedPage * pReflowPage,CPDF_Page * pPage,FX_FLOAT topIndent,FX_FLOAT fWidth,FX_FLOAT fHeight,IFX_Pause * pPause,int flags)348 void CPDF_ProgressiveReflowPageParser::Start(IPDF_ReflowedPage* pReflowPage, CPDF_Page* pPage, FX_FLOAT topIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, IFX_Pause* pPause, int flags)
349 {
350 if (NULL == pReflowPage) {
351 m_Status = Failed;
352 return;
353 }
354 m_flags = flags;
355 m_pReflowPage = (CPDF_ReflowedPage*)pReflowPage;
356 m_pReflowPage->m_pPDFPage = pPage;
357 m_pReflowPage->ReleasePageObjsMemberShip();
358 m_pPDFPage = pPage;
359 m_TopIndent = topIndent;
360 m_pPause = pPause;
361 m_fScreenHeight = fHeight;
362 m_ReflowedWidth = fWidth;
363 m_pProvider = IPDF_LayoutProvider::Create_LayoutProvider_TaggedPDF(m_pPDFPage);
364 LayoutStatus status = m_pProvider->StartLoad(pPause);
365 if(status == LayoutError) {
366 delete m_pProvider;
367 m_pProvider = IPDF_LayoutProvider::Create_LayoutProvider_AutoReflow(m_pPDFPage, m_flags & RF_PARSER_READERORDER);
368 if (NULL == m_pProvider) {
369 m_Status = Failed;
370 return;
371 }
372 status = m_pProvider->StartLoad(pPause);
373 }
374 if(status == LayoutError) {
375 delete m_pProvider;
376 m_pProvider = NULL;
377 m_Status = Failed;
378 return;
379 }
380 if(status == LayoutToBeContinued) {
381 m_Status = ToBeContinued;
382 } else if (status == LayoutFinished) {
383 m_pReflowEngine = IPDF_LayoutProcessor::Create_LayoutProcessor_Reflow(topIndent, fWidth, fHeight, pReflowPage, m_flags, m_ParseStyle.m_LineSpace);
384 if(NULL == m_pReflowEngine) {
385 delete m_pProvider;
386 m_pProvider = NULL;
387 m_Status = Failed;
388 return;
389 }
390 CFX_AffineMatrix matrix;
391 pPage->GetDisplayMatrix(matrix, 0, 0, (int)(pPage->GetPageWidth()), (int)(pPage->GetPageHeight()), 0);
392 CFX_AffineMatrix matrix1 = pPage->GetPageMatrix();
393 if((status = m_pReflowEngine->StartProcess(m_pProvider->GetRoot(), pPause, &matrix)) != LayoutToBeContinued) {
394 delete m_pReflowEngine;
395 m_pReflowEngine = NULL;
396 m_Status = Done;
397 } else {
398 m_Status = ToBeContinued;
399 }
400 }
401 if(status != LayoutToBeContinued) {
402 delete m_pProvider;
403 m_pProvider = NULL;
404 }
405 if(m_TopIndent && m_Status == Done) {
406 m_pReflowPage->m_PageHeight -= m_TopIndent;
407 }
408 return;
409 }
~CPDF_ProgressiveReflowPageRender()410 CPDF_ProgressiveReflowPageRender::~CPDF_ProgressiveReflowPageRender()
411 {
412 if(m_pDisplayMatrix) {
413 delete m_pDisplayMatrix;
414 }
415 m_pDisplayMatrix = NULL;
416 }
CPDF_ProgressiveReflowPageRender()417 CPDF_ProgressiveReflowPageRender::CPDF_ProgressiveReflowPageRender()
418 {
419 m_Status = Ready;
420 m_pReflowPage = NULL;
421 m_pDisplayMatrix = NULL;
422 m_CurrNum = 0;
423 m_pFontEncoding = NULL;
424 m_DisplayColor = -1;
425 }
_CIDTransformToFloat(FX_BYTE ch)426 static FX_FLOAT _CIDTransformToFloat(FX_BYTE ch)
427 {
428 if (ch < 128) {
429 return ch * 1.0f / 127;
430 }
431 return (-255 + ch) * 1.0f / 127;
432 }
GetPosition()433 int CPDF_ProgressiveReflowPageRender::GetPosition()
434 {
435 if(m_CurrNum == 0 || NULL == m_pReflowPage) {
436 return 0;
437 }
438 int size = m_pReflowPage->m_pReflowed->GetSize();
439 if(size == 0 || m_CurrNum >= size) {
440 return 100;
441 }
442 return (int)(m_CurrNum * 100 / size);
443 }
Display(IFX_Pause * pPause)444 void CPDF_ProgressiveReflowPageRender::Display(IFX_Pause* pPause)
445 {
446 if (NULL == m_pReflowPage) {
447 m_Status = Done;
448 return;
449 }
450 FX_RECT clipBox = m_pFXDevice->GetClipBox();
451 int size = m_pReflowPage->m_pReflowed->GetSize();
452 if (size < 1 || NULL == m_pDisplayMatrix) {
453 m_Status = Done;
454 return;
455 }
456 for(int i = m_CurrNum; i < size; i++) {
457 CRF_Data* pData = (*m_pReflowPage->m_pReflowed)[i];
458 if(!pData) {
459 continue;
460 }
461 CFX_FloatRect rect (pData->m_PosX, pData->m_PosY + pData->m_Height, pData->m_PosX + pData->m_Width, pData->m_PosY);
462 m_pDisplayMatrix->TransformRect(rect);
463 if(rect.left > clipBox.right || rect.right < clipBox.left || rect.bottom > clipBox.bottom || rect.top < clipBox.top) {
464 continue;
465 }
466 if(pData->GetType() == CRF_Data::Text) {
467 CRF_CharData* pCharData = (CRF_CharData*)pData;
468 CPDF_Font* pPDFFont = pCharData->m_pCharState->m_pFont;
469 if(pPDFFont->GetFontType() == PDFFONT_TYPE3) {
470 continue;
471 }
472 FX_FLOAT x = pData->m_PosX, y = pData->m_PosY - pCharData->m_pCharState->m_fDescent;
473 FXTEXT_CHARPOS charpos ;
474 charpos.m_GlyphIndex = pPDFFont->GlyphFromCharCode(pCharData->m_CharCode);
475 charpos.m_FontCharWidth = pPDFFont->m_Font.GetGlyphWidth(charpos.m_GlyphIndex);
476 charpos.m_OriginX = x;
477 charpos.m_OriginY = y;
478 FX_FLOAT charW = pData->m_Width * 1000 / pData->m_Height;
479 if(charW != charpos.m_FontCharWidth) {
480 charpos.m_bGlyphAdjust = TRUE;
481 charpos.m_AdjustMatrix[0] = charW / charpos.m_FontCharWidth;
482 charpos.m_AdjustMatrix[1] = 0;
483 charpos.m_AdjustMatrix[2] = 0;
484 charpos.m_AdjustMatrix[3] = 1;
485 } else {
486 charpos.m_bGlyphAdjust = FALSE;
487 }
488 FX_BOOL bRet = FALSE;
489 if(m_DisplayColor == -1)
490 bRet = m_pFXDevice->DrawNormalText(1, &charpos, &(pPDFFont->m_Font),
491 NULL, pCharData->m_pCharState->m_fFontSize,
492 m_pDisplayMatrix, pCharData->m_pCharState->m_Color + 0xff000000, FXTEXT_CLEARTYPE);
493 else
494 bRet = m_pFXDevice->DrawNormalText(1, &charpos, &(pPDFFont->m_Font),
495 NULL, pCharData->m_pCharState->m_fFontSize, m_pDisplayMatrix, m_DisplayColor, FXTEXT_CLEARTYPE);
496 } else if(pData->GetType() == CRF_Data::Image) {
497 CRF_ImageData* pImageData = (CRF_ImageData*)pData;
498 if(!pImageData->m_pBitmap) {
499 continue;
500 }
501 int left = 0, top = 0;
502 CFX_DIBitmap* pDiBmp = NULL;
503 CFX_DIBSource* pDispSource = pImageData->m_pBitmap;
504 if(pImageData->m_Matrix.d < 0) {
505 CFX_AffineMatrix matrix(pImageData->m_Matrix.a, 0, 0, -pImageData->m_Matrix.d, 0, 0);
506 int left, top;
507 pDiBmp = pImageData->m_pBitmap->TransformTo(&matrix, left, top);
508 pDispSource = pDiBmp;
509 }
510 if (NULL == pDispSource) {
511 continue;
512 }
513 if (pDispSource->GetFormat() == FXDIB_1bppMask || pDispSource->GetFormat() == FXDIB_8bppMask) {
514 m_pFXDevice->StretchBitMask(pDispSource, (int)(rect.left + 0.5), (int)(rect.bottom + 0.5), (int)(rect.Width() + 0.5), (int)(rect.Height() + 0.5), 0xff000000);
515 } else {
516 m_pFXDevice->StretchDIBits(pDispSource, (int)(rect.left + 0.5), (int)(rect.bottom + 0.5), (int)(rect.Width() + 0.5), (int)(rect.Height() + 0.5));
517 }
518 if(m_pFXDevice->GetBitmap() && m_pFXDevice->GetBitmap()->GetFormat() == FXDIB_8bppRgb &&
519 m_pFXDevice->GetBitmap()->GetPalette() == NULL) {
520 int nPalette = 0;
521 switch(m_DitherBits) {
522 case 0:
523 nPalette = 0;
524 break;
525 case 1:
526 nPalette = 2;
527 break;
528 case 2:
529 nPalette = 4;
530 break;
531 case 3:
532 nPalette = 8;
533 break;
534 case 4:
535 nPalette = 16;
536 break;
537 case 5:
538 nPalette = 32;
539 break;
540 case 6:
541 nPalette = 64;
542 break;
543 case 7:
544 nPalette = 128;
545 break;
546 default:
547 nPalette = 256;
548 break;
549 }
550 if(nPalette >= 2) {
551 FX_ARGB * palette = FX_Alloc(FX_ARGB, nPalette);
552 nPalette --;
553 palette[0] = 0;
554 palette[nPalette] = 255;
555 FX_FLOAT Dither = (FX_FLOAT)255 / (nPalette);
556 for(int i = 1; i < nPalette; i++) {
557 palette[i] = (FX_ARGB)(Dither * i + 0.5);
558 }
559 FX_RECT tmpRect = rect.GetOutterRect();
560 m_pFXDevice->GetBitmap()->DitherFS(palette, nPalette + 1, &tmpRect);
561 FX_Free (palette);
562 }
563 }
564 if(pDiBmp) {
565 delete pDiBmp;
566 }
567 } else if(pData->GetType() == CRF_Data::Path) {
568 }
569 if(!(i % 10)) {
570 if(pPause && pPause->NeedToPauseNow()) {
571 i++;
572 m_CurrNum = i;
573 m_Status = ToBeContinued;
574 return;
575 }
576 }
577 }
578 m_CurrNum = size;
579 m_Status = Done;
580 }
Start(IPDF_ReflowedPage * pReflowPage,CFX_RenderDevice * pDevice,const CFX_AffineMatrix * pMatrix,IFX_Pause * pPause,int DitherBits)581 void CPDF_ProgressiveReflowPageRender::Start(IPDF_ReflowedPage* pReflowPage, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pMatrix, IFX_Pause* pPause, int DitherBits)
582 {
583 if(!pReflowPage || !pDevice || !pMatrix) {
584 m_Status = Failed;
585 return;
586 }
587 m_DitherBits = DitherBits;
588 m_Status = Ready;
589 m_CurrNum = 0;
590 m_pReflowPage = (CPDF_ReflowedPage*)pReflowPage;
591 m_pFXDevice = pDevice;
592 if(NULL == m_pDisplayMatrix) {
593 m_pDisplayMatrix = new CFX_AffineMatrix;
594 }
595 m_pDisplayMatrix->Copy(*pMatrix);
596 m_Status = ToBeContinued;
597 Display(pPause);
598 }
Continue(IFX_Pause * pPause)599 void CPDF_ProgressiveReflowPageRender::Continue(IFX_Pause* pPause)
600 {
601 Display(pPause);
602 }
SetDisplayColor(FX_COLORREF color)603 void CPDF_ProgressiveReflowPageRender::SetDisplayColor(FX_COLORREF color)
604 {
605 m_DisplayColor = color;
606 }
Clear()607 void CPDF_ProgressiveReflowPageRender::Clear()
608 {
609 if (m_pDisplayMatrix) {
610 delete m_pDisplayMatrix;
611 }
612 m_pDisplayMatrix = NULL;
613 m_pReflowPage = NULL;
614 m_pFXDevice = NULL;
615 m_CurrNum = 0;
616 m_Status = Ready;
617 }
618